diff --git a/samples/angular-migration/README.md b/samples/angular-migration/README.md
new file mode 100644
index 000000000..7ec65612a
--- /dev/null
+++ b/samples/angular-migration/README.md
@@ -0,0 +1,39 @@
+# Migrating existing Angular applications to SharePoint Framework sample
+
+## Summary
+
+Sample Angular application before and after migration to a SharePoint Framework client-side web part.
+
+Application before migration:
+![Angular todo application](./assets/angular-todo-preview.png)
+
+Application after migration:
+![Angular todo application as a SharePoint Framework client-side web part](./assets/angular-todo-spfx-preview.png)
+
+## Applies to
+
+* [SharePoint Framework Developer Preview](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
+* [Office 365 developer tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
+
+## Solution
+
+Solution|Author(s)
+--------|---------
+angular-migration|Waldek Mastykarz (MVP, Rencore, @waldekm)
+
+## Version history
+
+Version|Date|Comments
+-------|----|--------
+1.0.0|October 21, 2016|Initial release
+
+## Disclaimer
+**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
+
+---
+
+Follow the setup instructions:
+- [Angular application](./angular-todo/README.md)
+- [SharePoint Framework client-side web part](./angular-todo-webpart/README.md)
+
+![](https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/angular-migration)
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/.editorconfig b/samples/angular-migration/angular-todo-webpart/.editorconfig
new file mode 100755
index 000000000..8ffcdc4ec
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/.editorconfig
@@ -0,0 +1,25 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+
+[*]
+
+# change these settings to your own preference
+indent_style = space
+indent_size = 2
+
+# we recommend you to keep these unchanged
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[{package,bower}.json]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/.gitattributes b/samples/angular-migration/angular-todo-webpart/.gitattributes
new file mode 100755
index 000000000..212566614
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/.gitattributes
@@ -0,0 +1 @@
+* text=auto
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/.gitignore b/samples/angular-migration/angular-todo-webpart/.gitignore
new file mode 100755
index 000000000..63c4ae010
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/.gitignore
@@ -0,0 +1,32 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+
+# Dependency directories
+node_modules
+
+# Build generated files
+dist
+lib
+solution
+temp
+*.spapp
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# OSX
+.DS_Store
+
+# Visual Studio files
+.ntvs_analysis.dat
+.vs
+bin
+obj
+
+# Resx Generated Code
+*.resx.ts
+
+# Styles Generated Code
+*.scss.ts
diff --git a/samples/angular-migration/angular-todo-webpart/.npmignore b/samples/angular-migration/angular-todo-webpart/.npmignore
new file mode 100755
index 000000000..2c93a9384
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/.npmignore
@@ -0,0 +1,14 @@
+# Folders
+.vscode
+coverage
+node_modules
+sharepoint
+src
+temp
+
+# Files
+*.csproj
+.git*
+.yo-rc.json
+gulpfile.js
+tsconfig.json
diff --git a/samples/angular-migration/angular-todo-webpart/.vscode/settings.json b/samples/angular-migration/angular-todo-webpart/.vscode/settings.json
new file mode 100755
index 000000000..ab46aaa4f
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/.vscode/settings.json
@@ -0,0 +1,21 @@
+{
+ // The number of spaces a tab is equal to.
+ "editor.tabSize": 2,
+
+ // When enabled, will trim trailing whitespace when you save a file.
+ "files.trimTrailingWhitespace": true,
+
+ // Controls if the editor should automatically close brackets after opening them
+ "editor.autoClosingBrackets": false,
+
+ // Configure glob patterns for excluding files and folders.
+ "search.exclude": {
+ "**/bower_components": true,
+ "**/node_modules": true,
+ "coverage": true,
+ "dist": true,
+ "lib-amd": true,
+ "lib": true,
+ "temp": true
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/.vscode/tasks.json b/samples/angular-migration/angular-todo-webpart/.vscode/tasks.json
new file mode 100755
index 000000000..5204908d6
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/.vscode/tasks.json
@@ -0,0 +1,34 @@
+{
+ // See http://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "0.1.0",
+ "command": "gulp",
+ "isShellCommand": true,
+ "showOutput": "always",
+ "args": [
+ "--no-color"
+ ],
+ "tasks": [
+ {
+ "taskName": "bundle",
+ "isBuildCommand": true,
+ "problemMatcher": [
+ "$tsc"
+ ]
+ },
+ {
+ "taskName": "test",
+ "isTestCommand": true,
+ "problemMatcher": [
+ "$tsc"
+ ]
+ },
+ {
+ "taskName": "serve",
+ "isWatching": true,
+ "problemMatcher": [
+ "$tsc"
+ ]
+ }
+ ]
+}
diff --git a/samples/angular-migration/angular-todo-webpart/.yo-rc.json b/samples/angular-migration/angular-todo-webpart/.yo-rc.json
new file mode 100755
index 000000000..ee34aec47
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/.yo-rc.json
@@ -0,0 +1,7 @@
+{
+ "@microsoft/generator-sharepoint": {
+ "libraryName": "angular-todo-webpart",
+ "libraryId": "27900554-c8a2-437a-b1de-0f1bd05d8145",
+ "framework": "none"
+ }
+}
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/README.md b/samples/angular-migration/angular-todo-webpart/README.md
new file mode 100755
index 000000000..1f91691fb
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/README.md
@@ -0,0 +1,56 @@
+# SharePoint Framework todo web part built with Angular
+
+## Summary
+
+Sample SharePoint Framework client-side web part for managing tasks stored in a SharePoint list, built using Angular.
+
+![Angular todo application as a SharePoint Framework client-side web part](../assets/angular-todo-spfx-preview.png)
+
+## Applies to
+
+* [SharePoint Framework Developer Preview](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
+* [Office 365 developer tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
+
+## Solution
+
+Solution|Author(s)
+--------|---------
+angular-todo-webpart|Waldek Mastykarz (MVP, Rencore, @waldekm)
+
+## Version history
+
+Version|Date|Comments
+-------|----|--------
+1.0.0|October 21, 2016|Initial release
+
+## Disclaimer
+**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
+
+---
+
+## Minimal Path to Awesome
+
+- create **Todo** list
+ - in SharePoint site create a new list called `Todo`
+ - in the **Todo** list add a new choice column called `Status`
+ - as available choices enter (each value in new line): `Not started`, `In progress`, `Completed`
+- deploy web part
+ - clone this repo
+ - in the command line execute:
+ - `npm i`
+ - `gulp serve --nobrowser`
+ - create a copy of the **./temp/workbench.html** file and change its extension to **.aspx**
+ - in the **workbench.aspx** file, change the value of the **webAbsoluteUrl** property to the absolute URL of your SharePoint site
+ - upload the **workbench.aspx** file to a document library in your site
+- in the web browser navigate to the **workbench.aspx** page
+
+## Features
+
+Sample web part in this solution illustrates the following concepts on top of the SharePoint Framework:
+
+- building SharePoint Framework client-side web parts with Angular
+- building Angular applications with TypeScript
+- communicating with the SharePoint REST API in Angular applications
+- passing web part properties values into Angular application
+
+![](https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/angular-todo/angular-spfx)
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/angular-todo.njsproj b/samples/angular-migration/angular-todo-webpart/angular-todo.njsproj
new file mode 100755
index 000000000..fbe5c5caa
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/angular-todo.njsproj
@@ -0,0 +1,86 @@
+
+
+
+ Debug
+ 2.0
+ {27900554-c8a2-437a-b1de-0f1bd05d8145}
+
+ ProjectFiles
+ node_modules\gulp\bin\gulp.js
+ .
+ .
+ {3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}
+ true
+ CommonJS
+ false
+ 11.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+ serve
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ True
+ 0
+ /
+ http://localhost:48022/
+ False
+ True
+ http://localhost:1337
+ False
+
+
+
+
+
+
+ CurrentPage
+ True
+ False
+ False
+ False
+
+
+
+
+
+
+
+
+ False
+ False
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/config/config.json b/samples/angular-migration/angular-todo-webpart/config/config.json
new file mode 100755
index 000000000..655e413c5
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/config/config.json
@@ -0,0 +1,26 @@
+{
+ "entries": [
+ {
+ "entry": "./lib/webparts/toDo/ToDoWebPart.js",
+ "manifest": "./src/webparts/toDo/ToDoWebPart.manifest.json",
+ "outputPath": "./dist/to-do.bundle.js"
+ }
+ ],
+ "externals": {
+ "@microsoft/sp-client-base": "node_modules/@microsoft/sp-client-base/dist/sp-client-base.js",
+ "@microsoft/sp-client-preview": "node_modules/@microsoft/sp-client-preview/dist/sp-client-preview.js",
+ "@microsoft/sp-lodash-subset": "node_modules/@microsoft/sp-lodash-subset/dist/sp-lodash-subset.js",
+ "office-ui-fabric-react": "node_modules/office-ui-fabric-react/dist/office-ui-fabric-react.js",
+ "react": "node_modules/react/dist/react.min.js",
+ "react-dom": "node_modules/react-dom/dist/react-dom.min.js",
+ "react-dom/server": "node_modules/react-dom/dist/react-dom-server.min.js",
+ "angular": {
+ "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
+ "globalName": "angular"
+ },
+ "ng-office-ui-fabric": "https://cdnjs.cloudflare.com/ajax/libs/ngOfficeUiFabric/0.12.3/ngOfficeUiFabric.js"
+ },
+ "localizedResources": {
+ "toDoStrings": "webparts/toDo/loc/{locale}.js"
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/config/deploy-azure-storage.json b/samples/angular-migration/angular-todo-webpart/config/deploy-azure-storage.json
new file mode 100755
index 000000000..8a5bd2357
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/config/deploy-azure-storage.json
@@ -0,0 +1,6 @@
+{
+ "workingDir": "./temp/deploy/",
+ "account": "",
+ "container": "angular-todo",
+ "accessKey": ""
+}
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/config/package-solution.json b/samples/angular-migration/angular-todo-webpart/config/package-solution.json
new file mode 100755
index 000000000..b548cc015
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/config/package-solution.json
@@ -0,0 +1,10 @@
+{
+ "solution": {
+ "name": "angular-todo-client-side-solution",
+ "id": "27900554-c8a2-437a-b1de-0f1bd05d8145",
+ "version": "1.0.0.0"
+ },
+ "paths": {
+ "zippedPackage": "solution/angular-todo.spapp"
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/config/prepare-deploy.json b/samples/angular-migration/angular-todo-webpart/config/prepare-deploy.json
new file mode 100755
index 000000000..6aca63656
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/config/prepare-deploy.json
@@ -0,0 +1,3 @@
+{
+ "deployCdnPath": "temp/deploy"
+}
diff --git a/samples/angular-migration/angular-todo-webpart/config/serve.json b/samples/angular-migration/angular-todo-webpart/config/serve.json
new file mode 100755
index 000000000..087899637
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/config/serve.json
@@ -0,0 +1,9 @@
+{
+ "port": 4321,
+ "initialPage": "https://localhost:5432/workbench",
+ "https": true,
+ "api": {
+ "port": 5432,
+ "entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/config/tslint.json b/samples/angular-migration/angular-todo-webpart/config/tslint.json
new file mode 100755
index 000000000..bf3362c87
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/config/tslint.json
@@ -0,0 +1,51 @@
+{
+ // Display errors as warnings
+ "displayAsWarning": true,
+ // The TSLint task may have been configured with several custom lint rules
+ // before this config file is read (for example lint rules from the tslint-microsoft-contrib
+ // project). If true, this flag will deactivate any of these rules.
+ "removeExistingRules": true,
+ // When true, the TSLint task is configured with some default TSLint "rules.":
+ "useDefaultConfigAsBase": false,
+ // Since removeExistingRules=true and useDefaultConfigAsBase=false, there will be no lint rules
+ // which are active, other than the list of rules below.
+ "lintConfig": {
+ // Opt-in to Lint rules which help to eliminate bugs in JavaScript
+ "rules": {
+ "class-name": false,
+ "export-name": false,
+ "forin": false,
+ "label-position": false,
+ "label-undefined": false,
+ "member-access": true,
+ "no-arg": false,
+ "no-console": false,
+ "no-construct": false,
+ "no-duplicate-case": true,
+ "no-duplicate-key": false,
+ "no-duplicate-variable": true,
+ "no-eval": false,
+ "no-function-expression": true,
+ "no-internal-module": true,
+ "no-shadowed-variable": true,
+ "no-switch-case-fall-through": true,
+ "no-unnecessary-semicolons": true,
+ "no-unused-expression": true,
+ "no-unused-imports": true,
+ "no-unused-variable": true,
+ "no-unreachable": true,
+ "no-use-before-declare": true,
+ "no-with-statement": true,
+ "semicolon": true,
+ "trailing-comma": false,
+ "typedef": false,
+ "typedef-whitespace": false,
+ "use-named-parameter": true,
+ "valid-typeof": true,
+ "variable-name": false,
+ "whitespace": false,
+ "prefer-const": true,
+ "a11y-role": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/config/write-manifests.json b/samples/angular-migration/angular-todo-webpart/config/write-manifests.json
new file mode 100755
index 000000000..0a4bafb06
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/config/write-manifests.json
@@ -0,0 +1,3 @@
+{
+ "cdnBasePath": ""
+}
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/gulpfile.js b/samples/angular-migration/angular-todo-webpart/gulpfile.js
new file mode 100755
index 000000000..7d36ddb1c
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/gulpfile.js
@@ -0,0 +1,6 @@
+'use strict';
+
+const gulp = require('gulp');
+const build = require('@microsoft/sp-build-web');
+
+build.initialize(gulp);
diff --git a/samples/angular-migration/angular-todo-webpart/package.json b/samples/angular-migration/angular-todo-webpart/package.json
new file mode 100755
index 000000000..f6d4cdedc
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "angular-todo-webpart",
+ "version": "1.0.0",
+ "private": true,
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "dependencies": {
+ "@microsoft/sp-client-base": "~0.4.0",
+ "@microsoft/sp-client-preview": "~0.5.0"
+ },
+ "devDependencies": {
+ "@microsoft/sp-build-web": "~0.7.0",
+ "@microsoft/sp-module-interfaces": "~0.4.0",
+ "@microsoft/sp-webpart-workbench": "~0.5.0",
+ "@types/angular": "^1.5.16",
+ "gulp": "~3.9.1"
+ },
+ "scripts": {
+ "build": "gulp bundle",
+ "clean": "gulp nuke",
+ "test": "gulp test"
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/src/tests.js b/samples/angular-migration/angular-todo-webpart/src/tests.js
new file mode 100755
index 000000000..cb4bb5cf2
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/tests.js
@@ -0,0 +1,5 @@
+var context = require.context('.', true, /.+\.test\.js?$/);
+
+context.keys().forEach(context);
+
+module.exports = context;
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/IToDoWebPartProps.ts b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/IToDoWebPartProps.ts
new file mode 100755
index 000000000..c49bd9cda
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/IToDoWebPartProps.ts
@@ -0,0 +1,4 @@
+export interface IToDoWebPartProps {
+ todoListName: string;
+ hideFinishedTasks: boolean;
+}
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDo.module.scss b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDo.module.scss
new file mode 100755
index 000000000..61609a127
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDo.module.scss
@@ -0,0 +1,25 @@
+.toDo {
+ .loading {
+ margin: 0 auto;
+ width: 6em;
+ }
+
+ .configurationNeeded {
+ margin: 0 auto;
+ width: 100%;
+ text-align: center;
+ }
+
+ .done :global .ms-ListItem-primaryText {
+ text-decoration: line-through;
+ }
+
+ ul, li {
+ margin: 0;
+ padding: 0;
+ }
+
+ :global {
+ .ms-ListItem{font-family:"Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;font-size:14px;font-weight:400;box-sizing:border-box;margin:0;padding:0;box-shadow:none;padding:9px 28px 3px;position:relative;display:block}.ms-ListItem::after,.ms-ListItem::before{display:table;content:"";line-height:0}.ms-ListItem::after{clear:both}.ms-ListItem-primaryText,.ms-ListItem-secondaryText,.ms-ListItem-tertiaryText{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}.ms-ListItem-primaryText{font-family:"Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;font-size:21px;font-weight:100;padding-right:80px;position:relative;top:-4px}.ms-ListItem-secondaryText{font-family:"Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;font-size:14px;font-weight:400;line-height:25px;position:relative;top:-7px;padding-right:30px}.ms-ListItem-tertiaryText{font-family:"Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;font-size:14px;font-weight:400;position:relative;top:-9px;margin-bottom:-4px;padding-right:30px}.ms-ListItem-metaText{font-family:"Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;font-size:11px;font-weight:400;position:absolute;right:30px;top:39px}.ms-ListItem-image{float:left;height:70px;margin-left:-8px;margin-right:10px;width:70px}.ms-ListItem-selectionTarget{display:none}.ms-ListItem-actions{max-width:80px;position:absolute;right:30px;text-align:right;top:10px}.ms-ListItem-action{color:#a6a6a6;display:inline-block;font-size:15px;position:relative;text-align:center;top:3px;cursor:pointer;height:16px;width:16px}.ms-ListItem-action .ms-Icon{vertical-align:top}.ms-ListItem-action:hover{color:#666666;outline:1px solid transparent}.ms-ListItem.is-unread{border-left:3px solid #0078d7;padding-left:27px}.ms-ListItem.is-unread .ms-ListItem-metaText,.ms-ListItem.is-unread .ms-ListItem-secondaryText{color:#0078d7;font-weight:600}.ms-ListItem.is-unseen:after{border-right:10px solid transparent;border-top:10px solid #0078d7;left:0;position:absolute;top:0}.ms-ListItem.is-selectable .ms-ListItem-selectionTarget{display:block;height:20px;left:6px;position:absolute;top:13px;width:20px}.ms-ListItem.is-selectable .ms-ListItem-image{margin-left:0}.ms-ListItem.is-selectable:hover{background-color:#eaeaea;cursor:pointer;outline:1px solid transparent}.ms-ListItem.is-selectable:hover:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-family:FabricMDL2Icons;font-style:normal;font-weight:400;speak:none;position:absolute;top:12px;left:6px;height:15px;width:15px;border:1px solid #767676}.ms-ListItem.is-selected:before{border:1px solid transparent}.ms-ListItem.is-selected:before,.ms-ListItem.is-selected:hover:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-family:FabricMDL2Icons;font-style:normal;font-weight:400;speak:none;content:'\e041';font-size:15px;color:#767676;position:absolute;top:12px;left:6px}.ms-ListItem.is-selected:hover{background-color:#c7e0f4;outline:1px solid transparent}.ms-ListItem.ms-ListItem--document{padding:0}.ms-ListItem.ms-ListItem--document .ms-ListItem-itemIcon{width:70px;height:70px;float:left;text-align:center}.ms-ListItem.ms-ListItem--document .ms-ListItem-itemIcon .ms-Icon{font-size:38px;line-height:70px;color:#666666}.ms-ListItem.ms-ListItem--document .ms-ListItem-primaryText{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;padding-top:15px;padding-right:0;position:static}.ms-ListItem.ms-ListItem--document .ms-ListItem-secondaryText{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:"Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;font-size:11px;font-weight:400;padding-top:6px}.MailList{overflow-y:auto;-webkit-overflow-scrolling:touch;max-height:500px}.MailTile{margin-bottom:5px;padding:10px;background:red}
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDoWebPart.manifest.json b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDoWebPart.manifest.json
new file mode 100755
index 000000000..5789dab66
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDoWebPart.manifest.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
+
+ "id": "56d31bd5-3965-4f6a-9c08-bedf6f52e587",
+ "componentType": "WebPart",
+ "version": "0.0.1",
+ "manifestVersion": 2,
+
+ "preconfiguredEntries": [{
+ "groupId": "56d31bd5-3965-4f6a-9c08-bedf6f52e587",
+ "group": { "default": "Under Development" },
+ "title": { "default": "To do" },
+ "description": { "default": "Simple management of to do tasks" },
+ "officeFabricIconFontName": "Page",
+ "properties": {
+ "todoListName": "Todo",
+ "hideFinishedTasks": false
+ }
+ }]
+}
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDoWebPart.ts b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDoWebPart.ts
new file mode 100755
index 000000000..6002a1a4a
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/ToDoWebPart.ts
@@ -0,0 +1,88 @@
+import {
+ BaseClientSideWebPart,
+ IPropertyPaneSettings,
+ IWebPartContext,
+ PropertyPaneTextField,
+ PropertyPaneToggle
+} from '@microsoft/sp-client-preview';
+
+import styles from './ToDo.module.scss';
+import * as strings from 'toDoStrings';
+import { IToDoWebPartProps } from './IToDoWebPartProps';
+import * as angular from 'angular';
+import 'ng-office-ui-fabric';
+
+export default class ToDoWebPart extends BaseClientSideWebPart {
+ private $injector: angular.auto.IInjectorService;
+
+ public constructor(context: IWebPartContext) {
+ super(context);
+ }
+
+ public render(): void {
+ if (this.renderedOnce === false) {
+ require('./app/app.module');
+
+ this.domElement.innerHTML = `
+
+
+
+ Loading...
+
+
+
+
+
+
+ {{todo.title}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`;
+
+ this.$injector = angular.bootstrap(this.domElement, ['todoapp']);
+ }
+
+ this.$injector.get('$rootScope').$broadcast('configurationChanged', {
+ sharePointApi: this.context.pageContext.web.absoluteUrl + '/_api/',
+ todoListName: this.properties.todoListName,
+ hideFinishedTasks: this.properties.hideFinishedTasks
+ });
+ }
+
+ protected get propertyPaneSettings(): IPropertyPaneSettings {
+ return {
+ pages: [
+ {
+ header: {
+ description: strings.PropertyPaneDescription
+ },
+ groups: [
+ {
+ groupName: strings.BasicGroupName,
+ groupFields: [
+ PropertyPaneTextField('todoListName', {
+ label: strings.ListNameFieldLabel
+ }),
+ PropertyPaneToggle('hideFinishedTasks', {
+ label: strings.HideFinishedTasksFieldLabel
+ })
+ ]
+ }
+ ]
+ }
+ ]
+ };
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/DataService.ts b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/DataService.ts
new file mode 100755
index 000000000..d08bc1882
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/DataService.ts
@@ -0,0 +1,180 @@
+import * as angular from 'angular';
+
+export interface ITodo {
+ id: number;
+ title: string;
+ done: boolean;
+}
+
+interface ITodoItem {
+ Id: number;
+ Title: string;
+ Status: string;
+}
+
+export interface IDataService {
+ getTodos: (sharePointApi: string, todoListName: string, hideFinishedTasks: boolean) => angular.IPromise;
+ addTodo: (todo: string, sharePointApi: string, todoListName: string) => angular.IPromise<{}>;
+ deleteTodo: (todo: ITodo, sharePointApi: string, todoListName: string) => angular.IPromise<{}>;
+ setTodoStatus: (todo: ITodo, done: boolean, sharePointApi: string, todoListName: string) => angular.IPromise<{}>;
+}
+
+export default class DataService implements IDataService {
+ public static $inject: string[] = ['$q', '$http'];
+
+ constructor(private $q: angular.IQService, private $http: angular.IHttpService) {
+ }
+
+ public getTodos(sharePointApi: string, todoListName: string, hideFinishedTasks: boolean): angular.IPromise {
+ const deferred: angular.IDeferred = this.$q.defer();
+
+ let url: string = `${sharePointApi}web/lists/getbytitle('${todoListName}')/items?$select=Id,Title,Status&$orderby=ID desc`;
+
+ if (hideFinishedTasks === true) {
+ url += "&$filter=Status ne 'Completed'";
+ }
+
+ this.$http({
+ url: url,
+ method: 'GET',
+ headers: {
+ 'Accept': 'application/json;odata=nometadata'
+ }
+ }).then((result: angular.IHttpPromiseCallbackArg<{ value: ITodoItem[] }>): void => {
+ const todos: ITodo[] = [];
+ for (let i: number = 0; i < result.data.value.length; i++) {
+ const todo: ITodoItem = result.data.value[i];
+ todos.push({
+ id: todo.Id,
+ title: todo.Title,
+ done: todo.Status === 'Completed'
+ });
+ }
+ deferred.resolve(todos);
+ });
+
+ return deferred.promise;
+ }
+
+ public addTodo(todo: string, sharePointApi: string, todoListName: string): angular.IPromise<{}> {
+ const deferred: angular.IDeferred<{}> = this.$q.defer();
+
+ let listItemEntityTypeFullName: string = undefined;
+ this.getListItemEntityTypeFullName(sharePointApi, todoListName)
+ .then((entityTypeName: string): angular.IPromise => {
+ listItemEntityTypeFullName = entityTypeName;
+ return this.getRequestDigest(sharePointApi);
+ })
+ .then((requestDigest: string): void => {
+ const body: string = JSON.stringify({
+ '__metadata': { 'type': listItemEntityTypeFullName },
+ 'Title': todo
+ });
+ this.$http({
+ url: `${sharePointApi}web/lists/getbytitle('${todoListName}')/items`,
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json;odata=nometadata',
+ 'Content-type': 'application/json;odata=verbose',
+ 'X-RequestDigest': requestDigest
+ },
+ data: body
+ }).then((result: angular.IHttpPromiseCallbackArg<{}>): void => {
+ deferred.resolve();
+ });
+ });
+
+ return deferred.promise;
+ }
+
+ public deleteTodo(todo: ITodo, sharePointApi: string, todoListName: string): angular.IPromise<{}> {
+ const deferred: angular.IDeferred<{}> = this.$q.defer();
+
+ this.getRequestDigest(sharePointApi)
+ .then((requestDigest: string): void => {
+ this.$http({
+ url: `${sharePointApi}web/lists/getbytitle('${todoListName}')/items(${todo.id})`,
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json;odata=nometadata',
+ 'X-RequestDigest': requestDigest,
+ 'IF-MATCH': '*',
+ 'X-HTTP-Method': 'DELETE'
+ }
+ }).then((result: angular.IHttpPromiseCallbackArg<{}>): void => {
+ deferred.resolve();
+ });
+ });
+
+ return deferred.promise;
+ }
+
+ public setTodoStatus(todo: ITodo, done: boolean, sharePointApi: string, todoListName: string): angular.IPromise<{}> {
+ const deferred: angular.IDeferred<{}> = this.$q.defer();
+
+ let listItemEntityTypeFullName: string = undefined;
+ this.getListItemEntityTypeFullName(sharePointApi, todoListName)
+ .then((entityTypeName: string): angular.IPromise => {
+ listItemEntityTypeFullName = entityTypeName;
+ return this.getRequestDigest(sharePointApi);
+ })
+ .then((requestDigest: string): void => {
+ const body: string = JSON.stringify({
+ '__metadata': { 'type': listItemEntityTypeFullName },
+ 'Status': done ? 'Completed' : 'Not started'
+ });
+ this.$http({
+ url: `${sharePointApi}web/lists/getbytitle('${todoListName}')/items(${todo.id})`,
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json;odata=nometadata',
+ 'Content-type': 'application/json;odata=verbose',
+ 'X-RequestDigest': requestDigest,
+ 'IF-MATCH': '*',
+ 'X-HTTP-Method': 'MERGE'
+ },
+ data: body
+ }).then((result: angular.IHttpPromiseCallbackArg<{}>): void => {
+ deferred.resolve();
+ });
+ });
+
+ return deferred.promise;
+ }
+
+ private getRequestDigest(sharePointApi: string): angular.IPromise {
+ const deferred: angular.IDeferred = this.$q.defer();
+
+ this.$http({
+ url: sharePointApi + 'contextinfo',
+ method: 'POST',
+ headers: {
+ 'Accept': 'application/json;odata=nometadata'
+ }
+ }).then((result: angular.IHttpPromiseCallbackArg<{ FormDigestValue: string }>): void => {
+ deferred.resolve(result.data.FormDigestValue);
+ }, (err: any): void => {
+ deferred.reject(err);
+ });
+
+ return deferred.promise;
+ }
+
+ private getListItemEntityTypeFullName(sharePointApi: string, todoListName: string): angular.IPromise {
+ const deferred: angular.IDeferred = this.$q.defer();
+
+ this.$http({
+ url: `${sharePointApi}web/lists/getbytitle('${todoListName}')?$select=ListItemEntityTypeFullName`,
+ method: 'GET',
+ headers: {
+ 'Accept': 'application/json;odata=nometadata'
+ }
+ }).then((result: angular.IHttpPromiseCallbackArg<{ ListItemEntityTypeFullName: string }>): void => {
+ deferred.resolve(result.data.ListItemEntityTypeFullName);
+ }, (err: any): void => {
+ deferred.reject(err);
+ });
+
+ return deferred.promise;
+ }
+}
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/HomeController.ts b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/HomeController.ts
new file mode 100755
index 000000000..f055c345e
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/HomeController.ts
@@ -0,0 +1,121 @@
+import * as angular from 'angular';
+import { IDataService, ITodo } from './DataService';
+
+export default class HomeController {
+ public isLoading: boolean = false;
+ public newItem: string = null;
+ public todoCollection: ITodo[] = [];
+ private sharePointApi: string = undefined;
+ private todoListName: string = undefined;
+ private hideFinishedTasks: boolean = false;
+ private configurationNeeded: boolean = true;
+
+ public static $inject: string[] = ['DataService', '$window', '$rootScope'];
+
+ constructor(private dataService: IDataService,
+ private $window: angular.IWindowService,
+ $rootScope: angular.IRootScopeService) {
+ const vm: HomeController = this;
+ this.init(undefined, undefined);
+
+ $rootScope.$on('configurationChanged',
+ (event: angular.IAngularEvent,
+ args: {
+ sharePointApi: string;
+ todoListName: string;
+ hideFinishedTasks: boolean;
+ }): void => {
+ vm.init(args.sharePointApi, args.todoListName, args.hideFinishedTasks);
+ });
+ }
+
+ private init(sharePointApi: string, todoListName: string, hideFinishedTasks?: boolean): void {
+ if (sharePointApi !== undefined && sharePointApi.length > 0 &&
+ todoListName !== undefined && todoListName.length > 0) {
+ this.sharePointApi = sharePointApi;
+ this.todoListName = todoListName;
+ this.hideFinishedTasks = hideFinishedTasks;
+ this.loadTodos();
+ this.configurationNeeded = false;
+ }
+ else {
+ this.configurationNeeded = true;
+ }
+ }
+
+ private loadTodos(): void {
+ this.isLoading = true;
+ this.dataService.getTodos(this.sharePointApi, this.todoListName, this.hideFinishedTasks)
+ .then((todos: ITodo[]): void => {
+ this.todoCollection = todos;
+ })
+ .finally((): void => {
+ this.isLoading = false;
+ });
+ }
+
+ public todoKeyDown($event: KeyboardEvent): void {
+ if ($event.keyCode === 13 && this.newItem.length > 0) {
+ $event.preventDefault();
+
+ this.todoCollection.unshift({ id: -1, title: this.newItem, done: false });
+
+ this.dataService.addTodo(this.newItem, this.sharePointApi, this.todoListName)
+ .then((): void => {
+ this.newItem = null;
+ this.dataService.getTodos(this.sharePointApi, this.todoListName, this.hideFinishedTasks)
+ .then((todos: ITodo[]): void => {
+ this.todoCollection = todos;
+ });
+ });
+ }
+ }
+
+ public deleteTodo(todo: ITodo): void {
+ if (this.$window.confirm('Are you sure you want to delete this todo item?')) {
+ let index: number = -1;
+ for (let i: number = 0; i < this.todoCollection.length; i++) {
+ if (this.todoCollection[i].id === todo.id) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index > -1) {
+ this.todoCollection.splice(index, 1);
+ }
+
+ this.dataService.deleteTodo(todo, this.sharePointApi, this.todoListName)
+ .then((): void => {
+ this.dataService.getTodos(this.sharePointApi, this.todoListName, this.hideFinishedTasks)
+ .then((todos: ITodo[]): void => {
+ this.todoCollection = todos;
+ });
+ });
+ }
+ }
+
+ public completeTodo(todo: ITodo): void {
+ todo.done = true;
+
+ this.dataService.setTodoStatus(todo, true, this.sharePointApi, this.todoListName)
+ .then((): void => {
+ this.dataService.getTodos(this.sharePointApi, this.todoListName, this.hideFinishedTasks)
+ .then((todos: ITodo[]): void => {
+ this.todoCollection = todos;
+ });
+ });
+ }
+
+ public undoTodo(todo: ITodo): void {
+ todo.done = false;
+
+ this.dataService.setTodoStatus(todo, false, this.sharePointApi, this.todoListName)
+ .then((): void => {
+ this.dataService.getTodos(this.sharePointApi, this.todoListName, this.hideFinishedTasks)
+ .then((todos: ITodo[]): void => {
+ this.todoCollection = todos;
+ });
+ });
+ }
+}
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/app.module.ts b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/app.module.ts
new file mode 100755
index 000000000..cf31c07f5
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/app/app.module.ts
@@ -0,0 +1,14 @@
+import * as angular from 'angular';
+import HomeController from './HomeController';
+import DataService from './DataService';
+
+import 'ng-office-ui-fabric';
+
+const todoapp: angular.IModule = angular.module('todoapp', [
+ 'officeuifabric.core',
+ 'officeuifabric.components'
+]);
+
+todoapp
+ .controller('HomeController', HomeController)
+ .service('DataService', DataService);
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/loc/en-us.js b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/loc/en-us.js
new file mode 100755
index 000000000..b5685a20e
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/loc/en-us.js
@@ -0,0 +1,8 @@
+define([], function() {
+ return {
+ "PropertyPaneDescription": "Description",
+ "BasicGroupName": "Group Name",
+ "ListNameFieldLabel": "List name",
+ "HideFinishedTasksFieldLabel": "Hide finished tasks"
+ }
+});
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/loc/mystrings.d.ts b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/loc/mystrings.d.ts
new file mode 100755
index 000000000..41a6e3f87
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/loc/mystrings.d.ts
@@ -0,0 +1,11 @@
+declare interface IToDoStrings {
+ PropertyPaneDescription: string;
+ BasicGroupName: string;
+ ListNameFieldLabel: string;
+ HideFinishedTasksFieldLabel: string;
+}
+
+declare module 'toDoStrings' {
+ const strings: IToDoStrings;
+ export = strings;
+}
diff --git a/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/tests/ToDo.test.ts b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/tests/ToDo.test.ts
new file mode 100755
index 000000000..8ffae85a7
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/src/webparts/toDo/tests/ToDo.test.ts
@@ -0,0 +1,7 @@
+import * as assert from 'assert';
+
+describe('ToDoWebPart', () => {
+ it('should do something', () => {
+ assert.ok(true);
+ });
+});
diff --git a/samples/angular-migration/angular-todo-webpart/tsconfig.json b/samples/angular-migration/angular-todo-webpart/tsconfig.json
new file mode 100755
index 000000000..98c8662a9
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "commonjs",
+ "jsx": "react",
+ "declaration": true,
+ "sourceMap": true
+ }
+}
diff --git a/samples/angular-migration/angular-todo-webpart/typings/@ms/odsp-webpack.d.ts b/samples/angular-migration/angular-todo-webpart/typings/@ms/odsp-webpack.d.ts
new file mode 100755
index 000000000..f2b3b03df
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/@ms/odsp-webpack.d.ts
@@ -0,0 +1,13 @@
+// Type definitions for webpack in Microsoft ODSP projects
+// Project: ODSP-WEBPACK
+
+/*
+ * This definition of webpack require overrides all other definitions of require in our toolchain
+ * Make sure all other definitions of require are commented out e.g. in node.d.ts
+ */
+declare var require: {
+ (path: string): any;
+ (paths: string[], callback: (...modules: any[]) => void): void;
+ resolve: (id: string) => string;
+ ensure: (paths: string[], callback: (require: (path: string) => T) => void, path: string) => void;
+};
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/typings/@ms/odsp.d.ts b/samples/angular-migration/angular-todo-webpart/typings/@ms/odsp.d.ts
new file mode 100755
index 000000000..ae3334fe0
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/@ms/odsp.d.ts
@@ -0,0 +1,10 @@
+// Type definitions for Microsoft ODSP projects
+// Project: ODSP
+
+///
+
+/* Global definition for DEBUG builds */
+declare const DEBUG: boolean;
+
+/* Global definition for UNIT_TEST builds */
+declare const UNIT_TEST: boolean;
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/typings/assertion-error/assertion-error.d.ts b/samples/angular-migration/angular-todo-webpart/typings/assertion-error/assertion-error.d.ts
new file mode 100755
index 000000000..08217c9e5
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/assertion-error/assertion-error.d.ts
@@ -0,0 +1,15 @@
+// Type definitions for assertion-error 1.0.0
+// Project: https://github.com/chaijs/assertion-error
+// Definitions by: Bart van der Schoor
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module 'assertion-error' {
+ class AssertionError implements Error {
+ constructor(message: string, props?: any, ssf?: Function);
+ name: string;
+ message: string;
+ showDiff: boolean;
+ stack: string;
+ }
+ export = AssertionError;
+}
diff --git a/samples/angular-migration/angular-todo-webpart/typings/chai/chai.d.ts b/samples/angular-migration/angular-todo-webpart/typings/chai/chai.d.ts
new file mode 100755
index 000000000..da4d718e1
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/chai/chai.d.ts
@@ -0,0 +1,388 @@
+// Type definitions for chai 3.2.0
+// Project: http://chaijs.com/
+// Definitions by: Jed Mao ,
+// Bart van der Schoor ,
+// Andrew Brown ,
+// Olivier Chevet
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+//
+
+declare module Chai {
+
+ interface ChaiStatic {
+ expect: ExpectStatic;
+ should(): Should;
+ /**
+ * Provides a way to extend the internals of Chai
+ */
+ use(fn: (chai: any, utils: any) => void): any;
+ assert: AssertStatic;
+ config: Config;
+ AssertionError: AssertionError;
+ }
+
+ export interface ExpectStatic extends AssertionStatic {
+ fail(actual?: any, expected?: any, message?: string, operator?: string): void;
+ }
+
+ export interface AssertStatic extends Assert {
+ }
+
+ export interface AssertionStatic {
+ (target: any, message?: string): Assertion;
+ }
+
+ interface ShouldAssertion {
+ equal(value1: any, value2: any, message?: string): void;
+ Throw: ShouldThrow;
+ throw: ShouldThrow;
+ exist(value: any, message?: string): void;
+ }
+
+ interface Should extends ShouldAssertion {
+ not: ShouldAssertion;
+ fail(actual: any, expected: any, message?: string, operator?: string): void;
+ }
+
+ interface ShouldThrow {
+ (actual: Function): void;
+ (actual: Function, expected: string|RegExp, message?: string): void;
+ (actual: Function, constructor: Error|Function, expected?: string|RegExp, message?: string): void;
+ }
+
+ interface Assertion extends LanguageChains, NumericComparison, TypeComparison {
+ not: Assertion;
+ deep: Deep;
+ any: KeyFilter;
+ all: KeyFilter;
+ a: TypeComparison;
+ an: TypeComparison;
+ include: Include;
+ includes: Include;
+ contain: Include;
+ contains: Include;
+ ok: Assertion;
+ true: Assertion;
+ false: Assertion;
+ null: Assertion;
+ undefined: Assertion;
+ NaN: Assertion;
+ exist: Assertion;
+ empty: Assertion;
+ arguments: Assertion;
+ Arguments: Assertion;
+ equal: Equal;
+ equals: Equal;
+ eq: Equal;
+ eql: Equal;
+ eqls: Equal;
+ property: Property;
+ ownProperty: OwnProperty;
+ haveOwnProperty: OwnProperty;
+ ownPropertyDescriptor: OwnPropertyDescriptor;
+ haveOwnPropertyDescriptor: OwnPropertyDescriptor;
+ length: Length;
+ lengthOf: Length;
+ match: Match;
+ matches: Match;
+ string(string: string, message?: string): Assertion;
+ keys: Keys;
+ key(string: string): Assertion;
+ throw: Throw;
+ throws: Throw;
+ Throw: Throw;
+ respondTo: RespondTo;
+ respondsTo: RespondTo;
+ itself: Assertion;
+ satisfy: Satisfy;
+ satisfies: Satisfy;
+ closeTo(expected: number, delta: number, message?: string): Assertion;
+ members: Members;
+ increase: PropertyChange;
+ increases: PropertyChange;
+ decrease: PropertyChange;
+ decreases: PropertyChange;
+ change: PropertyChange;
+ changes: PropertyChange;
+ extensible: Assertion;
+ sealed: Assertion;
+ frozen: Assertion;
+
+ }
+
+ interface LanguageChains {
+ to: Assertion;
+ be: Assertion;
+ been: Assertion;
+ is: Assertion;
+ that: Assertion;
+ which: Assertion;
+ and: Assertion;
+ has: Assertion;
+ have: Assertion;
+ with: Assertion;
+ at: Assertion;
+ of: Assertion;
+ same: Assertion;
+ }
+
+ interface NumericComparison {
+ above: NumberComparer;
+ gt: NumberComparer;
+ greaterThan: NumberComparer;
+ least: NumberComparer;
+ gte: NumberComparer;
+ below: NumberComparer;
+ lt: NumberComparer;
+ lessThan: NumberComparer;
+ most: NumberComparer;
+ lte: NumberComparer;
+ within(start: number, finish: number, message?: string): Assertion;
+ }
+
+ interface NumberComparer {
+ (value: number, message?: string): Assertion;
+ }
+
+ interface TypeComparison {
+ (type: string, message?: string): Assertion;
+ instanceof: InstanceOf;
+ instanceOf: InstanceOf;
+ }
+
+ interface InstanceOf {
+ (constructor: Object, message?: string): Assertion;
+ }
+
+ interface Deep {
+ equal: Equal;
+ include: Include;
+ property: Property;
+ members: Members;
+ }
+
+ interface KeyFilter {
+ keys: Keys;
+ }
+
+ interface Equal {
+ (value: any, message?: string): Assertion;
+ }
+
+ interface Property {
+ (name: string, value?: any, message?: string): Assertion;
+ }
+
+ interface OwnProperty {
+ (name: string, message?: string): Assertion;
+ }
+
+ interface OwnPropertyDescriptor {
+ (name: string, descriptor: PropertyDescriptor, message?: string): Assertion;
+ (name: string, message?: string): Assertion;
+ }
+
+ interface Length extends LanguageChains, NumericComparison {
+ (length: number, message?: string): Assertion;
+ }
+
+ interface Include {
+ (value: Object, message?: string): Assertion;
+ (value: string, message?: string): Assertion;
+ (value: number, message?: string): Assertion;
+ keys: Keys;
+ members: Members;
+ any: KeyFilter;
+ all: KeyFilter;
+ }
+
+ interface Match {
+ (regexp: RegExp|string, message?: string): Assertion;
+ }
+
+ interface Keys {
+ (...keys: string[]): Assertion;
+ (keys: any[]): Assertion;
+ (keys: Object): Assertion;
+ }
+
+ interface Throw {
+ (): Assertion;
+ (expected: string, message?: string): Assertion;
+ (expected: RegExp, message?: string): Assertion;
+ (constructor: Error, expected?: string, message?: string): Assertion;
+ (constructor: Error, expected?: RegExp, message?: string): Assertion;
+ (constructor: Function, expected?: string, message?: string): Assertion;
+ (constructor: Function, expected?: RegExp, message?: string): Assertion;
+ }
+
+ interface RespondTo {
+ (method: string, message?: string): Assertion;
+ }
+
+ interface Satisfy {
+ (matcher: Function, message?: string): Assertion;
+ }
+
+ interface Members {
+ (set: any[], message?: string): Assertion;
+ }
+
+ interface PropertyChange {
+ (object: Object, prop: string, msg?: string): Assertion;
+ }
+
+ export interface Assert {
+ /**
+ * @param expression Expression to test for truthiness.
+ * @param message Message to display on error.
+ */
+ (expression: any, message?: string): void;
+
+ fail(actual?: any, expected?: any, msg?: string, operator?: string): void;
+
+ ok(val: any, msg?: string): void;
+ isOk(val: any, msg?: string): void;
+ notOk(val: any, msg?: string): void;
+ isNotOk(val: any, msg?: string): void;
+
+ equal(act: any, exp: any, msg?: string): void;
+ notEqual(act: any, exp: any, msg?: string): void;
+
+ strictEqual(act: any, exp: any, msg?: string): void;
+ notStrictEqual(act: any, exp: any, msg?: string): void;
+
+ deepEqual(act: any, exp: any, msg?: string): void;
+ notDeepEqual(act: any, exp: any, msg?: string): void;
+
+ isTrue(val: any, msg?: string): void;
+ isFalse(val: any, msg?: string): void;
+
+ isNull(val: any, msg?: string): void;
+ isNotNull(val: any, msg?: string): void;
+
+ isUndefined(val: any, msg?: string): void;
+ isDefined(val: any, msg?: string): void;
+
+ isNaN(val: any, msg?: string): void;
+ isNotNaN(val: any, msg?: string): void;
+
+ isAbove(val: number, abv: number, msg?: string): void;
+ isBelow(val: number, blw: number, msg?: string): void;
+
+ isFunction(val: any, msg?: string): void;
+ isNotFunction(val: any, msg?: string): void;
+
+ isObject(val: any, msg?: string): void;
+ isNotObject(val: any, msg?: string): void;
+
+ isArray(val: any, msg?: string): void;
+ isNotArray(val: any, msg?: string): void;
+
+ isString(val: any, msg?: string): void;
+ isNotString(val: any, msg?: string): void;
+
+ isNumber(val: any, msg?: string): void;
+ isNotNumber(val: any, msg?: string): void;
+
+ isBoolean(val: any, msg?: string): void;
+ isNotBoolean(val: any, msg?: string): void;
+
+ typeOf(val: any, type: string, msg?: string): void;
+ notTypeOf(val: any, type: string, msg?: string): void;
+
+ instanceOf(val: any, type: Function, msg?: string): void;
+ notInstanceOf(val: any, type: Function, msg?: string): void;
+
+ include(exp: string, inc: any, msg?: string): void;
+ include(exp: any[], inc: any, msg?: string): void;
+
+ notInclude(exp: string, inc: any, msg?: string): void;
+ notInclude(exp: any[], inc: any, msg?: string): void;
+
+ match(exp: any, re: RegExp, msg?: string): void;
+ notMatch(exp: any, re: RegExp, msg?: string): void;
+
+ property(obj: Object, prop: string, msg?: string): void;
+ notProperty(obj: Object, prop: string, msg?: string): void;
+ deepProperty(obj: Object, prop: string, msg?: string): void;
+ notDeepProperty(obj: Object, prop: string, msg?: string): void;
+
+ propertyVal(obj: Object, prop: string, val: any, msg?: string): void;
+ propertyNotVal(obj: Object, prop: string, val: any, msg?: string): void;
+
+ deepPropertyVal(obj: Object, prop: string, val: any, msg?: string): void;
+ deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string): void;
+
+ lengthOf(exp: any, len: number, msg?: string): void;
+ //alias frenzy
+ throw(fn: Function, msg?: string): void;
+ throw(fn: Function, regExp: RegExp): void;
+ throw(fn: Function, errType: Function, msg?: string): void;
+ throw(fn: Function, errType: Function, regExp: RegExp): void;
+
+ throws(fn: Function, msg?: string): void;
+ throws(fn: Function, regExp: RegExp): void;
+ throws(fn: Function, errType: Function, msg?: string): void;
+ throws(fn: Function, errType: Function, regExp: RegExp): void;
+
+ Throw(fn: Function, msg?: string): void;
+ Throw(fn: Function, regExp: RegExp): void;
+ Throw(fn: Function, errType: Function, msg?: string): void;
+ Throw(fn: Function, errType: Function, regExp: RegExp): void;
+
+ doesNotThrow(fn: Function, msg?: string): void;
+ doesNotThrow(fn: Function, regExp: RegExp): void;
+ doesNotThrow(fn: Function, errType: Function, msg?: string): void;
+ doesNotThrow(fn: Function, errType: Function, regExp: RegExp): void;
+
+ operator(val: any, operator: string, val2: any, msg?: string): void;
+ closeTo(act: number, exp: number, delta: number, msg?: string): void;
+
+ sameMembers(set1: any[], set2: any[], msg?: string): void;
+ sameDeepMembers(set1: any[], set2: any[], msg?: string): void;
+ includeMembers(superset: any[], subset: any[], msg?: string): void;
+
+ ifError(val: any, msg?: string): void;
+
+ isExtensible(obj: {}, msg?: string): void;
+ extensible(obj: {}, msg?: string): void;
+ isNotExtensible(obj: {}, msg?: string): void;
+ notExtensible(obj: {}, msg?: string): void;
+
+ isSealed(obj: {}, msg?: string): void;
+ sealed(obj: {}, msg?: string): void;
+ isNotSealed(obj: {}, msg?: string): void;
+ notSealed(obj: {}, msg?: string): void;
+
+ isFrozen(obj: Object, msg?: string): void;
+ frozen(obj: Object, msg?: string): void;
+ isNotFrozen(obj: Object, msg?: string): void;
+ notFrozen(obj: Object, msg?: string): void;
+
+
+ }
+
+ export interface Config {
+ includeStack: boolean;
+ }
+
+ export class AssertionError {
+ constructor(message: string, _props?: any, ssf?: Function);
+ name: string;
+ message: string;
+ showDiff: boolean;
+ stack: string;
+ }
+}
+
+declare var chai: Chai.ChaiStatic;
+
+declare module "chai" {
+ export = chai;
+}
+
+interface Object {
+ should: Chai.Assertion;
+}
diff --git a/samples/angular-migration/angular-todo-webpart/typings/combokeys/combokeys.d.ts b/samples/angular-migration/angular-todo-webpart/typings/combokeys/combokeys.d.ts
new file mode 100755
index 000000000..f7e1e5b03
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/combokeys/combokeys.d.ts
@@ -0,0 +1,107 @@
+// Type definitions for Combokeys v2.4.6
+// Project: https://github.com/PolicyStat/combokeys
+// Definitions by: Ian Clanton-Thuon
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+declare namespace Combokeys {
+ interface CombokeysStatic {
+ new (element: Element): Combokeys;
+
+ /**
+ * all instances of Combokeys
+ */
+ instances: Combokeys[];
+
+ /**
+ * reset all instances
+ */
+ reset(): void;
+ }
+
+ interface Combokeys {
+ element: Element;
+
+ /**
+ * binds an event to Combokeys
+ *
+ * can be a single key, a combination of keys separated with +,
+ * an array of keys, or a sequence of keys separated by spaces
+ *
+ * be sure to list the modifier keys first to make sure that the
+ * correct key ends up getting bound (the last key in the pattern)
+ *
+ * @param {keys} key combination or combinations
+ * @param {callback} callback function
+ * @param {handler} optional - one of "keypress", "keydown", or "keyup"
+ * @returns void
+ */
+ bind(keys: string | string[], callback: () => void, action?: string): void;
+
+
+ /**
+ * binds multiple combinations to the same callback
+ *
+ * @param {keys} key combinations
+ * @param {callback} callback function
+ * @param {handler} optional - one of "keypress", "keydown", or "keyup"
+ * @returns void
+ */
+ bindMultiple(keys: string[], callback: () => void, action?: string): void;
+
+ /**
+ * unbinds an event to Combokeys
+ *
+ * the unbinding sets the callback function of the specified key combo
+ * to an empty function and deletes the corresponding key in the
+ * directMap dict.
+ *
+ * the keycombo+action has to be exactly the same as
+ * it was defined in the bind method
+ *
+ * @param {keys} key combination or combinations
+ * @param {action} optional - one of "keypress", "keydown", or "keyup"
+ * @returns void
+ */
+ unbind(keys: string | string[], action?: string): void;
+
+ /**
+ * triggers an event that has already been bound
+ *
+ * @param {keys} key combination
+ * @param {action} optional - one of "keypress", "keydown", or "keyup"
+ * @returns void
+ */
+ trigger(keys: string, action?: string): void;
+
+ /**
+ * resets the library back to its initial state. This is useful
+ * if you want to clear out the current keyboard shortcuts and bind
+ * new ones - for example if you switch to another page
+ *
+ * @returns void
+ */
+ reset(): void;
+
+ /**
+ * should we stop this event before firing off callbacks
+ *
+ * @param {e} event
+ * @param {element} bound element
+ * @return {boolean}
+ */
+ stopCallback(e: Event, element: Element): boolean;
+
+ /**
+ * detach all listners from the bound element
+ *
+ * @return {void}
+ */
+ detach(): void;
+ }
+}
+
+declare var combokeys: Combokeys.CombokeysStatic;
+
+declare module "combokeys" {
+ export = combokeys;
+}
diff --git a/samples/angular-migration/angular-todo-webpart/typings/es6-collections/es6-collections.d.ts b/samples/angular-migration/angular-todo-webpart/typings/es6-collections/es6-collections.d.ts
new file mode 100755
index 000000000..bc39df295
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/es6-collections/es6-collections.d.ts
@@ -0,0 +1,113 @@
+// Type definitions for es6-collections v0.5.1
+// Project: https://github.com/WebReflection/es6-collections/
+// Definitions by: Ron Buckton
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+/* *****************************************************************************
+Copyright (c) Microsoft Corporation. All rights reserved.
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at http://www.apache.org/licenses/LICENSE-2.0
+
+THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+MERCHANTABLITY OR NON-INFRINGEMENT.
+
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+
+interface IteratorResult {
+ done: boolean;
+ value?: T;
+}
+
+interface Iterator {
+ next(value?: any): IteratorResult;
+ return?(value?: any): IteratorResult;
+ throw?(e?: any): IteratorResult;
+}
+
+interface ForEachable {
+ forEach(callbackfn: (value: T) => void): void;
+}
+
+interface Map {
+ clear(): void;
+ delete(key: K): boolean;
+ forEach(callbackfn: (value: V, index: K, map: Map) => void, thisArg?: any): void;
+ get(key: K): V;
+ has(key: K): boolean;
+ set(key: K, value?: V): Map;
+ entries(): Iterator<[K, V]>;
+ keys(): Iterator;
+ values(): Iterator;
+ size: number;
+}
+
+interface MapConstructor {
+ new (): Map;
+ new (iterable: ForEachable<[K, V]>): Map;
+ prototype: Map;
+}
+
+declare var Map: MapConstructor;
+
+interface Set {
+ add(value: T): Set;
+ clear(): void;
+ delete(value: T): boolean;
+ forEach(callbackfn: (value: T, index: T, set: Set) => void, thisArg?: any): void;
+ has(value: T): boolean;
+ entries(): Iterator<[T, T]>;
+ keys(): Iterator;
+ values(): Iterator;
+ size: number;
+}
+
+interface SetConstructor {
+ new (): Set;
+ new (iterable: ForEachable): Set;
+ prototype: Set;
+}
+
+declare var Set: SetConstructor;
+
+interface WeakMap {
+ delete(key: K): boolean;
+ clear(): void;
+ get(key: K): V;
+ has(key: K): boolean;
+ set(key: K, value?: V): WeakMap;
+}
+
+interface WeakMapConstructor {
+ new (): WeakMap;
+ new (iterable: ForEachable<[K, V]>): WeakMap;
+ prototype: WeakMap;
+}
+
+declare var WeakMap: WeakMapConstructor;
+
+interface WeakSet {
+ delete(value: T): boolean;
+ clear(): void;
+ add(value: T): WeakSet;
+ has(value: T): boolean;
+}
+
+interface WeakSetConstructor {
+ new (): WeakSet;
+ new (iterable: ForEachable): WeakSet;
+ prototype: WeakSet;
+}
+
+declare var WeakSet: WeakSetConstructor;
+
+declare module "es6-collections" {
+ var Map: MapConstructor;
+ var Set: SetConstructor;
+ var WeakMap: WeakMapConstructor;
+ var WeakSet: WeakSetConstructor;
+}
\ No newline at end of file
diff --git a/samples/angular-migration/angular-todo-webpart/typings/es6-promise/es6-promise.d.ts b/samples/angular-migration/angular-todo-webpart/typings/es6-promise/es6-promise.d.ts
new file mode 100755
index 000000000..a8f8d7845
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/es6-promise/es6-promise.d.ts
@@ -0,0 +1,74 @@
+// Type definitions for es6-promise
+// Project: https://github.com/jakearchibald/ES6-Promise
+// Definitions by: François de Campredon , vvakame
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+interface Thenable {
+ then(onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Thenable;
+ then(onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => void): Thenable;
+ catch(onRejected?: (error: any) => U | Thenable): Thenable;
+}
+
+declare class Promise implements Thenable {
+ /**
+ * If you call resolve in the body of the callback passed to the constructor,
+ * your promise is fulfilled with result object passed to resolve.
+ * If you call reject your promise is rejected with the object passed to reject.
+ * For consistency and debugging (eg stack traces), obj should be an instanceof Error.
+ * Any errors thrown in the constructor callback will be implicitly passed to reject().
+ */
+ constructor(callback: (resolve : (value?: R | Thenable) => void, reject: (error?: any) => void) => void);
+
+ /**
+ * onFulfilled is called when/if "promise" resolves. onRejected is called when/if "promise" rejects.
+ * Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called.
+ * Both callbacks have a single parameter , the fulfillment value or rejection reason.
+ * "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve.
+ * If an error is thrown in the callback, the returned promise rejects with that error.
+ *
+ * @param onFulfilled called when/if "promise" resolves
+ * @param onRejected called when/if "promise" rejects
+ */
+ then(onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => U | Thenable): Promise;
+ then(onFulfilled?: (value: R) => U | Thenable, onRejected?: (error: any) => void): Promise;
+
+ /**
+ * Sugar for promise.then(undefined, onRejected)
+ *
+ * @param onRejected called when/if "promise" rejects
+ */
+ catch(onRejected?: (error: any) => U | Thenable): Promise;
+}
+
+declare module Promise {
+ /**
+ * Make a new promise from the thenable.
+ * A thenable is promise-like in as far as it has a "then" method.
+ */
+ function resolve(value?: R | Thenable): Promise;
+
+ /**
+ * Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error
+ */
+ function reject(error: any): Promise;
+
+ /**
+ * Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects.
+ * the array passed to all can be a mixture of promise-like objects and other objects.
+ * The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value.
+ */
+ function all(promises: (R | Thenable)[]): Promise;
+
+ /**
+ * Make a Promise that fulfills when any item fulfills, and rejects if any item rejects.
+ */
+ function race(promises: (R | Thenable)[]): Promise;
+}
+
+declare module 'es6-promise' {
+ var foo: typeof Promise; // Temp variable to reference Promise in local context
+ module rsvp {
+ export var Promise: typeof foo;
+ }
+ export = rsvp;
+}
diff --git a/samples/angular-migration/angular-todo-webpart/typings/knockout/knockout.d.ts b/samples/angular-migration/angular-todo-webpart/typings/knockout/knockout.d.ts
new file mode 100755
index 000000000..267f3174c
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/knockout/knockout.d.ts
@@ -0,0 +1,631 @@
+// Type definitions for Knockout v3.2.0
+// Project: http://knockoutjs.com
+// Definitions by: Boris Yankov , Igor Oleinikov , Clément Bourgeois
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+
+interface KnockoutSubscribableFunctions {
+ [key: string]: KnockoutBindingHandler;
+
+ notifySubscribers(valueToWrite?: T, event?: string): void;
+}
+
+interface KnockoutComputedFunctions {
+ [key: string]: KnockoutBindingHandler;
+}
+
+interface KnockoutObservableFunctions {
+ [key: string]: KnockoutBindingHandler;
+
+ equalityComparer(a: any, b: any): boolean;
+}
+
+interface KnockoutObservableArrayFunctions {
+ // General Array functions
+ indexOf(searchElement: T, fromIndex?: number): number;
+ slice(start: number, end?: number): T[];
+ splice(start: number): T[];
+ splice(start: number, deleteCount: number, ...items: T[]): T[];
+ pop(): T;
+ push(...items: T[]): void;
+ shift(): T;
+ unshift(...items: T[]): number;
+ reverse(): KnockoutObservableArray;
+ sort(): KnockoutObservableArray;
+ sort(compareFunction: (left: T, right: T) => number): KnockoutObservableArray;
+
+ // Ko specific
+ [key: string]: KnockoutBindingHandler;
+
+ replace(oldItem: T, newItem: T): void;
+
+ remove(item: T): T[];
+ remove(removeFunction: (item: T) => boolean): T[];
+ removeAll(items: T[]): T[];
+ removeAll(): T[];
+
+ destroy(item: T): void;
+ destroy(destroyFunction: (item: T) => boolean): void;
+ destroyAll(items: T[]): void;
+ destroyAll(): void;
+}
+
+interface KnockoutSubscribableStatic {
+ fn: KnockoutSubscribableFunctions;
+
+ new (): KnockoutSubscribable;
+}
+
+interface KnockoutSubscription {
+ dispose(): void;
+}
+
+interface KnockoutSubscribable extends KnockoutSubscribableFunctions {
+ subscribe(callback: (newValue: T) => void, target?: any, event?: string): KnockoutSubscription;
+ subscribe(callback: (newValue: TEvent) => void, target: any, event: string): KnockoutSubscription;
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutSubscribable;
+ getSubscriptionsCount(): number;
+}
+
+interface KnockoutComputedStatic {
+ fn: KnockoutComputedFunctions;
+
+ (): KnockoutComputed;
+ (func: () => T, context?: any, options?: any): KnockoutComputed;
+ (def: KnockoutComputedDefine, context?: any): KnockoutComputed;
+}
+
+interface KnockoutComputed extends KnockoutObservable, KnockoutComputedFunctions {
+ fn: KnockoutComputedFunctions;
+
+ dispose(): void;
+ isActive(): boolean;
+ getDependenciesCount(): number;
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutComputed;
+}
+
+interface KnockoutObservableArrayStatic {
+ fn: KnockoutObservableArrayFunctions;
+
+ (value?: T[]): KnockoutObservableArray;
+}
+
+interface KnockoutObservableArray extends KnockoutObservable, KnockoutObservableArrayFunctions {
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutObservableArray;
+}
+
+interface KnockoutObservableStatic {
+ fn: KnockoutObservableFunctions;
+
+ (value?: T): KnockoutObservable;
+}
+
+interface KnockoutObservable extends KnockoutSubscribable, KnockoutObservableFunctions {
+ (): T;
+ (value: T): void;
+
+ peek(): T;
+ valueHasMutated?:{(): void;};
+ valueWillMutate?:{(): void;};
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutObservable;
+}
+
+interface KnockoutComputedDefine {
+ read(): T;
+ write? (value: T): void;
+ disposeWhenNodeIsRemoved?: Node;
+ disposeWhen? (): boolean;
+ owner?: any;
+ deferEvaluation?: boolean;
+ pure?: boolean;
+}
+
+interface KnockoutBindingContext {
+ $parent: any;
+ $parents: any[];
+ $root: any;
+ $data: any;
+ $rawData: any | KnockoutObservable;
+ $index?: KnockoutObservable;
+ $parentContext?: KnockoutBindingContext;
+ $component: any;
+ $componentTemplateNodes: Node[];
+
+ extend(properties: any): any;
+ createChildContext(dataItemOrAccessor: any, dataItemAlias?: any, extendCallback?: Function): any;
+}
+
+interface KnockoutAllBindingsAccessor {
+ (): any;
+ get(name: string): any;
+ has(name: string): boolean;
+}
+
+interface KnockoutBindingHandler {
+ after?: Array;
+ init?: (element: any, valueAccessor: () => any, allBindingsAccessor?: KnockoutAllBindingsAccessor, viewModel?: any, bindingContext?: KnockoutBindingContext) => void | { controlsDescendantBindings: boolean; };
+ update?: (element: any, valueAccessor: () => any, allBindingsAccessor?: KnockoutAllBindingsAccessor, viewModel?: any, bindingContext?: KnockoutBindingContext) => void;
+ options?: any;
+ preprocess?: (value: string, name: string, addBindingCallback?: (name: string, value: string) => void) => string;
+}
+
+interface KnockoutBindingHandlers {
+ [bindingHandler: string]: KnockoutBindingHandler;
+
+ // Controlling text and appearance
+ visible: KnockoutBindingHandler;
+ text: KnockoutBindingHandler;
+ html: KnockoutBindingHandler;
+ css: KnockoutBindingHandler;
+ style: KnockoutBindingHandler;
+ attr: KnockoutBindingHandler;
+
+ // Control Flow
+ foreach: KnockoutBindingHandler;
+ if: KnockoutBindingHandler;
+ ifnot: KnockoutBindingHandler;
+ with: KnockoutBindingHandler;
+
+ // Working with form fields
+ click: KnockoutBindingHandler;
+ event: KnockoutBindingHandler;
+ submit: KnockoutBindingHandler;
+ enable: KnockoutBindingHandler;
+ disable: KnockoutBindingHandler;
+ value: KnockoutBindingHandler;
+ textInput: KnockoutBindingHandler;
+ hasfocus: KnockoutBindingHandler;
+ checked: KnockoutBindingHandler;
+ options: KnockoutBindingHandler;
+ selectedOptions: KnockoutBindingHandler;
+ uniqueName: KnockoutBindingHandler;
+
+ // Rendering templates
+ template: KnockoutBindingHandler;
+
+ // Components (new for v3.2)
+ component: KnockoutBindingHandler;
+}
+
+interface KnockoutMemoization {
+ memoize(callback: () => string): string;
+ unmemoize(memoId: string, callbackParams: any[]): boolean;
+ unmemoizeDomNodeAndDescendants(domNode: any, extraCallbackParamsArray: any[]): boolean;
+ parseMemoText(memoText: string): string;
+}
+
+interface KnockoutVirtualElement {}
+
+interface KnockoutVirtualElements {
+ allowedBindings: { [bindingName: string]: boolean; };
+ emptyNode(node: KnockoutVirtualElement ): void;
+ firstChild(node: KnockoutVirtualElement ): KnockoutVirtualElement;
+ insertAfter( container: KnockoutVirtualElement, nodeToInsert: Node, insertAfter: Node ): void;
+ nextSibling(node: KnockoutVirtualElement): Node;
+ prepend(node: KnockoutVirtualElement, toInsert: Node ): void;
+ setDomNodeChildren(node: KnockoutVirtualElement, newChildren: { length: number;[index: number]: Node; } ): void;
+ childNodes(node: KnockoutVirtualElement ): Node[];
+}
+
+interface KnockoutExtenders {
+ throttle(target: any, timeout: number): KnockoutComputed;
+ notify(target: any, notifyWhen: string): any;
+
+ rateLimit(target: any, timeout: number): any;
+ rateLimit(target: any, options: { timeout: number; method?: string; }): any;
+
+ trackArrayChanges(target: any): any;
+}
+
+//
+// NOTE TO MAINTAINERS AND CONTRIBUTORS : pay attention to only include symbols that are
+// publicly exported in the minified version of ko, without that you can give the false
+// impression that some functions will be available in production builds.
+//
+interface KnockoutUtils {
+ //////////////////////////////////
+ // utils.domData.js
+ //////////////////////////////////
+
+ domData: {
+ get (node: Element, key: string): any;
+
+ set (node: Element, key: string, value: any): void;
+
+ getAll(node: Element, createIfNotFound: boolean): any;
+
+ clear(node: Element): boolean;
+ };
+
+ //////////////////////////////////
+ // utils.domNodeDisposal.js
+ //////////////////////////////////
+
+ domNodeDisposal: {
+ addDisposeCallback(node: Element, callback: Function): void;
+
+ removeDisposeCallback(node: Element, callback: Function): void;
+
+ cleanNode(node: Node): Element;
+
+ removeNode(node: Node): void;
+ };
+
+ addOrRemoveItem(array: T[] | KnockoutObservable, value: T, included: T): void;
+
+ arrayFilter(array: T[], predicate: (item: T) => boolean): T[];
+
+ arrayFirst(array: T[], predicate: (item: T) => boolean, predicateOwner?: any): T;
+
+ arrayForEach(array: T[], action: (item: T, index: number) => void): void;
+
+ arrayGetDistinctValues(array: T[]): T[];
+
+ arrayIndexOf(array: T[], item: T): number;
+
+ arrayMap(array: T[], mapping: (item: T) => U): U[];
+
+ arrayPushAll(array: T[] | KnockoutObservableArray, valuesToPush: T[]): T[];
+
+ arrayRemoveItem(array: any[], itemToRemove: any): void;
+
+ compareArrays(a: T[], b: T[]): Array>;
+
+ extend(target: Object, source: Object): Object;
+
+ fieldsIncludedWithJsonPost: any[];
+
+ getFormFields(form: any, fieldName: string): any[];
+
+ objectForEach(obj: any, action: (key: any, value: any) => void): void;
+
+ parseHtmlFragment(html: string): any[];
+
+ parseJson(jsonString: string): any;
+
+ postJson(urlOrForm: any, data: any, options: any): void;
+
+ peekObservable(value: KnockoutObservable): T;
+
+ range(min: any, max: any): any;
+
+ registerEventHandler(element: any, eventType: any, handler: Function): void;
+
+ setHtml(node: Element, html: () => string): void;
+
+ setHtml(node: Element, html: string): void;
+
+ setTextContent(element: any, textContent: string | KnockoutObservable): void;
+
+ stringifyJson(data: any, replacer?: Function, space?: string): string;
+
+ toggleDomNodeCssClass(node: any, className: string, shouldHaveClass: boolean): void;
+
+ triggerEvent(element: any, eventType: any): void;
+
+ unwrapObservable(value: KnockoutObservable | T): T;
+
+ // NOT PART OF THE MINIFIED API SURFACE (ONLY IN knockout-{version}.debug.js) https://github.com/SteveSanderson/knockout/issues/670
+ // forceRefresh(node: any): void;
+ // ieVersion: number;
+ // isIe6: boolean;
+ // isIe7: boolean;
+ // jQueryHtmlParse(html: string): any[];
+ // makeArray(arrayLikeObject: any): any[];
+ // moveCleanedNodesToContainerElement(nodes: any[]): HTMLElement;
+ // replaceDomNodes(nodeToReplaceOrNodeArray: any, newNodesArray: any[]): void;
+ // setDomNodeChildren(domNode: any, childNodes: any[]): void;
+ // setElementName(element: any, name: string): void;
+ // setOptionNodeSelectionState(optionNode: any, isSelected: boolean): void;
+ // simpleHtmlParse(html: string): any[];
+ // stringStartsWith(str: string, startsWith: string): boolean;
+ // stringTokenize(str: string, delimiter: string): string[];
+ // stringTrim(str: string): string;
+ // tagNameLower(element: any): string;
+}
+
+interface KnockoutArrayChange {
+ status: string;
+ value: T;
+ index: number;
+ moved?: number;
+}
+
+//////////////////////////////////
+// templateSources.js
+//////////////////////////////////
+
+interface KnockoutTemplateSourcesDomElement {
+ text(): any;
+ text(value: any): void;
+
+ data(key: string): any;
+ data(key: string, value: any): any;
+}
+
+interface KnockoutTemplateAnonymous extends KnockoutTemplateSourcesDomElement {
+ nodes(): any;
+ nodes(value: any): void;
+}
+
+interface KnockoutTemplateSources {
+
+ domElement: {
+ prototype: KnockoutTemplateSourcesDomElement
+ new (element: Element): KnockoutTemplateSourcesDomElement
+ };
+
+ anonymousTemplate: {
+ prototype: KnockoutTemplateAnonymous;
+ new (element: Element): KnockoutTemplateAnonymous;
+ };
+}
+
+//////////////////////////////////
+// nativeTemplateEngine.js
+//////////////////////////////////
+
+interface KnockoutNativeTemplateEngine {
+
+ renderTemplateSource(templateSource: Object, bindingContext?: KnockoutBindingContext, options?: Object): any[];
+}
+
+//////////////////////////////////
+// templateEngine.js
+//////////////////////////////////
+
+interface KnockoutTemplateEngine extends KnockoutNativeTemplateEngine {
+
+ createJavaScriptEvaluatorBlock(script: string): string;
+
+ makeTemplateSource(template: any, templateDocument?: Document): any;
+
+ renderTemplate(template: any, bindingContext: KnockoutBindingContext, options: Object, templateDocument: Document): any;
+
+ isTemplateRewritten(template: any, templateDocument: Document): boolean;
+
+ rewriteTemplate(template: any, rewriterCallback: Function, templateDocument: Document): void;
+}
+
+/////////////////////////////////
+
+interface KnockoutStatic {
+ utils: KnockoutUtils;
+ memoization: KnockoutMemoization;
+
+ bindingHandlers: KnockoutBindingHandlers;
+ getBindingHandler(handler: string): KnockoutBindingHandler;
+
+ virtualElements: KnockoutVirtualElements;
+ extenders: KnockoutExtenders;
+
+ applyBindings(viewModelOrBindingContext?: any, rootNode?: any): void;
+ applyBindingsToDescendants(viewModelOrBindingContext: any, rootNode: any): void;
+ applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, bindingContext: KnockoutBindingContext): void;
+ applyBindingAccessorsToNode(node: Node, bindings: {}, bindingContext: KnockoutBindingContext): void;
+ applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, viewModel: any): void;
+ applyBindingAccessorsToNode(node: Node, bindings: {}, viewModel: any): void;
+ applyBindingsToNode(node: Node, bindings: any, viewModelOrBindingContext?: any): any;
+
+ subscribable: KnockoutSubscribableStatic;
+ observable: KnockoutObservableStatic;
+
+ computed: KnockoutComputedStatic;
+ pureComputed(evaluatorFunction: () => T, context?: any): KnockoutComputed;
+ pureComputed(options: KnockoutComputedDefine, context?: any): KnockoutComputed;
+
+ observableArray: KnockoutObservableArrayStatic;
+
+ contextFor(node: any): any;
+ isSubscribable(instance: any): boolean;
+ toJSON(viewModel: any, replacer?: Function, space?: any): string;
+ toJS(viewModel: any): any;
+ isObservable(instance: any): boolean;
+ isWriteableObservable(instance: any): boolean;
+ isComputed(instance: any): boolean;
+ dataFor(node: any): any;
+ removeNode(node: Element): void;
+ cleanNode(node: Element): Element;
+ renderTemplate(template: Function, viewModel: any, options?: any, target?: any, renderMode?: any): any;
+ renderTemplate(template: string, viewModel: any, options?: any, target?: any, renderMode?: any): any;
+ unwrap(value: KnockoutObservable | T): T;
+
+ computedContext: KnockoutComputedContext;
+
+ //////////////////////////////////
+ // templateSources.js
+ //////////////////////////////////
+
+ templateSources: KnockoutTemplateSources;
+
+ //////////////////////////////////
+ // templateEngine.js
+ //////////////////////////////////
+
+ templateEngine: {
+
+ prototype: KnockoutTemplateEngine;
+
+ new (): KnockoutTemplateEngine;
+ };
+
+ //////////////////////////////////
+ // templateRewriting.js
+ //////////////////////////////////
+
+ templateRewriting: {
+
+ ensureTemplateIsRewritten(template: Node, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any;
+ ensureTemplateIsRewritten(template: string, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any;
+
+ memoizeBindingAttributeSyntax(htmlString: string, templateEngine: KnockoutTemplateEngine): any;
+
+ applyMemoizedBindingsToNextSibling(bindings: any, nodeName: string): string;
+ };
+
+ //////////////////////////////////
+ // nativeTemplateEngine.js
+ //////////////////////////////////
+
+ nativeTemplateEngine: {
+
+ prototype: KnockoutNativeTemplateEngine;
+
+ new (): KnockoutNativeTemplateEngine;
+
+ instance: KnockoutNativeTemplateEngine;
+ };
+
+ //////////////////////////////////
+ // jqueryTmplTemplateEngine.js
+ //////////////////////////////////
+
+ jqueryTmplTemplateEngine: {
+
+ prototype: KnockoutTemplateEngine;
+
+ renderTemplateSource(templateSource: Object, bindingContext: KnockoutBindingContext, options: Object): Node[];
+
+ createJavaScriptEvaluatorBlock(script: string): string;
+
+ addTemplate(templateName: string, templateMarkup: string): void;
+ };
+
+ //////////////////////////////////
+ // templating.js
+ //////////////////////////////////
+
+ setTemplateEngine(templateEngine: KnockoutNativeTemplateEngine): void;
+
+ renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
+ renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
+ renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
+ renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
+ renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
+ renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
+ renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
+ renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
+
+ renderTemplateForEach(template: Function, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
+ renderTemplateForEach(template: any, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
+ renderTemplateForEach(template: Function, arrayOrObservableArray: KnockoutObservable, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
+ renderTemplateForEach(template: any, arrayOrObservableArray: KnockoutObservable, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
+
+ expressionRewriting: {
+ bindingRewriteValidators: any;
+ parseObjectLiteral: { (objectLiteralString: string): any[] }
+ };
+
+ /////////////////////////////////
+
+ bindingProvider: {
+ instance: KnockoutBindingProvider;
+ new (): KnockoutBindingProvider;
+ }
+
+ /////////////////////////////////
+ // selectExtensions.js
+ /////////////////////////////////
+
+ selectExtensions: {
+
+ readValue(element: HTMLElement): any;
+
+ writeValue(element: HTMLElement, value: any): void;
+ };
+
+ components: KnockoutComponents;
+}
+
+interface KnockoutBindingProvider {
+ nodeHasBindings(node: Node): boolean;
+ getBindings(node: Node, bindingContext: KnockoutBindingContext): {};
+ getBindingAccessors?(node: Node, bindingContext: KnockoutBindingContext): { [key: string]: string; };
+}
+
+interface KnockoutComputedContext {
+ getDependenciesCount(): number;
+ isInitial: () => boolean;
+ isSleeping: boolean;
+}
+
+//
+// refactored types into a namespace to reduce global pollution
+// and used Union Types to simplify overloads (requires TypeScript 1.4)
+//
+declare module KnockoutComponentTypes {
+
+ interface Config {
+ viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule;
+ template: string | Node[]| DocumentFragment | TemplateElement | AMDModule;
+ synchronous?: boolean;
+ }
+
+ interface ComponentConfig {
+ viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule;
+ template: any;
+ createViewModel?: any;
+ }
+
+ interface EmptyConfig {
+ }
+
+ // common AMD type
+ interface AMDModule {
+ require: string;
+ }
+
+ // viewmodel types
+ interface ViewModelFunction {
+ (params?: any): any;
+ }
+
+ interface ViewModelSharedInstance {
+ instance: any;
+ }
+
+ interface ViewModelFactoryFunction {
+ createViewModel: (params?: any, componentInfo?: ComponentInfo) => any;
+ }
+
+ interface ComponentInfo {
+ element: Node;
+ templateNodes: Node[];
+ }
+
+ interface TemplateElement {
+ element: string | Node;
+ }
+
+ interface Loader {
+ getConfig? (componentName: string, callback: (result: ComponentConfig) => void): void;
+ loadComponent? (componentName: string, config: ComponentConfig, callback: (result: Definition) => void): void;
+ loadTemplate? (componentName: string, templateConfig: any, callback: (result: Node[]) => void): void;
+ loadViewModel? (componentName: string, viewModelConfig: any, callback: (result: any) => void): void;
+ suppressLoaderExceptions?: boolean;
+ }
+
+ interface Definition {
+ template: Node[];
+ createViewModel? (params: any, options: { element: Node; }): any;
+ }
+}
+
+interface KnockoutComponents {
+ // overloads for register method:
+ register(componentName: string, config: KnockoutComponentTypes.Config | KnockoutComponentTypes.EmptyConfig): void;
+
+ isRegistered(componentName: string): boolean;
+ unregister(componentName: string): void;
+ get(componentName: string, callback: (definition: KnockoutComponentTypes.Definition) => void): void;
+ clearCachedDefinition(componentName: string): void
+ defaultLoader: KnockoutComponentTypes.Loader;
+ loaders: KnockoutComponentTypes.Loader[];
+ getComponentNameForNode(node: Node): string;
+}
+
+declare var ko: KnockoutStatic;
+
+declare module "knockout" {
+ export = ko;
+}
diff --git a/samples/angular-migration/angular-todo-webpart/typings/lodash/lodash.d.ts b/samples/angular-migration/angular-todo-webpart/typings/lodash/lodash.d.ts
new file mode 100755
index 000000000..1e39d223f
--- /dev/null
+++ b/samples/angular-migration/angular-todo-webpart/typings/lodash/lodash.d.ts
@@ -0,0 +1,20808 @@
+// Type definitions for Lo-Dash
+// Project: http://lodash.com/
+// Definitions by: Brian Zengel , Ilya Mochalov , Stepan Mikhaylyuk
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+
+/**
+### 4.0.0 Changelog (https://github.com/lodash/lodash/wiki/Changelog)
+
+#### TODO:
+removed:
+- [x] Removed _.support
+- [x] Removed _.findWhere in favor of _.find with iteratee shorthand
+- [x] Removed _.where in favor of _.filter with iteratee shorthand
+- [x] Removed _.pluck in favor of _.map with iteratee shorthand
+
+renamed:
+- [x] Renamed _.first to _.head
+- [x] Renamed _.indexBy to _.keyBy
+- [x] Renamed _.invoke to _.invokeMap
+- [x] Renamed _.overArgs to _.overArgs
+- [x] Renamed _.padLeft & _.padRight to _.padStart & _.padEnd
+- [x] Renamed _.pairs to _.toPairs
+- [x] Renamed _.rest to _.tail
+- [x] Renamed _.restParam to _.rest
+- [x] Renamed _.sortByOrder to _.orderBy
+- [x] Renamed _.trimLeft & _.trimRight to _.trimStart & _.trimEnd
+- [x] Renamed _.trunc to _.truncate
+
+split:
+- [x] Split _.indexOf & _.lastIndexOf into _.sortedIndexOf & _.sortedLastIndexOf
+- [x] Split _.max & _.min into _.maxBy & _.minBy
+- [x] Split _.omit & _.pick into _.omitBy & _.pickBy
+- [x] Split _.sample into _.sampleSize
+- [x] Split _.sortedIndex into _.sortedIndexBy
+- [x] Split _.sortedLastIndex into _.sortedLastIndexBy
+- [x] Split _.uniq into _.sortedUniq, _.sortedUniqBy, & _.uniqBy
+
+changes:
+- [x] Absorbed _.sortByAll into _.sortBy
+- [x] Changed the category of _.at to “Object”
+- [x] Changed the category of _.bindAll to “Utility”
+- [x] Made _.capitalize uppercase the first character & lowercase the rest
+- [x] Made _.functions return only own method names
+
+
+added 23 array methods:
+- [x] _.concat
+- [x] _.differenceBy
+- [x] _.differenceWith
+- [x] _.flatMap
+- [x] _.fromPairs
+- [x] _.intersectionBy
+- [x] _.intersectionWith
+- [x] _.join
+- [x] _.pullAll
+- [x] _.pullAllBy
+- [x] _.reverse
+- [x] _.sortedIndexBy
+- [x] _.sortedIndexOf
+- [x] _.sortedLastIndexBy
+- [x] _.sortedLastIndexOf
+- [x] _.sortedUniq
+- [x] _.sortedUniqBy
+- [x] _.unionBy
+- [x] _.unionWith
+- [x] _.uniqBy
+- [x] _.uniqWith
+- [x] _.xorBy
+- [x] _.xorWith
+
+added 18 lang methods:
+- [x] _.cloneDeepWith
+- [x] _.cloneWith
+- [x] _.eq
+- [x] _.isArrayLike
+- [x] _.isArrayLikeObject
+- [x] _.isEqualWith
+- [x] _.isInteger
+- [x] _.isLength
+- [x] _.isMatchWith
+- [x] _.isNil
+- [x] _.isObjectLike
+- [x] _.isSafeInteger
+- [x] _.isSymbol
+- [x] _.toInteger
+- [x] _.toLength
+- [x] _.toNumber
+- [x] _.toSafeInteger
+- [x] _.toString
+
+added 13 object methods:
+- [x] _.assignIn
+- [x] _.assignInWith
+- [x] _.assignWith
+- [x] _.functionsIn
+- [x] _.hasIn
+- [x] _.mergeWith
+- [x] _.omitBy
+- [x] _.pickBy
+
+
+added 8 string methods:
+- [x] _.lowerCase
+- [x] _.lowerFirst
+- [x] _.upperCase
+- [x] _.upperFirst
+- [x] _.toLower
+- [x] _.toUpper
+
+added 8 utility methods:
+- [x] _.toPath
+
+added 4 math methods:
+- [x] _.maxBy
+- [x] _.mean
+- [x] _.minBy
+- [x] _.sumBy
+
+added 2 function methods:
+- [x] _.flip
+- [x] _.unary
+
+added 2 number methods:
+- [x] _.clamp
+- [x] _.subtract
+
+added collection method:
+- [x] _.sampleSize
+
+Added 3 aliases
+
+- [x] _.first as an alias of _.head
+
+Removed 17 aliases
+- [x] Removed aliase _.all
+- [x] Removed aliase _.any
+- [x] Removed aliase _.backflow
+- [x] Removed aliase _.callback
+- [x] Removed aliase _.collect
+- [x] Removed aliase _.compose
+- [x] Removed aliase _.contains
+- [x] Removed aliase _.detect
+- [x] Removed aliase _.foldl
+- [x] Removed aliase _.foldr
+- [x] Removed aliase _.include
+- [x] Removed aliase _.inject
+- [x] Removed aliase _.methods
+- [x] Removed aliase _.object
+- [x] Removed aliase _.run
+- [x] Removed aliase _.select
+- [x] Removed aliase _.unique
+
+Other changes
+- [x] Added support for array buffers to _.isEqual
+- [x] Added support for converting iterators to _.toArray
+- [x] Added support for deep paths to _.zipObject
+- [x] Changed UMD to export to window or self when available regardless of other exports
+- [x] Ensured debounce cancel clears args & thisArg references
+- [x] Ensured _.add, _.subtract, & _.sum don’t skip NaN values
+- [x] Ensured _.clone treats generators like functions
+- [x] Ensured _.clone produces clones with the source’s [[Prototype]]
+- [x] Ensured _.defaults assigns properties that shadow Object.prototype
+- [x] Ensured _.defaultsDeep doesn’t merge a string into an array
+- [x] Ensured _.defaultsDeep & _.merge don’t modify sources
+- [x] Ensured _.defaultsDeep works with circular references
+- [x] Ensured _.keys skips “length” on strict mode arguments objects in Safari 9
+- [x] Ensured _.merge doesn’t convert strings to arrays
+- [x] Ensured _.merge merges plain-objects onto non plain-objects
+- [x] Ensured _#plant resets iterator data of cloned sequences
+- [x] Ensured _.random swaps min & max if min is greater than max
+- [x] Ensured _.range preserves the sign of start of -0
+- [x] Ensured _.reduce & _.reduceRight use getIteratee in their array branch
+- [x] Fixed rounding issue with the precision param of _.floor
+
+** LATER **
+Misc:
+- [ ] Made _.forEach, _.forIn, _.forOwn, & _.times implicitly end a chain sequence
+- [ ] Removed thisArg params from most methods
+- [ ] Made “By” methods provide a single param to iteratees
+- [ ] Made _.words chainable by default
+- [ ] Removed isDeep params from _.clone & _.flatten
+- [ ] Removed _.bindAll support for binding all methods when no names are provided
+- [ ] Removed func-first param signature from _.before & _.after
+- [ ] _.extend as an alias of _.assignIn
+- [ ] _.extendWith as an alias of _.assignInWith
+- [ ] Added clear method to _.memoize.Cache
+- [ ] Added flush method to debounced & throttled functions
+- [ ] Added support for ES6 maps, sets, & symbols to _.clone, _.isEqual, & _.toArray
+- [ ] Enabled _.flow & _.flowRight to accept an array of functions
+- [ ] Ensured “Collection” methods treat functions as objects
+- [ ] Ensured _.assign, _.defaults, & _.merge coerce object values to objects
+- [ ] Ensured _.bindKey bound functions call object[key] when called with the new operator
+- [ ] Ensured _.isFunction returns true for generator functions
+- [ ] Ensured _.merge assigns typed arrays directly
+- [ ] Made _(...) an iterator & iterable
+- [ ] Made _.drop, _.take, & right forms coerce n of undefined to 0
+
+Methods:
+- [ ] _.concat
+- [ ] _.differenceBy
+- [ ] _.differenceWith
+- [ ] _.flatMap
+- [ ] _.fromPairs
+- [ ] _.intersectionBy
+- [ ] _.intersectionWith
+- [ ] _.join
+- [ ] _.pullAll
+- [ ] _.pullAllBy
+- [ ] _.reverse
+- [ ] _.sortedLastIndexOf
+- [ ] _.unionBy
+- [ ] _.unionWith
+- [ ] _.uniqWith
+- [ ] _.xorBy
+- [ ] _.xorWith
+- [ ] _.toString
+
+- [ ] _.invoke
+- [ ] _.setWith
+- [ ] _.toPairs
+- [ ] _.toPairsIn
+- [ ] _.unset
+
+- [ ] _.replace
+- [ ] _.split
+
+- [ ] _.cond
+- [ ] _.conforms
+- [ ] _.nthArg
+- [ ] _.over
+- [ ] _.overEvery
+- [ ] _.overSome
+- [ ] _.rangeRight
+
+- [ ] _.next
+*/
+
+declare var _: _.LoDashStatic;
+
+declare module _ {
+ interface LoDashStatic {
+ /**
+ * Creates a lodash object which wraps the given value to enable intuitive method chaining.
+ *
+ * In addition to Lo-Dash methods, wrappers also have the following Array methods:
+ * concat, join, pop, push, reverse, shift, slice, sort, splice, and unshift
+ *
+ * Chaining is supported in custom builds as long as the value method is implicitly or
+ * explicitly included in the build.
+ *
+ * The chainable wrapper functions are:
+ * after, assign, bind, bindAll, bindKey, chain, chunk, compact, compose, concat, countBy,
+ * createCallback, curry, debounce, defaults, defer, delay, difference, filter, flatten,
+ * forEach, forEachRight, forIn, forInRight, forOwn, forOwnRight, functions, groupBy,
+ * keyBy, initial, intersection, invert, invoke, keys, map, max, memoize, merge, min,
+ * object, omit, once, pairs, partial, partialRight, pick, pluck, pull, push, range, reject,
+ * remove, rest, reverse, sample, shuffle, slice, sort, sortBy, splice, tap, throttle, times,
+ * toArray, transform, union, uniq, unset, unshift, unzip, values, where, without, wrap, and zip
+ *
+ * The non-chainable wrapper functions are:
+ * clone, cloneDeep, contains, escape, every, find, findIndex, findKey, findLast,
+ * findLastIndex, findLastKey, has, identity, indexOf, isArguments, isArray, isBoolean,
+ * isDate, isElement, isEmpty, isEqual, isFinite, isFunction, isNaN, isNull, isNumber,
+ * isObject, isPlainObject, isRegExp, isString, isUndefined, join, lastIndexOf, mixin,
+ * noConflict, parseInt, pop, random, reduce, reduceRight, result, shift, size, some,
+ * sortedIndex, runInContext, template, unescape, uniqueId, and value
+ *
+ * The wrapper functions first and last return wrapped values when n is provided, otherwise
+ * they return unwrapped values.
+ *
+ * Explicit chaining can be enabled by using the _.chain method.
+ **/
+ (value: number): LoDashImplicitWrapper;
+ (value: string): LoDashImplicitStringWrapper;
+ (value: boolean): LoDashImplicitWrapper;
+ (value: Array): LoDashImplicitNumberArrayWrapper;
+ (value: Array): LoDashImplicitArrayWrapper;
+ (value: T): LoDashImplicitObjectWrapper;
+ (value: any): LoDashImplicitWrapper;
+
+ /**
+ * The semantic version number.
+ **/
+ VERSION: string;
+
+ /**
+ * By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby
+ * (ERB). Change the following template settings to use alternative delimiters.
+ **/
+ templateSettings: TemplateSettings;
+ }
+
+ /**
+ * By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby
+ * (ERB). Change the following template settings to use alternative delimiters.
+ **/
+ interface TemplateSettings {
+ /**
+ * The "escape" delimiter.
+ **/
+ escape?: RegExp;
+
+ /**
+ * The "evaluate" delimiter.
+ **/
+ evaluate?: RegExp;
+
+ /**
+ * An object to import into the template as local variables.
+ **/
+ imports?: Dictionary;
+
+ /**
+ * The "interpolate" delimiter.
+ **/
+ interpolate?: RegExp;
+
+ /**
+ * Used to reference the data object in the template text.
+ **/
+ variable?: string;
+ }
+
+ /**
+ * Creates a cache object to store key/value pairs.
+ */
+ interface MapCache {
+ /**
+ * Removes `key` and its value from the cache.
+ * @param key The key of the value to remove.
+ * @return Returns `true` if the entry was removed successfully, else `false`.
+ */
+ delete(key: string): boolean;
+
+ /**
+ * Gets the cached value for `key`.
+ * @param key The key of the value to get.
+ * @return Returns the cached value.
+ */
+ get(key: string): any;
+
+ /**
+ * Checks if a cached value for `key` exists.
+ * @param key The key of the entry to check.
+ * @return Returns `true` if an entry for `key` exists, else `false`.
+ */
+ has(key: string): boolean;
+
+ /**
+ * Sets `value` to `key` of the cache.
+ * @param key The key of the value to cache.
+ * @param value The value to cache.
+ * @return Returns the cache object.
+ */
+ set(key: string, value: any): _.Dictionary;
+ }
+
+ interface LoDashWrapperBase { }
+
+ interface LoDashImplicitWrapperBase extends LoDashWrapperBase { }
+
+ interface LoDashExplicitWrapperBase extends LoDashWrapperBase { }
+
+ interface LoDashImplicitWrapper extends LoDashImplicitWrapperBase> { }
+
+ interface LoDashExplicitWrapper extends LoDashExplicitWrapperBase> { }
+
+ interface LoDashImplicitStringWrapper extends LoDashImplicitWrapper { }
+
+ interface LoDashExplicitStringWrapper extends LoDashExplicitWrapper { }
+
+ interface LoDashImplicitObjectWrapper extends LoDashImplicitWrapperBase> { }
+
+ interface LoDashExplicitObjectWrapper extends LoDashExplicitWrapperBase> { }
+
+ interface LoDashImplicitArrayWrapper extends LoDashImplicitWrapperBase> {
+ pop(): T;
+ push(...items: T[]): LoDashImplicitArrayWrapper;
+ shift(): T;
+ sort(compareFn?: (a: T, b: T) => number): LoDashImplicitArrayWrapper;
+ splice(start: number): LoDashImplicitArrayWrapper;
+ splice(start: number, deleteCount: number, ...items: any[]): LoDashImplicitArrayWrapper;
+ unshift(...items: T[]): LoDashImplicitArrayWrapper;
+ }
+
+ interface LoDashExplicitArrayWrapper extends LoDashExplicitWrapperBase> { }
+
+ interface LoDashImplicitNumberArrayWrapper extends LoDashImplicitArrayWrapper { }
+
+ interface LoDashExplicitNumberArrayWrapper extends LoDashExplicitArrayWrapper { }
+
+ /*********
+ * Array *
+ *********/
+
+ //_.chunk
+ interface LoDashStatic {
+ /**
+ * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the
+ * final chunk will be the remaining elements.
+ *
+ * @param array The array to process.
+ * @param size The length of each chunk.
+ * @return Returns the new array containing chunks.
+ */
+ chunk(
+ array: List,
+ size?: number
+ ): T[][];
+ }
+
+ interface LoDashImplicitArrayWrapper {
+ /**
+ * @see _.chunk
+ */
+ chunk(size?: number): LoDashImplicitArrayWrapper;
+ }
+
+ interface LoDashImplicitObjectWrapper {
+ /**
+ * @see _.chunk
+ */
+ chunk(size?: number): LoDashImplicitArrayWrapper;
+ }
+
+ interface LoDashExplicitArrayWrapper {
+ /**
+ * @see _.chunk
+ */
+ chunk(size?: number): LoDashExplicitArrayWrapper;
+ }
+
+ interface LoDashExplicitObjectWrapper {
+ /**
+ * @see _.chunk
+ */
+ chunk(size?: number): LoDashExplicitArrayWrapper;
+ }
+
+ //_.compact
+ interface LoDashStatic {
+ /**
+ * Creates an array with all falsey values removed. The values false, null, 0, "", undefined, and NaN are
+ * falsey.
+ *
+ * @param array The array to compact.
+ * @return (Array) Returns the new array of filtered values.
+ */
+ compact(array?: List): T[];
+ }
+
+ interface LoDashImplicitArrayWrapper {
+ /**
+ * @see _.compact
+ */
+ compact(): LoDashImplicitArrayWrapper;
+ }
+
+ interface LoDashImplicitObjectWrapper {
+ /**
+ * @see _.compact
+ */
+ compact(): LoDashImplicitArrayWrapper;
+ }
+
+ interface LoDashExplicitArrayWrapper {
+ /**
+ * @see _.compact
+ */
+ compact(): LoDashExplicitArrayWrapper;
+ }
+
+ interface LoDashExplicitObjectWrapper {
+ /**
+ * @see _.compact
+ */
+ compact(): LoDashExplicitArrayWrapper;
+ }
+
+ //_.concat DUMMY
+ interface LoDashStatic {
+ /**
+ * Creates a new array concatenating `array` with any additional arrays
+ * and/or values.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to concatenate.
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var other = _.concat(array, 2, [3], [[4]]);
+ *
+ * console.log(other);
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+ concat(...values: (T[]|List)[]) : T[];
+ }
+
+ //_.difference
+ interface LoDashStatic {
+ /**
+ * Creates an array of unique array values not included in the other provided arrays using SameValueZero for
+ * equality comparisons.
+ *
+ * @param array The array to inspect.
+ * @param values The arrays of values to exclude.
+ * @return Returns the new array of filtered values.
+ */
+ difference(
+ array: T[]|List,
+ ...values: Array>
+ ): T[];
+ }
+
+ interface LoDashImplicitArrayWrapper {
+ /**
+ * @see _.difference
+ */
+ difference(...values: (T[]|List)[]): LoDashImplicitArrayWrapper;
+ }
+
+ interface LoDashImplicitObjectWrapper {
+ /**
+ * @see _.difference
+ */
+ difference(...values: (TValue[]|List)[]): LoDashImplicitArrayWrapper;
+ }
+
+ interface LoDashExplicitArrayWrapper {
+ /**
+ * @see _.difference
+ */
+ difference(...values: (T[]|List)[]): LoDashExplicitArrayWrapper;
+ }
+
+ interface LoDashExplicitObjectWrapper {
+ /**
+ * @see _.difference
+ */
+ difference(...values: (TValue[]|List)[]): LoDashExplicitArrayWrapper;
+ }
+
+ //_.differenceBy
+ interface LoDashStatic {
+ /**
+ * This method is like _.difference except that it accepts iteratee which is invoked for each element of array
+ * and values to generate the criterion by which uniqueness is computed. The iteratee is invoked with one
+ * argument: (value).
+ *
+ * @param array The array to inspect.
+ * @param values The values to exclude.
+ * @param iteratee The iteratee invoked per element.
+ * @returns Returns the new array of filtered values.
+ */
+ differenceBy(
+ array: T[]|List,
+ values?: T[]|List,
+ iteratee?: ((value: T) => any)|string
+ ): T[];
+
+ /**
+ * @see _.differenceBy
+ */
+ differenceBy(
+ array: T[]|List