diff --git a/angular/common/index.ts b/angular/common/index.ts
new file mode 100644
index 0000000..e727e2e
--- /dev/null
+++ b/angular/common/index.ts
@@ -0,0 +1,14 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+// This file is not used to build this module. It is only used during editing
+// by the TypeScript language service and during build for verification. `ngc`
+// replaces this file with production index.ts when it rewrites private symbol
+// names.
+
+export * from './public_api';
diff --git a/angular/common/public_api.ts b/angular/common/public_api.ts
new file mode 100644
index 0000000..a55ca93
--- /dev/null
+++ b/angular/common/public_api.ts
@@ -0,0 +1,16 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+/**
+ * @module
+ * @description
+ * Entry point for all public APIs of the common package.
+ */
+export * from './src/common';
+
+// This file only reexports content of the `src` folder. Keep it that way.
diff --git a/angular/common/src/common.ts b/angular/common/src/common.ts
new file mode 100644
index 0000000..5e79a49
--- /dev/null
+++ b/angular/common/src/common.ts
@@ -0,0 +1,22 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+/**
+ * @module
+ * @description
+ * Entry point for all public APIs of the common package.
+ */
+export * from './location/index';
+export {NgLocaleLocalization, NgLocalization} from './localization';
+export {parseCookieValue as ɵparseCookieValue} from './cookie';
+export {CommonModule, DeprecatedI18NPipesModule} from './common_module';
+export {NgClass, NgFor, NgForOf, NgForOfContext, NgIf, NgIfContext, NgPlural, NgPluralCase, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet, NgComponentOutlet} from './directives/index';
+export {DOCUMENT} from './dom_tokens';
+export {AsyncPipe, DatePipe, I18nPluralPipe, I18nSelectPipe, JsonPipe, LowerCasePipe, CurrencyPipe, DecimalPipe, PercentPipe, SlicePipe, UpperCasePipe, TitleCasePipe} from './pipes/index';
+export {PLATFORM_BROWSER_ID as ɵPLATFORM_BROWSER_ID, PLATFORM_SERVER_ID as ɵPLATFORM_SERVER_ID, PLATFORM_WORKER_APP_ID as ɵPLATFORM_WORKER_APP_ID, PLATFORM_WORKER_UI_ID as ɵPLATFORM_WORKER_UI_ID, isPlatformBrowser, isPlatformServer, isPlatformWorkerApp, isPlatformWorkerUi} from './platform_id';
+export {VERSION} from './version';
diff --git a/angular/common/src/common_module.ts b/angular/common/src/common_module.ts
new file mode 100644
index 0000000..4a75bb4
--- /dev/null
+++ b/angular/common/src/common_module.ts
@@ -0,0 +1,47 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {NgModule} from '@angular/core';
+
+import {COMMON_DEPRECATED_DIRECTIVES, COMMON_DIRECTIVES} from './directives/index';
+import {NgLocaleLocalization, NgLocalization} from './localization';
+import {COMMON_PIPES} from './pipes/index';
+
+
+// Note: This does not contain the location providers,
+// as they need some platform specific implementations to work.
+/**
+ * The module that includes all the basic Angular directives like {@link NgIf}, {@link NgForOf}, ...
+ *
+ * @stable
+ */
+@NgModule({
+ declarations: [COMMON_DIRECTIVES, COMMON_PIPES],
+ exports: [COMMON_DIRECTIVES, COMMON_PIPES],
+ providers: [
+ {provide: NgLocalization, useClass: NgLocaleLocalization},
+ ],
+})
+export class CommonModule {
+}
+
+/**
+ * I18N pipes are being changed to move away from using the JS Intl API.
+ *
+ * The former pipes relying on the Intl API will be moved to this module while the `CommonModule`
+ * will contain the new pipes that do not rely on Intl.
+ *
+ * As a first step this module is created empty to ease the migration.
+ *
+ * see https://github.com/angular/angular/pull/18284
+ *
+ * @deprecated from v5
+ */
+@NgModule({declarations: [], exports: []})
+export class DeprecatedI18NPipesModule {
+}
diff --git a/angular/common/src/cookie.ts b/angular/common/src/cookie.ts
new file mode 100644
index 0000000..1e577cf
--- /dev/null
+++ b/angular/common/src/cookie.ts
@@ -0,0 +1,20 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+export function parseCookieValue(cookieStr: string, name: string): string|null {
+ name = encodeURIComponent(name);
+ for (const cookie of cookieStr.split(';')) {
+ const eqIndex = cookie.indexOf('=');
+ const [cookieName, cookieValue]: string[] =
+ eqIndex == -1 ? [cookie, ''] : [cookie.slice(0, eqIndex), cookie.slice(eqIndex + 1)];
+ if (cookieName.trim() === name) {
+ return decodeURIComponent(cookieValue);
+ }
+ }
+ return null;
+}
diff --git a/angular/common/src/directives/index.ts b/angular/common/src/directives/index.ts
new file mode 100644
index 0000000..b78d576
--- /dev/null
+++ b/angular/common/src/directives/index.ts
@@ -0,0 +1,60 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {Provider} from '@angular/core';
+
+import {NgClass} from './ng_class';
+import {NgComponentOutlet} from './ng_component_outlet';
+import {NgFor, NgForOf, NgForOfContext} from './ng_for_of';
+import {NgIf, NgIfContext} from './ng_if';
+import {NgPlural, NgPluralCase} from './ng_plural';
+import {NgStyle} from './ng_style';
+import {NgSwitch, NgSwitchCase, NgSwitchDefault} from './ng_switch';
+import {NgTemplateOutlet} from './ng_template_outlet';
+
+export {
+ NgClass,
+ NgComponentOutlet,
+ NgFor,
+ NgForOf,
+ NgForOfContext,
+ NgIf,
+ NgIfContext,
+ NgPlural,
+ NgPluralCase,
+ NgStyle,
+ NgSwitch,
+ NgSwitchCase,
+ NgSwitchDefault,
+ NgTemplateOutlet
+};
+
+
+
+/**
+ * A collection of Angular directives that are likely to be used in each and every Angular
+ * application.
+ */
+export const COMMON_DIRECTIVES: Provider[] = [
+ NgClass,
+ NgComponentOutlet,
+ NgForOf,
+ NgIf,
+ NgTemplateOutlet,
+ NgStyle,
+ NgSwitch,
+ NgSwitchCase,
+ NgSwitchDefault,
+ NgPlural,
+ NgPluralCase,
+];
+
+/**
+ * A collection of deprecated directives that are no longer part of the core module.
+ */
+export const COMMON_DEPRECATED_DIRECTIVES: Provider[] = [NgFor];
diff --git a/angular/common/src/directives/ng_class.ts b/angular/common/src/directives/ng_class.ts
new file mode 100644
index 0000000..73ec957
--- /dev/null
+++ b/angular/common/src/directives/ng_class.ts
@@ -0,0 +1,142 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {Directive, DoCheck, ElementRef, Input, IterableChanges, IterableDiffer, IterableDiffers, KeyValueChanges, KeyValueDiffer, KeyValueDiffers, Renderer, ɵisListLikeIterable as isListLikeIterable, ɵstringify as stringify} from '@angular/core';
+
+/**
+ * @ngModule CommonModule
+ *
+ * @whatItDoes Adds and removes CSS classes on an HTML element.
+ *
+ * @howToUse
+ * ```
+ * ...
+ *
+ * ...
+ *
+ * ...
+ *
+ * ...
+ *
+ * ...
+ * ```
+ *
+ * @description
+ *
+ * The CSS classes are updated as follows, depending on the type of the expression evaluation:
+ * - `string` - the CSS classes listed in the string (space delimited) are added,
+ * - `Array` - the CSS classes declared as Array elements are added,
+ * - `Object` - keys are CSS classes that get added when the expression given in the value
+ * evaluates to a truthy value, otherwise they are removed.
+ *
+ * @stable
+ */
+@Directive({selector: '[ngClass]'})
+export class NgClass implements DoCheck {
+ private _iterableDiffer: IterableDiffer|null;
+ private _keyValueDiffer: KeyValueDiffer|null;
+ private _initialClasses: string[] = [];
+ private _rawClass: string[]|Set|{[klass: string]: any};
+
+ constructor(
+ private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
+ private _ngEl: ElementRef, private _renderer: Renderer) {}
+
+ @Input('class')
+ set klass(v: string) {
+ this._applyInitialClasses(true);
+ this._initialClasses = typeof v === 'string' ? v.split(/\s+/) : [];
+ this._applyInitialClasses(false);
+ this._applyClasses(this._rawClass, false);
+ }
+
+ @Input()
+ set ngClass(v: string|string[]|Set|{[klass: string]: any}) {
+ this._cleanupClasses(this._rawClass);
+
+ this._iterableDiffer = null;
+ this._keyValueDiffer = null;
+
+ this._rawClass = typeof v === 'string' ? v.split(/\s+/) : v;
+
+ if (this._rawClass) {
+ if (isListLikeIterable(this._rawClass)) {
+ this._iterableDiffer = this._iterableDiffers.find(this._rawClass).create();
+ } else {
+ this._keyValueDiffer = this._keyValueDiffers.find(this._rawClass).create();
+ }
+ }
+ }
+
+ ngDoCheck(): void {
+ if (this._iterableDiffer) {
+ const iterableChanges = this._iterableDiffer.diff(this._rawClass as string[]);
+ if (iterableChanges) {
+ this._applyIterableChanges(iterableChanges);
+ }
+ } else if (this._keyValueDiffer) {
+ const keyValueChanges = this._keyValueDiffer.diff(this._rawClass as{[k: string]: any});
+ if (keyValueChanges) {
+ this._applyKeyValueChanges(keyValueChanges);
+ }
+ }
+ }
+
+ private _cleanupClasses(rawClassVal: string[]|{[klass: string]: any}): void {
+ this._applyClasses(rawClassVal, true);
+ this._applyInitialClasses(false);
+ }
+
+ private _applyKeyValueChanges(changes: KeyValueChanges): void {
+ changes.forEachAddedItem((record) => this._toggleClass(record.key, record.currentValue));
+ changes.forEachChangedItem((record) => this._toggleClass(record.key, record.currentValue));
+ changes.forEachRemovedItem((record) => {
+ if (record.previousValue) {
+ this._toggleClass(record.key, false);
+ }
+ });
+ }
+
+ private _applyIterableChanges(changes: IterableChanges): void {
+ changes.forEachAddedItem((record) => {
+ if (typeof record.item === 'string') {
+ this._toggleClass(record.item, true);
+ } else {
+ throw new Error(
+ `NgClass can only toggle CSS classes expressed as strings, got ${stringify(record.item)}`);
+ }
+ });
+
+ changes.forEachRemovedItem((record) => this._toggleClass(record.item, false));
+ }
+
+ private _applyInitialClasses(isCleanup: boolean) {
+ this._initialClasses.forEach(klass => this._toggleClass(klass, !isCleanup));
+ }
+
+ private _applyClasses(
+ rawClassVal: string[]|Set|{[klass: string]: any}, isCleanup: boolean) {
+ if (rawClassVal) {
+ if (Array.isArray(rawClassVal) || rawClassVal instanceof Set) {
+ (rawClassVal).forEach((klass: string) => this._toggleClass(klass, !isCleanup));
+ } else {
+ Object.keys(rawClassVal).forEach(klass => {
+ if (rawClassVal[klass] != null) this._toggleClass(klass, !isCleanup);
+ });
+ }
+ }
+ }
+
+ private _toggleClass(klass: string, enabled: any): void {
+ klass = klass.trim();
+ if (klass) {
+ klass.split(/\s+/g).forEach(
+ klass => { this._renderer.setElementClass(this._ngEl.nativeElement, klass, !!enabled); });
+ }
+ }
+}
diff --git a/angular/common/src/directives/ng_component_outlet.ts b/angular/common/src/directives/ng_component_outlet.ts
new file mode 100644
index 0000000..3c018a7
--- /dev/null
+++ b/angular/common/src/directives/ng_component_outlet.ts
@@ -0,0 +1,112 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {ComponentFactoryResolver, ComponentRef, Directive, Injector, Input, NgModuleFactory, NgModuleRef, OnChanges, OnDestroy, SimpleChanges, StaticProvider, Type, ViewContainerRef} from '@angular/core';
+
+
+/**
+ * Instantiates a single {@link Component} type and inserts its Host View into current View.
+ * `NgComponentOutlet` provides a declarative approach for dynamic component creation.
+ *
+ * `NgComponentOutlet` requires a component type, if a falsy value is set the view will clear and
+ * any existing component will get destroyed.
+ *
+ * ### Fine tune control
+ *
+ * You can control the component creation process by using the following optional attributes:
+ *
+ * * `ngComponentOutletInjector`: Optional custom {@link Injector} that will be used as parent for
+ * the Component. Defaults to the injector of the current view container.
+ *
+ * * `ngComponentOutletContent`: Optional list of projectable nodes to insert into the content
+ * section of the component, if exists.
+ *
+ * * `ngComponentOutletNgModuleFactory`: Optional module factory to allow dynamically loading other
+ * module, then load a component from that module.
+ *
+ * ### Syntax
+ *
+ * Simple
+ * ```
+ *
+ * ```
+ *
+ * Customized injector/content
+ * ```
+ *
+ *
+ * ```
+ *
+ * Customized ngModuleFactory
+ * ```
+ *
+ *
+ * ```
+ * ## Example
+ *
+ * {@example common/ngComponentOutlet/ts/module.ts region='SimpleExample'}
+ *
+ * A more complete example with additional options:
+ *
+ * {@example common/ngComponentOutlet/ts/module.ts region='CompleteExample'}
+
+ * A more complete example with ngModuleFactory:
+ *
+ * {@example common/ngComponentOutlet/ts/module.ts region='NgModuleFactoryExample'}
+ *
+ * @experimental
+ */
+@Directive({selector: '[ngComponentOutlet]'})
+export class NgComponentOutlet implements OnChanges, OnDestroy {
+ @Input() ngComponentOutlet: Type;
+ @Input() ngComponentOutletInjector: Injector;
+ @Input() ngComponentOutletContent: any[][];
+ @Input() ngComponentOutletNgModuleFactory: NgModuleFactory;
+
+ private _componentRef: ComponentRef|null = null;
+ private _moduleRef: NgModuleRef|null = null;
+
+ constructor(private _viewContainerRef: ViewContainerRef) {}
+
+ ngOnChanges(changes: SimpleChanges) {
+ this._viewContainerRef.clear();
+ this._componentRef = null;
+
+ if (this.ngComponentOutlet) {
+ const elInjector = this.ngComponentOutletInjector || this._viewContainerRef.parentInjector;
+
+ if (changes['ngComponentOutletNgModuleFactory']) {
+ if (this._moduleRef) this._moduleRef.destroy();
+
+ if (this.ngComponentOutletNgModuleFactory) {
+ const parentModule = elInjector.get(NgModuleRef);
+ this._moduleRef = this.ngComponentOutletNgModuleFactory.create(parentModule.injector);
+ } else {
+ this._moduleRef = null;
+ }
+ }
+
+ const componentFactoryResolver = this._moduleRef ? this._moduleRef.componentFactoryResolver :
+ elInjector.get(ComponentFactoryResolver);
+
+ const componentFactory =
+ componentFactoryResolver.resolveComponentFactory(this.ngComponentOutlet);
+
+ this._componentRef = this._viewContainerRef.createComponent(
+ componentFactory, this._viewContainerRef.length, elInjector,
+ this.ngComponentOutletContent);
+ }
+ }
+
+ ngOnDestroy() {
+ if (this._moduleRef) this._moduleRef.destroy();
+ }
+}
diff --git a/angular/common/src/directives/ng_for_of.ts b/angular/common/src/directives/ng_for_of.ts
new file mode 100644
index 0000000..1441567
--- /dev/null
+++ b/angular/common/src/directives/ng_for_of.ts
@@ -0,0 +1,214 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {ChangeDetectorRef, Directive, DoCheck, EmbeddedViewRef, Input, IterableChangeRecord, IterableChanges, IterableDiffer, IterableDiffers, NgIterable, OnChanges, SimpleChanges, TemplateRef, TrackByFunction, ViewContainerRef, forwardRef, isDevMode} from '@angular/core';
+
+/**
+ * @stable
+ */
+export class NgForOfContext {
+ constructor(
+ public $implicit: T, public ngForOf: NgIterable, public index: number,
+ public count: number) {}
+
+ get first(): boolean { return this.index === 0; }
+
+ get last(): boolean { return this.index === this.count - 1; }
+
+ get even(): boolean { return this.index % 2 === 0; }
+
+ get odd(): boolean { return !this.even; }
+}
+
+/**
+ * The `NgForOf` directive instantiates a template once per item from an iterable. The context
+ * for each instantiated template inherits from the outer context with the given loop variable
+ * set to the current item from the iterable.
+ *
+ * ### Local Variables
+ *
+ * `NgForOf` provides several exported values that can be aliased to local variables:
+ *
+ * - `$implicit: T`: The value of the individual items in the iterable (`ngForOf`).
+ * - `ngForOf: NgIterable`: The value of the iterable expression. Useful when the expression is
+ * more complex then a property access, for example when using the async pipe (`userStreams |
+ * async`).
+ * - `index: number`: The index of the current item in the iterable.
+ * - `first: boolean`: True when the item is the first item in the iterable.
+ * - `last: boolean`: True when the item is the last item in the iterable.
+ * - `even: boolean`: True when the item has an even index in the iterable.
+ * - `odd: boolean`: True when the item has an odd index in the iterable.
+ *
+ * ```
+ *
+ * {{i}}/{{users.length}}. {{user}} default
+ *
+ * ```
+ *
+ * ### Change Propagation
+ *
+ * When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM:
+ *
+ * * When an item is added, a new instance of the template is added to the DOM.
+ * * When an item is removed, its template instance is removed from the DOM.
+ * * When items are reordered, their respective templates are reordered in the DOM.
+ * * Otherwise, the DOM element for that item will remain the same.
+ *
+ * Angular uses object identity to track insertions and deletions within the iterator and reproduce
+ * those changes in the DOM. This has important implications for animations and any stateful
+ * controls (such as `` elements which accept user input) that are present. Inserted rows can
+ * be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state
+ * such as user input.
+ *
+ * It is possible for the identities of elements in the iterator to change while the data does not.
+ * This can happen, for example, if the iterator produced from an RPC to the server, and that
+ * RPC is re-run. Even if the data hasn't changed, the second response will produce objects with
+ * different identities, and Angular will tear down the entire DOM and rebuild it (as if all old
+ * elements were deleted and all new elements inserted). This is an expensive operation and should
+ * be avoided if possible.
+ *
+ * To customize the default tracking algorithm, `NgForOf` supports `trackBy` option.
+ * `trackBy` takes a function which has two arguments: `index` and `item`.
+ * If `trackBy` is given, Angular tracks changes by the return value of the function.
+ *
+ * ### Syntax
+ *
+ * - `
...
`
+ * - `
...
`
+ *
+ * With `` element:
+ *
+ * ```
+ *
+ *
...
+ *
+ * ```
+ *
+ * ### Example
+ *
+ * See a [live demo](http://plnkr.co/edit/KVuXxDp0qinGDyo307QW?p=preview) for a more detailed
+ * example.
+ *
+ * @stable
+ */
+@Directive({selector: '[ngFor][ngForOf]'})
+export class NgForOf implements DoCheck, OnChanges {
+ @Input() ngForOf: NgIterable;
+ @Input()
+ set ngForTrackBy(fn: TrackByFunction) {
+ if (isDevMode() && fn != null && typeof fn !== 'function') {
+ // TODO(vicb): use a log service once there is a public one available
+ if (console && console.warn) {
+ console.warn(
+ `trackBy must be a function, but received ${JSON.stringify(fn)}. ` +
+ `See https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html#!#change-propagation for more information.`);
+ }
+ }
+ this._trackByFn = fn;
+ }
+
+ get ngForTrackBy(): TrackByFunction { return this._trackByFn; }
+
+ private _differ: IterableDiffer|null = null;
+ private _trackByFn: TrackByFunction;
+
+ constructor(
+ private _viewContainer: ViewContainerRef, private _template: TemplateRef>,
+ private _differs: IterableDiffers) {}
+
+ @Input()
+ set ngForTemplate(value: TemplateRef>) {
+ // TODO(TS2.1): make TemplateRef>> once we move to TS v2.1
+ // The current type is too restrictive; a template that just uses index, for example,
+ // should be acceptable.
+ if (value) {
+ this._template = value;
+ }
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if ('ngForOf' in changes) {
+ // React on ngForOf changes only once all inputs have been initialized
+ const value = changes['ngForOf'].currentValue;
+ if (!this._differ && value) {
+ try {
+ this._differ = this._differs.find(value).create(this.ngForTrackBy);
+ } catch (e) {
+ throw new Error(
+ `Cannot find a differ supporting object '${value}' of type '${getTypeNameForDebugging(value)}'. NgFor only supports binding to Iterables such as Arrays.`);
+ }
+ }
+ }
+ }
+
+ ngDoCheck(): void {
+ if (this._differ) {
+ const changes = this._differ.diff(this.ngForOf);
+ if (changes) this._applyChanges(changes);
+ }
+ }
+
+ private _applyChanges(changes: IterableChanges) {
+ const insertTuples: RecordViewTuple[] = [];
+ changes.forEachOperation(
+ (item: IterableChangeRecord, adjustedPreviousIndex: number, currentIndex: number) => {
+ if (item.previousIndex == null) {
+ const view = this._viewContainer.createEmbeddedView(
+ this._template, new NgForOfContext(null !, this.ngForOf, -1, -1), currentIndex);
+ const tuple = new RecordViewTuple(item, view);
+ insertTuples.push(tuple);
+ } else if (currentIndex == null) {
+ this._viewContainer.remove(adjustedPreviousIndex);
+ } else {
+ const view = this._viewContainer.get(adjustedPreviousIndex) !;
+ this._viewContainer.move(view, currentIndex);
+ const tuple = new RecordViewTuple(item, >>view);
+ insertTuples.push(tuple);
+ }
+ });
+
+ for (let i = 0; i < insertTuples.length; i++) {
+ this._perViewChange(insertTuples[i].view, insertTuples[i].record);
+ }
+
+ for (let i = 0, ilen = this._viewContainer.length; i < ilen; i++) {
+ const viewRef = >>this._viewContainer.get(i);
+ viewRef.context.index = i;
+ viewRef.context.count = ilen;
+ }
+
+ changes.forEachIdentityChange((record: any) => {
+ const viewRef =
+ >>this._viewContainer.get(record.currentIndex);
+ viewRef.context.$implicit = record.item;
+ });
+ }
+
+ private _perViewChange(
+ view: EmbeddedViewRef>, record: IterableChangeRecord) {
+ view.context.$implicit = record.item;
+ }
+}
+
+class RecordViewTuple {
+ constructor(public record: any, public view: EmbeddedViewRef>) {}
+}
+
+/**
+ * @deprecated from v4.0.0 - Use NgForOf instead.
+ */
+export type NgFor = NgForOf;
+
+/**
+ * @deprecated from v4.0.0 - Use NgForOf instead.
+ */
+export const NgFor = NgForOf;
+
+export function getTypeNameForDebugging(type: any): string {
+ return type['name'] || typeof type;
+}
diff --git a/angular/common/src/directives/ng_if.ts b/angular/common/src/directives/ng_if.ts
new file mode 100644
index 0000000..8943fd6
--- /dev/null
+++ b/angular/common/src/directives/ng_if.ts
@@ -0,0 +1,163 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '@angular/core';
+
+
+/**
+ * Conditionally includes a template based on the value of an `expression`.
+ *
+ * `ngIf` evaluates the `expression` and then renders the `then` or `else` template in its place
+ * when expression is truthy or falsy respectively. Typically the:
+ * - `then` template is the inline template of `ngIf` unless bound to a different value.
+ * - `else` template is blank unless it is bound.
+ *
+ * ## Most common usage
+ *
+ * The most common usage of the `ngIf` directive is to conditionally show the inline template as
+ * seen in this example:
+ * {@example common/ngIf/ts/module.ts region='NgIfSimple'}
+ *
+ * ## Showing an alternative template using `else`
+ *
+ * If it is necessary to display a template when the `expression` is falsy use the `else` template
+ * binding as shown. Note that the `else` binding points to a `` labeled `#elseBlock`.
+ * The template can be defined anywhere in the component view but is typically placed right after
+ * `ngIf` for readability.
+ *
+ * {@example common/ngIf/ts/module.ts region='NgIfElse'}
+ *
+ * ## Using non-inlined `then` template
+ *
+ * Usually the `then` template is the inlined template of the `ngIf`, but it can be changed using
+ * a binding (just like `else`). Because `then` and `else` are bindings, the template references can
+ * change at runtime as shown in this example.
+ *
+ * {@example common/ngIf/ts/module.ts region='NgIfThenElse'}
+ *
+ * ## Storing conditional result in a variable
+ *
+ * A common pattern is that we need to show a set of properties from the same object. If the
+ * object is undefined, then we have to use the safe-traversal-operator `?.` to guard against
+ * dereferencing a `null` value. This is especially the case when waiting on async data such as
+ * when using the `async` pipe as shown in following example:
+ *
+ * ```
+ * Hello {{ (userStream|async)?.last }}, {{ (userStream|async)?.first }}!
+ * ```
+ *
+ * There are several inefficiencies in the above example:
+ * - We create multiple subscriptions on `userStream`. One for each `async` pipe, or two in the
+ * example above.
+ * - We cannot display an alternative screen while waiting for the data to arrive asynchronously.
+ * - We have to use the safe-traversal-operator `?.` to access properties, which is cumbersome.
+ * - We have to place the `async` pipe in parenthesis.
+ *
+ * A better way to do this is to use `ngIf` and store the result of the condition in a local
+ * variable as shown in the the example below:
+ *
+ * {@example common/ngIf/ts/module.ts region='NgIfAs'}
+ *
+ * Notice that:
+ * - We use only one `async` pipe and hence only one subscription gets created.
+ * - `ngIf` stores the result of the `userStream|async` in the local variable `user`.
+ * - The local `user` can then be bound repeatedly in a more efficient way.
+ * - No need to use the safe-traversal-operator `?.` to access properties as `ngIf` will only
+ * display the data if `userStream` returns a value.
+ * - We can display an alternative template while waiting for the data.
+ *
+ * ### Syntax
+ *
+ * Simple form:
+ * - `
...
`
+ * - `
...
`
+ * - `
...
`
+ *
+ * Form with an else block:
+ * ```
+ *
...
+ * ...
+ * ```
+ *
+ * Form with a `then` and `else` block:
+ * ```
+ *
+ * ...
+ * ...
+ * ```
+ *
+ * Form with storing the value locally:
+ * ```
+ *
{{value}}
+ * ...
+ * ```
+ *
+ * @stable
+ */
+@Directive({selector: '[ngIf]'})
+export class NgIf {
+ private _context: NgIfContext = new NgIfContext();
+ private _thenTemplateRef: TemplateRef|null = null;
+ private _elseTemplateRef: TemplateRef|null = null;
+ private _thenViewRef: EmbeddedViewRef|null = null;
+ private _elseViewRef: EmbeddedViewRef|null = null;
+
+ constructor(private _viewContainer: ViewContainerRef, templateRef: TemplateRef) {
+ this._thenTemplateRef = templateRef;
+ }
+
+ @Input()
+ set ngIf(condition: any) {
+ this._context.$implicit = this._context.ngIf = condition;
+ this._updateView();
+ }
+
+ @Input()
+ set ngIfThen(templateRef: TemplateRef) {
+ this._thenTemplateRef = templateRef;
+ this._thenViewRef = null; // clear previous view if any.
+ this._updateView();
+ }
+
+ @Input()
+ set ngIfElse(templateRef: TemplateRef) {
+ this._elseTemplateRef = templateRef;
+ this._elseViewRef = null; // clear previous view if any.
+ this._updateView();
+ }
+
+ private _updateView() {
+ if (this._context.$implicit) {
+ if (!this._thenViewRef) {
+ this._viewContainer.clear();
+ this._elseViewRef = null;
+ if (this._thenTemplateRef) {
+ this._thenViewRef =
+ this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
+ }
+ }
+ } else {
+ if (!this._elseViewRef) {
+ this._viewContainer.clear();
+ this._thenViewRef = null;
+ if (this._elseTemplateRef) {
+ this._elseViewRef =
+ this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * @stable
+ */
+export class NgIfContext {
+ public $implicit: any = null;
+ public ngIf: any = null;
+}
diff --git a/angular/common/src/directives/ng_plural.ts b/angular/common/src/directives/ng_plural.ts
new file mode 100644
index 0000000..e014a5e
--- /dev/null
+++ b/angular/common/src/directives/ng_plural.ts
@@ -0,0 +1,109 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+
+import {Attribute, Directive, Host, Input, TemplateRef, ViewContainerRef} from '@angular/core';
+
+import {NgLocalization, getPluralCategory} from '../localization';
+
+import {SwitchView} from './ng_switch';
+
+
+/**
+ * @ngModule CommonModule
+ *
+ * @whatItDoes Adds / removes DOM sub-trees based on a numeric value. Tailored for pluralization.
+ *
+ * @howToUse
+ * ```
+ *
+ * there is nothing
+ * there is one
+ * there are a few
+ *
+ * ```
+ *
+ * @description
+ *
+ * Displays DOM sub-trees that match the switch expression value, or failing that, DOM sub-trees
+ * that match the switch expression's pluralization category.
+ *
+ * To use this directive you must provide a container element that sets the `[ngPlural]` attribute
+ * to a switch expression. Inner elements with a `[ngPluralCase]` will display based on their
+ * expression:
+ * - if `[ngPluralCase]` is set to a value starting with `=`, it will only display if the value
+ * matches the switch expression exactly,
+ * - otherwise, the view will be treated as a "category match", and will only display if exact
+ * value matches aren't found and the value maps to its category for the defined locale.
+ *
+ * See http://cldr.unicode.org/index/cldr-spec/plural-rules
+ *
+ * @experimental
+ */
+@Directive({selector: '[ngPlural]'})
+export class NgPlural {
+ private _switchValue: number;
+ private _activeView: SwitchView;
+ private _caseViews: {[k: string]: SwitchView} = {};
+
+ constructor(private _localization: NgLocalization) {}
+
+ @Input()
+ set ngPlural(value: number) {
+ this._switchValue = value;
+ this._updateView();
+ }
+
+ addCase(value: string, switchView: SwitchView): void { this._caseViews[value] = switchView; }
+
+ private _updateView(): void {
+ this._clearViews();
+
+ const cases = Object.keys(this._caseViews);
+ const key = getPluralCategory(this._switchValue, cases, this._localization);
+ this._activateView(this._caseViews[key]);
+ }
+
+ private _clearViews() {
+ if (this._activeView) this._activeView.destroy();
+ }
+
+ private _activateView(view: SwitchView) {
+ if (view) {
+ this._activeView = view;
+ this._activeView.create();
+ }
+ }
+}
+
+/**
+ * @ngModule CommonModule
+ *
+ * @whatItDoes Creates a view that will be added/removed from the parent {@link NgPlural} when the
+ * given expression matches the plural expression according to CLDR rules.
+ *
+ * @howToUse
+ * ```
+ *
+ * ...
+ * ...
+ *
+ *```
+ *
+ * See {@link NgPlural} for more details and example.
+ *
+ * @experimental
+ */
+@Directive({selector: '[ngPluralCase]'})
+export class NgPluralCase {
+ constructor(
+ @Attribute('ngPluralCase') public value: string, template: TemplateRef