GUI starting point

Change-Id: Ic7d23bfce0307c4b7cfc9fad9fb5834286ee195c
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..93f1361
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+node_modules
+npm-debug.log
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..1923d41
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,8 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..176a458
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fa28be8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.tmp/
+coverage/
+dist/
+node_modules/
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..28b50b1
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,6 @@
+[gerrit]
+host=gerrit.opencord.org
+port=29418
+project=xos-gui.git
+defaultremote=origin
+defaultbranch=master
diff --git a/.yo-rc.json b/.yo-rc.json
new file mode 100644
index 0000000..3e329b3
--- /dev/null
+++ b/.yo-rc.json
@@ -0,0 +1,21 @@
+{
+  "generator-fountain-angular2": {
+    "version": "1.0.0-rc1",
+    "props": {
+      "framework": "angular2",
+      "modules": "webpack",
+      "argv": {
+        "remain": [],
+        "cooked": [],
+        "original": []
+      },
+      "ci": [],
+      "css": "scss",
+      "resolved": "/usr/local/lib/node_modules/generator-fountain-webapp/node_modules/generator-fountain-angular2/generators/app/index.js",
+      "js": "typescript",
+      "namespace": "fountain-angular2",
+      "sample": "hello",
+      "router": "router"
+    }
+  }
+}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..e0551dd
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,28 @@
+# To build use: docker build -t xosproject/xos-gui .
+# To run use: docker run -p 80:80 -d xosproject/xos-gui
+
+FROM nginx
+
+# Set environment vars
+ENV CODE_SOURCE .
+ENV CODE_DEST /var/www
+ENV VHOST /usr/share/nginx/html
+
+# Install nodeJs
+RUN apt-get update
+RUN apt-get install curl git -y
+RUN curl -sL https://deb.nodesource.com/setup_4.x > install_node.sh
+RUN chmod a+x install_node.sh
+RUN ./install_node.sh
+RUN apt-get install -y nodejs
+
+# Add the app
+COPY ${CODE_SOURCE} ${CODE_DEST}
+
+# Build the app
+WORKDIR ${CODE_DEST}
+RUN npm install 
+RUN npm run build
+
+# Move the builded code to nginx vhost
+RUN mv ${CODE_DEST}/dist/* ${VHOST}
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c53e867
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+#XOS GUI
diff --git a/conf/browsersync-dist.conf.js b/conf/browsersync-dist.conf.js
new file mode 100644
index 0000000..fa45845
--- /dev/null
+++ b/conf/browsersync-dist.conf.js
@@ -0,0 +1,12 @@
+const conf = require('./gulp.conf');
+
+module.exports = function () {
+  return {
+    server: {
+      baseDir: [
+        conf.paths.dist
+      ]
+    },
+    open: false
+  };
+};
diff --git a/conf/browsersync.conf.js b/conf/browsersync.conf.js
new file mode 100644
index 0000000..49936d4
--- /dev/null
+++ b/conf/browsersync.conf.js
@@ -0,0 +1,13 @@
+const conf = require('./gulp.conf');
+
+module.exports = function () {
+  return {
+    server: {
+      baseDir: [
+        conf.paths.tmp,
+        conf.paths.src
+      ]
+    },
+    open: false
+  };
+};
diff --git a/conf/gulp.conf.js b/conf/gulp.conf.js
new file mode 100644
index 0000000..12e482e
--- /dev/null
+++ b/conf/gulp.conf.js
@@ -0,0 +1,45 @@
+'use strict';
+
+/**
+ *  This file contains the variables used in other gulp files
+ *  which defines tasks
+ *  By design, we only put there very generic config values
+ *  which are used in several places to keep good readability
+ *  of the tasks
+ */
+
+const path = require('path');
+const gutil = require('gulp-util');
+
+/**
+ *  The main paths of your project handle these with care
+ */
+exports.paths = {
+  src: 'src',
+  dist: 'dist',
+  tmp: '.tmp',
+  e2e: 'e2e',
+  tasks: 'gulp_tasks'
+};
+
+exports.path = {};
+for (const pathName in exports.paths) {
+  if (exports.paths.hasOwnProperty(pathName)) {
+    exports.path[pathName] = function pathJoin() {
+      const pathValue = exports.paths[pathName];
+      const funcArgs = Array.prototype.slice.call(arguments);
+      const joinArgs = [pathValue].concat(funcArgs);
+      return path.join.apply(this, joinArgs);
+    };
+  }
+}
+
+/**
+ *  Common implementation for an error handler of a Gulp plugin
+ */
+exports.errorHandler = function (title) {
+  return function (err) {
+    gutil.log(gutil.colors.red(`[${title}]`), err.toString());
+    this.emit('end');
+  };
+};
diff --git a/conf/karma-auto.conf.js b/conf/karma-auto.conf.js
new file mode 100644
index 0000000..c665d66
--- /dev/null
+++ b/conf/karma-auto.conf.js
@@ -0,0 +1,46 @@
+const conf = require('./gulp.conf');
+
+module.exports = function (config) {
+  const configuration = {
+    basePath: '../',
+    singleRun: false,
+    autoWatch: true,
+    logLevel: 'INFO',
+    junitReporter: {
+      outputDir: 'test-reports'
+    },
+    browsers: [
+      'Chrome'
+    ],
+    frameworks: [
+      'jasmine'
+    ],
+    files: [
+      'node_modules/es6-shim/es6-shim.js',
+      conf.path.src('index.spec.js')
+    ],
+    preprocessors: {
+      [conf.path.src('index.spec.js')]: [
+        'webpack'
+      ]
+    },
+    reporters: ['progress', 'coverage'],
+    coverageReporter: {
+      type: 'html',
+      dir: 'coverage/'
+    },
+    webpack: require('./webpack-test.conf'),
+    webpackMiddleware: {
+      noInfo: true
+    },
+    plugins: [
+      require('karma-jasmine'),
+      require('karma-junit-reporter'),
+      require('karma-coverage'),
+      require('karma-chrome-launcher'),
+      require('karma-webpack')
+    ]
+  };
+
+  config.set(configuration);
+};
diff --git a/conf/karma.conf.js b/conf/karma.conf.js
new file mode 100644
index 0000000..806a6f4
--- /dev/null
+++ b/conf/karma.conf.js
@@ -0,0 +1,46 @@
+const conf = require('./gulp.conf');
+
+module.exports = function (config) {
+  const configuration = {
+    basePath: '../',
+    singleRun: true,
+    autoWatch: false,
+    logLevel: 'INFO',
+    junitReporter: {
+      outputDir: 'test-reports'
+    },
+    browsers: [
+      'PhantomJS'
+    ],
+    frameworks: [
+      'jasmine'
+    ],
+    files: [
+      'node_modules/es6-shim/es6-shim.js',
+      conf.path.src('index.spec.js')
+    ],
+    preprocessors: {
+      [conf.path.src('index.spec.js')]: [
+        'webpack'
+      ]
+    },
+    reporters: ['progress', 'coverage'],
+    coverageReporter: {
+      type: 'html',
+      dir: 'coverage/'
+    },
+    webpack: require('./webpack-test.conf'),
+    webpackMiddleware: {
+      noInfo: true
+    },
+    plugins: [
+      require('karma-jasmine'),
+      require('karma-junit-reporter'),
+      require('karma-coverage'),
+      require('karma-phantomjs-launcher'),
+      require('karma-webpack')
+    ]
+  };
+
+  config.set(configuration);
+};
diff --git a/conf/webpack-dist.conf.js b/conf/webpack-dist.conf.js
new file mode 100644
index 0000000..3ba4a8a
--- /dev/null
+++ b/conf/webpack-dist.conf.js
@@ -0,0 +1,80 @@
+const webpack = require('webpack');
+const conf = require('./gulp.conf');
+const path = require('path');
+
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const autoprefixer = require('autoprefixer');
+
+module.exports = {
+  module: {
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: ExtractTextPlugin.extract({
+          fallbackLoader: 'style',
+          loader: 'css?minimize!sass!postcss'
+        })
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html'
+        ]
+      }
+    ]
+  },
+  plugins: [
+    new webpack.optimize.OccurrenceOrderPlugin(),
+    new webpack.NoErrorsPlugin(),
+    new HtmlWebpackPlugin({
+      template: conf.path.src('index.html')
+    }),
+    new webpack.ContextReplacementPlugin(
+      /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
+      conf.paths.src
+    ),
+    new webpack.DefinePlugin({
+      'process.env.NODE_ENV': '"production"'
+    }),
+    new webpack.optimize.UglifyJsPlugin({
+      compress: {unused: true, dead_code: true, warnings: false} // eslint-disable-line camelcase
+    }),
+    new ExtractTextPlugin('index-[contenthash].css'),
+    new webpack.optimize.CommonsChunkPlugin({name: 'vendor'})
+  ],
+  postcss: () => [autoprefixer],
+  output: {
+    path: path.join(process.cwd(), conf.paths.dist),
+    filename: '[name]-[hash].js'
+  },
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  entry: `./${conf.path.src('index')}`,
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  }
+};
diff --git a/conf/webpack-test.conf.js b/conf/webpack-test.conf.js
new file mode 100644
index 0000000..c39b1c4
--- /dev/null
+++ b/conf/webpack-test.conf.js
@@ -0,0 +1,58 @@
+const webpack = require('webpack');
+const conf = require('./gulp.conf');
+module.exports = {
+  module: {
+    preLoaders: [
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loader: 'tslint'
+      }
+    ],
+
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html'
+        ]
+      }
+    ]
+  },
+  plugins: [
+    new webpack.ContextReplacementPlugin(
+      /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
+      conf.paths.src
+    )
+  ],
+  debug: true,
+  devtool: 'source-map',
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  }
+};
diff --git a/conf/webpack.conf.js b/conf/webpack.conf.js
new file mode 100644
index 0000000..f7830ce
--- /dev/null
+++ b/conf/webpack.conf.js
@@ -0,0 +1,83 @@
+const webpack = require('webpack');
+const conf = require('./gulp.conf');
+const path = require('path');
+
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const autoprefixer = require('autoprefixer');
+
+module.exports = {
+  module: {
+    preLoaders: [
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loader: 'tslint'
+      }
+    ],
+
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: [
+          'style',
+          'css',
+          'sass',
+          'postcss'
+        ]
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html'
+        ]
+      }
+    ]
+  },
+  plugins: [
+    new webpack.optimize.OccurrenceOrderPlugin(),
+    new webpack.NoErrorsPlugin(),
+    new HtmlWebpackPlugin({
+      template: conf.path.src('index.html')
+    }),
+    new webpack.ContextReplacementPlugin(
+      /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
+      conf.paths.src
+    )
+  ],
+  postcss: () => [autoprefixer],
+  debug: true,
+  devtool: 'source-map',
+  output: {
+    path: path.join(process.cwd(), conf.paths.tmp),
+    filename: 'index.js'
+  },
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  entry: `./${conf.path.src('index')}`,
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  }
+};
diff --git a/gulp_tasks/browsersync.js b/gulp_tasks/browsersync.js
new file mode 100644
index 0000000..945a88d
--- /dev/null
+++ b/gulp_tasks/browsersync.js
@@ -0,0 +1,21 @@
+const gulp = require('gulp');
+const browserSync = require('browser-sync');
+const spa = require('browser-sync-spa');
+
+const browserSyncConf = require('../conf/browsersync.conf');
+const browserSyncDistConf = require('../conf/browsersync-dist.conf');
+
+browserSync.use(spa());
+
+gulp.task('browsersync', browserSyncServe);
+gulp.task('browsersync:dist', browserSyncDist);
+
+function browserSyncServe(done) {
+  browserSync.init(browserSyncConf());
+  done();
+}
+
+function browserSyncDist(done) {
+  browserSync.init(browserSyncDistConf());
+  done();
+}
diff --git a/gulp_tasks/karma.js b/gulp_tasks/karma.js
new file mode 100644
index 0000000..98aaf1d
--- /dev/null
+++ b/gulp_tasks/karma.js
@@ -0,0 +1,27 @@
+process.env.NODE_ENV = 'test';
+
+const path = require('path');
+
+const gulp = require('gulp');
+const karma = require('karma');
+
+gulp.task('karma:single-run', karmaSingleRun);
+gulp.task('karma:auto-run', karmaAutoRun);
+
+function karmaFinishHandler(done) {
+  return failCount => {
+    done(failCount ? new Error(`Failed ${failCount} tests.`) : null);
+  };
+}
+
+function karmaSingleRun(done) {
+  const configFile = path.join(process.cwd(), 'conf', 'karma.conf.js');
+  const karmaServer = new karma.Server({configFile}, karmaFinishHandler(done));
+  karmaServer.start();
+}
+
+function karmaAutoRun(done) {
+  const configFile = path.join(process.cwd(), 'conf', 'karma-auto.conf.js');
+  const karmaServer = new karma.Server({configFile}, karmaFinishHandler(done));
+  karmaServer.start();
+}
diff --git a/gulp_tasks/misc.js b/gulp_tasks/misc.js
new file mode 100644
index 0000000..6cc14bc
--- /dev/null
+++ b/gulp_tasks/misc.js
@@ -0,0 +1,25 @@
+const path = require('path');
+
+const gulp = require('gulp');
+const del = require('del');
+const filter = require('gulp-filter');
+
+const conf = require('../conf/gulp.conf');
+
+gulp.task('clean', clean);
+gulp.task('other', other);
+
+function clean() {
+  return del([conf.paths.dist, conf.paths.tmp]);
+}
+
+function other() {
+  const fileFilter = filter(file => file.stat.isFile());
+
+  return gulp.src([
+    path.join(conf.paths.src, '/**/*'),
+    path.join(`!${conf.paths.src}`, '/**/*.{scss,ts,html}')
+  ])
+    .pipe(fileFilter)
+    .pipe(gulp.dest(conf.paths.dist));
+}
diff --git a/gulp_tasks/webpack.js b/gulp_tasks/webpack.js
new file mode 100644
index 0000000..ec8e8b1
--- /dev/null
+++ b/gulp_tasks/webpack.js
@@ -0,0 +1,49 @@
+const gulp = require('gulp');
+const gutil = require('gulp-util');
+
+const webpack = require('webpack');
+const webpackConf = require('../conf/webpack.conf');
+const webpackDistConf = require('../conf/webpack-dist.conf');
+const gulpConf = require('../conf/gulp.conf');
+const browsersync = require('browser-sync');
+
+gulp.task('webpack:dev', done => {
+  webpackWrapper(false, webpackConf, done);
+});
+
+gulp.task('webpack:watch', done => {
+  webpackWrapper(true, webpackConf, done);
+});
+
+gulp.task('webpack:dist', done => {
+  process.env.NODE_ENV = 'production';
+  webpackWrapper(false, webpackDistConf, done);
+});
+
+function webpackWrapper(watch, conf, done) {
+  const webpackBundler = webpack(conf);
+
+  const webpackChangeHandler = (err, stats) => {
+    if (err) {
+      gulpConf.errorHandler('Webpack')(err);
+    }
+    gutil.log(stats.toString({
+      colors: true,
+      chunks: false,
+      hash: false,
+      version: false
+    }));
+    if (done) {
+      done();
+      done = null;
+    } else {
+      browsersync.reload();
+    }
+  };
+
+  if (watch) {
+    webpackBundler.watch(200, webpackChangeHandler);
+  } else {
+    webpackBundler.run(webpackChangeHandler);
+  }
+}
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..541d6e4
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,29 @@
+const gulp = require('gulp');
+const HubRegistry = require('gulp-hub');
+const browserSync = require('browser-sync');
+
+const conf = require('./conf/gulp.conf');
+
+// Load some files into the registry
+const hub = new HubRegistry([conf.path.tasks('*.js')]);
+
+// Tell gulp to use the tasks just loaded
+gulp.registry(hub);
+
+gulp.task('build', gulp.series(gulp.parallel('other', 'webpack:dist')));
+gulp.task('test', gulp.series('karma:single-run'));
+gulp.task('test:auto', gulp.series('karma:auto-run'));
+gulp.task('serve', gulp.series('webpack:watch', 'watch', 'browsersync'));
+gulp.task('serve:dist', gulp.series('default', 'browsersync:dist'));
+gulp.task('default', gulp.series('clean', 'build'));
+gulp.task('watch', watch);
+
+function reloadBrowserSync(cb) {
+  browserSync.reload();
+  cb();
+}
+
+function watch(done) {
+  gulp.watch(conf.path.tmp('index.html'), reloadBrowserSync);
+  done();
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..dc798f8
--- /dev/null
+++ b/package.json
@@ -0,0 +1,76 @@
+{
+  "dependencies": {
+    "@angular/core": "^2.0.0",
+    "@angular/compiler": "^2.0.0",
+    "@angular/common": "^2.0.0",
+    "@angular/platform-browser": "^2.0.0",
+    "@angular/platform-browser-dynamic": "^2.0.0",
+    "@angular/http": "^2.0.0",
+    "rxjs": "5.0.0-beta.12",
+    "zone.js": "^0.6.23",
+    "core-js": "^2.4.1",
+    "@angular/router": "^3.0.0"
+  },
+  "devDependencies": {
+    "del": "^2.0.2",
+    "gulp": "gulpjs/gulp#4ed9a4a3275559c73a396eff7e1fde3824951ebb",
+    "gulp-hub": "frankwallis/gulp-hub#d461b9c700df9010d0a8694e4af1fb96d9f38bf4",
+    "gulp-filter": "^4.0.0",
+    "gulp-util": "^3.0.7",
+    "gulp-sass": "^2.1.1",
+    "browser-sync": "^2.9.11",
+    "browser-sync-spa": "^1.0.3",
+    "karma": "^1.3.0",
+    "karma-coverage": "^1.1.1",
+    "karma-jasmine": "^1.0.2",
+    "karma-junit-reporter": "^1.1.0",
+    "jasmine": "^2.4.1",
+    "es6-shim": "^0.35.0",
+    "karma-chrome-launcher": "^0.2.3",
+    "karma-phantomjs-launcher": "^0.2.1",
+    "babel-plugin-istanbul": "^2.0.1",
+    "karma-webpack": "^1.7.0",
+    "webpack": "2.1.0-beta.20",
+    "html-webpack-plugin": "^2.9.0",
+    "style-loader": "^0.13.0",
+    "css-loader": "^0.23.1",
+    "postcss-loader": "^0.8.0",
+    "autoprefixer": "^6.2.2",
+    "json-loader": "^0.5.4",
+    "extract-text-webpack-plugin": "^2.0.0-beta.3",
+    "html-loader": "^0.4.3",
+    "ts-loader": "^0.8.2",
+    "sass-loader": "^3.1.2",
+    "node-sass": "^3.4.2",
+    "eslint": "^3.2.2",
+    "eslint-config-xo-space": "^0.12.0",
+    "eslint-loader": "^1.3.0",
+    "babel-loader": "^6.2.0",
+    "babel-eslint": "^6.0.2",
+    "eslint-plugin-babel": "^3.1.0",
+    "tslint": "^3.2.1",
+    "typescript": "^2.0.2",
+    "typings": "^1.0.4",
+    "tslint-loader": "^2.1.0",
+    "codelyzer": "^0.0.25",
+    "phantomjs": "^2.1.3"
+  },
+  "scripts": {
+    "start": "gulp serve",
+    "build": "gulp",
+    "serve": "gulp serve",
+    "serve:dist": "gulp serve:dist",
+    "test": "gulp test",
+    "test:auto": "gulp test:auto"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "browser": true,
+      "jasmine": true
+    },
+    "extends": [
+      "xo-space/esnext"
+    ]
+  }
+}
diff --git a/src/app/hello.html b/src/app/hello.html
new file mode 100644
index 0000000..2ec8382
--- /dev/null
+++ b/src/app/hello.html
@@ -0,0 +1 @@
+<h1>{{ hello }}</h1>
\ No newline at end of file
diff --git a/src/app/hello.spec.ts b/src/app/hello.spec.ts
new file mode 100644
index 0000000..7e3b2cc
--- /dev/null
+++ b/src/app/hello.spec.ts
@@ -0,0 +1,22 @@
+/// <reference path="../../typings/index.d.ts"/>
+
+import {HelloComponent} from './hello';
+import {TestBed, async} from '@angular/core/testing';
+
+describe('hello component', () => {
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [
+        HelloComponent
+      ]
+    });
+    TestBed.compileComponents();
+  }));
+
+  it('should render hello world', () => {
+    const fixture = TestBed.createComponent(HelloComponent);
+    fixture.detectChanges();
+    const hello = fixture.nativeElement;
+    expect(hello.querySelector('h1').textContent).toBe('Hello World!');
+  });
+});
diff --git a/src/app/hello.ts b/src/app/hello.ts
new file mode 100644
index 0000000..9f42916
--- /dev/null
+++ b/src/app/hello.ts
@@ -0,0 +1,13 @@
+import {Component} from '@angular/core';
+
+@Component({
+  selector: 'fountain-app',
+  template: require('./hello.html')
+})
+export class HelloComponent {
+  public hello: string;
+
+  constructor() {
+    this.hello = 'Hello World!';
+  }
+}
diff --git a/src/app/index.ts b/src/app/index.ts
new file mode 100644
index 0000000..5f02fe6
--- /dev/null
+++ b/src/app/index.ts
@@ -0,0 +1,18 @@
+import {NgModule} from '@angular/core';
+import {BrowserModule} from '@angular/platform-browser';
+import {routing, RootComponent} from './routes';
+
+import {HelloComponent} from './hello';
+
+@NgModule({
+  imports: [
+    BrowserModule,
+    routing
+  ],
+  declarations: [
+    RootComponent,
+    HelloComponent
+  ],
+  bootstrap: [RootComponent]
+})
+export class AppModule {}
diff --git a/src/app/routes.ts b/src/app/routes.ts
new file mode 100644
index 0000000..9a197e7
--- /dev/null
+++ b/src/app/routes.ts
@@ -0,0 +1,20 @@
+/// <reference path="../../typings/index.d.ts"/>
+
+import {Component} from '@angular/core';
+import {RouterModule, Routes} from '@angular/router';
+import {HelloComponent} from './hello';
+
+@Component({
+  selector: 'fountain-root',
+  template: '<router-outlet></router-outlet>'
+})
+export class RootComponent {}
+
+export const routes: Routes = [
+  {
+    path: '',
+    component: HelloComponent
+  }
+];
+
+export const routing = RouterModule.forRoot(routes);
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000..2d0e805
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+  <head>
+    <base href="/">
+    <meta charset="utf-8">
+    <title>FountainJS</title>
+    <meta name="description" content="">
+    <meta name="viewport" content="width=device-width">
+    <link rel="icon" type="image/png" href="http://fountainjs.io/assets/imgs/fountain.png" />
+  </head>
+
+  <body>
+    <fountain-root>Loading...</fountain-root>
+  </body>
+</html>
diff --git a/src/index.scss b/src/index.scss
new file mode 100644
index 0000000..f1df96a
--- /dev/null
+++ b/src/index.scss
@@ -0,0 +1,3 @@
+body {
+  background-color: lightgrey;
+}
diff --git a/src/index.spec.js b/src/index.spec.js
new file mode 100644
index 0000000..3f4ad63
--- /dev/null
+++ b/src/index.spec.js
@@ -0,0 +1,20 @@
+Error.stackTraceLimit = Infinity;
+
+require('core-js/client/shim');
+
+require('@angular/common');
+require('rxjs');
+
+require('zone.js/dist/zone');
+require('zone.js/dist/long-stack-trace-zone');
+require('zone.js/dist/proxy');
+require('zone.js/dist/sync-test');
+require('zone.js/dist/jasmine-patch');
+require('zone.js/dist/async-test');
+require('zone.js/dist/fake-async-test');
+const context = require.context('./app', true, /\.(js|ts|tsx)$/);
+context.keys().forEach(context);
+const testing = require('@angular/core/testing');
+const testingBrowser = require('@angular/platform-browser-dynamic/testing');
+
+testing.TestBed.initTestEnvironment(testingBrowser.BrowserDynamicTestingModule, testingBrowser.platformBrowserDynamicTesting());
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..f7b360a
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,23 @@
+/// <reference path="../typings/index.d.ts"/>
+
+import 'core-js/client/shim';
+import 'zone.js/dist/zone';
+
+import '@angular/common';
+import 'rxjs';
+
+import './index.scss';
+
+import {enableProdMode} from '@angular/core';
+import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
+import {AppModule} from './app';
+
+declare var process: any;
+if (process.env.NODE_ENV === 'production') {
+  enableProdMode();
+} else {
+  Error['stackTraceLimit'] = Infinity; // tslint:disable-line:no-string-literal
+  require('zone.js/dist/long-stack-trace-zone'); // tslint:disable-line:no-var-requires
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..60aa28a
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,16 @@
+{
+  "compilerOptions": {
+    "sourceMap": true,
+    "emitDecoratorMetadata": true,
+    "experimentalDecorators": true,
+    "removeComments": false,
+    "noImplicitAny": false
+  },
+  "compileOnSave": false,
+  "filesGlob": [
+    "src/**/*.ts",
+    "src/**/*.tsx",
+    "!typings/**",
+    "!node_modules/**"
+  ]
+}
diff --git a/tslint.json b/tslint.json
new file mode 100644
index 0000000..373c573
--- /dev/null
+++ b/tslint.json
@@ -0,0 +1,105 @@
+{
+  "rulesDirectory": [
+    "node_modules/codelyzer"
+  ],
+  "rules": {
+    "directive-selector-name": [true, "camelCase"],
+    "component-selector-name": [true, "kebab-case"],
+    "directive-selector-type": [true, "attribute"],
+    "component-selector-type": [true, "element"],
+    "directive-selector-prefix": [true, "fountain"],
+    "component-selector-prefix": [true, "fountain"],
+    "use-input-property-decorator": true,
+    "use-output-property-decorator": true,
+    "use-host-property-decorator": true,
+    "no-attribute-parameter-decorator": true,
+    "no-input-rename": true,
+    "no-output-rename": true,
+    "no-forward-ref" :true,
+    "use-life-cycle-interface": true,
+    "use-pipe-transform-interface": true,
+    "pipe-naming": [true, "camelCase", "fountain"],
+    "component-class-suffix": true,
+    "directive-class-suffix": true,
+    "ban": [true,
+      ["_", "extend"],
+      ["_", "isNull"],
+      ["_", "isDefined"]
+    ],
+    "class-name": true,
+    "comment-format": [true,
+      "check-space",
+      "check-lowercase"
+    ],
+    "curly": true,
+    "eofline": true,
+    "forin": true,
+    "indent": [true, 2],
+    "interface-name": true,
+    "jsdoc-format": true,
+    "label-position": true,
+    "label-undefined": true,
+    "max-line-length": [false, 140],
+    "member-ordering": [true,
+      "public-before-private",
+      "static-before-instance",
+      "variables-before-functions"
+    ],
+    "no-arg": true,
+    "no-bitwise": true,
+    "no-console": [true,
+      "debug",
+      "info",
+      "time",
+      "timeEnd",
+      "trace"
+    ],
+    "no-construct": true,
+    "no-constructor-vars": false,
+    "no-debugger": true,
+    "no-duplicate-key": true,
+    "no-duplicate-variable": true,
+    "no-empty": true,
+    "no-eval": true,
+    "no-string-literal": true,
+    "no-switch-case-fall-through": true,
+    "trailing-comma": true,
+    "no-trailing-whitespace": true,
+    "no-unused-expression": true,
+    "no-unused-variable": true,
+    "no-unreachable": true,
+    "no-use-before-declare": true,
+    "no-var-requires": true,
+    "one-line": [true,
+      "check-open-brace",
+      "check-catch",
+      "check-else",
+      "check-whitespace"
+    ],
+    "quotemark": [true, "single"],
+    "radix": true,
+    "semicolon": true,
+    "triple-equals": [true, "allow-null-check"],
+    "typedef": [true,
+      "callSignature",
+      "indexSignature",
+      "parameter",
+      "propertySignature",
+      "variableDeclarator"
+    ],
+    "typedef-whitespace": [true,
+      ["callSignature", "noSpace"],
+      ["catchClause", "noSpace"],
+      ["indexSignature", "space"]
+    ],
+    "use-strict": false,
+    "variable-name": false,
+    "whitespace": [true,
+      "check-branch",
+      "check-decl",
+      "check-operator",
+      "check-separator",
+      "check-type"
+    ]
+  }
+}
diff --git a/typings.json b/typings.json
new file mode 100644
index 0000000..3a1d944
--- /dev/null
+++ b/typings.json
@@ -0,0 +1,7 @@
+{
+  "globalDependencies": {
+    "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dc9dabe74a5be62613b17a3605309783a12ff28a",
+    "require": "registry:dt/require#2.1.20+20160316155526",
+    "es6-shim": "registry:dt/es6-shim#0.31.2+20160602141504"
+  }
+}
diff --git a/typings/globals/es6-shim/index.d.ts b/typings/globals/es6-shim/index.d.ts
new file mode 100644
index 0000000..6ad8ced
--- /dev/null
+++ b/typings/globals/es6-shim/index.d.ts
@@ -0,0 +1,666 @@
+// Generated by typings
+// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/9807d9b701f58be068cb07833d2b24235351d052/es6-shim/es6-shim.d.ts
+declare type PropertyKey = string | number | symbol;
+
+interface IteratorResult<T> {
+    done: boolean;
+    value?: T;
+}
+
+interface IterableShim<T> {
+    /**
+      * Shim for an ES6 iterable. Not intended for direct use by user code.
+      */
+    "_es6-shim iterator_"(): Iterator<T>;
+}
+
+interface Iterator<T> {
+    next(value?: any): IteratorResult<T>;
+    return?(value?: any): IteratorResult<T>;
+    throw?(e?: any): IteratorResult<T>;
+}
+
+interface IterableIteratorShim<T> extends IterableShim<T>, Iterator<T> {
+    /**
+      * Shim for an ES6 iterable iterator. Not intended for direct use by user code.
+      */
+    "_es6-shim iterator_"(): IterableIteratorShim<T>;
+}
+
+interface StringConstructor {
+    /**
+      * Return the String value whose elements are, in order, the elements in the List elements.
+      * If length is 0, the empty string is returned.
+      */
+    fromCodePoint(...codePoints: number[]): string;
+
+    /**
+      * String.raw is intended for use as a tag function of a Tagged Template String. When called
+      * as such the first argument will be a well formed template call site object and the rest
+      * parameter will contain the substitution values.
+      * @param template A well-formed template string call site representation.
+      * @param substitutions A set of substitution values.
+      */
+    raw(template: TemplateStringsArray, ...substitutions: any[]): string;
+}
+
+interface String {
+    /**
+      * Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point
+      * value of the UTF-16 encoded code point starting at the string element at position pos in
+      * the String resulting from converting this object to a String.
+      * If there is no element at that position, the result is undefined.
+      * If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.
+      */
+    codePointAt(pos: number): number;
+
+    /**
+      * Returns true if searchString appears as a substring of the result of converting this
+      * object to a String, at one or more positions that are
+      * greater than or equal to position; otherwise, returns false.
+      * @param searchString search string
+      * @param position If position is undefined, 0 is assumed, so as to search all of the String.
+      */
+    includes(searchString: string, position?: number): boolean;
+
+    /**
+      * Returns true if the sequence of elements of searchString converted to a String is the
+      * same as the corresponding elements of this object (converted to a String) starting at
+      * endPosition – length(this). Otherwise returns false.
+      */
+    endsWith(searchString: string, endPosition?: number): boolean;
+
+    /**
+      * Returns a String value that is made from count copies appended together. If count is 0,
+      * T is the empty String is returned.
+      * @param count number of copies to append
+      */
+    repeat(count: number): string;
+
+    /**
+      * Returns true if the sequence of elements of searchString converted to a String is the
+      * same as the corresponding elements of this object (converted to a String) starting at
+      * position. Otherwise returns false.
+      */
+    startsWith(searchString: string, position?: number): boolean;
+
+    /**
+      * Returns an <a> HTML anchor element and sets the name attribute to the text value
+      * @param name
+      */
+    anchor(name: string): string;
+
+    /** Returns a <big> HTML element */
+    big(): string;
+
+    /** Returns a <blink> HTML element */
+    blink(): string;
+
+    /** Returns a <b> HTML element */
+    bold(): string;
+
+    /** Returns a <tt> HTML element */
+    fixed(): string
+
+    /** Returns a <font> HTML element and sets the color attribute value */
+    fontcolor(color: string): string
+
+    /** Returns a <font> HTML element and sets the size attribute value */
+    fontsize(size: number): string;
+
+    /** Returns a <font> HTML element and sets the size attribute value */
+    fontsize(size: string): string;
+
+    /** Returns an <i> HTML element */
+    italics(): string;
+
+    /** Returns an <a> HTML element and sets the href attribute value */
+    link(url: string): string;
+
+    /** Returns a <small> HTML element */
+    small(): string;
+
+    /** Returns a <strike> HTML element */
+    strike(): string;
+
+    /** Returns a <sub> HTML element */
+    sub(): string;
+
+    /** Returns a <sup> HTML element */
+    sup(): string;
+
+    /**
+      * Shim for an ES6 iterable. Not intended for direct use by user code.
+      */
+    "_es6-shim iterator_"(): IterableIteratorShim<string>;
+}
+
+interface ArrayConstructor {
+    /**
+      * Creates an array from an array-like object.
+      * @param arrayLike An array-like object to convert to an array.
+      * @param mapfn A mapping function to call on every element of the array.
+      * @param thisArg Value of 'this' used to invoke the mapfn.
+      */
+    from<T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): Array<U>;
+
+    /**
+      * Creates an array from an iterable object.
+      * @param iterable An iterable object to convert to an array.
+      * @param mapfn A mapping function to call on every element of the array.
+      * @param thisArg Value of 'this' used to invoke the mapfn.
+      */
+    from<T, U>(iterable: IterableShim<T>, mapfn: (v: T, k: number) => U, thisArg?: any): Array<U>;
+
+    /**
+      * Creates an array from an array-like object.
+      * @param arrayLike An array-like object to convert to an array.
+      */
+    from<T>(arrayLike: ArrayLike<T>): Array<T>;
+
+    /**
+      * Creates an array from an iterable object.
+      * @param iterable An iterable object to convert to an array.
+      */
+    from<T>(iterable: IterableShim<T>): Array<T>;
+
+    /**
+      * Returns a new array from a set of elements.
+      * @param items A set of elements to include in the new array object.
+      */
+    of<T>(...items: T[]): Array<T>;
+}
+
+interface Array<T> {
+    /**
+      * Returns the value of the first element in the array where predicate is true, and undefined
+      * otherwise.
+      * @param predicate find calls predicate once for each element of the array, in ascending
+      * order, until it finds one where predicate returns true. If such an element is found, find
+      * immediately returns that element value. Otherwise, find returns undefined.
+      * @param thisArg If provided, it will be used as the this value for each invocation of
+      * predicate. If it is not provided, undefined is used instead.
+      */
+    find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T;
+
+    /**
+      * Returns the index of the first element in the array where predicate is true, and undefined
+      * otherwise.
+      * @param predicate find calls predicate once for each element of the array, in ascending
+      * order, until it finds one where predicate returns true. If such an element is found, find
+      * immediately returns that element value. Otherwise, find returns undefined.
+      * @param thisArg If provided, it will be used as the this value for each invocation of
+      * predicate. If it is not provided, undefined is used instead.
+      */
+    findIndex(predicate: (value: T) => boolean, thisArg?: any): number;
+
+    /**
+      * Returns the this object after filling the section identified by start and end with value
+      * @param value value to fill array section with
+      * @param start index to start filling the array at. If start is negative, it is treated as
+      * length+start where length is the length of the array.
+      * @param end index to stop filling the array at. If end is negative, it is treated as
+      * length+end.
+      */
+    fill(value: T, start?: number, end?: number): T[];
+
+    /**
+      * Returns the this object after copying a section of the array identified by start and end
+      * to the same array starting at position target
+      * @param target If target is negative, it is treated as length+target where length is the
+      * length of the array.
+      * @param start If start is negative, it is treated as length+start. If end is negative, it
+      * is treated as length+end.
+      * @param end If not specified, length of the this object is used as its default value.
+      */
+    copyWithin(target: number, start: number, end?: number): T[];
+
+    /**
+      * Returns an array of key, value pairs for every entry in the array
+      */
+    entries(): IterableIteratorShim<[number, T]>;
+
+    /**
+      * Returns an list of keys in the array
+      */
+    keys(): IterableIteratorShim<number>;
+
+    /**
+      * Returns an list of values in the array
+      */
+    values(): IterableIteratorShim<T>;
+
+    /**
+      * Shim for an ES6 iterable. Not intended for direct use by user code.
+      */
+    "_es6-shim iterator_"(): IterableIteratorShim<T>;
+}
+
+interface NumberConstructor {
+    /**
+      * The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1
+      * that is representable as a Number value, which is approximately:
+      * 2.2204460492503130808472633361816 x 10‍−‍16.
+      */
+    EPSILON: number;
+
+    /**
+      * Returns true if passed value is finite.
+      * Unlike the global isFininte, Number.isFinite doesn't forcibly convert the parameter to a
+      * number. Only finite values of the type number, result in true.
+      * @param number A numeric value.
+      */
+    isFinite(number: number): boolean;
+
+    /**
+      * Returns true if the value passed is an integer, false otherwise.
+      * @param number A numeric value.
+      */
+    isInteger(number: number): boolean;
+
+    /**
+      * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a
+      * number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter
+      * to a number. Only values of the type number, that are also NaN, result in true.
+      * @param number A numeric value.
+      */
+    isNaN(number: number): boolean;
+
+    /**
+      * Returns true if the value passed is a safe integer.
+      * @param number A numeric value.
+      */
+    isSafeInteger(number: number): boolean;
+
+    /**
+      * The value of the largest integer n such that n and n + 1 are both exactly representable as
+      * a Number value.
+      * The value of Number.MIN_SAFE_INTEGER is 9007199254740991 2^53 − 1.
+      */
+    MAX_SAFE_INTEGER: number;
+
+    /**
+      * The value of the smallest integer n such that n and n − 1 are both exactly representable as
+      * a Number value.
+      * The value of Number.MIN_SAFE_INTEGER is −9007199254740991 (−(2^53 − 1)).
+      */
+    MIN_SAFE_INTEGER: number;
+
+    /**
+      * Converts a string to a floating-point number.
+      * @param string A string that contains a floating-point number.
+      */
+    parseFloat(string: string): number;
+
+    /**
+      * Converts A string to an integer.
+      * @param s A string to convert into a number.
+      * @param radix A value between 2 and 36 that specifies the base of the number in numString.
+      * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.
+      * All other strings are considered decimal.
+      */
+    parseInt(string: string, radix?: number): number;
+}
+
+interface ObjectConstructor {
+    /**
+      * Copy the values of all of the enumerable own properties from one or more source objects to a
+      * target object. Returns the target object.
+      * @param target The target object to copy to.
+      * @param sources One or more source objects to copy properties from.
+      */
+    assign(target: any, ...sources: any[]): any;
+
+    /**
+      * Returns true if the values are the same value, false otherwise.
+      * @param value1 The first value.
+      * @param value2 The second value.
+      */
+    is(value1: any, value2: any): boolean;
+
+    /**
+      * Sets the prototype of a specified object o to  object proto or null. Returns the object o.
+      * @param o The object to change its prototype.
+      * @param proto The value of the new prototype or null.
+      * @remarks Requires `__proto__` support.
+      */
+    setPrototypeOf(o: any, proto: any): any;
+}
+
+interface RegExp {
+    /**
+      * Returns a string indicating the flags of the regular expression in question. This field is read-only.
+      * The characters in this string are sequenced and concatenated in the following order:
+      *
+      *    - "g" for global
+      *    - "i" for ignoreCase
+      *    - "m" for multiline
+      *    - "u" for unicode
+      *    - "y" for sticky
+      *
+      * If no flags are set, the value is the empty string.
+      */
+    flags: string;
+}
+
+interface Math {
+    /**
+      * Returns the number of leading zero bits in the 32-bit binary representation of a number.
+      * @param x A numeric expression.
+      */
+    clz32(x: number): number;
+
+    /**
+      * Returns the result of 32-bit multiplication of two numbers.
+      * @param x First number
+      * @param y Second number
+      */
+    imul(x: number, y: number): number;
+
+    /**
+      * Returns the sign of the x, indicating whether x is positive, negative or zero.
+      * @param x The numeric expression to test
+      */
+    sign(x: number): number;
+
+    /**
+      * Returns the base 10 logarithm of a number.
+      * @param x A numeric expression.
+      */
+    log10(x: number): number;
+
+    /**
+      * Returns the base 2 logarithm of a number.
+      * @param x A numeric expression.
+      */
+    log2(x: number): number;
+
+    /**
+      * Returns the natural logarithm of 1 + x.
+      * @param x A numeric expression.
+      */
+    log1p(x: number): number;
+
+    /**
+      * Returns the result of (e^x - 1) of x (e raised to the power of x, where e is the base of
+      * the natural logarithms).
+      * @param x A numeric expression.
+      */
+    expm1(x: number): number;
+
+    /**
+      * Returns the hyperbolic cosine of a number.
+      * @param x A numeric expression that contains an angle measured in radians.
+      */
+    cosh(x: number): number;
+
+    /**
+      * Returns the hyperbolic sine of a number.
+      * @param x A numeric expression that contains an angle measured in radians.
+      */
+    sinh(x: number): number;
+
+    /**
+      * Returns the hyperbolic tangent of a number.
+      * @param x A numeric expression that contains an angle measured in radians.
+      */
+    tanh(x: number): number;
+
+    /**
+      * Returns the inverse hyperbolic cosine of a number.
+      * @param x A numeric expression that contains an angle measured in radians.
+      */
+    acosh(x: number): number;
+
+    /**
+      * Returns the inverse hyperbolic sine of a number.
+      * @param x A numeric expression that contains an angle measured in radians.
+      */
+    asinh(x: number): number;
+
+    /**
+      * Returns the inverse hyperbolic tangent of a number.
+      * @param x A numeric expression that contains an angle measured in radians.
+      */
+    atanh(x: number): number;
+
+    /**
+      * Returns the square root of the sum of squares of its arguments.
+      * @param values Values to compute the square root for.
+      *     If no arguments are passed, the result is +0.
+      *     If there is only one argument, the result is the absolute value.
+      *     If any argument is +Infinity or -Infinity, the result is +Infinity.
+      *     If any argument is NaN, the result is NaN.
+      *     If all arguments are either +0 or −0, the result is +0.
+      */
+    hypot(...values: number[]): number;
+
+    /**
+      * Returns the integral part of the a numeric expression, x, removing any fractional digits.
+      * If x is already an integer, the result is x.
+      * @param x A numeric expression.
+      */
+    trunc(x: number): number;
+
+    /**
+      * Returns the nearest single precision float representation of a number.
+      * @param x A numeric expression.
+      */
+    fround(x: number): number;
+
+    /**
+      * Returns an implementation-dependent approximation to the cube root of number.
+      * @param x A numeric expression.
+      */
+    cbrt(x: number): number;
+}
+
+interface PromiseLike<T> {
+    /**
+    * Attaches callbacks for the resolution and/or rejection of the Promise.
+    * @param onfulfilled The callback to execute when the Promise is resolved.
+    * @param onrejected The callback to execute when the Promise is rejected.
+    * @returns A Promise for the completion of which ever callback is executed.
+    */
+    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
+    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;
+}
+
+/**
+ * Represents the completion of an asynchronous operation
+ */
+interface Promise<T> {
+    /**
+    * Attaches callbacks for the resolution and/or rejection of the Promise.
+    * @param onfulfilled The callback to execute when the Promise is resolved.
+    * @param onrejected The callback to execute when the Promise is rejected.
+    * @returns A Promise for the completion of which ever callback is executed.
+    */
+    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;
+    then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
+
+    /**
+     * Attaches a callback for only the rejection of the Promise.
+     * @param onrejected The callback to execute when the Promise is rejected.
+     * @returns A Promise for the completion of the callback.
+     */
+    catch(onrejected?: (reason: any) => T | PromiseLike<T>): Promise<T>;
+    catch(onrejected?: (reason: any) => void): Promise<T>;
+}
+
+interface PromiseConstructor {
+    /**
+      * A reference to the prototype.
+      */
+    prototype: Promise<any>;
+
+    /**
+     * Creates a new Promise.
+     * @param executor A callback used to initialize the promise. This callback is passed two arguments:
+     * a resolve callback used resolve the promise with a value or the result of another promise,
+     * and a reject callback used to reject the promise with a provided reason or error.
+     */
+    new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
+
+    /**
+     * Creates a Promise that is resolved with an array of results when all of the provided Promises
+     * resolve, or rejected when any Promise is rejected.
+     * @param values An array of Promises.
+     * @returns A new Promise.
+     */
+    all<T>(values: IterableShim<T | PromiseLike<T>>): Promise<T[]>;
+
+    /**
+     * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
+     * or rejected.
+     * @param values An array of Promises.
+     * @returns A new Promise.
+     */
+    race<T>(values: IterableShim<T | PromiseLike<T>>): Promise<T>;
+
+    /**
+     * Creates a new rejected promise for the provided reason.
+     * @param reason The reason the promise was rejected.
+     * @returns A new rejected Promise.
+     */
+    reject(reason: any): Promise<void>;
+
+    /**
+     * Creates a new rejected promise for the provided reason.
+     * @param reason The reason the promise was rejected.
+     * @returns A new rejected Promise.
+     */
+    reject<T>(reason: any): Promise<T>;
+
+    /**
+      * Creates a new resolved promise for the provided value.
+      * @param value A promise.
+      * @returns A promise whose internal state matches the provided promise.
+      */
+    resolve<T>(value: T | PromiseLike<T>): Promise<T>;
+
+    /**
+     * Creates a new resolved promise .
+     * @returns A resolved promise.
+     */
+    resolve(): Promise<void>;
+}
+
+declare var Promise: PromiseConstructor;
+
+interface Map<K, V> {
+    clear(): void;
+    delete(key: K): boolean;
+    forEach(callbackfn: (value: V, index: K, map: Map<K, V>) => void, thisArg?: any): void;
+    get(key: K): V;
+    has(key: K): boolean;
+    set(key: K, value?: V): Map<K, V>;
+    size: number;
+    entries(): IterableIteratorShim<[K, V]>;
+    keys(): IterableIteratorShim<K>;
+    values(): IterableIteratorShim<V>;
+}
+
+interface MapConstructor {
+    new <K, V>(): Map<K, V>;
+    new <K, V>(iterable: IterableShim<[K, V]>): Map<K, V>;
+    prototype: Map<any, any>;
+}
+
+declare var Map: MapConstructor;
+
+interface Set<T> {
+    add(value: T): Set<T>;
+    clear(): void;
+    delete(value: T): boolean;
+    forEach(callbackfn: (value: T, index: T, set: Set<T>) => void, thisArg?: any): void;
+    has(value: T): boolean;
+    size: number;
+    entries(): IterableIteratorShim<[T, T]>;
+    keys(): IterableIteratorShim<T>;
+    values(): IterableIteratorShim<T>;
+    '_es6-shim iterator_'(): IterableIteratorShim<T>;
+}
+
+interface SetConstructor {
+    new <T>(): Set<T>;
+    new <T>(iterable: IterableShim<T>): Set<T>;
+    prototype: Set<any>;
+}
+
+declare var Set: SetConstructor;
+
+interface WeakMap<K, V> {
+    delete(key: K): boolean;
+    get(key: K): V;
+    has(key: K): boolean;
+    set(key: K, value?: V): WeakMap<K, V>;
+}
+
+interface WeakMapConstructor {
+    new <K, V>(): WeakMap<K, V>;
+    new <K, V>(iterable: IterableShim<[K, V]>): WeakMap<K, V>;
+    prototype: WeakMap<any, any>;
+}
+
+declare var WeakMap: WeakMapConstructor;
+
+interface WeakSet<T> {
+    add(value: T): WeakSet<T>;
+    delete(value: T): boolean;
+    has(value: T): boolean;
+}
+
+interface WeakSetConstructor {
+    new <T>(): WeakSet<T>;
+    new <T>(iterable: IterableShim<T>): WeakSet<T>;
+    prototype: WeakSet<any>;
+}
+
+declare var WeakSet: WeakSetConstructor;
+
+declare namespace Reflect {
+    function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
+    function construct(target: Function, argumentsList: ArrayLike<any>): any;
+    function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
+    function deleteProperty(target: any, propertyKey: PropertyKey): boolean;
+    function enumerate(target: any): IterableIteratorShim<any>;
+    function get(target: any, propertyKey: PropertyKey, receiver?: any): any;
+    function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor;
+    function getPrototypeOf(target: any): any;
+    function has(target: any, propertyKey: PropertyKey): boolean;
+    function isExtensible(target: any): boolean;
+    function ownKeys(target: any): Array<PropertyKey>;
+    function preventExtensions(target: any): boolean;
+    function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean;
+    function setPrototypeOf(target: any, proto: any): boolean;
+}
+
+declare module "es6-shim" {
+    var String: StringConstructor;
+    var Array: ArrayConstructor;
+    var Number: NumberConstructor;
+    var Math: Math;
+    var Object: ObjectConstructor;
+    var Map: MapConstructor;
+    var Set: SetConstructor;
+    var WeakMap: WeakMapConstructor;
+    var WeakSet: WeakSetConstructor;
+    var Promise: PromiseConstructor;
+    namespace Reflect {
+        function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
+        function construct(target: Function, argumentsList: ArrayLike<any>): any;
+        function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
+        function deleteProperty(target: any, propertyKey: PropertyKey): boolean;
+        function enumerate(target: any): Iterator<any>;
+        function get(target: any, propertyKey: PropertyKey, receiver?: any): any;
+        function getOwnPropertyDescriptor(target: any, propertyKey: PropertyKey): PropertyDescriptor;
+        function getPrototypeOf(target: any): any;
+        function has(target: any, propertyKey: PropertyKey): boolean;
+        function isExtensible(target: any): boolean;
+        function ownKeys(target: any): Array<PropertyKey>;
+        function preventExtensions(target: any): boolean;
+        function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean;
+        function setPrototypeOf(target: any, proto: any): boolean;
+    }
+}
diff --git a/typings/globals/es6-shim/typings.json b/typings/globals/es6-shim/typings.json
new file mode 100644
index 0000000..9a84847
--- /dev/null
+++ b/typings/globals/es6-shim/typings.json
@@ -0,0 +1,8 @@
+{
+  "resolution": "main",
+  "tree": {
+    "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/9807d9b701f58be068cb07833d2b24235351d052/es6-shim/es6-shim.d.ts",
+    "raw": "registry:dt/es6-shim#0.31.2+20160602141504",
+    "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/9807d9b701f58be068cb07833d2b24235351d052/es6-shim/es6-shim.d.ts"
+  }
+}
diff --git a/typings/globals/jasmine/index.d.ts b/typings/globals/jasmine/index.d.ts
new file mode 100644
index 0000000..3e63179
--- /dev/null
+++ b/typings/globals/jasmine/index.d.ts
@@ -0,0 +1,489 @@
+// Generated by typings
+// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/dc9dabe74a5be62613b17a3605309783a12ff28a/jasmine/jasmine.d.ts
+declare function describe(description: string, specDefinitions: () => void): void;
+declare function fdescribe(description: string, specDefinitions: () => void): void;
+declare function xdescribe(description: string, specDefinitions: () => void): void;
+
+declare function it(expectation: string, assertion?: () => void, timeout?: number): void;
+declare function it(expectation: string, assertion?: (done: () => void) => void, timeout?: number): void;
+declare function fit(expectation: string, assertion?: () => void, timeout?: number): void;
+declare function fit(expectation: string, assertion?: (done: () => void) => void, timeout?: number): void;
+declare function xit(expectation: string, assertion?: () => void, timeout?: number): void;
+declare function xit(expectation: string, assertion?: (done: () => void) => void, timeout?: number): void;
+
+/** If you call the function pending anywhere in the spec body, no matter the expectations, the spec will be marked pending. */
+declare function pending(reason?: string): void;
+
+declare function beforeEach(action: () => void, timeout?: number): void;
+declare function beforeEach(action: (done: () => void) => void, timeout?: number): void;
+declare function afterEach(action: () => void, timeout?: number): void;
+declare function afterEach(action: (done: () => void) => void, timeout?: number): void;
+
+declare function beforeAll(action: () => void, timeout?: number): void;
+declare function beforeAll(action: (done: () => void) => void, timeout?: number): void;
+declare function afterAll(action: () => void, timeout?: number): void;
+declare function afterAll(action: (done: () => void) => void, timeout?: number): void;
+
+declare function expect(spy: Function): jasmine.Matchers;
+declare function expect(actual: any): jasmine.Matchers;
+
+declare function fail(e?: any): void;
+
+declare function spyOn(object: any, method: string): jasmine.Spy;
+
+declare function runs(asyncMethod: Function): void;
+declare function waitsFor(latchMethod: () => boolean, failureMessage?: string, timeout?: number): void;
+declare function waits(timeout?: number): void;
+
+declare module jasmine {
+
+    var clock: () => Clock;
+
+    function any(aclass: any): Any;
+    function anything(): Any;
+    function arrayContaining(sample: any[]): ArrayContaining;
+    function objectContaining(sample: any): ObjectContaining;
+    function createSpy(name: string, originalFn?: Function): Spy;
+    function createSpyObj(baseName: string, methodNames: any[]): any;
+    function createSpyObj<T>(baseName: string, methodNames: any[]): T;
+    function pp(value: any): string;
+    function getEnv(): Env;
+    function addCustomEqualityTester(equalityTester: CustomEqualityTester): void;
+    function addMatchers(matchers: CustomMatcherFactories): void;
+    function stringMatching(str: string): Any;
+    function stringMatching(str: RegExp): Any;
+
+    interface Any {
+
+        new (expectedClass: any): any;
+
+        jasmineMatches(other: any): boolean;
+        jasmineToString(): string;
+    }
+
+    // taken from TypeScript lib.core.es6.d.ts, applicable to CustomMatchers.contains()
+    interface ArrayLike<T> {
+        length: number;
+        [n: number]: T;
+    }
+
+    interface ArrayContaining {
+        new (sample: any[]): any;
+
+        asymmetricMatch(other: any): boolean;
+        jasmineToString(): string;
+    }
+
+    interface ObjectContaining {
+        new (sample: any): any;
+
+        jasmineMatches(other: any, mismatchKeys: any[], mismatchValues: any[]): boolean;
+        jasmineToString(): string;
+    }
+
+    interface Block {
+
+        new (env: Env, func: SpecFunction, spec: Spec): any;
+
+        execute(onComplete: () => void): void;
+    }
+
+    interface WaitsBlock extends Block {
+        new (env: Env, timeout: number, spec: Spec): any;
+    }
+
+    interface WaitsForBlock extends Block {
+        new (env: Env, timeout: number, latchFunction: SpecFunction, message: string, spec: Spec): any;
+    }
+
+    interface Clock {
+        install(): void;
+        uninstall(): void;
+        /** Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds. */
+        tick(ms: number): void;
+        mockDate(date?: Date): void;
+    }
+
+    interface CustomEqualityTester {
+        (first: any, second: any): boolean;
+    }
+
+    interface CustomMatcher {
+        compare<T>(actual: T, expected: T): CustomMatcherResult;
+        compare(actual: any, expected: any): CustomMatcherResult;
+    }
+
+    interface CustomMatcherFactory {
+        (util: MatchersUtil, customEqualityTesters: Array<CustomEqualityTester>): CustomMatcher;
+    }
+
+    interface CustomMatcherFactories {
+        [index: string]: CustomMatcherFactory;
+    }
+
+    interface CustomMatcherResult {
+        pass: boolean;
+        message?: string;
+    }
+
+    interface MatchersUtil {
+        equals(a: any, b: any, customTesters?: Array<CustomEqualityTester>): boolean;
+        contains<T>(haystack: ArrayLike<T> | string, needle: any, customTesters?: Array<CustomEqualityTester>): boolean;
+        buildFailureMessage(matcherName: string, isNot: boolean, actual: any, ...expected: Array<any>): string;
+    }
+
+    interface Env {
+        setTimeout: any;
+        clearTimeout: void;
+        setInterval: any;
+        clearInterval: void;
+        updateInterval: number;
+
+        currentSpec: Spec;
+
+        matchersClass: Matchers;
+
+        version(): any;
+        versionString(): string;
+        nextSpecId(): number;
+        addReporter(reporter: Reporter): void;
+        execute(): void;
+        describe(description: string, specDefinitions: () => void): Suite;
+        // ddescribe(description: string, specDefinitions: () => void): Suite; Not a part of jasmine. Angular team adds these
+        beforeEach(beforeEachFunction: () => void): void;
+        beforeAll(beforeAllFunction: () => void): void;
+        currentRunner(): Runner;
+        afterEach(afterEachFunction: () => void): void;
+        afterAll(afterAllFunction: () => void): void;
+        xdescribe(desc: string, specDefinitions: () => void): XSuite;
+        it(description: string, func: () => void): Spec;
+        // iit(description: string, func: () => void): Spec; Not a part of jasmine. Angular team adds these
+        xit(desc: string, func: () => void): XSpec;
+        compareRegExps_(a: RegExp, b: RegExp, mismatchKeys: string[], mismatchValues: string[]): boolean;
+        compareObjects_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean;
+        equals_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean;
+        contains_(haystack: any, needle: any): boolean;
+        addCustomEqualityTester(equalityTester: CustomEqualityTester): void;
+        addMatchers(matchers: CustomMatcherFactories): void;
+        specFilter(spec: Spec): boolean;
+    }
+
+    interface FakeTimer {
+
+        new (): any;
+
+        reset(): void;
+        tick(millis: number): void;
+        runFunctionsWithinRange(oldMillis: number, nowMillis: number): void;
+        scheduleFunction(timeoutKey: any, funcToCall: () => void, millis: number, recurring: boolean): void;
+    }
+
+    interface HtmlReporter {
+        new (): any;
+    }
+
+    interface HtmlSpecFilter {
+        new (): any;
+    }
+
+    interface Result {
+        type: string;
+    }
+
+    interface NestedResults extends Result {
+        description: string;
+
+        totalCount: number;
+        passedCount: number;
+        failedCount: number;
+
+        skipped: boolean;
+
+        rollupCounts(result: NestedResults): void;
+        log(values: any): void;
+        getItems(): Result[];
+        addResult(result: Result): void;
+        passed(): boolean;
+    }
+
+    interface MessageResult extends Result  {
+        values: any;
+        trace: Trace;
+    }
+
+    interface ExpectationResult extends Result  {
+        matcherName: string;
+        passed(): boolean;
+        expected: any;
+        actual: any;
+        message: string;
+        trace: Trace;
+    }
+
+    interface Trace {
+        name: string;
+        message: string;
+        stack: any;
+    }
+
+    interface PrettyPrinter {
+
+        new (): any;
+
+        format(value: any): void;
+        iterateObject(obj: any, fn: (property: string, isGetter: boolean) => void): void;
+        emitScalar(value: any): void;
+        emitString(value: string): void;
+        emitArray(array: any[]): void;
+        emitObject(obj: any): void;
+        append(value: any): void;
+    }
+
+    interface StringPrettyPrinter extends PrettyPrinter {
+    }
+
+    interface Queue {
+
+        new (env: any): any;
+
+        env: Env;
+        ensured: boolean[];
+        blocks: Block[];
+        running: boolean;
+        index: number;
+        offset: number;
+        abort: boolean;
+
+        addBefore(block: Block, ensure?: boolean): void;
+        add(block: any, ensure?: boolean): void;
+        insertNext(block: any, ensure?: boolean): void;
+        start(onComplete?: () => void): void;
+        isRunning(): boolean;
+        next_(): void;
+        results(): NestedResults;
+    }
+
+    interface Matchers {
+
+        new (env: Env, actual: any, spec: Env, isNot?: boolean): any;
+
+        env: Env;
+        actual: any;
+        spec: Env;
+        isNot?: boolean;
+        message(): any;
+
+        toBe(expected: any, expectationFailOutput?: any): boolean;
+        toEqual(expected: any, expectationFailOutput?: any): boolean;
+        toMatch(expected: string | RegExp, expectationFailOutput?: any): boolean;
+        toBeDefined(expectationFailOutput?: any): boolean;
+        toBeUndefined(expectationFailOutput?: any): boolean;
+        toBeNull(expectationFailOutput?: any): boolean;
+        toBeNaN(): boolean;
+        toBeTruthy(expectationFailOutput?: any): boolean;
+        toBeFalsy(expectationFailOutput?: any): boolean;
+        toHaveBeenCalled(): boolean;
+        toHaveBeenCalledWith(...params: any[]): boolean;
+        toContain(expected: any, expectationFailOutput?: any): boolean;
+        toBeLessThan(expected: number, expectationFailOutput?: any): boolean;
+        toBeGreaterThan(expected: number, expectationFailOutput?: any): boolean;
+        toBeCloseTo(expected: number, precision: any, expectationFailOutput?: any): boolean;
+        toThrow(expected?: any): boolean;
+        toThrowError(message?: string | RegExp): boolean;
+        toThrowError(expected?: Error, message?: string | RegExp): boolean;
+        not: Matchers;
+
+        Any: Any;
+    }
+
+    interface Reporter {
+        reportRunnerStarting(runner: Runner): void;
+        reportRunnerResults(runner: Runner): void;
+        reportSuiteResults(suite: Suite): void;
+        reportSpecStarting(spec: Spec): void;
+        reportSpecResults(spec: Spec): void;
+        log(str: string): void;
+    }
+
+    interface MultiReporter extends Reporter {
+        addReporter(reporter: Reporter): void;
+    }
+
+    interface Runner {
+
+        new (env: Env): any;
+
+        execute(): void;
+        beforeEach(beforeEachFunction: SpecFunction): void;
+        afterEach(afterEachFunction: SpecFunction): void;
+        beforeAll(beforeAllFunction: SpecFunction): void;
+        afterAll(afterAllFunction: SpecFunction): void;
+        finishCallback(): void;
+        addSuite(suite: Suite): void;
+        add(block: Block): void;
+        specs(): Spec[];
+        suites(): Suite[];
+        topLevelSuites(): Suite[];
+        results(): NestedResults;
+    }
+
+    interface SpecFunction {
+        (spec?: Spec): void;
+    }
+
+    interface SuiteOrSpec {
+        id: number;
+        env: Env;
+        description: string;
+        queue: Queue;
+    }
+
+    interface Spec extends SuiteOrSpec {
+
+        new (env: Env, suite: Suite, description: string): any;
+
+        suite: Suite;
+
+        afterCallbacks: SpecFunction[];
+        spies_: Spy[];
+
+        results_: NestedResults;
+        matchersClass: Matchers;
+
+        getFullName(): string;
+        results(): NestedResults;
+        log(arguments: any): any;
+        runs(func: SpecFunction): Spec;
+        addToQueue(block: Block): void;
+        addMatcherResult(result: Result): void;
+        expect(actual: any): any;
+        waits(timeout: number): Spec;
+        waitsFor(latchFunction: SpecFunction, timeoutMessage?: string, timeout?: number): Spec;
+        fail(e?: any): void;
+        getMatchersClass_(): Matchers;
+        addMatchers(matchersPrototype: CustomMatcherFactories): void;
+        finishCallback(): void;
+        finish(onComplete?: () => void): void;
+        after(doAfter: SpecFunction): void;
+        execute(onComplete?: () => void): any;
+        addBeforesAndAftersToQueue(): void;
+        explodes(): void;
+        spyOn(obj: any, methodName: string, ignoreMethodDoesntExist: boolean): Spy;
+        removeAllSpies(): void;
+    }
+
+    interface XSpec {
+        id: number;
+        runs(): void;
+    }
+
+    interface Suite extends SuiteOrSpec {
+
+        new (env: Env, description: string, specDefinitions: () => void, parentSuite: Suite): any;
+
+        parentSuite: Suite;
+
+        getFullName(): string;
+        finish(onComplete?: () => void): void;
+        beforeEach(beforeEachFunction: SpecFunction): void;
+        afterEach(afterEachFunction: SpecFunction): void;
+        beforeAll(beforeAllFunction: SpecFunction): void;
+        afterAll(afterAllFunction: SpecFunction): void;
+        results(): NestedResults;
+        add(suiteOrSpec: SuiteOrSpec): void;
+        specs(): Spec[];
+        suites(): Suite[];
+        children(): any[];
+        execute(onComplete?: () => void): void;
+    }
+
+    interface XSuite {
+        execute(): void;
+    }
+
+    interface Spy {
+        (...params: any[]): any;
+
+        identity: string;
+        and: SpyAnd;
+        calls: Calls;
+        mostRecentCall: { args: any[]; };
+        argsForCall: any[];
+        wasCalled: boolean;
+    }
+
+    interface SpyAnd {
+        /** By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation. */
+        callThrough(): Spy;
+        /** By chaining the spy with and.returnValue, all calls to the function will return a specific value. */
+        returnValue(val: any): void;
+        /** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function. */
+        callFake(fn: Function): Spy;
+        /** By chaining the spy with and.throwError, all calls to the spy will throw the specified value. */
+        throwError(msg: string): void;
+        /** When a calling strategy is used for a spy, the original stubbing behavior can be returned at any time with and.stub. */
+        stub(): Spy;
+    }
+
+    interface Calls {
+        /** By chaining the spy with calls.any(), will return false if the spy has not been called at all, and then true once at least one call happens. **/
+        any(): boolean;
+        /** By chaining the spy with calls.count(), will return the number of times the spy was called **/
+        count(): number;
+        /** By chaining the spy with calls.argsFor(), will return the arguments passed to call number index **/
+        argsFor(index: number): any[];
+        /** By chaining the spy with calls.allArgs(), will return the arguments to all calls **/
+        allArgs(): any[];
+        /** By chaining the spy with calls.all(), will return the context (the this) and arguments passed all calls **/
+        all(): CallInfo[];
+        /** By chaining the spy with calls.mostRecent(), will return the context (the this) and arguments for the most recent call **/
+        mostRecent(): CallInfo;
+        /** By chaining the spy with calls.first(), will return the context (the this) and arguments for the first call **/
+        first(): CallInfo;
+        /** By chaining the spy with calls.reset(), will clears all tracking for a spy **/
+        reset(): void;
+    }
+
+    interface CallInfo {
+        /** The context (the this) for the call */
+        object: any;
+        /** All arguments passed to the call */
+        args: any[];
+    }
+
+    interface Util {
+        inherit(childClass: Function, parentClass: Function): any;
+        formatException(e: any): any;
+        htmlEscape(str: string): string;
+        argsToArray(args: any): any;
+        extend(destination: any, source: any): any;
+    }
+
+    interface JsApiReporter extends Reporter {
+
+        started: boolean;
+        finished: boolean;
+        result: any;
+        messages: any;
+
+        new (): any;
+
+        suites(): Suite[];
+        summarize_(suiteOrSpec: SuiteOrSpec): any;
+        results(): any;
+        resultsForSpec(specId: any): any;
+        log(str: any): any;
+        resultsForSpecs(specIds: any): any;
+        summarizeResult_(result: any): any;
+    }
+
+    interface Jasmine {
+        Spec: Spec;
+        clock: Clock;
+        util: Util;
+    }
+
+    export var HtmlReporter: HtmlReporter;
+    export var HtmlSpecFilter: HtmlSpecFilter;
+    export var DEFAULT_TIMEOUT_INTERVAL: number;
+}
diff --git a/typings/globals/jasmine/typings.json b/typings/globals/jasmine/typings.json
new file mode 100644
index 0000000..b8e2a53
--- /dev/null
+++ b/typings/globals/jasmine/typings.json
@@ -0,0 +1,8 @@
+{
+  "resolution": "main",
+  "tree": {
+    "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/dc9dabe74a5be62613b17a3605309783a12ff28a/jasmine/jasmine.d.ts",
+    "raw": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#dc9dabe74a5be62613b17a3605309783a12ff28a",
+    "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/dc9dabe74a5be62613b17a3605309783a12ff28a/jasmine/jasmine.d.ts"
+  }
+}
diff --git a/typings/globals/require/index.d.ts b/typings/globals/require/index.d.ts
new file mode 100644
index 0000000..ca713f4
--- /dev/null
+++ b/typings/globals/require/index.d.ts
@@ -0,0 +1,368 @@
+// Generated by typings
+// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/56295f5058cac7ae458540423c50ac2dcf9fc711/requirejs/require.d.ts
+declare module 'module' {
+	var mod: {
+		config: () => any;
+		id: string;
+		uri: string;
+	}
+	export = mod;
+}
+
+interface RequireError extends Error {
+
+	/**
+	* The error ID that maps to an ID on a web page.
+	**/
+	requireType: string;
+
+	/**
+	* Required modules.
+	**/
+	requireModules: string[];
+
+	/**
+	* The original error, if there is one (might be null).
+	**/
+	originalError: Error;
+}
+
+interface RequireShim {
+
+	/**
+	* List of dependencies.
+	**/
+	deps?: string[];
+
+	/**
+	* Name the module will be exported as.
+	**/
+	exports?: string;
+
+	/**
+	* Initialize function with all dependcies passed in,
+	* if the function returns a value then that value is used
+	* as the module export value instead of the object
+	* found via the 'exports' string.
+	* @param dependencies
+	* @return
+	**/
+	init?: (...dependencies: any[]) => any;
+}
+
+interface RequireConfig {
+
+	// The root path to use for all module lookups.
+	baseUrl?: string;
+
+	// Path mappings for module names not found directly under
+	// baseUrl.
+	paths?: { [key: string]: any; };
+
+
+	// Dictionary of Shim's.
+	// does not cover case of key->string[]
+	shim?: { [key: string]: RequireShim; };
+
+	/**
+	* For the given module prefix, instead of loading the
+	* module with the given ID, substitude a different
+	* module ID.
+	*
+	* @example
+	* requirejs.config({
+	*	map: {
+	*		'some/newmodule': {
+	*			'foo': 'foo1.2'
+	*		},
+	*		'some/oldmodule': {
+	*			'foo': 'foo1.0'
+	*		}
+	*	}
+	* });
+	**/
+	map?: {
+		[id: string]: {
+			[id: string]: string;
+		};
+	};
+
+	/**
+	* Allows pointing multiple module IDs to a module ID that contains a bundle of modules.
+	*
+	* @example
+	* requirejs.config({
+	*	bundles: {
+	*		'primary': ['main', 'util', 'text', 'text!template.html'],
+	*		'secondary': ['text!secondary.html']
+	*	}
+	* });
+	**/
+	bundles?: { [key: string]: string[]; };
+
+	/**
+	* AMD configurations, use module.config() to access in
+	* define() functions
+	**/
+	config?: { [id: string]: {}; };
+
+	/**
+	* Configures loading modules from CommonJS packages.
+	**/
+	packages?: {};
+
+	/**
+	* The number of seconds to wait before giving up on loading
+	* a script.  The default is 7 seconds.
+	**/
+	waitSeconds?: number;
+
+	/**
+	* A name to give to a loading context.  This allows require.js
+	* to load multiple versions of modules in a page, as long as
+	* each top-level require call specifies a unique context string.
+	**/
+	context?: string;
+
+	/**
+	* An array of dependencies to load.
+	**/
+	deps?: string[];
+
+	/**
+	* A function to pass to require that should be require after
+	* deps have been loaded.
+	* @param modules
+	**/
+	callback?: (...modules: any[]) => void;
+
+	/**
+	* If set to true, an error will be thrown if a script loads
+	* that does not call define() or have shim exports string
+	* value that can be checked.
+	**/
+	enforceDefine?: boolean;
+
+	/**
+	* If set to true, document.createElementNS() will be used
+	* to create script elements.
+	**/
+	xhtml?: boolean;
+
+	/**
+	* Extra query string arguments appended to URLs that RequireJS
+	* uses to fetch resources.  Most useful to cache bust when
+	* the browser or server is not configured correctly.
+	*
+	* @example
+	* urlArgs: "bust= + (new Date()).getTime()
+	**/
+	urlArgs?: string;
+
+	/**
+	* Specify the value for the type="" attribute used for script
+	* tags inserted into the document by RequireJS.  Default is
+	* "text/javascript".  To use Firefox's JavasScript 1.8
+	* features, use "text/javascript;version=1.8".
+	**/
+	scriptType?: string;
+
+	/**
+	* If set to true, skips the data-main attribute scanning done
+	* to start module loading. Useful if RequireJS is embedded in
+	* a utility library that may interact with other RequireJS
+	* library on the page, and the embedded version should not do
+	* data-main loading.
+	**/
+	skipDataMain?: boolean;
+
+	/**
+	* Allow extending requirejs to support Subresource Integrity
+	* (SRI).
+	**/
+	onNodeCreated?: (node: HTMLScriptElement, config: RequireConfig, moduleName: string, url: string) => void;
+}
+
+// todo: not sure what to do with this guy
+interface RequireModule {
+
+	/**
+	*
+	**/
+	config(): {};
+
+}
+
+/**
+*
+**/
+interface RequireMap {
+
+	/**
+	*
+	**/
+	prefix: string;
+
+	/**
+	*
+	**/
+	name: string;
+
+	/**
+	*
+	**/
+	parentMap: RequireMap;
+
+	/**
+	*
+	**/
+	url: string;
+
+	/**
+	*
+	**/
+	originalName: string;
+
+	/**
+	*
+	**/
+	fullName: string;
+}
+
+interface Require {
+
+	/**
+	* Configure require.js
+	**/
+	config(config: RequireConfig): Require;
+
+	/**
+	* CommonJS require call
+	* @param module Module to load
+	* @return The loaded module
+	*/
+	(module: string): any;
+
+	/**
+	* Start the main app logic.
+	* Callback is optional.
+	* Can alternatively use deps and callback.
+	* @param modules Required modules to load.
+	**/
+	(modules: string[]): void;
+
+	/**
+	* @see Require()
+	* @param ready Called when required modules are ready.
+	**/
+	(modules: string[], ready: Function): void;
+
+	/**
+	* @see http://requirejs.org/docs/api.html#errbacks
+	* @param ready Called when required modules are ready.
+	**/
+	(modules: string[], ready: Function, errback: Function): void;
+
+	/**
+	* Generate URLs from require module
+	* @param module Module to URL
+	* @return URL string
+	**/
+	toUrl(module: string): string;
+
+	/**
+	* Returns true if the module has already been loaded and defined.
+	* @param module Module to check
+	**/
+	defined(module: string): boolean;
+
+	/**
+	* Returns true if the module has already been requested or is in the process of loading and should be available at some point.
+	* @param module Module to check
+	**/
+	specified(module: string): boolean;
+
+	/**
+	* On Error override
+	* @param err
+	**/
+	onError(err: RequireError, errback?: (err: RequireError) => void): void;
+
+	/**
+	* Undefine a module
+	* @param module Module to undefine.
+	**/
+	undef(module: string): void;
+
+	/**
+	* Semi-private function, overload in special instance of undef()
+	**/
+	onResourceLoad(context: Object, map: RequireMap, depArray: RequireMap[]): void;
+}
+
+interface RequireDefine {
+
+	/**
+	* Define Simple Name/Value Pairs
+	* @param config Dictionary of Named/Value pairs for the config.
+	**/
+	(config: { [key: string]: any; }): void;
+
+	/**
+	* Define function.
+	* @param func: The function module.
+	**/
+	(func: () => any): void;
+
+	/**
+	* Define function with dependencies.
+	* @param deps List of dependencies module IDs.
+	* @param ready Callback function when the dependencies are loaded.
+	*	callback param deps module dependencies
+	*	callback return module definition
+	**/
+    	(deps: string[], ready: Function): void;
+
+	/**
+	*  Define module with simplified CommonJS wrapper.
+	* @param ready
+	*	callback require requirejs instance
+	*	callback exports exports object
+	*	callback module module
+	*	callback return module definition
+	**/
+	(ready: (require: Require, exports: { [key: string]: any; }, module: RequireModule) => any): void;
+
+	/**
+	* Define a module with a name and dependencies.
+	* @param name The name of the module.
+	* @param deps List of dependencies module IDs.
+	* @param ready Callback function when the dependencies are loaded.
+	*	callback deps module dependencies
+	*	callback return module definition
+	**/
+	(name: string, deps: string[], ready: Function): void;
+
+	/**
+	* Define a module with a name.
+	* @param name The name of the module.
+	* @param ready Callback function when the dependencies are loaded.
+	*	callback return module definition
+	**/
+	(name: string, ready: Function): void;
+
+	/**
+	* Used to allow a clear indicator that a global define function (as needed for script src browser loading) conforms
+	* to the AMD API, any global define function SHOULD have a property called "amd" whose value is an object.
+	* This helps avoid conflict with any other existing JavaScript code that could have defined a define() function
+	* that does not conform to the AMD API.
+	* define.amd.jQuery is specific to jQuery and indicates that the loader is able to account for multiple version
+	* of jQuery being loaded simultaneously.
+	*/
+	amd: Object;
+}
+
+// Ambient declarations for 'require' and 'define'
+declare var requirejs: Require;
+declare var require: Require;
+declare var define: RequireDefine;
diff --git a/typings/globals/require/typings.json b/typings/globals/require/typings.json
new file mode 100644
index 0000000..446025f
--- /dev/null
+++ b/typings/globals/require/typings.json
@@ -0,0 +1,8 @@
+{
+  "resolution": "main",
+  "tree": {
+    "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/56295f5058cac7ae458540423c50ac2dcf9fc711/requirejs/require.d.ts",
+    "raw": "registry:dt/require#2.1.20+20160316155526",
+    "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/56295f5058cac7ae458540423c50ac2dcf9fc711/requirejs/require.d.ts"
+  }
+}
diff --git a/typings/index.d.ts b/typings/index.d.ts
new file mode 100644
index 0000000..2613c55
--- /dev/null
+++ b/typings/index.d.ts
@@ -0,0 +1,3 @@
+/// <reference path="globals/es6-shim/index.d.ts" />
+/// <reference path="globals/jasmine/index.d.ts" />
+/// <reference path="globals/require/index.d.ts" />