/**
 * @license Angular v8.2.14
 * (c) 2010-2019 Google LLC. https://angular.io/
 * License: MIT
 */

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs'), require('rxjs/operators')) :
    typeof define === 'function' && define.amd ? define('@angular/core', ['exports', 'rxjs', 'rxjs/operators'], factory) :
    (global = global || self, factory((global.ng = global.ng || {}, global.ng.core = {}), global.rxjs, global.rxjs.operators));
}(this, function (exports, rxjs, operators) { 'use strict';

    /*! *****************************************************************************
    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 ON AN *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.
    ***************************************************************************** */
    /* global Reflect, Promise */

    var extendStatics = function(d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var __assign = function() {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };

    function __rest(s, e) {
        var t = {};
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
            t[p] = s[p];
        if (s != null && typeof Object.getOwnPropertySymbols === "function")
            for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
                t[p[i]] = s[p[i]];
        return t;
    }

    function __decorate(decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
        else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    }

    function __param(paramIndex, decorator) {
        return function (target, key) { decorator(target, key, paramIndex); }
    }

    function __metadata(metadataKey, metadataValue) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
    }

    function __awaiter(thisArg, _arguments, P, generator) {
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
            function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
            function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    }

    function __generator(thisArg, body) {
        var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f) throw new TypeError("Generator is already executing.");
            while (_) try {
                if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
                if (y = 0, t) op = [op[0] & 2, t.value];
                switch (op[0]) {
                    case 0: case 1: t = op; break;
                    case 4: _.label++; return { value: op[1], done: false };
                    case 5: _.label++; y = op[1]; op = [0]; continue;
                    case 7: op = _.ops.pop(); _.trys.pop(); continue;
                    default:
                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                        if (t[2]) _.ops.pop();
                        _.trys.pop(); continue;
                }
                op = body.call(thisArg, _);
            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
            if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
        }
    }

    function __exportStar(m, exports) {
        for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
    }

    function __values(o) {
        var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
        if (m) return m.call(o);
        return {
            next: function () {
                if (o && i >= o.length) o = void 0;
                return { value: o && o[i++], done: !o };
            }
        };
    }

    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m) return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
        }
        catch (error) { e = { error: error }; }
        finally {
            try {
                if (r && !r.done && (m = i["return"])) m.call(i);
            }
            finally { if (e) throw e.error; }
        }
        return ar;
    }

    function __spread() {
        for (var ar = [], i = 0; i < arguments.length; i++)
            ar = ar.concat(__read(arguments[i]));
        return ar;
    }

    function __await(v) {
        return this instanceof __await ? (this.v = v, this) : new __await(v);
    }

    function __asyncGenerator(thisArg, _arguments, generator) {
        if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
        var g = generator.apply(thisArg, _arguments || []), i, q = [];
        return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
        function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
        function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
        function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
        function fulfill(value) { resume("next", value); }
        function reject(value) { resume("throw", value); }
        function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
    }

    function __asyncDelegator(o) {
        var i, p;
        return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
        function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
    }

    function __asyncValues(o) {
        if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
        var m = o[Symbol.asyncIterator], i;
        return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
        function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
        function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
    }

    function __makeTemplateObject(cooked, raw) {
        if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
        return cooked;
    };

    function __importStar(mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
        result.default = mod;
        return result;
    }

    function __importDefault(mod) {
        return (mod && mod.__esModule) ? mod : { default: mod };
    }

    /**
     * @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
     */
    var ANNOTATIONS = '__annotations__';
    var PARAMETERS = '__parameters__';
    var PROP_METADATA = '__prop__metadata__';
    /**
     * @suppress {globalThis}
     */
    function makeDecorator(name, props, parentClass, additionalProcessing, typeFn) {
        var metaCtor = makeMetadataCtor(props);
        function DecoratorFactory() {
            var _a;
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            if (this instanceof DecoratorFactory) {
                metaCtor.call.apply(metaCtor, __spread([this], args));
                return this;
            }
            var annotationInstance = new ((_a = DecoratorFactory).bind.apply(_a, __spread([void 0], args)))();
            return function TypeDecorator(cls) {
                if (typeFn)
                    typeFn.apply(void 0, __spread([cls], args));
                // Use of Object.defineProperty is important since it creates non-enumerable property which
                // prevents the property is copied during subclassing.
                var annotations = cls.hasOwnProperty(ANNOTATIONS) ?
                    cls[ANNOTATIONS] :
                    Object.defineProperty(cls, ANNOTATIONS, { value: [] })[ANNOTATIONS];
                annotations.push(annotationInstance);
                if (additionalProcessing)
                    additionalProcessing(cls);
                return cls;
            };
        }
        if (parentClass) {
            DecoratorFactory.prototype = Object.create(parentClass.prototype);
        }
        DecoratorFactory.prototype.ngMetadataName = name;
        DecoratorFactory.annotationCls = DecoratorFactory;
        return DecoratorFactory;
    }
    function makeMetadataCtor(props) {
        return function ctor() {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            if (props) {
                var values = props.apply(void 0, __spread(args));
                for (var propName in values) {
                    this[propName] = values[propName];
                }
            }
        };
    }
    function makeParamDecorator(name, props, parentClass) {
        var metaCtor = makeMetadataCtor(props);
        function ParamDecoratorFactory() {
            var _a;
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            if (this instanceof ParamDecoratorFactory) {
                metaCtor.apply(this, args);
                return this;
            }
            var annotationInstance = new ((_a = ParamDecoratorFactory).bind.apply(_a, __spread([void 0], args)))();
            ParamDecorator.annotation = annotationInstance;
            return ParamDecorator;
            function ParamDecorator(cls, unusedKey, index) {
                // Use of Object.defineProperty is important since it creates non-enumerable property which
                // prevents the property is copied during subclassing.
                var parameters = cls.hasOwnProperty(PARAMETERS) ?
                    cls[PARAMETERS] :
                    Object.defineProperty(cls, PARAMETERS, { value: [] })[PARAMETERS];
                // there might be gaps if some in between parameters do not have annotations.
                // we pad with nulls.
                while (parameters.length <= index) {
                    parameters.push(null);
                }
                (parameters[index] = parameters[index] || []).push(annotationInstance);
                return cls;
            }
        }
        if (parentClass) {
            ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
        }
        ParamDecoratorFactory.prototype.ngMetadataName = name;
        ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
        return ParamDecoratorFactory;
    }
    function makePropDecorator(name, props, parentClass, additionalProcessing) {
        var metaCtor = makeMetadataCtor(props);
        function PropDecoratorFactory() {
            var _a;
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            if (this instanceof PropDecoratorFactory) {
                metaCtor.apply(this, args);
                return this;
            }
            var decoratorInstance = new ((_a = PropDecoratorFactory).bind.apply(_a, __spread([void 0], args)))();
            function PropDecorator(target, name) {
                var constructor = target.constructor;
                // Use of Object.defineProperty is important since it creates non-enumerable property which
                // prevents the property is copied during subclassing.
                var meta = constructor.hasOwnProperty(PROP_METADATA) ?
                    constructor[PROP_METADATA] :
                    Object.defineProperty(constructor, PROP_METADATA, { value: {} })[PROP_METADATA];
                meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
                meta[name].unshift(decoratorInstance);
                if (additionalProcessing)
                    additionalProcessing.apply(void 0, __spread([target, name], args));
            }
            return PropDecorator;
        }
        if (parentClass) {
            PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
        }
        PropDecoratorFactory.prototype.ngMetadataName = name;
        PropDecoratorFactory.annotationCls = PropDecoratorFactory;
        return PropDecoratorFactory;
    }

    /**
     * @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
     */
    var ɵ0 = function (token) { return ({ token: token }); };
    /**
     * Inject decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var Inject = makeParamDecorator('Inject', ɵ0);
    /**
     * Optional decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var Optional = makeParamDecorator('Optional');
    /**
     * Self decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var Self = makeParamDecorator('Self');
    /**
     * SkipSelf decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var SkipSelf = makeParamDecorator('SkipSelf');
    /**
     * Host decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var Host = makeParamDecorator('Host');
    var ɵ1 = function (attributeName) { return ({ attributeName: attributeName }); };
    /**
     * Attribute decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var Attribute = makeParamDecorator('Attribute', ɵ1);

    /**
     * @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
     */
    (function (InjectFlags) {
        // TODO(alxhub): make this 'const' when ngc no longer writes exports of it into ngfactory files.
        /** Check self and check parent injector if needed */
        InjectFlags[InjectFlags["Default"] = 0] = "Default";
        /**
         * Specifies that an injector should retrieve a dependency from any injector until reaching the
         * host element of the current component. (Only used with Element Injector)
         */
        InjectFlags[InjectFlags["Host"] = 1] = "Host";
        /** Don't ascend to ancestors of the node requesting injection. */
        InjectFlags[InjectFlags["Self"] = 2] = "Self";
        /** Skip the node that is requesting injection. */
        InjectFlags[InjectFlags["SkipSelf"] = 4] = "SkipSelf";
        /** Inject `defaultValue` instead if token not found. */
        InjectFlags[InjectFlags["Optional"] = 8] = "Optional";
    })(exports.InjectFlags || (exports.InjectFlags = {}));

    /**
     * @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
     */
    function getClosureSafeProperty(objWithPropertyToExtract) {
        for (var key in objWithPropertyToExtract) {
            if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
                return key;
            }
        }
        throw Error('Could not find renamed property on target object.');
    }
    /**
     * Sets properties on a target object from a source object, but only if
     * the property doesn't already exist on the target object.
     * @param target The target to set properties on
     * @param source The source of the property keys and values to set
     */
    function fillProperties(target, source) {
        for (var key in source) {
            if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) {
                target[key] = source[key];
            }
        }
    }

    /**
     * @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
     */
    /**
     * Construct an `InjectableDef` which defines how a token will be constructed by the DI system, and
     * in which injectors (if any) it will be available.
     *
     * This should be assigned to a static `ngInjectableDef` field on a type, which will then be an
     * `InjectableType`.
     *
     * Options:
     * * `providedIn` determines which injectors will include the injectable, by either associating it
     *   with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
     *   provided in the `'root'` injector, which will be the application-level injector in most apps.
     * * `factory` gives the zero argument function which will create an instance of the injectable.
     *   The factory can call `inject` to access the `Injector` and request injection of dependencies.
     *
     * @codeGenApi
     */
    function ɵɵdefineInjectable(opts) {
        return {
            token: opts.token, providedIn: opts.providedIn || null, factory: opts.factory,
            value: undefined,
        };
    }
    /**
     * @deprecated in v8, delete after v10. This API should be used only be generated code, and that
     * code should now use ɵɵdefineInjectable instead.
     * @publicApi
     */
    var defineInjectable = ɵɵdefineInjectable;
    /**
     * Construct an `InjectorDef` which configures an injector.
     *
     * This should be assigned to a static `ngInjectorDef` field on a type, which will then be an
     * `InjectorType`.
     *
     * Options:
     *
     * * `factory`: an `InjectorType` is an instantiable type, so a zero argument `factory` function to
     *   create the type must be provided. If that factory function needs to inject arguments, it can
     *   use the `inject` function.
     * * `providers`: an optional array of providers to add to the injector. Each provider must
     *   either have a factory or point to a type which has an `ngInjectableDef` static property (the
     *   type must be an `InjectableType`).
     * * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
     *   whose providers will also be added to the injector. Locally provided types will override
     *   providers from imports.
     *
     * @publicApi
     */
    function ɵɵdefineInjector(options) {
        return {
            factory: options.factory, providers: options.providers || [], imports: options.imports || [],
        };
    }
    /**
     * Read the `ngInjectableDef` for `type` in a way which is immune to accidentally reading inherited
     * value.
     *
     * @param type A type which may have its own (non-inherited) `ngInjectableDef`.
     */
    function getInjectableDef(type) {
        var def = type[NG_INJECTABLE_DEF];
        // The definition read above may come from a base class. `hasOwnProperty` is not sufficient to
        // distinguish this case, as in older browsers (e.g. IE10) static property inheritance is
        // implemented by copying the properties.
        //
        // Instead, the ngInjectableDef's token is compared to the type, and if they don't match then the
        // property was not defined directly on the type itself, and was likely inherited. The definition
        // is only returned if the type matches the def.token.
        return def && def.token === type ? def : null;
    }
    /**
     * Read the `ngInjectableDef` for `type` or read the `ngInjectableDef` from one of its ancestors.
     *
     * @param type A type which may have `ngInjectableDef`, via inheritance.
     *
     * @deprecated Will be removed in v10, where an error will occur in the scenario if we find the
     * `ngInjectableDef` on an ancestor only.
     */
    function getInheritedInjectableDef(type) {
        if (type && type[NG_INJECTABLE_DEF]) {
            // TODO(FW-1307): Re-add ngDevMode when closure can handle it
            // ngDevMode &&
            console.warn("DEPRECATED: DI is instantiating a token \"" + type.name + "\" that inherits its @Injectable decorator but does not provide one itself.\n" +
                ("This will become an error in v10. Please add @Injectable() to the \"" + type.name + "\" class."));
            return type[NG_INJECTABLE_DEF];
        }
        else {
            return null;
        }
    }
    /**
     * Read the `ngInjectorDef` type in a way which is immune to accidentally reading inherited value.
     *
     * @param type type which may have `ngInjectorDef`
     */
    function getInjectorDef(type) {
        return type && type.hasOwnProperty(NG_INJECTOR_DEF) ? type[NG_INJECTOR_DEF] : null;
    }
    var NG_INJECTABLE_DEF = getClosureSafeProperty({ ngInjectableDef: getClosureSafeProperty });
    var NG_INJECTOR_DEF = getClosureSafeProperty({ ngInjectorDef: getClosureSafeProperty });

    /**
     * @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
     */
    function stringify(token) {
        if (typeof token === 'string') {
            return token;
        }
        if (token instanceof Array) {
            return '[' + token.map(stringify).join(', ') + ']';
        }
        if (token == null) {
            return '' + token;
        }
        if (token.overriddenName) {
            return "" + token.overriddenName;
        }
        if (token.name) {
            return "" + token.name;
        }
        var res = token.toString();
        if (res == null) {
            return '' + res;
        }
        var newLineIndex = res.indexOf('\n');
        return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
    }

    /**
     * @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
     */
    var __forward_ref__ = getClosureSafeProperty({ __forward_ref__: getClosureSafeProperty });
    /**
     * Allows to refer to references which are not yet defined.
     *
     * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
     * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
     * a query is not yet defined.
     *
     * @usageNotes
     * ### Example
     * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
     * @publicApi
     */
    function forwardRef(forwardRefFn) {
        forwardRefFn.__forward_ref__ = forwardRef;
        forwardRefFn.toString = function () { return stringify(this()); };
        return forwardRefFn;
    }
    /**
     * Lazily retrieves the reference value from a forwardRef.
     *
     * Acts as the identity function when given a non-forward-ref value.
     *
     * @usageNotes
     * ### Example
     *
     * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
     *
     * @see `forwardRef`
     * @publicApi
     */
    function resolveForwardRef(type) {
        var fn = type;
        if (typeof fn === 'function' && fn.hasOwnProperty(__forward_ref__) &&
            fn.__forward_ref__ === forwardRef) {
            return fn();
        }
        else {
            return type;
        }
    }

    /**
     * @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
     */
    var __globalThis = typeof globalThis !== 'undefined' && globalThis;
    var __window = typeof window !== 'undefined' && window;
    var __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
        self instanceof WorkerGlobalScope && self;
    var __global = typeof global !== 'undefined' && global;
    // Always use __globalThis if available, which is the spec-defined global variable across all
    // environments, then fallback to __global first, because in Node tests both __global and
    // __window may be defined and _global should be __global in that case.
    var _global = __globalThis || __global || __window || __self;

    /**
     * @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
     */
    var R3ResolvedDependencyType;
    (function (R3ResolvedDependencyType) {
        R3ResolvedDependencyType[R3ResolvedDependencyType["Token"] = 0] = "Token";
        R3ResolvedDependencyType[R3ResolvedDependencyType["Attribute"] = 1] = "Attribute";
        R3ResolvedDependencyType[R3ResolvedDependencyType["ChangeDetectorRef"] = 2] = "ChangeDetectorRef";
    })(R3ResolvedDependencyType || (R3ResolvedDependencyType = {}));

    /**
     * @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
     */
    function getCompilerFacade() {
        var globalNg = _global['ng'];
        if (!globalNg || !globalNg.ɵcompilerFacade) {
            throw new Error("Angular JIT compilation failed: '@angular/compiler' not loaded!\n" +
                "  - JIT compilation is discouraged for production use-cases! Consider AOT mode instead.\n" +
                "  - Did you bootstrap using '@angular/platform-browser-dynamic' or '@angular/platform-server'?\n" +
                "  - Alternatively provide the compiler with 'import \"@angular/compiler\";' before bootstrapping.");
        }
        return globalNg.ɵcompilerFacade;
    }

    /**
     * @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
     */
    /**
     * Creates a token that can be used in a DI Provider.
     *
     * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
     * runtime representation) such as when injecting an interface, callable type, array or
     * parameterized type.
     *
     * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
     * the `Injector`. This provides additional level of type safety.
     *
     * ```
     * interface MyInterface {...}
     * var myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
     * // myInterface is inferred to be MyInterface.
     * ```
     *
     * When creating an `InjectionToken`, you can optionally specify a factory function which returns
     * (possibly by creating) a default value of the parameterized type `T`. This sets up the
     * `InjectionToken` using this factory as a provider as if it was defined explicitly in the
     * application's root injector. If the factory function, which takes zero arguments, needs to inject
     * dependencies, it can do so using the `inject` function. See below for an example.
     *
     * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
     * overrides the above behavior and marks the token as belonging to a particular `@NgModule`. As
     * mentioned above, `'root'` is the default value for `providedIn`.
     *
     * @usageNotes
     * ### Basic Example
     *
     * ### Plain InjectionToken
     *
     * {@example core/di/ts/injector_spec.ts region='InjectionToken'}
     *
     * ### Tree-shakable InjectionToken
     *
     * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
     *
     *
     * @publicApi
     */
    var InjectionToken = /** @class */ (function () {
        function InjectionToken(_desc, options) {
            this._desc = _desc;
            /** @internal */
            this.ngMetadataName = 'InjectionToken';
            this.ngInjectableDef = undefined;
            if (typeof options == 'number') {
                // This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
                // __NG_ELEMENT_ID__ is Used by Ivy to determine bloom filter id.
                // We are using it to assign `-1` which is used to identify `Injector`.
                this.__NG_ELEMENT_ID__ = options;
            }
            else if (options !== undefined) {
                this.ngInjectableDef = ɵɵdefineInjectable({
                    token: this,
                    providedIn: options.providedIn || 'root',
                    factory: options.factory,
                });
            }
        }
        InjectionToken.prototype.toString = function () { return "InjectionToken " + this._desc; };
        return InjectionToken;
    }());

    /**
     * @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
     */
    /**
     * An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
     *
     * Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
     * project.
     *
     * @publicApi
     */
    var INJECTOR = new InjectionToken('INJECTOR', -1 // `-1` is used by Ivy DI system as special value to recognize it as `Injector`.
    );
    var _THROW_IF_NOT_FOUND = new Object();
    var THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
    var NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
    var NG_TOKEN_PATH = 'ngTokenPath';
    var NEW_LINE = /\n/gm;
    var NO_NEW_LINE = 'ɵ';
    var SOURCE = '__source';
    var ɵ0$1 = getClosureSafeProperty;
    var USE_VALUE = getClosureSafeProperty({ provide: String, useValue: ɵ0$1 });
    /**
     * Current injector value used by `inject`.
     * - `undefined`: it is an error to call `inject`
     * - `null`: `inject` can be called but there is no injector (limp-mode).
     * - Injector instance: Use the injector for resolution.
     */
    var _currentInjector = undefined;
    function setCurrentInjector(injector) {
        var former = _currentInjector;
        _currentInjector = injector;
        return former;
    }
    /**
     * Current implementation of inject.
     *
     * By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
     * to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
     * way for two reasons:
     *  1. `Injector` should not depend on ivy logic.
     *  2. To maintain tree shake-ability we don't want to bring in unnecessary code.
     */
    var _injectImplementation;
    /**
     * Sets the current inject implementation.
     */
    function setInjectImplementation(impl) {
        var previous = _injectImplementation;
        _injectImplementation = impl;
        return previous;
    }
    function injectInjectorOnly(token, flags) {
        if (flags === void 0) { flags = exports.InjectFlags.Default; }
        if (_currentInjector === undefined) {
            throw new Error("inject() must be called from an injection context");
        }
        else if (_currentInjector === null) {
            return injectRootLimpMode(token, undefined, flags);
        }
        else {
            return _currentInjector.get(token, flags & exports.InjectFlags.Optional ? null : undefined, flags);
        }
    }
    function ɵɵinject(token, flags) {
        if (flags === void 0) { flags = exports.InjectFlags.Default; }
        return (_injectImplementation || injectInjectorOnly)(token, flags);
    }
    /**
     * Injects a token from the currently active injector.
     *
     * Must be used in the context of a factory function such as one defined for an
     * `InjectionToken`. Throws an error if not called from such a context.
     *
     * Within such a factory function, using this function to request injection of a dependency
     * is faster and more type-safe than providing an additional array of dependencies
     * (as has been common with `useFactory` providers).
     *
     * @param token The injection token for the dependency to be injected.
     * @param flags Optional flags that control how injection is executed.
     * The flags correspond to injection strategies that can be specified with
     * parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
     * @returns True if injection is successful, null otherwise.
     *
     * @usageNotes
     *
     * ### Example
     *
     * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
     *
     * @publicApi
     */
    var inject = ɵɵinject;
    /**
     * Injects `root` tokens in limp mode.
     *
     * If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
     * `"root"`. This is known as the limp mode injection. In such case the value is stored in the
     * `InjectableDef`.
     */
    function injectRootLimpMode(token, notFoundValue, flags) {
        var injectableDef = getInjectableDef(token);
        if (injectableDef && injectableDef.providedIn == 'root') {
            return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
                injectableDef.value;
        }
        if (flags & exports.InjectFlags.Optional)
            return null;
        if (notFoundValue !== undefined)
            return notFoundValue;
        throw new Error("Injector: NOT_FOUND [" + stringify(token) + "]");
    }
    function injectArgs(types) {
        var args = [];
        for (var i = 0; i < types.length; i++) {
            var arg = resolveForwardRef(types[i]);
            if (Array.isArray(arg)) {
                if (arg.length === 0) {
                    throw new Error('Arguments array must have arguments.');
                }
                var type = undefined;
                var flags = exports.InjectFlags.Default;
                for (var j = 0; j < arg.length; j++) {
                    var meta = arg[j];
                    if (meta instanceof Optional || meta.ngMetadataName === 'Optional' || meta === Optional) {
                        flags |= exports.InjectFlags.Optional;
                    }
                    else if (meta instanceof SkipSelf || meta.ngMetadataName === 'SkipSelf' || meta === SkipSelf) {
                        flags |= exports.InjectFlags.SkipSelf;
                    }
                    else if (meta instanceof Self || meta.ngMetadataName === 'Self' || meta === Self) {
                        flags |= exports.InjectFlags.Self;
                    }
                    else if (meta instanceof Inject || meta === Inject) {
                        type = meta.token;
                    }
                    else {
                        type = meta;
                    }
                }
                args.push(ɵɵinject(type, flags));
            }
            else {
                args.push(ɵɵinject(arg));
            }
        }
        return args;
    }
    var NullInjector = /** @class */ (function () {
        function NullInjector() {
        }
        NullInjector.prototype.get = function (token, notFoundValue) {
            if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
            if (notFoundValue === THROW_IF_NOT_FOUND) {
                // Intentionally left behind: With dev tools open the debugger will stop here. There is no
                // reason why correctly written application should cause this exception.
                // TODO(misko): uncomment the next line once `ngDevMode` works with closure.
                // if(ngDevMode) debugger;
                var error = new Error("NullInjectorError: No provider for " + stringify(token) + "!");
                error.name = 'NullInjectorError';
                throw error;
            }
            return notFoundValue;
        };
        return NullInjector;
    }());
    function catchInjectorError(e, token, injectorErrorName, source) {
        var tokenPath = e[NG_TEMP_TOKEN_PATH];
        if (token[SOURCE]) {
            tokenPath.unshift(token[SOURCE]);
        }
        e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
        e[NG_TOKEN_PATH] = tokenPath;
        e[NG_TEMP_TOKEN_PATH] = null;
        throw e;
    }
    function formatError(text, obj, injectorErrorName, source) {
        if (source === void 0) { source = null; }
        text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.substr(2) : text;
        var context = stringify(obj);
        if (obj instanceof Array) {
            context = obj.map(stringify).join(' -> ');
        }
        else if (typeof obj === 'object') {
            var parts = [];
            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    var value = obj[key];
                    parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
                }
            }
            context = "{" + parts.join(', ') + "}";
        }
        return "" + injectorErrorName + (source ? '(' + source + ')' : '') + "[" + context + "]: " + text.replace(NEW_LINE, '\n  ');
    }

    /**
     * @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
     */
    /**
     * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
     *
     * This should be kept up to date with the public exports of @angular/core.
     */
    var angularCoreDiEnv = {
        'ɵɵdefineInjectable': ɵɵdefineInjectable,
        'ɵɵdefineInjector': ɵɵdefineInjector,
        'ɵɵinject': ɵɵinject,
        'ɵɵgetFactoryOf': getFactoryOf,
    };
    function getFactoryOf(type) {
        var typeAny = type;
        var def = getInjectableDef(typeAny) || getInjectorDef(typeAny);
        if (!def || def.factory === undefined) {
            return null;
        }
        return def.factory;
    }

    /**
     * @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
     */
    /**
     * Represents an instance of an NgModule created via a {@link NgModuleFactory}.
     *
     * `NgModuleRef` provides access to the NgModule Instance as well other objects related to this
     * NgModule Instance.
     *
     * @publicApi
     */
    var NgModuleRef = /** @class */ (function () {
        function NgModuleRef() {
        }
        return NgModuleRef;
    }());
    /**
     * @publicApi
     */
    var NgModuleFactory = /** @class */ (function () {
        function NgModuleFactory() {
        }
        return NgModuleFactory;
    }());

    /**
     * @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
     */
    /**
    * Equivalent to ES6 spread, add each item to an array.
    *
    * @param items The items to add
    * @param arr The array to which you want to add the items
    */
    function addAllToArray(items, arr) {
        for (var i = 0; i < items.length; i++) {
            arr.push(items[i]);
        }
    }
    /**
     * Flattens an array.
     */
    function flatten(list, dst) {
        if (dst === undefined)
            dst = list;
        for (var i = 0; i < list.length; i++) {
            var item = list[i];
            if (Array.isArray(item)) {
                // we need to inline it.
                if (dst === list) {
                    // Our assumption that the list was already flat was wrong and
                    // we need to clone flat since we need to write to it.
                    dst = list.slice(0, i);
                }
                flatten(item, dst);
            }
            else if (dst !== list) {
                dst.push(item);
            }
        }
        return dst;
    }
    function deepForEach(input, fn) {
        input.forEach(function (value) { return Array.isArray(value) ? deepForEach(value, fn) : fn(value); });
    }
    function addToArray(arr, index, value) {
        // perf: array.push is faster than array.splice!
        if (index >= arr.length) {
            arr.push(value);
        }
        else {
            arr.splice(index, 0, value);
        }
    }
    function removeFromArray(arr, index) {
        // perf: array.pop is faster than array.splice!
        if (index >= arr.length - 1) {
            return arr.pop();
        }
        else {
            return arr.splice(index, 1)[0];
        }
    }

    /**
     * @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
     */
    function assertNumber(actual, msg) {
        if (typeof actual != 'number') {
            throwError(msg);
        }
    }
    function assertEqual(actual, expected, msg) {
        if (actual != expected) {
            throwError(msg);
        }
    }
    function assertNotEqual(actual, expected, msg) {
        if (actual == expected) {
            throwError(msg);
        }
    }
    function assertSame(actual, expected, msg) {
        if (actual !== expected) {
            throwError(msg);
        }
    }
    function assertNotSame(actual, expected, msg) {
        if (actual === expected) {
            throwError(msg);
        }
    }
    function assertLessThan(actual, expected, msg) {
        if (actual >= expected) {
            throwError(msg);
        }
    }
    function assertGreaterThan(actual, expected, msg) {
        if (actual <= expected) {
            throwError(msg);
        }
    }
    function assertNotDefined(actual, msg) {
        if (actual != null) {
            throwError(msg);
        }
    }
    function assertDefined(actual, msg) {
        if (actual == null) {
            throwError(msg);
        }
    }
    function throwError(msg) {
        // tslint:disable-next-line
        debugger; // Left intentionally for better debugger experience.
        throw new Error("ASSERTION ERROR: " + msg);
    }
    function assertDomNode(node) {
        // If we're in a worker, `Node` will not be defined.
        assertEqual((typeof Node !== 'undefined' && node instanceof Node) ||
            (typeof node === 'object' && node != null &&
                node.constructor.name === 'WebWorkerRenderNode'), true, "The provided value must be an instance of a DOM Node but got " + stringify(node));
    }
    function assertDataInRange(arr, index) {
        var maxLen = arr ? arr.length : 0;
        assertLessThan(index, maxLen, "Index expected to be less than " + maxLen + " but got " + index);
    }

    /**
     * @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
     */
    function ngDevModeResetPerfCounters() {
        var locationString = typeof location !== 'undefined' ? location.toString() : '';
        var newCounters = {
            namedConstructors: locationString.indexOf('ngDevMode=namedConstructors') != -1,
            firstTemplatePass: 0,
            tNode: 0,
            tView: 0,
            rendererCreateTextNode: 0,
            rendererSetText: 0,
            rendererCreateElement: 0,
            rendererAddEventListener: 0,
            rendererSetAttribute: 0,
            rendererRemoveAttribute: 0,
            rendererSetProperty: 0,
            rendererSetClassName: 0,
            rendererAddClass: 0,
            rendererRemoveClass: 0,
            rendererSetStyle: 0,
            rendererRemoveStyle: 0,
            rendererDestroy: 0,
            rendererDestroyNode: 0,
            rendererMoveNode: 0,
            rendererRemoveNode: 0,
            rendererAppendChild: 0,
            rendererInsertBefore: 0,
            rendererCreateComment: 0,
            styleMap: 0,
            styleMapCacheMiss: 0,
            classMap: 0,
            classMapCacheMiss: 0,
            styleProp: 0,
            stylePropCacheMiss: 0,
            classProp: 0,
            classPropCacheMiss: 0,
            flushStyling: 0,
            classesApplied: 0,
            stylesApplied: 0,
            stylingWritePersistedState: 0,
            stylingReadPersistedState: 0,
        };
        // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
        var allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
        _global['ngDevMode'] = allowNgDevModeTrue && newCounters;
        return newCounters;
    }
    /**
     * This checks to see if the `ngDevMode` has been set. If yes,
     * then we honor it, otherwise we default to dev mode with additional checks.
     *
     * The idea is that unless we are doing production build where we explicitly
     * set `ngDevMode == false` we should be helping the developer by providing
     * as much early warning and errors as possible.
     *
     * NOTE: changes to the `ngDevMode` name must be synced with `compiler-cli/src/tooling.ts`.
     */
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
        ngDevModeResetPerfCounters();
    }

    /**
     * @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
     */
    (function (ChangeDetectionStrategy) {
        /**
         * Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated
         * until reactivated by setting the strategy to `Default` (`CheckAlways`).
         * Change detection can still be explicitly invoked.
         * This strategy applies to all child directives and cannot be overridden.
         */
        ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
        /**
         * Use the default `CheckAlways` strategy, in which change detection is automatic until
         * explicitly deactivated.
         */
        ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
    })(exports.ChangeDetectionStrategy || (exports.ChangeDetectionStrategy = {}));
    (function (ChangeDetectorStatus) {
        /**
         * A state in which, after calling `detectChanges()`, the change detector
         * state becomes `Checked`, and must be explicitly invoked or reactivated.
         */
        ChangeDetectorStatus[ChangeDetectorStatus["CheckOnce"] = 0] = "CheckOnce";
        /**
         * A state in which change detection is skipped until the change detector mode
         * becomes `CheckOnce`.
         */
        ChangeDetectorStatus[ChangeDetectorStatus["Checked"] = 1] = "Checked";
        /**
         * A state in which change detection continues automatically until explicitly
         * deactivated.
         */
        ChangeDetectorStatus[ChangeDetectorStatus["CheckAlways"] = 2] = "CheckAlways";
        /**
         * A state in which a change detector sub tree is not a part of the main tree and
         * should be skipped.
         */
        ChangeDetectorStatus[ChangeDetectorStatus["Detached"] = 3] = "Detached";
        /**
         * Indicates that the change detector encountered an error checking a binding
         * or calling a directive lifecycle method and is now in an inconsistent state. Change
         * detectors in this state do not detect changes.
         */
        ChangeDetectorStatus[ChangeDetectorStatus["Errored"] = 4] = "Errored";
        /**
         * Indicates that the change detector has been destroyed.
         */
        ChangeDetectorStatus[ChangeDetectorStatus["Destroyed"] = 5] = "Destroyed";
    })(exports.ɵChangeDetectorStatus || (exports.ɵChangeDetectorStatus = {}));
    /**
     * Reports whether a given strategy is currently the default for change detection.
     * @param changeDetectionStrategy The strategy to check.
     * @returns True if the given strategy is the current default, false otherwise.
     * @see `ChangeDetectorStatus`
     * @see `ChangeDetectorRef`
     */
    function isDefaultChangeDetectionStrategy(changeDetectionStrategy) {
        return changeDetectionStrategy == null ||
            changeDetectionStrategy === exports.ChangeDetectionStrategy.Default;
    }

    /**
     * @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
     */
    (function (ViewEncapsulation) {
        /**
         * Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
         * Element and pre-processing the style rules provided via {@link Component#styles styles} or
         * {@link Component#styleUrls styleUrls}, and adding the new Host Element attribute to all
         * selectors.
         *
         * This is the default option.
         */
        ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
        /**
         * @deprecated v6.1.0 - use {ViewEncapsulation.ShadowDom} instead.
         * Use the native encapsulation mechanism of the renderer.
         *
         * For the DOM this means using the deprecated [Shadow DOM
         * v0](https://w3c.github.io/webcomponents/spec/shadow/) and
         * creating a ShadowRoot for Component's Host Element.
         */
        ViewEncapsulation[ViewEncapsulation["Native"] = 1] = "Native";
        /**
         * Don't provide any template or style encapsulation.
         */
        ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
        /**
         * Use Shadow DOM to encapsulate styles.
         *
         * For the DOM this means using modern [Shadow
         * DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
         * creating a ShadowRoot for Component's Host Element.
         */
        ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
    })(exports.ViewEncapsulation || (exports.ViewEncapsulation = {}));

    /**
     * @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
     */
    /**
     * Convince closure compiler that the wrapped function has no side-effects.
     *
     * Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
     * allow us to execute a function but have closure compiler mark the call as no-side-effects.
     * It is important that the return value for the `noSideEffects` function be assigned
     * to something which is retained otherwise the call to `noSideEffects` will be removed by closure
     * compiler.
     */
    function noSideEffects(fn) {
        return '' + { toString: fn };
    }

    /**
    * @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 contains reuseable "empty" symbols that can be used as default return values
     * in different parts of the rendering code. Because the same symbols are returned, this
     * allows for identity checks against these values to be consistently used by the framework
     * code.
     */
    var EMPTY_OBJ = {};
    var EMPTY_ARRAY = [];
    // freezing the values prevents any code from accidentally inserting new values in
    if (typeof ngDevMode !== 'undefined' && ngDevMode) {
        // These property accesses can be ignored because ngDevMode will be set to false
        // when optimizing code and the whole if statement will be dropped.
        // tslint:disable-next-line:no-toplevel-property-access
        Object.freeze(EMPTY_OBJ);
        // tslint:disable-next-line:no-toplevel-property-access
        Object.freeze(EMPTY_ARRAY);
    }

    /**
     * @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
     */
    var NG_COMPONENT_DEF = getClosureSafeProperty({ ngComponentDef: getClosureSafeProperty });
    var NG_DIRECTIVE_DEF = getClosureSafeProperty({ ngDirectiveDef: getClosureSafeProperty });
    var NG_PIPE_DEF = getClosureSafeProperty({ ngPipeDef: getClosureSafeProperty });
    var NG_MODULE_DEF = getClosureSafeProperty({ ngModuleDef: getClosureSafeProperty });
    var NG_LOCALE_ID_DEF = getClosureSafeProperty({ ngLocaleIdDef: getClosureSafeProperty });
    var NG_BASE_DEF = getClosureSafeProperty({ ngBaseDef: getClosureSafeProperty });
    /**
     * If a directive is diPublic, bloomAdd sets a property on the type with this constant as
     * the key and the directive's unique ID as the value. This allows us to map directives to their
     * bloom filter bit for DI.
     */
    // TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
    var NG_ELEMENT_ID = getClosureSafeProperty({ __NG_ELEMENT_ID__: getClosureSafeProperty });

    /**
     * @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
     */
    var _renderCompCount = 0;
    /**
     * Create a component definition object.
     *
     *
     * # Example
     * ```
     * class MyDirective {
     *   // Generated by Angular Template Compiler
     *   // [Symbol] syntax will not be supported by TypeScript until v2.7
     *   static ngComponentDef = defineComponent({
     *     ...
     *   });
     * }
     * ```
     * @codeGenApi
     */
    function ɵɵdefineComponent(componentDefinition) {
        var type = componentDefinition.type;
        var typePrototype = type.prototype;
        var declaredInputs = {};
        var def = {
            type: type,
            providersResolver: null,
            consts: componentDefinition.consts,
            vars: componentDefinition.vars,
            factory: componentDefinition.factory,
            template: componentDefinition.template || null,
            ngContentSelectors: componentDefinition.ngContentSelectors,
            hostBindings: componentDefinition.hostBindings || null,
            contentQueries: componentDefinition.contentQueries || null,
            declaredInputs: declaredInputs,
            inputs: null,
            outputs: null,
            exportAs: componentDefinition.exportAs || null,
            onChanges: null,
            onInit: typePrototype.ngOnInit || null,
            doCheck: typePrototype.ngDoCheck || null,
            afterContentInit: typePrototype.ngAfterContentInit || null,
            afterContentChecked: typePrototype.ngAfterContentChecked || null,
            afterViewInit: typePrototype.ngAfterViewInit || null,
            afterViewChecked: typePrototype.ngAfterViewChecked || null,
            onDestroy: typePrototype.ngOnDestroy || null,
            onPush: componentDefinition.changeDetection === exports.ChangeDetectionStrategy.OnPush,
            directiveDefs: null,
            pipeDefs: null,
            selectors: componentDefinition.selectors,
            viewQuery: componentDefinition.viewQuery || null,
            features: componentDefinition.features || null,
            data: componentDefinition.data || {},
            // TODO(misko): convert ViewEncapsulation into const enum so that it can be used directly in the
            // next line. Also `None` should be 0 not 2.
            encapsulation: componentDefinition.encapsulation || exports.ViewEncapsulation.Emulated,
            id: 'c',
            styles: componentDefinition.styles || EMPTY_ARRAY,
            _: null,
            setInput: null,
            schemas: componentDefinition.schemas || null,
            tView: null,
        };
        def._ = noSideEffects(function () {
            var directiveTypes = componentDefinition.directives;
            var feature = componentDefinition.features;
            var pipeTypes = componentDefinition.pipes;
            def.id += _renderCompCount++;
            def.inputs = invertObject(componentDefinition.inputs, declaredInputs),
                def.outputs = invertObject(componentDefinition.outputs),
                feature && feature.forEach(function (fn) { return fn(def); });
            def.directiveDefs = directiveTypes ?
                function () { return (typeof directiveTypes === 'function' ? directiveTypes() : directiveTypes)
                    .map(extractDirectiveDef); } :
                null;
            def.pipeDefs = pipeTypes ?
                function () { return (typeof pipeTypes === 'function' ? pipeTypes() : pipeTypes).map(extractPipeDef); } :
                null;
            // Add ngInjectableDef so components are reachable through the module injector by default
            // (unless it has already been set by the @Injectable decorator). This is mostly to
            // support injecting components in tests. In real application code, components should
            // be retrieved through the node injector, so this isn't a problem.
            if (!type.hasOwnProperty(NG_INJECTABLE_DEF)) {
                type[NG_INJECTABLE_DEF] =
                    ɵɵdefineInjectable({ token: type, factory: componentDefinition.factory });
            }
        });
        return def;
    }
    /**
     * @codeGenApi
     */
    function ɵɵsetComponentScope(type, directives, pipes) {
        var def = type.ngComponentDef;
        def.directiveDefs = function () { return directives.map(extractDirectiveDef); };
        def.pipeDefs = function () { return pipes.map(extractPipeDef); };
    }
    function extractDirectiveDef(type) {
        var def = getComponentDef(type) || getDirectiveDef(type);
        if (ngDevMode && !def) {
            throw new Error("'" + type.name + "' is neither 'ComponentType' or 'DirectiveType'.");
        }
        return def;
    }
    function extractPipeDef(type) {
        var def = getPipeDef(type);
        if (ngDevMode && !def) {
            throw new Error("'" + type.name + "' is not a 'PipeType'.");
        }
        return def;
    }
    /**
     * @codeGenApi
     */
    function ɵɵdefineNgModule(def) {
        var res = {
            type: def.type,
            bootstrap: def.bootstrap || EMPTY_ARRAY,
            declarations: def.declarations || EMPTY_ARRAY,
            imports: def.imports || EMPTY_ARRAY,
            exports: def.exports || EMPTY_ARRAY,
            transitiveCompileScopes: null,
            schemas: def.schemas || null,
            id: def.id || null,
        };
        return res;
    }
    /**
     * Adds the module metadata that is necessary to compute the module's transitive scope to an
     * existing module definition.
     *
     * Scope metadata of modules is not used in production builds, so calls to this function can be
     * marked pure to tree-shake it from the bundle, allowing for all referenced declarations
     * to become eligible for tree-shaking as well.
     *
     * @codeGenApi
     */
    function ɵɵsetNgModuleScope(type, scope) {
        return noSideEffects(function () {
            var ngModuleDef = getNgModuleDef(type, true);
            ngModuleDef.declarations = scope.declarations || EMPTY_ARRAY;
            ngModuleDef.imports = scope.imports || EMPTY_ARRAY;
            ngModuleDef.exports = scope.exports || EMPTY_ARRAY;
        });
    }
    /**
     * Inverts an inputs or outputs lookup such that the keys, which were the
     * minified keys, are part of the values, and the values are parsed so that
     * the publicName of the property is the new key
     *
     * e.g. for
     *
     * ```
     * class Comp {
     *   @Input()
     *   propName1: string;
     *
     *   @Input('publicName2')
     *   declaredPropName2: number;
     * }
     * ```
     *
     * will be serialized as
     *
     * ```
     * {
     *   propName1: 'propName1',
     *   declaredPropName2: ['publicName2', 'declaredPropName2'],
     * }
     * ```
     *
     * which is than translated by the minifier as:
     *
     * ```
     * {
     *   minifiedPropName1: 'propName1',
     *   minifiedPropName2: ['publicName2', 'declaredPropName2'],
     * }
     * ```
     *
     * becomes: (public name => minifiedName)
     *
     * ```
     * {
     *  'propName1': 'minifiedPropName1',
     *  'publicName2': 'minifiedPropName2',
     * }
     * ```
     *
     * Optionally the function can take `secondary` which will result in: (public name => declared name)
     *
     * ```
     * {
     *  'propName1': 'propName1',
     *  'publicName2': 'declaredPropName2',
     * }
     * ```
     *

     */
    function invertObject(obj, secondary) {
        if (obj == null)
            return EMPTY_OBJ;
        var newLookup = {};
        for (var minifiedKey in obj) {
            if (obj.hasOwnProperty(minifiedKey)) {
                var publicName = obj[minifiedKey];
                var declaredName = publicName;
                if (Array.isArray(publicName)) {
                    declaredName = publicName[1];
                    publicName = publicName[0];
                }
                newLookup[publicName] = minifiedKey;
                if (secondary) {
                    (secondary[publicName] = declaredName);
                }
            }
        }
        return newLookup;
    }
    /**
     * Create a base definition
     *
     * # Example
     * ```ts
     * class ShouldBeInherited {
     *   static ngBaseDef = ɵɵdefineBase({
     *      ...
     *   })
     * }
     * ```
     *
     * @param baseDefinition The base definition parameters
     *
     * @codeGenApi
     */
    function ɵɵdefineBase(baseDefinition) {
        var declaredInputs = {};
        return {
            inputs: invertObject(baseDefinition.inputs, declaredInputs),
            declaredInputs: declaredInputs,
            outputs: invertObject(baseDefinition.outputs),
            viewQuery: baseDefinition.viewQuery || null,
            contentQueries: baseDefinition.contentQueries || null,
            hostBindings: baseDefinition.hostBindings || null
        };
    }
    /**
     * Create a directive definition object.
     *
     * # Example
     * ```ts
     * class MyDirective {
     *   // Generated by Angular Template Compiler
     *   // [Symbol] syntax will not be supported by TypeScript until v2.7
     *   static ngDirectiveDef = ɵɵdefineDirective({
     *     ...
     *   });
     * }
     * ```
     *
     * @codeGenApi
     */
    var ɵɵdefineDirective = ɵɵdefineComponent;
    /**
     * Create a pipe definition object.
     *
     * # Example
     * ```
     * class MyPipe implements PipeTransform {
     *   // Generated by Angular Template Compiler
     *   static ngPipeDef = definePipe({
     *     ...
     *   });
     * }
     * ```
     * @param pipeDef Pipe definition generated by the compiler
     *
     * @codeGenApi
     */
    function ɵɵdefinePipe(pipeDef) {
        return {
            name: pipeDef.name,
            factory: pipeDef.factory,
            pure: pipeDef.pure !== false,
            onDestroy: pipeDef.type.prototype.ngOnDestroy || null
        };
    }
    /**
     * The following getter methods retrieve the definition form the type. Currently the retrieval
     * honors inheritance, but in the future we may change the rule to require that definitions are
     * explicit. This would require some sort of migration strategy.
     */
    function getComponentDef(type) {
        return type[NG_COMPONENT_DEF] || null;
    }
    function getDirectiveDef(type) {
        return type[NG_DIRECTIVE_DEF] || null;
    }
    function getPipeDef(type) {
        return type[NG_PIPE_DEF] || null;
    }
    function getBaseDef(type) {
        return type[NG_BASE_DEF] || null;
    }
    function getNgModuleDef(type, throwNotFound) {
        var ngModuleDef = type[NG_MODULE_DEF] || null;
        if (!ngModuleDef && throwNotFound === true) {
            throw new Error("Type " + stringify(type) + " does not have 'ngModuleDef' property.");
        }
        return ngModuleDef;
    }
    function getNgLocaleIdDef(type) {
        return type[NG_LOCALE_ID_DEF] || null;
    }

    /**
     * @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
     */
    // Below are constants for LView indices to help us look up LView members
    // without having to remember the specific indices.
    // Uglify will inline these when minifying so there shouldn't be a cost.
    var HOST = 0;
    var TVIEW = 1;
    var FLAGS = 2;
    var PARENT = 3;
    var NEXT = 4;
    var QUERIES = 5;
    var T_HOST = 6;
    var BINDING_INDEX = 7;
    var CLEANUP = 8;
    var CONTEXT = 9;
    var INJECTOR$1 = 10;
    var RENDERER_FACTORY = 11;
    var RENDERER = 12;
    var SANITIZER = 13;
    var CHILD_HEAD = 14;
    var CHILD_TAIL = 15;
    var DECLARATION_VIEW = 16;
    var DECLARATION_LCONTAINER = 17;
    var PREORDER_HOOK_FLAGS = 18;
    /** Size of LView's header. Necessary to adjust for it when setting slots.  */
    var HEADER_OFFSET = 19;
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd = 1;

    /**
     * @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
     */
    /**
     * Special location which allows easy identification of type. If we have an array which was
     * retrieved from the `LView` and that array has `true` at `TYPE` location, we know it is
     * `LContainer`.
     */
    var TYPE = 1;
    /**
     * Below are constants for LContainer indices to help us look up LContainer members
     * without having to remember the specific indices.
     * Uglify will inline these when minifying so there shouldn't be a cost.
     */
    var ACTIVE_INDEX = 2;
    // PARENT and NEXT are indices 3 and 4
    // As we already have these constants in LView, we don't need to re-create them.
    var MOVED_VIEWS = 5;
    // T_HOST is index 6
    // We already have this constants in LView, we don't need to re-create it.
    var NATIVE = 7;
    var VIEW_REFS = 8;
    /**
     * Size of LContainer's header. Represents the index after which all views in the
     * container will be inserted. We need to keep a record of current views so we know
     * which views are already in the DOM (and don't need to be re-added) and so we can
     * remove views from the DOM when they are no longer required.
     */
    var CONTAINER_HEADER_OFFSET = 9;
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$1 = 1;

    /**
     * @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
     */
    /**
    * True if `value` is `LView`.
    * @param value wrapped value of `RNode`, `LView`, `LContainer`
    */
    function isLView(value) {
        return Array.isArray(value) && typeof value[TYPE] === 'object';
    }
    /**
     * True if `value` is `LContainer`.
     * @param value wrapped value of `RNode`, `LView`, `LContainer`
     */
    function isLContainer(value) {
        return Array.isArray(value) && value[TYPE] === true;
    }
    function isContentQueryHost(tNode) {
        return (tNode.flags & 4 /* hasContentQuery */) !== 0;
    }
    function isComponent(tNode) {
        return (tNode.flags & 1 /* isComponent */) === 1 /* isComponent */;
    }
    function isComponentDef(def) {
        return def.template !== null;
    }
    function isRootView(target) {
        return (target[FLAGS] & 512 /* IsRoot */) !== 0;
    }

    /**
     * @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
     */
    function assertTNodeForLView(tNode, lView) {
        tNode.hasOwnProperty('tView_') && assertEqual(tNode.tView_, lView[TVIEW], 'This TNode does not belong to this LView.');
    }
    function assertComponentType(actual, msg) {
        if (msg === void 0) { msg = 'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.'; }
        if (!getComponentDef(actual)) {
            throwError(msg);
        }
    }
    function assertNgModuleType(actual, msg) {
        if (msg === void 0) { msg = 'Type passed in is not NgModuleType, it does not have \'ngModuleDef\' property.'; }
        if (!getNgModuleDef(actual)) {
            throwError(msg);
        }
    }
    function assertPreviousIsParent(isParent) {
        assertEqual(isParent, true, 'previousOrParentTNode should be a parent');
    }
    function assertHasParent(tNode) {
        assertDefined(tNode, 'previousOrParentTNode should exist!');
        assertDefined(tNode.parent, 'previousOrParentTNode should have a parent');
    }
    function assertDataNext(lView, index, arr) {
        if (arr == null)
            arr = lView;
        assertEqual(arr.length, index, "index " + index + " expected to be at the end of arr (length " + arr.length + ")");
    }
    function assertLContainerOrUndefined(value) {
        value && assertEqual(isLContainer(value), true, 'Expecting LContainer or undefined or null');
    }
    function assertLContainer(value) {
        assertDefined(value, 'LContainer must be defined');
        assertEqual(isLContainer(value), true, 'Expecting LContainer');
    }
    function assertLViewOrUndefined(value) {
        value && assertEqual(isLView(value), true, 'Expecting LView or undefined or null');
    }
    function assertLView(value) {
        assertDefined(value, 'LView must be defined');
        assertEqual(isLView(value), true, 'Expecting LView');
    }
    function assertFirstTemplatePass(tView, errMessage) {
        assertEqual(tView.firstTemplatePass, true, errMessage);
    }

    /**
     * @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
     */
    var TNODE = 8;
    var PARENT_INJECTOR = 8;
    var INJECTOR_BLOOM_PARENT_SIZE = 9;
    var NO_PARENT_INJECTOR = -1;
    /**
     * Each injector is saved in 9 contiguous slots in `LView` and 9 contiguous slots in
     * `TView.data`. This allows us to store information about the current node's tokens (which
     * can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be
     * shared, so they live in `LView`).
     *
     * Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter
     * determines whether a directive is available on the associated node or not. This prevents us
     * from searching the directives array at this level unless it's probable the directive is in it.
     *
     * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
     *
     * Because all injectors have been flattened into `LView` and `TViewData`, they cannot typed
     * using interfaces as they were previously. The start index of each `LInjector` and `TInjector`
     * will differ based on where it is flattened into the main array, so it's not possible to know
     * the indices ahead of time and save their types here. The interfaces are still included here
     * for documentation purposes.
     *
     * export interface LInjector extends Array<any> {
     *
     *    // Cumulative bloom for directive IDs 0-31  (IDs are % BLOOM_SIZE)
     *    [0]: number;
     *
     *    // Cumulative bloom for directive IDs 32-63
     *    [1]: number;
     *
     *    // Cumulative bloom for directive IDs 64-95
     *    [2]: number;
     *
     *    // Cumulative bloom for directive IDs 96-127
     *    [3]: number;
     *
     *    // Cumulative bloom for directive IDs 128-159
     *    [4]: number;
     *
     *    // Cumulative bloom for directive IDs 160 - 191
     *    [5]: number;
     *
     *    // Cumulative bloom for directive IDs 192 - 223
     *    [6]: number;
     *
     *    // Cumulative bloom for directive IDs 224 - 255
     *    [7]: number;
     *
     *    // We need to store a reference to the injector's parent so DI can keep looking up
     *    // the injector tree until it finds the dependency it's looking for.
     *    [PARENT_INJECTOR]: number;
     * }
     *
     * export interface TInjector extends Array<any> {
     *
     *    // Shared node bloom for directive IDs 0-31  (IDs are % BLOOM_SIZE)
     *    [0]: number;
     *
     *    // Shared node bloom for directive IDs 32-63
     *    [1]: number;
     *
     *    // Shared node bloom for directive IDs 64-95
     *    [2]: number;
     *
     *    // Shared node bloom for directive IDs 96-127
     *    [3]: number;
     *
     *    // Shared node bloom for directive IDs 128-159
     *    [4]: number;
     *
     *    // Shared node bloom for directive IDs 160 - 191
     *    [5]: number;
     *
     *    // Shared node bloom for directive IDs 192 - 223
     *    [6]: number;
     *
     *    // Shared node bloom for directive IDs 224 - 255
     *    [7]: number;
     *
     *    // Necessary to find directive indices for a particular node.
     *    [TNODE]: TElementNode|TElementContainerNode|TContainerNode;
     *  }
     */
    /**
    * Factory for creating instances of injectors in the NodeInjector.
    *
    * This factory is complicated by the fact that it can resolve `multi` factories as well.
    *
    * NOTE: Some of the fields are optional which means that this class has two hidden classes.
    * - One without `multi` support (most common)
    * - One with `multi` values, (rare).
    *
    * Since VMs can cache up to 4 inline hidden classes this is OK.
    *
    * - Single factory: Only `resolving` and `factory` is defined.
    * - `providers` factory: `componentProviders` is a number and `index = -1`.
    * - `viewProviders` factory: `componentProviders` is a number and `index` points to `providers`.
    */
    var NodeInjectorFactory = /** @class */ (function () {
        function NodeInjectorFactory(
        /**
         * Factory to invoke in order to create a new instance.
         */
        factory, 
        /**
         * Set to `true` if the token is declared in `viewProviders` (or if it is component).
         */
        isViewProvider, injectImplementation) {
            this.factory = factory;
            /**
             * Marker set to true during factory invocation to see if we get into recursive loop.
             * Recursive loop causes an error to be displayed.
             */
            this.resolving = false;
            this.canSeeViewProviders = isViewProvider;
            this.injectImpl = injectImplementation;
        }
        return NodeInjectorFactory;
    }());
    function isFactory(obj) {
        // See: https://jsperf.com/instanceof-vs-getprototypeof
        return obj !== null && typeof obj == 'object' &&
            Object.getPrototypeOf(obj) == NodeInjectorFactory.prototype;
    }
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$2 = 1;

    /**
     * @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
     */
    function assertNodeType(tNode, type) {
        assertDefined(tNode, 'should be called with a TNode');
        assertEqual(tNode.type, type, "should be a " + typeName(type));
    }
    function assertNodeOfPossibleTypes(tNode) {
        var types = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            types[_i - 1] = arguments[_i];
        }
        assertDefined(tNode, 'should be called with a TNode');
        var found = types.some(function (type) { return tNode.type === type; });
        assertEqual(found, true, "Should be one of " + types.map(typeName).join(', ') + " but got " + typeName(tNode.type));
    }
    function typeName(type) {
        if (type == 1 /* Projection */)
            return 'Projection';
        if (type == 0 /* Container */)
            return 'Container';
        if (type == 2 /* View */)
            return 'View';
        if (type == 3 /* Element */)
            return 'Element';
        if (type == 4 /* ElementContainer */)
            return 'ElementContainer';
        return '<unknown>';
    }

    /**
     * @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
     */
    /**
     * Adds all directive lifecycle hooks from the given `DirectiveDef` to the given `TView`.
     *
     * Must be run *only* on the first template pass.
     *
     * Sets up the pre-order hooks on the provided `tView`,
     * see {@link HookData} for details about the data structure.
     *
     * @param directiveIndex The index of the directive in LView
     * @param directiveDef The definition containing the hooks to setup in tView
     * @param tView The current TView
     * @param nodeIndex The index of the node to which the directive is attached
     * @param initialPreOrderHooksLength the number of pre-order hooks already registered before the
     * current process, used to know if the node index has to be added to the array. If it is -1,
     * the node index is never added.
     * @param initialPreOrderCheckHooksLength same as previous for pre-order check hooks
     */
    function registerPreOrderHooks(directiveIndex, directiveDef, tView, nodeIndex, initialPreOrderHooksLength, initialPreOrderCheckHooksLength) {
        ngDevMode &&
            assertEqual(tView.firstTemplatePass, true, 'Should only be called on first template pass');
        var onChanges = directiveDef.onChanges, onInit = directiveDef.onInit, doCheck = directiveDef.doCheck;
        if (initialPreOrderHooksLength >= 0 &&
            (!tView.preOrderHooks || initialPreOrderHooksLength === tView.preOrderHooks.length) &&
            (onChanges || onInit || doCheck)) {
            (tView.preOrderHooks || (tView.preOrderHooks = [])).push(nodeIndex);
        }
        if (initialPreOrderCheckHooksLength >= 0 &&
            (!tView.preOrderCheckHooks ||
                initialPreOrderCheckHooksLength === tView.preOrderCheckHooks.length) &&
            (onChanges || doCheck)) {
            (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(nodeIndex);
        }
        if (onChanges) {
            (tView.preOrderHooks || (tView.preOrderHooks = [])).push(directiveIndex, onChanges);
            (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(directiveIndex, onChanges);
        }
        if (onInit) {
            (tView.preOrderHooks || (tView.preOrderHooks = [])).push(-directiveIndex, onInit);
        }
        if (doCheck) {
            (tView.preOrderHooks || (tView.preOrderHooks = [])).push(directiveIndex, doCheck);
            (tView.preOrderCheckHooks || (tView.preOrderCheckHooks = [])).push(directiveIndex, doCheck);
        }
    }
    /**
     *
     * Loops through the directives on the provided `tNode` and queues hooks to be
     * run that are not initialization hooks.
     *
     * Should be executed during `elementEnd()` and similar to
     * preserve hook execution order. Content, view, and destroy hooks for projected
     * components and directives must be called *before* their hosts.
     *
     * Sets up the content, view, and destroy hooks on the provided `tView`,
     * see {@link HookData} for details about the data structure.
     *
     * NOTE: This does not set up `onChanges`, `onInit` or `doCheck`, those are set up
     * separately at `elementStart`.
     *
     * @param tView The current TView
     * @param tNode The TNode whose directives are to be searched for hooks to queue
     */
    function registerPostOrderHooks(tView, tNode) {
        if (tView.firstTemplatePass) {
            // It's necessary to loop through the directives at elementEnd() (rather than processing in
            // directiveCreate) so we can preserve the current hook order. Content, view, and destroy
            // hooks for projected components and directives must be called *before* their hosts.
            for (var i = tNode.directiveStart, end = tNode.directiveEnd; i < end; i++) {
                var directiveDef = tView.data[i];
                if (directiveDef.afterContentInit) {
                    (tView.contentHooks || (tView.contentHooks = [])).push(-i, directiveDef.afterContentInit);
                }
                if (directiveDef.afterContentChecked) {
                    (tView.contentHooks || (tView.contentHooks = [])).push(i, directiveDef.afterContentChecked);
                    (tView.contentCheckHooks || (tView.contentCheckHooks = [])).push(i, directiveDef.afterContentChecked);
                }
                if (directiveDef.afterViewInit) {
                    (tView.viewHooks || (tView.viewHooks = [])).push(-i, directiveDef.afterViewInit);
                }
                if (directiveDef.afterViewChecked) {
                    (tView.viewHooks || (tView.viewHooks = [])).push(i, directiveDef.afterViewChecked);
                    (tView.viewCheckHooks || (tView.viewCheckHooks = [])).push(i, directiveDef.afterViewChecked);
                }
                if (directiveDef.onDestroy != null) {
                    (tView.destroyHooks || (tView.destroyHooks = [])).push(i, directiveDef.onDestroy);
                }
            }
        }
    }
    /**
     * Executing hooks requires complex logic as we need to deal with 2 constraints.
     *
     * 1. Init hooks (ngOnInit, ngAfterContentInit, ngAfterViewInit) must all be executed once and only
     * once, across many change detection cycles. This must be true even if some hooks throw, or if
     * some recursively trigger a change detection cycle.
     * To solve that, it is required to track the state of the execution of these init hooks.
     * This is done by storing and maintaining flags in the view: the {@link InitPhaseState},
     * and the index within that phase. They can be seen as a cursor in the following structure:
     * [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]
     * They are are stored as flags in LView[FLAGS].
     *
     * 2. Pre-order hooks can be executed in batches, because of the select instruction.
     * To be able to pause and resume their execution, we also need some state about the hook's array
     * that is being processed:
     * - the index of the next hook to be executed
     * - the number of init hooks already found in the processed part of the  array
     * They are are stored as flags in LView[PREORDER_HOOK_FLAGS].
     */
    /**
     * Executes necessary hooks at the start of executing a template.
     *
     * Executes hooks that are to be run during the initialization of a directive such
     * as `onChanges`, `onInit`, and `doCheck`.
     *
     * @param lView The current view
     * @param tView Static data for the view containing the hooks to be executed
     * @param checkNoChangesMode Whether or not we're in checkNoChanges mode.
     * @param @param currentNodeIndex 2 cases depending the the value:
     * - undefined: execute hooks only from the saved index until the end of the array (pre-order case,
     * when flushing the remaining hooks)
     * - number: execute hooks only from the saved index until that node index exclusive (pre-order
     * case, when executing select(number))
     */
    function executePreOrderHooks(currentView, tView, checkNoChangesMode, currentNodeIndex) {
        if (!checkNoChangesMode) {
            executeHooks(currentView, tView.preOrderHooks, tView.preOrderCheckHooks, checkNoChangesMode, 0 /* OnInitHooksToBeRun */, currentNodeIndex !== undefined ? currentNodeIndex : null);
        }
    }
    /**
     * Executes hooks against the given `LView` based off of whether or not
     * This is the first pass.
     *
     * @param currentView The view instance data to run the hooks against
     * @param firstPassHooks An array of hooks to run if we're in the first view pass
     * @param checkHooks An Array of hooks to run if we're not in the first view pass.
     * @param checkNoChangesMode Whether or not we're in no changes mode.
     * @param initPhaseState the current state of the init phase
     * @param currentNodeIndex 3 cases depending the the value:
     * - undefined: all hooks from the array should be executed (post-order case)
     * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
     * flushing the remaining hooks)
     * - number: execute hooks only from the saved index until that node index exclusive (pre-order
     * case, when executing select(number))
     */
    function executeHooks(currentView, firstPassHooks, checkHooks, checkNoChangesMode, initPhaseState, currentNodeIndex) {
        if (checkNoChangesMode)
            return;
        var hooksToCall = (currentView[FLAGS] & 3 /* InitPhaseStateMask */) === initPhaseState ?
            firstPassHooks :
            checkHooks;
        if (hooksToCall) {
            callHooks(currentView, hooksToCall, initPhaseState, currentNodeIndex);
        }
        // The init phase state must be always checked here as it may have been recursively updated
        if (currentNodeIndex == null &&
            (currentView[FLAGS] & 3 /* InitPhaseStateMask */) === initPhaseState &&
            initPhaseState !== 3 /* InitPhaseCompleted */) {
            currentView[FLAGS] &= 1023 /* IndexWithinInitPhaseReset */;
            currentView[FLAGS] += 1 /* InitPhaseStateIncrementer */;
        }
    }
    /**
     * Calls lifecycle hooks with their contexts, skipping init hooks if it's not
     * the first LView pass
     *
     * @param currentView The current view
     * @param arr The array in which the hooks are found
     * @param initPhaseState the current state of the init phase
     * @param currentNodeIndex 3 cases depending the the value:
     * - undefined: all hooks from the array should be executed (post-order case)
     * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
     * flushing the remaining hooks)
     * - number: execute hooks only from the saved index until that node index exclusive (pre-order
     * case, when executing select(number))
     */
    function callHooks(currentView, arr, initPhase, currentNodeIndex) {
        var startIndex = currentNodeIndex !== undefined ?
            (currentView[PREORDER_HOOK_FLAGS] & 65535 /* IndexOfTheNextPreOrderHookMaskMask */) :
            0;
        var nodeIndexLimit = currentNodeIndex != null ? currentNodeIndex : -1;
        var lastNodeIndexFound = 0;
        for (var i = startIndex; i < arr.length; i++) {
            var hook = arr[i + 1];
            if (typeof hook === 'number') {
                lastNodeIndexFound = arr[i];
                if (currentNodeIndex != null && lastNodeIndexFound >= currentNodeIndex) {
                    break;
                }
            }
            else {
                var isInitHook = arr[i] < 0;
                if (isInitHook)
                    currentView[PREORDER_HOOK_FLAGS] += 65536 /* NumberOfInitHooksCalledIncrementer */;
                if (lastNodeIndexFound < nodeIndexLimit || nodeIndexLimit == -1) {
                    callHook(currentView, initPhase, arr, i);
                    currentView[PREORDER_HOOK_FLAGS] =
                        (currentView[PREORDER_HOOK_FLAGS] & 4294901760 /* NumberOfInitHooksCalledMask */) + i +
                            2;
                }
                i++;
            }
        }
    }
    /**
     * Execute one hook against the current `LView`.
     *
     * @param currentView The current view
     * @param initPhaseState the current state of the init phase
     * @param arr The array in which the hooks are found
     * @param i The current index within the hook data array
     */
    function callHook(currentView, initPhase, arr, i) {
        var isInitHook = arr[i] < 0;
        var hook = arr[i + 1];
        var directiveIndex = isInitHook ? -arr[i] : arr[i];
        var directive = currentView[directiveIndex];
        if (isInitHook) {
            var indexWithintInitPhase = currentView[FLAGS] >> 10 /* IndexWithinInitPhaseShift */;
            // The init phase state must be always checked here as it may have been recursively
            // updated
            if (indexWithintInitPhase <
                (currentView[PREORDER_HOOK_FLAGS] >> 16 /* NumberOfInitHooksCalledShift */) &&
                (currentView[FLAGS] & 3 /* InitPhaseStateMask */) === initPhase) {
                currentView[FLAGS] += 1024 /* IndexWithinInitPhaseIncrementer */;
                hook.call(directive);
            }
        }
        else {
            hook.call(directive);
        }
    }

    /**
    * @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
    */
    /**
     * --------
     *
     * // TODO(matsko): add updateMask info
     *
     * This file contains all state-based logic for styling in Angular.
     *
     * Styling in Angular is evaluated with a series of styling-specific
     * template instructions which are called one after another each time
     * change detection occurs in Angular.
     *
     * Styling makes use of various temporary, state-based variables between
     * instructions so that it can better cache and optimize its values.
     * These values are usually populated and cleared when an element is
     * exited in change detection (once all the instructions are run for
     * that element).
     *
     * There are, however, situations where the state-based values
     * need to be stored and used at a later point. This ONLY occurs when
     * there are template-level as well as host-binding-level styling
     * instructions on the same element. The example below shows exactly
     * what could be:
     *
     * ```html
     * <!-- two sources of styling: the template and the directive -->
     * <div [style.width]="width" dir-that-sets-height></div>
     * ```
     *
     * If and when this situation occurs, the current styling state is
     * stored in a storage map value and then later accessed once the
     * host bindings are evaluated. Once styling for the current element
     * is over then the map entry will be cleared.
     *
     * To learn more about the algorithm see `TStylingContext`.
     *
     * --------
     */
    var _stylingState = null;
    var _stateStorage = new Map();
    // this value is not used outside this file and is only here
    // as a caching check for when the element changes.
    var _stylingElement = null;
    var STYLING_INDEX_START_VALUE = 1;
    var BIT_MASK_START_VALUE = 0;
    function getStylingState(element, readFromMap) {
        if (!_stylingElement || element !== _stylingElement) {
            _stylingElement = element;
            if (readFromMap) {
                _stylingState = _stateStorage.get(element) || null;
                ngDevMode && ngDevMode.stylingReadPersistedState++;
            }
            _stylingState = _stylingState || {
                classesBitMask: BIT_MASK_START_VALUE,
                classesIndex: STYLING_INDEX_START_VALUE,
                stylesBitMask: BIT_MASK_START_VALUE,
                stylesIndex: STYLING_INDEX_START_VALUE,
            };
        }
        return _stylingState;
    }
    function resetStylingState() {
        _stylingState = null;
        _stylingElement = null;
    }
    function storeStylingState(element, state) {
        ngDevMode && ngDevMode.stylingWritePersistedState++;
        _stateStorage.set(element, state);
    }
    function deleteStylingStateFromStorage(element) {
        _stateStorage.delete(element);
    }
    function resetAllStylingState() {
        resetStylingState();
        _stateStorage.clear();
    }

    /**
     * @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 property will be monkey-patched on elements, components and directives
     */
    var MONKEY_PATCH_KEY_NAME = '__ngContext__';

    /**
     * @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
     */
    /**
     * For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`)
     * in same location in `LView`. This is because we don't want to pre-allocate space for it
     * because the storage is sparse. This file contains utilities for dealing with such data types.
     *
     * How do we know what is stored at a given location in `LView`.
     * - `Array.isArray(value) === false` => `RNode` (The normal storage value)
     * - `Array.isArray(value) === true` => then the `value[0]` represents the wrapped value.
     *   - `typeof value[TYPE] === 'object'` => `LView`
     *      - This happens when we have a component at a given location
     *   - `typeof value[TYPE] === true` => `LContainer`
     *      - This happens when we have `LContainer` binding at a given location.
     *
     *
     * NOTE: it is assumed that `Array.isArray` and `typeof` operations are very efficient.
     */
    /**
     * Returns `RNode`.
     * @param value wrapped value of `RNode`, `LView`, `LContainer`
     */
    function unwrapRNode(value) {
        while (Array.isArray(value)) {
            value = value[HOST];
        }
        return value;
    }
    /**
     * Returns `LView` or `null` if not found.
     * @param value wrapped value of `RNode`, `LView`, `LContainer`
     */
    function unwrapLView(value) {
        while (Array.isArray(value)) {
            // This check is same as `isLView()` but we don't call at as we don't want to call
            // `Array.isArray()` twice and give JITer more work for inlining.
            if (typeof value[TYPE] === 'object')
                return value;
            value = value[HOST];
        }
        return null;
    }
    /**
     * Returns `LContainer` or `null` if not found.
     * @param value wrapped value of `RNode`, `LView`, `LContainer`
     */
    function unwrapLContainer(value) {
        while (Array.isArray(value)) {
            // This check is same as `isLContainer()` but we don't call at as we don't want to call
            // `Array.isArray()` twice and give JITer more work for inlining.
            if (value[TYPE] === true)
                return value;
            value = value[HOST];
        }
        return null;
    }
    /**
     * Retrieves an element value from the provided `viewData`, by unwrapping
     * from any containers, component views, or style contexts.
     */
    function getNativeByIndex(index, lView) {
        return unwrapRNode(lView[index + HEADER_OFFSET]);
    }
    /**
     * Retrieve an `RNode` for a given `TNode` and `LView`.
     *
     * This function guarantees in dev mode to retrieve a non-null `RNode`.
     *
     * @param tNode
     * @param lView
     */
    function getNativeByTNode(tNode, lView) {
        ngDevMode && assertTNodeForLView(tNode, lView);
        ngDevMode && assertDataInRange(lView, tNode.index);
        var node = unwrapRNode(lView[tNode.index]);
        ngDevMode && assertDomNode(node);
        return node;
    }
    /**
     * Retrieve an `RNode` or `null` for a given `TNode` and `LView`.
     *
     * Some `TNode`s don't have associated `RNode`s. For example `Projection`
     *
     * @param tNode
     * @param lView
     */
    function getNativeByTNodeOrNull(tNode, lView) {
        ngDevMode && assertTNodeForLView(tNode, lView);
        var index = tNode.index;
        var node = index == -1 ? null : unwrapRNode(lView[index]);
        ngDevMode && node !== null && assertDomNode(node);
        return node;
    }
    /**
     * A helper function that returns `true` if a given `TNode` has any matching directives.
     */
    function hasDirectives(tNode) {
        return tNode.directiveEnd > tNode.directiveStart;
    }
    function getTNode(index, view) {
        ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
        ngDevMode && assertLessThan(index, view[TVIEW].data.length, 'wrong index for TNode');
        return view[TVIEW].data[index + HEADER_OFFSET];
    }
    /** Retrieves a value from any `LView` or `TData`. */
    function loadInternal(view, index) {
        ngDevMode && assertDataInRange(view, index + HEADER_OFFSET);
        return view[index + HEADER_OFFSET];
    }
    function getComponentViewByIndex(nodeIndex, hostView) {
        // Could be an LView or an LContainer. If LContainer, unwrap to find LView.
        var slotValue = hostView[nodeIndex];
        var lView = isLView(slotValue) ? slotValue : slotValue[HOST];
        return lView;
    }
    /**
     * Returns the monkey-patch value data present on the target (which could be
     * a component, directive or a DOM node).
     */
    function readPatchedData(target) {
        ngDevMode && assertDefined(target, 'Target expected');
        return target[MONKEY_PATCH_KEY_NAME];
    }
    function readPatchedLView(target) {
        var value = readPatchedData(target);
        if (value) {
            return Array.isArray(value) ? value : value.lView;
        }
        return null;
    }
    /**
     * Returns a boolean for whether the view is attached to the change detection tree.
     *
     * Note: This determines whether a view should be checked, not whether it's inserted
     * into a container. For that, you'll want `viewAttachedToContainer` below.
     */
    function viewAttachedToChangeDetector(view) {
        return (view[FLAGS] & 128 /* Attached */) === 128 /* Attached */;
    }
    /** Returns a boolean for whether the view is attached to a container. */
    function viewAttachedToContainer(view) {
        return isLContainer(view[PARENT]);
    }
    /**
     * Resets the pre-order hook flags of the view.
     * @param lView the LView on which the flags are reset
     */
    function resetPreOrderHookFlags(lView) {
        lView[PREORDER_HOOK_FLAGS] = 0;
    }

    /**
     * @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
     */
    /**
     * Store the element depth count. This is used to identify the root elements of the template
     * so that we can than attach `LView` to only those elements.
     */
    var elementDepthCount;
    function getElementDepthCount() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return elementDepthCount;
    }
    function increaseElementDepthCount() {
        elementDepthCount++;
    }
    function decreaseElementDepthCount() {
        elementDepthCount--;
    }
    var currentDirectiveDef = null;
    function getCurrentDirectiveDef() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return currentDirectiveDef;
    }
    function setCurrentDirectiveDef(def) {
        currentDirectiveDef = def;
    }
    /**
     * Stores whether directives should be matched to elements.
     *
     * When template contains `ngNonBindable` than we need to prevent the runtime form matching
     * directives on children of that element.
     *
     * Example:
     * ```
     * <my-comp my-directive>
     *   Should match component / directive.
     * </my-comp>
     * <div ngNonBindable>
     *   <my-comp my-directive>
     *     Should not match component / directive because we are in ngNonBindable.
     *   </my-comp>
     * </div>
     * ```
     */
    var bindingsEnabled;
    function getBindingsEnabled() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return bindingsEnabled;
    }
    /**
     * Enables directive matching on elements.
     *
     *  * Example:
     * ```
     * <my-comp my-directive>
     *   Should match component / directive.
     * </my-comp>
     * <div ngNonBindable>
     *   <!-- ɵɵdisableBindings() -->
     *   <my-comp my-directive>
     *     Should not match component / directive because we are in ngNonBindable.
     *   </my-comp>
     *   <!-- ɵɵenableBindings() -->
     * </div>
     * ```
     *
     * @codeGenApi
     */
    function ɵɵenableBindings() {
        bindingsEnabled = true;
    }
    /**
     * Disables directive matching on element.
     *
     *  * Example:
     * ```
     * <my-comp my-directive>
     *   Should match component / directive.
     * </my-comp>
     * <div ngNonBindable>
     *   <!-- ɵɵdisableBindings() -->
     *   <my-comp my-directive>
     *     Should not match component / directive because we are in ngNonBindable.
     *   </my-comp>
     *   <!-- ɵɵenableBindings() -->
     * </div>
     * ```
     *
     * @codeGenApi
     */
    function ɵɵdisableBindings() {
        bindingsEnabled = false;
    }
    function getLView() {
        return lView;
    }
    /**
     * Used as the starting directive id value.
     *
     * All subsequent directives are incremented from this value onwards.
     * The reason why this value is `1` instead of `0` is because the `0`
     * value is reserved for the template.
     */
    var MIN_DIRECTIVE_ID = 1;
    var activeDirectiveId = MIN_DIRECTIVE_ID;
    /**
     * Position depth (with respect from leaf to root) in a directive sub-class inheritance chain.
     */
    var activeDirectiveSuperClassDepthPosition = 0;
    /**
     * Total count of how many directives are a part of an inheritance chain.
     *
     * When directives are sub-classed (extended) from one to another, Angular
     * needs to keep track of exactly how many were encountered so it can accurately
     * generate the next directive id (once the next directive id is visited).
     * Normally the next directive id just a single incremented value from the
     * previous one, however, if the previous directive is a part of an inheritance
     * chain (a series of sub-classed directives) then the incremented value must
     * also take into account the total amount of sub-classed values.
     *
     * Note that this value resets back to zero once the next directive is
     * visited (when `incrementActiveDirectiveId` or `setActiveHostElement`
     * is called).
     */
    var activeDirectiveSuperClassHeight = 0;
    /**
     * Sets the active directive host element and resets the directive id value
     * (when the provided elementIndex value has changed).
     *
     * @param elementIndex the element index value for the host element where
     *                     the directive/component instance lives
     */
    function setActiveHostElement(elementIndex) {
        if (elementIndex === void 0) { elementIndex = null; }
        if (_selectedIndex !== elementIndex) {
            setSelectedIndex(elementIndex == null ? -1 : elementIndex);
            activeDirectiveId = elementIndex == null ? 0 : MIN_DIRECTIVE_ID;
            activeDirectiveSuperClassDepthPosition = 0;
            activeDirectiveSuperClassHeight = 0;
        }
    }
    /**
     * Returns the current id value of the current directive.
     *
     * For example we have an element that has two directives on it:
     * <div dir-one dir-two></div>
     *
     * dirOne->hostBindings() (id == 1)
     * dirTwo->hostBindings() (id == 2)
     *
     * Note that this is only active when `hostBinding` functions are being processed.
     *
     * Note that directive id values are specific to an element (this means that
     * the same id value could be present on another element with a completely
     * different set of directives).
     */
    function getActiveDirectiveId() {
        return activeDirectiveId;
    }
    /**
     * Increments the current directive id value.
     *
     * For example we have an element that has two directives on it:
     * <div dir-one dir-two></div>
     *
     * dirOne->hostBindings() (index = 1)
     * // increment
     * dirTwo->hostBindings() (index = 2)
     *
     * Depending on whether or not a previous directive had any inherited
     * directives present, that value will be incremented in addition
     * to the id jumping up by one.
     *
     * Note that this is only active when `hostBinding` functions are being processed.
     *
     * Note that directive id values are specific to an element (this means that
     * the same id value could be present on another element with a completely
     * different set of directives).
     */
    function incrementActiveDirectiveId() {
        activeDirectiveId += 1 + activeDirectiveSuperClassHeight;
        // because we are dealing with a new directive this
        // means we have exited out of the inheritance chain
        activeDirectiveSuperClassDepthPosition = 0;
        activeDirectiveSuperClassHeight = 0;
    }
    /**
     * Set the current super class (reverse inheritance) position depth for a directive.
     *
     * For example we have two directives: Child and Other (but Child is a sub-class of Parent)
     * <div child-dir other-dir></div>
     *
     * // increment
     * parentInstance->hostBindings() (depth = 1)
     * // decrement
     * childInstance->hostBindings() (depth = 0)
     * otherInstance->hostBindings() (depth = 0 b/c it's a different directive)
     *
     * Note that this is only active when `hostBinding` functions are being processed.
     */
    function adjustActiveDirectiveSuperClassDepthPosition(delta) {
        activeDirectiveSuperClassDepthPosition += delta;
        // we keep track of the height value so that when the next directive is visited
        // then Angular knows to generate a new directive id value which has taken into
        // account how many sub-class directives were a part of the previous directive.
        activeDirectiveSuperClassHeight =
            Math.max(activeDirectiveSuperClassHeight, activeDirectiveSuperClassDepthPosition);
    }
    /**
     * Returns he current depth of the super/sub class inheritance chain.
     *
     * This will return how many inherited directive/component classes
     * exist in the current chain.
     *
     * ```typescript
     * @Directive({ selector: '[super-dir]' })
     * class SuperDir {}
     *
     * @Directive({ selector: '[sub-dir]' })
     * class SubDir extends SuperDir {}
     *
     * // if `<div sub-dir>` is used then the super class height is `1`
     * // if `<div super-dir>` is used then the super class height is `0`
     * ```
     */
    function getActiveDirectiveSuperClassHeight() {
        return activeDirectiveSuperClassHeight;
    }
    /**
     * Returns the current super class (reverse inheritance) depth for a directive.
     *
     * This is designed to help instruction code distinguish different hostBindings
     * calls from each other when a directive has extended from another directive.
     * Normally using the directive id value is enough, but with the case
     * of parent/sub-class directive inheritance more information is required.
     *
     * Note that this is only active when `hostBinding` functions are being processed.
     */
    function getActiveDirectiveSuperClassDepth() {
        return activeDirectiveSuperClassDepthPosition;
    }
    /**
     * Restores `contextViewData` to the given OpaqueViewState instance.
     *
     * Used in conjunction with the getCurrentView() instruction to save a snapshot
     * of the current view and restore it when listeners are invoked. This allows
     * walking the declaration view tree in listeners to get vars from parent views.
     *
     * @param viewToRestore The OpaqueViewState instance to restore.
     *
     * @codeGenApi
     */
    function ɵɵrestoreView(viewToRestore) {
        contextLView = viewToRestore;
    }
    /** Used to set the parent property when nodes are created and track query results. */
    var previousOrParentTNode;
    function getPreviousOrParentTNode() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return previousOrParentTNode;
    }
    function setPreviousOrParentTNode(tNode, _isParent) {
        previousOrParentTNode = tNode;
        isParent = _isParent;
    }
    function setTNodeAndViewData(tNode, view) {
        ngDevMode && assertLViewOrUndefined(view);
        previousOrParentTNode = tNode;
        lView = view;
    }
    /**
     * If `isParent` is:
     *  - `true`: then `previousOrParentTNode` points to a parent node.
     *  - `false`: then `previousOrParentTNode` points to previous node (sibling).
     */
    var isParent;
    function getIsParent() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return isParent;
    }
    function setIsNotParent() {
        isParent = false;
    }
    function setIsParent() {
        isParent = true;
    }
    /** Checks whether a given view is in creation mode */
    function isCreationMode(view) {
        if (view === void 0) { view = lView; }
        return (view[FLAGS] & 4 /* CreationMode */) === 4 /* CreationMode */;
    }
    /**
     * State of the current view being processed.
     *
     * An array of nodes (text, element, container, etc), pipes, their bindings, and
     * any local variables that need to be stored between invocations.
     */
    var lView;
    /**
     * The last viewData retrieved by nextContext().
     * Allows building nextContext() and reference() calls.
     *
     * e.g. const inner = x().$implicit; const outer = x().$implicit;
     */
    var contextLView = null;
    function getContextLView() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return contextLView;
    }
    /**
     * In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
     *
     * Necessary to support ChangeDetectorRef.checkNoChanges().
     */
    var checkNoChangesMode = false;
    function getCheckNoChangesMode() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return checkNoChangesMode;
    }
    function setCheckNoChangesMode(mode) {
        checkNoChangesMode = mode;
    }
    /**
     * The root index from which pure function instructions should calculate their binding
     * indices. In component views, this is TView.bindingStartIndex. In a host binding
     * context, this is the TView.expandoStartIndex + any dirs/hostVars before the given dir.
     */
    var bindingRootIndex = -1;
    // top level variables should not be exported for performance reasons (PERF_NOTES.md)
    function getBindingRoot() {
        return bindingRootIndex;
    }
    function setBindingRoot(value) {
        bindingRootIndex = value;
    }
    /**
     * Current index of a View or Content Query which needs to be processed next.
     * We iterate over the list of Queries and increment current query index at every step.
     */
    var currentQueryIndex = 0;
    function getCurrentQueryIndex() {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return currentQueryIndex;
    }
    function setCurrentQueryIndex(value) {
        currentQueryIndex = value;
    }
    /**
     * Swap the current state with a new state.
     *
     * For performance reasons we store the state in the top level of the module.
     * This way we minimize the number of properties to read. Whenever a new view
     * is entered we have to store the state for later, and when the view is
     * exited the state has to be restored
     *
     * @param newView New state to become active
     * @param host Element to which the View is a child of
     * @returns the previous state;
     */
    function enterView(newView, hostTNode) {
        ngDevMode && assertLViewOrUndefined(newView);
        var oldView = lView;
        if (newView) {
            var tView = newView[TVIEW];
            bindingRootIndex = tView.bindingStartIndex;
        }
        previousOrParentTNode = hostTNode;
        isParent = true;
        lView = contextLView = newView;
        return oldView;
    }
    function nextContextImpl(level) {
        if (level === void 0) { level = 1; }
        contextLView = walkUpViews(level, contextLView);
        return contextLView[CONTEXT];
    }
    function walkUpViews(nestingLevel, currentView) {
        while (nestingLevel > 0) {
            ngDevMode && assertDefined(currentView[DECLARATION_VIEW], 'Declaration view should be defined if nesting level is greater than 0.');
            currentView = currentView[DECLARATION_VIEW];
            nestingLevel--;
        }
        return currentView;
    }
    /**
     * Resets the application state.
     */
    function resetComponentState() {
        isParent = false;
        previousOrParentTNode = null;
        elementDepthCount = 0;
        bindingsEnabled = true;
        setCurrentStyleSanitizer(null);
        resetAllStylingState();
    }
    /**
     * Used in lieu of enterView to make it clear when we are exiting a child view. This makes
     * the direction of traversal (up or down the view tree) a bit clearer.
     *
     * @param newView New state to become active
     * @param safeToRunHooks Whether the runtime is in a state where running lifecycle hooks is valid.
     * This is not always the case (for example, the application may have crashed and `leaveView` is
     * being executed while unwinding the call stack).
     */
    function leaveView(newView, safeToRunHooks) {
        var tView = lView[TVIEW];
        if (isCreationMode(lView)) {
            lView[FLAGS] &= ~4 /* CreationMode */;
        }
        else {
            try {
                resetPreOrderHookFlags(lView);
                safeToRunHooks && executeHooks(lView, tView.viewHooks, tView.viewCheckHooks, checkNoChangesMode, 2 /* AfterViewInitHooksToBeRun */, undefined);
            }
            finally {
                // Views are clean and in update mode after being checked, so these bits are cleared
                lView[FLAGS] &= ~(64 /* Dirty */ | 8 /* FirstLViewPass */);
                lView[BINDING_INDEX] = tView.bindingStartIndex;
            }
        }
        enterView(newView, null);
    }
    var _selectedIndex = -1;
    /**
     * Gets the most recent index passed to {@link select}
     *
     * Used with {@link property} instruction (and more in the future) to identify the index in the
     * current `LView` to act on.
     */
    function getSelectedIndex() {
        return _selectedIndex;
    }
    /**
     * Sets the most recent index passed to {@link select}
     *
     * Used with {@link property} instruction (and more in the future) to identify the index in the
     * current `LView` to act on.
     */
    function setSelectedIndex(index) {
        _selectedIndex = index;
        // we have now jumped to another element
        // therefore the state is stale
        resetStylingState();
    }
    var _currentNamespace = null;
    /**
     * Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state.
     *
     * @codeGenApi
     */
    function ɵɵnamespaceSVG() {
        _currentNamespace = 'http://www.w3.org/2000/svg';
    }
    /**
     * Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.
     *
     * @codeGenApi
     */
    function ɵɵnamespaceMathML() {
        _currentNamespace = 'http://www.w3.org/1998/MathML/';
    }
    /**
     * Sets the namespace used to create elements to `null`, which forces element creation to use
     * `createElement` rather than `createElementNS`.
     *
     * @codeGenApi
     */
    function ɵɵnamespaceHTML() {
        namespaceHTMLInternal();
    }
    /**
     * Sets the namespace used to create elements to `null`, which forces element creation to use
     * `createElement` rather than `createElementNS`.
     */
    function namespaceHTMLInternal() {
        _currentNamespace = null;
    }
    function getNamespace() {
        return _currentNamespace;
    }
    var _currentSanitizer;
    function setCurrentStyleSanitizer(sanitizer) {
        _currentSanitizer = sanitizer;
    }
    function getCurrentStyleSanitizer() {
        return _currentSanitizer;
    }

    /**
     * @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
     */
    /**
     * Returns whether the values are different from a change detection stand point.
     *
     * Constraints are relaxed in checkNoChanges mode. See `devModeEqual` for details.
     */
    function isDifferent(a, b) {
        // NaN is the only value that is not equal to itself so the first
        // test checks if both a and b are not NaN
        return !(a !== a && b !== b) && a !== b;
    }
    /**
     * Used for stringify render output in Ivy.
     * Important! This function is very performance-sensitive and we should
     * be extra careful not to introduce megamorphic reads in it.
     */
    function renderStringify(value) {
        if (typeof value === 'string')
            return value;
        if (value == null)
            return '';
        return '' + value;
    }
    /**
     * Used to stringify a value so that it can be displayed in an error message.
     * Important! This function contains a megamorphic read and should only be
     * used for error messages.
     */
    function stringifyForError(value) {
        if (typeof value === 'function')
            return value.name || value.toString();
        if (typeof value === 'object' && value != null && typeof value.type === 'function') {
            return value.type.name || value.type.toString();
        }
        return renderStringify(value);
    }
    var ɵ0$2 = function () {
        return (typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame || // browser only
            setTimeout // everything else
        ).bind(_global);
    };
    var defaultScheduler = (ɵ0$2)();
    /**
     *
     * @codeGenApi
     */
    function ɵɵresolveWindow(element) {
        return { name: 'window', target: element.ownerDocument.defaultView };
    }
    /**
     *
     * @codeGenApi
     */
    function ɵɵresolveDocument(element) {
        return { name: 'document', target: element.ownerDocument };
    }
    /**
     *
     * @codeGenApi
     */
    function ɵɵresolveBody(element) {
        return { name: 'body', target: element.ownerDocument.body };
    }
    /**
     * The special delimiter we use to separate property names, prefixes, and suffixes
     * in property binding metadata. See storeBindingMetadata().
     *
     * We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
     * because it is a very uncommon character that is unlikely to be part of a user's
     * property names or interpolation strings. If it is in fact used in a property
     * binding, DebugElement.properties will not return the correct value for that
     * binding. However, there should be no runtime effect for real applications.
     *
     * This character is typically rendered as a question mark inside of a diamond.
     * See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
     *
     */
    var INTERPOLATION_DELIMITER = "\uFFFD";
    /**
     * Determines whether or not the given string is a property metadata string.
     * See storeBindingMetadata().
     */
    function isPropMetadataString(str) {
        return str.indexOf(INTERPOLATION_DELIMITER) >= 0;
    }
    /**
     * Unwrap a value which might be behind a closure (for forward declaration reasons).
     */
    function maybeUnwrapFn(value) {
        if (value instanceof Function) {
            return value();
        }
        else {
            return value;
        }
    }

    var MAP_BASED_ENTRY_PROP_NAME = '--MAP--';
    var TEMPLATE_DIRECTIVE_INDEX = 0;
    /**
     * Creates a new instance of the `TStylingContext`.
     *
     * The `TStylingContext` is used as a manifest of all style or all class bindings on
     * an element. Because it is a T-level data-structure, it is only created once per
     * tNode for styles and for classes. This function allocates a new instance of a
     * `TStylingContext` with the initial values (see `interfaces.ts` for more info).
     */
    function allocTStylingContext(initialStyling) {
        // because map-based bindings deal with a dynamic set of values, there
        // is no way to know ahead of time whether or not sanitization is required.
        // For this reason the configuration will always mark sanitization as active
        // (this means that when map-based values are applied then sanitization will
        // be checked against each property).
        var mapBasedConfig = 1 /* SanitizationRequired */;
        return [
            initialStyling || [''],
            0 /* Initial */,
            TEMPLATE_DIRECTIVE_INDEX,
            mapBasedConfig,
            0,
            MAP_BASED_ENTRY_PROP_NAME,
        ];
    }
    /**
     * Sets the provided directive as the last directive index in the provided `TStylingContext`.
     *
     * Styling in Angular can be applied from the template as well as multiple sources of
     * host bindings. This means that each binding function (the template function or the
     * hostBindings functions) will generate styling instructions as well as a styling
     * apply function (i.e. `stylingApply()`). Because host bindings functions and the
     * template function are independent from one another this means that the styling apply
     * function will be called multiple times. By tracking the last directive index (which
     * is what happens in this function) the styling algorithm knows exactly when to flush
     * styling (which is when the last styling apply function is executed).
     */
    function updateLastDirectiveIndex(context, lastDirectiveIndex) {
        if (lastDirectiveIndex === TEMPLATE_DIRECTIVE_INDEX) {
            var currentValue = context[2 /* LastDirectiveIndexPosition */];
            if (currentValue > TEMPLATE_DIRECTIVE_INDEX) {
                // This means that a directive or two contained a host bindings function, but
                // now the template function also contains styling. When this combination of sources
                // comes up then we need to tell the context to store the state between updates
                // (because host bindings evaluation happens after template binding evaluation).
                markContextToPersistState(context);
            }
        }
        else {
            context[2 /* LastDirectiveIndexPosition */] = lastDirectiveIndex;
        }
    }
    function getConfig(context) {
        return context[1 /* ConfigPosition */];
    }
    function setConfig(context, value) {
        context[1 /* ConfigPosition */] = value;
    }
    function getProp(context, index) {
        return context[index + 2 /* PropOffset */];
    }
    function getPropConfig(context, index) {
        return context[index + 0 /* ConfigAndGuardOffset */] &
            1 /* Mask */;
    }
    function isSanitizationRequired(context, index) {
        return (getPropConfig(context, index) & 1 /* SanitizationRequired */) > 0;
    }
    function getGuardMask(context, index) {
        var configGuardValue = context[index + 0 /* ConfigAndGuardOffset */];
        return configGuardValue >> 1 /* TotalBits */;
    }
    function setGuardMask(context, index, maskValue) {
        var config = getPropConfig(context, index);
        var guardMask = maskValue << 1 /* TotalBits */;
        context[index + 0 /* ConfigAndGuardOffset */] = config | guardMask;
    }
    function getValuesCount(context, index) {
        return context[index + 1 /* ValuesCountOffset */];
    }
    function getBindingValue(context, index, offset) {
        return context[index + 3 /* BindingsStartOffset */ + offset];
    }
    function getDefaultValue(context, index) {
        var valuesCount = getValuesCount(context, index);
        return context[index + 3 /* BindingsStartOffset */ + valuesCount - 1];
    }
    /**
     * Temporary function which determines whether or not a context is
     * allowed to be flushed based on the provided directive index.
     */
    function allowStylingFlush(context, index) {
        return (context && index === context[2 /* LastDirectiveIndexPosition */]) ? true :
            false;
    }
    function lockContext(context) {
        setConfig(context, getConfig(context) | 1 /* Locked */);
    }
    function isContextLocked(context) {
        return (getConfig(context) & 1 /* Locked */) > 0;
    }
    function stateIsPersisted(context) {
        return (getConfig(context) & 2 /* PersistStateValues */) > 0;
    }
    function markContextToPersistState(context) {
        setConfig(context, getConfig(context) | 2 /* PersistStateValues */);
    }
    function getPropValuesStartPosition(context) {
        return 6 /* MapBindingsBindingsStartPosition */ +
            context[4 /* MapBindingsValuesCountPosition */];
    }
    function isMapBased(prop) {
        return prop === MAP_BASED_ENTRY_PROP_NAME;
    }
    function hasValueChanged(a, b) {
        var compareValueA = Array.isArray(a) ? a[0 /* RawValuePosition */] : a;
        var compareValueB = Array.isArray(b) ? b[0 /* RawValuePosition */] : b;
        // these are special cases for String based values (which are created as artifacts
        // when sanitization is bypassed on a particular value)
        if (compareValueA instanceof String) {
            compareValueA = compareValueA.toString();
        }
        if (compareValueB instanceof String) {
            compareValueB = compareValueB.toString();
        }
        return isDifferent(compareValueA, compareValueB);
    }
    /**
     * Determines whether the provided styling value is truthy or falsy.
     */
    function isStylingValueDefined(value) {
        // the reason why null is compared against is because
        // a CSS class value that is set to `false` must be
        // respected (otherwise it would be treated as falsy).
        // Empty string values are because developers usually
        // set a value to an empty string to remove it.
        return value != null && value !== '';
    }
    function concatString(a, b, separator) {
        if (separator === void 0) { separator = ' '; }
        return a + ((b.length && a.length) ? separator : '') + b;
    }
    function hyphenate(value) {
        return value.replace(/[a-z][A-Z]/g, function (v) { return v.charAt(0) + '-' + v.charAt(1); }).toLowerCase();
    }
    /**
     * Returns an instance of `StylingMapArray`.
     *
     * This function is designed to find an instance of `StylingMapArray` in case it is stored
     * inside of an instance of `TStylingContext`. When a styling context is created it
     * will copy over an initial styling values from the tNode (which are stored as a
     * `StylingMapArray` on the `tNode.classes` or `tNode.styles` values).
     */
    function getStylingMapArray(value) {
        return isStylingContext(value) ?
            value[0 /* InitialStylingValuePosition */] :
            value;
    }
    function isStylingContext(value) {
        // the StylingMapArray is in the format of [initial, prop, string, prop, string]
        // and this is the defining value to distinguish between arrays
        return Array.isArray(value) &&
            value.length >= 6 /* MapBindingsBindingsStartPosition */ &&
            typeof value[1] !== 'string';
    }
    function getInitialStylingValue(context) {
        var map = getStylingMapArray(context);
        return map && map[0 /* RawValuePosition */] || '';
    }
    function hasClassInput(tNode) {
        return (tNode.flags & 8 /* hasClassInput */) !== 0;
    }
    function hasStyleInput(tNode) {
        return (tNode.flags & 16 /* hasStyleInput */) !== 0;
    }
    function getMapProp(map, index) {
        return map[index + 0 /* PropOffset */];
    }
    function setMapValue(map, index, value) {
        map[index + 1 /* ValueOffset */] = value;
    }
    function getMapValue(map, index) {
        return map[index + 1 /* ValueOffset */];
    }
    function forceClassesAsString(classes) {
        if (classes && typeof classes !== 'string') {
            classes = Object.keys(classes).join(' ');
        }
        return classes || '';
    }
    function forceStylesAsString(styles) {
        var str = '';
        if (styles) {
            var props = Object.keys(styles);
            for (var i = 0; i < props.length; i++) {
                var prop = props[i];
                str = concatString(str, prop + ":" + styles[prop], ';');
            }
        }
        return str;
    }

    /**
     * @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
     */
    // TODO: cleanup once the code is merged in angular/angular
    var RendererStyleFlags3;
    (function (RendererStyleFlags3) {
        RendererStyleFlags3[RendererStyleFlags3["Important"] = 1] = "Important";
        RendererStyleFlags3[RendererStyleFlags3["DashCase"] = 2] = "DashCase";
    })(RendererStyleFlags3 || (RendererStyleFlags3 = {}));
    /** Returns whether the `renderer` is a `ProceduralRenderer3` */
    function isProceduralRenderer(renderer) {
        return !!(renderer.listen);
    }
    var ɵ0$3 = function (hostElement, rendererType) { return document; };
    var domRendererFactory3 = {
        createRenderer: ɵ0$3
    };
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$3 = 1;

    /**
     * Assigns all attribute values to the provided element via the inferred renderer.
     *
     * This function accepts two forms of attribute entries:
     *
     * default: (key, value):
     *  attrs = [key1, value1, key2, value2]
     *
     * namespaced: (NAMESPACE_MARKER, uri, name, value)
     *  attrs = [NAMESPACE_MARKER, uri, name, value, NAMESPACE_MARKER, uri, name, value]
     *
     * The `attrs` array can contain a mix of both the default and namespaced entries.
     * The "default" values are set without a marker, but if the function comes across
     * a marker value then it will attempt to set a namespaced value. If the marker is
     * not of a namespaced value then the function will quit and return the index value
     * where it stopped during the iteration of the attrs array.
     *
     * See [AttributeMarker] to understand what the namespace marker value is.
     *
     * Note that this instruction does not support assigning style and class values to
     * an element. See `elementStart` and `elementHostAttrs` to learn how styling values
     * are applied to an element.
     *
     * @param native The element that the attributes will be assigned to
     * @param attrs The attribute array of values that will be assigned to the element
     * @returns the index value that was last accessed in the attributes array
     */
    function setUpAttributes(native, attrs) {
        var renderer = getLView()[RENDERER];
        var isProc = isProceduralRenderer(renderer);
        var i = 0;
        while (i < attrs.length) {
            var value = attrs[i];
            if (typeof value === 'number') {
                // only namespaces are supported. Other value types (such as style/class
                // entries) are not supported in this function.
                if (value !== 0 /* NamespaceURI */) {
                    break;
                }
                // we just landed on the marker value ... therefore
                // we should skip to the next entry
                i++;
                var namespaceURI = attrs[i++];
                var attrName = attrs[i++];
                var attrVal = attrs[i++];
                ngDevMode && ngDevMode.rendererSetAttribute++;
                isProc ?
                    renderer.setAttribute(native, attrName, attrVal, namespaceURI) :
                    native.setAttributeNS(namespaceURI, attrName, attrVal);
            }
            else {
                // attrName is string;
                var attrName = value;
                var attrVal = attrs[++i];
                // Standard attributes
                ngDevMode && ngDevMode.rendererSetAttribute++;
                if (isAnimationProp(attrName)) {
                    if (isProc) {
                        renderer.setProperty(native, attrName, attrVal);
                    }
                }
                else {
                    isProc ?
                        renderer
                            .setAttribute(native, attrName, attrVal) :
                        native.setAttribute(attrName, attrVal);
                }
                i++;
            }
        }
        // another piece of code may iterate over the same attributes array. Therefore
        // it may be helpful to return the exact spot where the attributes array exited
        // whether by running into an unsupported marker or if all the static values were
        // iterated over.
        return i;
    }
    function attrsStylingIndexOf(attrs, startIndex) {
        for (var i = startIndex; i < attrs.length; i++) {
            var val = attrs[i];
            if (val === 1 /* Classes */ || val === 2 /* Styles */) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Test whether the given value is a marker that indicates that the following
     * attribute values in a `TAttributes` array are only the names of attributes,
     * and not name-value pairs.
     * @param marker The attribute marker to test.
     * @returns true if the marker is a "name-only" marker (e.g. `Bindings`, `Template` or `I18n`).
     */
    function isNameOnlyAttributeMarker(marker) {
        return marker === 3 /* Bindings */ || marker === 4 /* Template */ ||
            marker === 6 /* I18n */;
    }
    var ANIMATION_PROP_PREFIX = '@';
    function isAnimationProp(name) {
        return name[0] === ANIMATION_PROP_PREFIX;
    }

    /**
     * @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
     */
    /// Parent Injector Utils ///////////////////////////////////////////////////////////////
    function hasParentInjector(parentLocation) {
        return parentLocation !== NO_PARENT_INJECTOR;
    }
    function getParentInjectorIndex(parentLocation) {
        return parentLocation & 32767 /* InjectorIndexMask */;
    }
    function getParentInjectorViewOffset(parentLocation) {
        return parentLocation >> 16 /* ViewOffsetShift */;
    }
    /**
     * Unwraps a parent injector location number to find the view offset from the current injector,
     * then walks up the declaration view tree until the view is found that contains the parent
     * injector.
     *
     * @param location The location of the parent injector, which contains the view offset
     * @param startView The LView instance from which to start walking up the view tree
     * @returns The LView instance that contains the parent injector
     */
    function getParentInjectorView(location, startView) {
        var viewOffset = getParentInjectorViewOffset(location);
        var parentView = startView;
        // For most cases, the parent injector can be found on the host node (e.g. for component
        // or container), but we must keep the loop here to support the rarer case of deeply nested
        // <ng-template> tags or inline views, where the parent injector might live many views
        // above the child injector.
        while (viewOffset > 0) {
            parentView = parentView[DECLARATION_VIEW];
            viewOffset--;
        }
        return parentView;
    }

    /**
     * @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
     */
    /**
     * Gets the parent LView of the passed LView, if the PARENT is an LContainer, will get the parent of
     * that LContainer, which is an LView
     * @param lView the lView whose parent to get
     */
    function getLViewParent(lView) {
        ngDevMode && assertLView(lView);
        var parent = lView[PARENT];
        return isLContainer(parent) ? parent[PARENT] : parent;
    }
    /**
     * Retrieve the root view from any component or `LView` by walking the parent `LView` until
     * reaching the root `LView`.
     *
     * @param componentOrLView any component or `LView`
     */
    function getRootView(componentOrLView) {
        ngDevMode && assertDefined(componentOrLView, 'component');
        var lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView);
        while (lView && !(lView[FLAGS] & 512 /* IsRoot */)) {
            lView = getLViewParent(lView);
        }
        ngDevMode && assertLView(lView);
        return lView;
    }
    /**
     * Given an `LView`, find the closest declaration view which is not an embedded view.
     *
     * This method searches for the `LView` associated with the component which declared the `LView`.
     *
     * This function may return itself if the `LView` passed in is not an embedded `LView`. Otherwise
     * it walks the declaration parents until it finds a component view (non-embedded-view.)
     *
     * @param lView LView for which we want a host element node
     * @returns The host node
     */
    function findComponentView(lView) {
        var rootTNode = lView[T_HOST];
        while (rootTNode !== null && rootTNode.type === 2 /* View */) {
            ngDevMode && assertDefined(lView[DECLARATION_VIEW], 'lView[DECLARATION_VIEW]');
            lView = lView[DECLARATION_VIEW];
            rootTNode = lView[T_HOST];
        }
        ngDevMode && assertLView(lView);
        return lView;
    }
    /**
     * Returns the `RootContext` instance that is associated with
     * the application where the target is situated. It does this by walking the parent views until it
     * gets to the root view, then getting the context off of that.
     *
     * @param viewOrComponent the `LView` or component to get the root context for.
     */
    function getRootContext(viewOrComponent) {
        var rootView = getRootView(viewOrComponent);
        ngDevMode &&
            assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
        return rootView[CONTEXT];
    }

    /**
     * @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
     */
    /**
     * Defines if the call to `inject` should include `viewProviders` in its resolution.
     *
     * This is set to true when we try to instantiate a component. This value is reset in
     * `getNodeInjectable` to a value which matches the declaration location of the token about to be
     * instantiated. This is done so that if we are injecting a token which was declared outside of
     * `viewProviders` we don't accidentally pull `viewProviders` in.
     *
     * Example:
     *
     * ```
     * @Injectable()
     * class MyService {
     *   constructor(public value: String) {}
     * }
     *
     * @Component({
     *   providers: [
     *     MyService,
     *     {provide: String, value: 'providers' }
     *   ]
     *   viewProviders: [
     *     {provide: String, value: 'viewProviders'}
     *   ]
     * })
     * class MyComponent {
     *   constructor(myService: MyService, value: String) {
     *     // We expect that Component can see into `viewProviders`.
     *     expect(value).toEqual('viewProviders');
     *     // `MyService` was not declared in `viewProviders` hence it can't see it.
     *     expect(myService.value).toEqual('providers');
     *   }
     * }
     *
     * ```
     */
    var includeViewProviders = true;
    function setIncludeViewProviders(v) {
        var oldValue = includeViewProviders;
        includeViewProviders = v;
        return oldValue;
    }
    /**
     * The number of slots in each bloom filter (used by DI). The larger this number, the fewer
     * directives that will share slots, and thus, the fewer false positives when checking for
     * the existence of a directive.
     */
    var BLOOM_SIZE = 256;
    var BLOOM_MASK = BLOOM_SIZE - 1;
    /** Counter used to generate unique IDs for directives. */
    var nextNgElementId = 0;
    /**
     * Registers this directive as present in its node's injector by flipping the directive's
     * corresponding bit in the injector's bloom filter.
     *
     * @param injectorIndex The index of the node injector where this token should be registered
     * @param tView The TView for the injector's bloom filters
     * @param type The directive token to register
     */
    function bloomAdd(injectorIndex, tView, type) {
        ngDevMode && assertEqual(tView.firstTemplatePass, true, 'expected firstTemplatePass to be true');
        var id = typeof type !== 'string' ? type[NG_ELEMENT_ID] : type.charCodeAt(0) || 0;
        // Set a unique ID on the directive type, so if something tries to inject the directive,
        // we can easily retrieve the ID and hash it into the bloom bit that should be checked.
        if (id == null) {
            id = type[NG_ELEMENT_ID] = nextNgElementId++;
        }
        // We only have BLOOM_SIZE (256) slots in our bloom filter (8 buckets * 32 bits each),
        // so all unique IDs must be modulo-ed into a number from 0 - 255 to fit into the filter.
        var bloomBit = id & BLOOM_MASK;
        // Create a mask that targets the specific bit associated with the directive.
        // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
        // to bit positions 0 - 31 in a 32 bit integer.
        var mask = 1 << bloomBit;
        // Use the raw bloomBit number to determine which bloom filter bucket we should check
        // e.g: bf0 = [0 - 31], bf1 = [32 - 63], bf2 = [64 - 95], bf3 = [96 - 127], etc
        var b7 = bloomBit & 0x80;
        var b6 = bloomBit & 0x40;
        var b5 = bloomBit & 0x20;
        var tData = tView.data;
        if (b7) {
            b6 ? (b5 ? (tData[injectorIndex + 7] |= mask) : (tData[injectorIndex + 6] |= mask)) :
                (b5 ? (tData[injectorIndex + 5] |= mask) : (tData[injectorIndex + 4] |= mask));
        }
        else {
            b6 ? (b5 ? (tData[injectorIndex + 3] |= mask) : (tData[injectorIndex + 2] |= mask)) :
                (b5 ? (tData[injectorIndex + 1] |= mask) : (tData[injectorIndex] |= mask));
        }
    }
    /**
     * Creates (or gets an existing) injector for a given element or container.
     *
     * @param tNode for which an injector should be retrieved / created.
     * @param hostView View where the node is stored
     * @returns Node injector
     */
    function getOrCreateNodeInjectorForNode(tNode, hostView) {
        var existingInjectorIndex = getInjectorIndex(tNode, hostView);
        if (existingInjectorIndex !== -1) {
            return existingInjectorIndex;
        }
        var tView = hostView[TVIEW];
        if (tView.firstTemplatePass) {
            tNode.injectorIndex = hostView.length;
            insertBloom(tView.data, tNode); // foundation for node bloom
            insertBloom(hostView, null); // foundation for cumulative bloom
            insertBloom(tView.blueprint, null);
            ngDevMode && assertEqual(tNode.flags === 0 || tNode.flags === 1 /* isComponent */, true, 'expected tNode.flags to not be initialized');
        }
        var parentLoc = getParentInjectorLocation(tNode, hostView);
        var parentIndex = getParentInjectorIndex(parentLoc);
        var parentLView = getParentInjectorView(parentLoc, hostView);
        var injectorIndex = tNode.injectorIndex;
        // If a parent injector can't be found, its location is set to -1.
        // In that case, we don't need to set up a cumulative bloom
        if (hasParentInjector(parentLoc)) {
            var parentData = parentLView[TVIEW].data;
            // Creates a cumulative bloom filter that merges the parent's bloom filter
            // and its own cumulative bloom (which contains tokens for all ancestors)
            for (var i = 0; i < 8; i++) {
                hostView[injectorIndex + i] = parentLView[parentIndex + i] | parentData[parentIndex + i];
            }
        }
        hostView[injectorIndex + PARENT_INJECTOR] = parentLoc;
        return injectorIndex;
    }
    function insertBloom(arr, footer) {
        arr.push(0, 0, 0, 0, 0, 0, 0, 0, footer);
    }
    function getInjectorIndex(tNode, hostView) {
        if (tNode.injectorIndex === -1 ||
            // If the injector index is the same as its parent's injector index, then the index has been
            // copied down from the parent node. No injector has been created yet on this node.
            (tNode.parent && tNode.parent.injectorIndex === tNode.injectorIndex) ||
            // After the first template pass, the injector index might exist but the parent values
            // might not have been calculated yet for this instance
            hostView[tNode.injectorIndex + PARENT_INJECTOR] == null) {
            return -1;
        }
        else {
            return tNode.injectorIndex;
        }
    }
    /**
     * Finds the index of the parent injector, with a view offset if applicable. Used to set the
     * parent injector initially.
     *
     * Returns a combination of number of `ViewData` we have to go up and index in that `Viewdata`
     */
    function getParentInjectorLocation(tNode, view) {
        if (tNode.parent && tNode.parent.injectorIndex !== -1) {
            return tNode.parent.injectorIndex; // ViewOffset is 0
        }
        // For most cases, the parent injector index can be found on the host node (e.g. for component
        // or container), so this loop will be skipped, but we must keep the loop here to support
        // the rarer case of deeply nested <ng-template> tags or inline views.
        var hostTNode = view[T_HOST];
        var viewOffset = 1;
        while (hostTNode && hostTNode.injectorIndex === -1) {
            view = view[DECLARATION_VIEW];
            hostTNode = view ? view[T_HOST] : null;
            viewOffset++;
        }
        return hostTNode ?
            hostTNode.injectorIndex | (viewOffset << 16 /* ViewOffsetShift */) :
            -1;
    }
    /**
     * Makes a type or an injection token public to the DI system by adding it to an
     * injector's bloom filter.
     *
     * @param di The node injector in which a directive will be added
     * @param token The type or the injection token to be made public
     */
    function diPublicInInjector(injectorIndex, tView, token) {
        bloomAdd(injectorIndex, tView, token);
    }
    /**
     * Inject static attribute value into directive constructor.
     *
     * This method is used with `factory` functions which are generated as part of
     * `defineDirective` or `defineComponent`. The method retrieves the static value
     * of an attribute. (Dynamic attributes are not supported since they are not resolved
     *  at the time of injection and can change over time.)
     *
     * # Example
     * Given:
     * ```
     * @Component(...)
     * class MyComponent {
     *   constructor(@Attribute('title') title: string) { ... }
     * }
     * ```
     * When instantiated with
     * ```
     * <my-component title="Hello"></my-component>
     * ```
     *
     * Then factory method generated is:
     * ```
     * MyComponent.ngComponentDef = defineComponent({
     *   factory: () => new MyComponent(injectAttribute('title'))
     *   ...
     * })
     * ```
     *
     * @publicApi
     */
    function injectAttributeImpl(tNode, attrNameToInject) {
        ngDevMode && assertNodeOfPossibleTypes(tNode, 0 /* Container */, 3 /* Element */, 4 /* ElementContainer */);
        ngDevMode && assertDefined(tNode, 'expecting tNode');
        if (attrNameToInject === 'class') {
            return getInitialStylingValue(tNode.classes);
        }
        if (attrNameToInject === 'style') {
            return getInitialStylingValue(tNode.styles);
        }
        var attrs = tNode.attrs;
        if (attrs) {
            var attrsLength = attrs.length;
            var i = 0;
            while (i < attrsLength) {
                var value = attrs[i];
                // If we hit a `Bindings` or `Template` marker then we are done.
                if (isNameOnlyAttributeMarker(value))
                    break;
                // Skip namespaced attributes
                if (value === 0 /* NamespaceURI */) {
                    // we skip the next two values
                    // as namespaced attributes looks like
                    // [..., AttributeMarker.NamespaceURI, 'http://someuri.com/test', 'test:exist',
                    // 'existValue', ...]
                    i = i + 2;
                }
                else if (typeof value === 'number') {
                    // Skip to the first value of the marked attribute.
                    i++;
                    while (i < attrsLength && typeof attrs[i] === 'string') {
                        i++;
                    }
                }
                else if (value === attrNameToInject) {
                    return attrs[i + 1];
                }
                else {
                    i = i + 2;
                }
            }
        }
        return null;
    }
    /**
     * Returns the value associated to the given token from the NodeInjectors => ModuleInjector.
     *
     * Look for the injector providing the token by walking up the node injector tree and then
     * the module injector tree.
     *
     * This function patches `token` with `__NG_ELEMENT_ID__` which contains the id for the bloom
     * filter. Negative values are reserved for special objects.
     *   - `-1` is reserved for injecting `Injector` (implemented by `NodeInjector`)
     *
     * @param tNode The Node where the search for the injector should start
     * @param lView The `LView` that contains the `tNode`
     * @param token The token to look for
     * @param flags Injection flags
     * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
     * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
     */
    function getOrCreateInjectable(tNode, lView, token, flags, notFoundValue) {
        if (flags === void 0) { flags = exports.InjectFlags.Default; }
        if (tNode) {
            var bloomHash = bloomHashBitOrFactory(token);
            // If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
            // so just call the factory function to create it.
            if (typeof bloomHash === 'function') {
                var savePreviousOrParentTNode = getPreviousOrParentTNode();
                var saveLView = getLView();
                setTNodeAndViewData(tNode, lView);
                try {
                    var value = bloomHash();
                    if (value == null && !(flags & exports.InjectFlags.Optional)) {
                        throw new Error("No provider for " + stringifyForError(token) + "!");
                    }
                    else {
                        return value;
                    }
                }
                finally {
                    setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
                }
            }
            else if (typeof bloomHash == 'number') {
                if (bloomHash === -1) {
                    // `-1` is a special value used to identify `Injector` types.
                    return new NodeInjector(tNode, lView);
                }
                // If the token has a bloom hash, then it is a token which could be in NodeInjector.
                // A reference to the previous injector TView that was found while climbing the element
                // injector tree. This is used to know if viewProviders can be accessed on the current
                // injector.
                var previousTView = null;
                var injectorIndex = getInjectorIndex(tNode, lView);
                var parentLocation = NO_PARENT_INJECTOR;
                var hostTElementNode = flags & exports.InjectFlags.Host ? findComponentView(lView)[T_HOST] : null;
                // If we should skip this injector, or if there is no injector on this node, start by
                // searching
                // the parent injector.
                if (injectorIndex === -1 || flags & exports.InjectFlags.SkipSelf) {
                    parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) :
                        lView[injectorIndex + PARENT_INJECTOR];
                    if (!shouldSearchParent(flags, false)) {
                        injectorIndex = -1;
                    }
                    else {
                        previousTView = lView[TVIEW];
                        injectorIndex = getParentInjectorIndex(parentLocation);
                        lView = getParentInjectorView(parentLocation, lView);
                    }
                }
                // Traverse up the injector tree until we find a potential match or until we know there
                // *isn't* a match.
                while (injectorIndex !== -1) {
                    parentLocation = lView[injectorIndex + PARENT_INJECTOR];
                    // Check the current injector. If it matches, see if it contains token.
                    var tView = lView[TVIEW];
                    if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {
                        // At this point, we have an injector which *may* contain the token, so we step through
                        // the providers and directives associated with the injector's corresponding node to get
                        // the instance.
                        var instance = searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode);
                        if (instance !== NOT_FOUND) {
                            return instance;
                        }
                    }
                    if (shouldSearchParent(flags, lView[TVIEW].data[injectorIndex + TNODE] === hostTElementNode) &&
                        bloomHasToken(bloomHash, injectorIndex, lView)) {
                        // The def wasn't found anywhere on this node, so it was a false positive.
                        // Traverse up the tree and continue searching.
                        previousTView = tView;
                        injectorIndex = getParentInjectorIndex(parentLocation);
                        lView = getParentInjectorView(parentLocation, lView);
                    }
                    else {
                        // If we should not search parent OR If the ancestor bloom filter value does not have the
                        // bit corresponding to the directive we can give up on traversing up to find the specific
                        // injector.
                        injectorIndex = -1;
                    }
                }
            }
        }
        if (flags & exports.InjectFlags.Optional && notFoundValue === undefined) {
            // This must be set or the NullInjector will throw for optional deps
            notFoundValue = null;
        }
        if ((flags & (exports.InjectFlags.Self | exports.InjectFlags.Host)) === 0) {
            var moduleInjector = lView[INJECTOR$1];
            // switch to `injectInjectorOnly` implementation for module injector, since module injector
            // should not have access to Component/Directive DI scope (that may happen through
            // `directiveInject` implementation)
            var previousInjectImplementation = setInjectImplementation(undefined);
            try {
                if (moduleInjector) {
                    return moduleInjector.get(token, notFoundValue, flags & exports.InjectFlags.Optional);
                }
                else {
                    return injectRootLimpMode(token, notFoundValue, flags & exports.InjectFlags.Optional);
                }
            }
            finally {
                setInjectImplementation(previousInjectImplementation);
            }
        }
        if (flags & exports.InjectFlags.Optional) {
            return notFoundValue;
        }
        else {
            throw new Error("NodeInjector: NOT_FOUND [" + stringifyForError(token) + "]");
        }
    }
    var NOT_FOUND = {};
    function searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode) {
        var currentTView = lView[TVIEW];
        var tNode = currentTView.data[injectorIndex + TNODE];
        // First, we need to determine if view providers can be accessed by the starting element.
        // There are two possibities
        var canAccessViewProviders = previousTView == null ?
            // 1) This is the first invocation `previousTView == null` which means that we are at the
            // `TNode` of where injector is starting to look. In such a case the only time we are allowed
            // to look into the ViewProviders is if:
            // - we are on a component
            // - AND the injector set `includeViewProviders` to true (implying that the token can see
            // ViewProviders because it is the Component or a Service which itself was declared in
            // ViewProviders)
            (isComponent(tNode) && includeViewProviders) :
            // 2) `previousTView != null` which means that we are now walking across the parent nodes.
            // In such a case we are only allowed to look into the ViewProviders if:
            // - We just crossed from child View to Parent View `previousTView != currentTView`
            // - AND the parent TNode is an Element.
            // This means that we just came from the Component's View and therefore are allowed to see
            // into the ViewProviders.
            (previousTView != currentTView && (tNode.type === 3 /* Element */));
        // This special case happens when there is a @host on the inject and when we are searching
        // on the host element node.
        var isHostSpecialCase = (flags & exports.InjectFlags.Host) && hostTElementNode === tNode;
        var injectableIdx = locateDirectiveOrProvider(tNode, currentTView, token, canAccessViewProviders, isHostSpecialCase);
        if (injectableIdx !== null) {
            return getNodeInjectable(currentTView.data, lView, injectableIdx, tNode);
        }
        else {
            return NOT_FOUND;
        }
    }
    /**
     * Searches for the given token among the node's directives and providers.
     *
     * @param tNode TNode on which directives are present.
     * @param tView The tView we are currently processing
     * @param token Provider token or type of a directive to look for.
     * @param canAccessViewProviders Whether view providers should be considered.
     * @param isHostSpecialCase Whether the host special case applies.
     * @returns Index of a found directive or provider, or null when none found.
     */
    function locateDirectiveOrProvider(tNode, tView, token, canAccessViewProviders, isHostSpecialCase) {
        var nodeProviderIndexes = tNode.providerIndexes;
        var tInjectables = tView.data;
        var injectablesStart = nodeProviderIndexes & 65535 /* ProvidersStartIndexMask */;
        var directivesStart = tNode.directiveStart;
        var directiveEnd = tNode.directiveEnd;
        var cptViewProvidersCount = nodeProviderIndexes >> 16 /* CptViewProvidersCountShift */;
        var startingIndex = canAccessViewProviders ? injectablesStart : injectablesStart + cptViewProvidersCount;
        // When the host special case applies, only the viewProviders and the component are visible
        var endIndex = isHostSpecialCase ? injectablesStart + cptViewProvidersCount : directiveEnd;
        for (var i = startingIndex; i < endIndex; i++) {
            var providerTokenOrDef = tInjectables[i];
            if (i < directivesStart && token === providerTokenOrDef ||
                i >= directivesStart && providerTokenOrDef.type === token) {
                return i;
            }
        }
        if (isHostSpecialCase) {
            var dirDef = tInjectables[directivesStart];
            if (dirDef && isComponentDef(dirDef) && dirDef.type === token) {
                return directivesStart;
            }
        }
        return null;
    }
    /**
    * Retrieve or instantiate the injectable from the `lData` at particular `index`.
    *
    * This function checks to see if the value has already been instantiated and if so returns the
    * cached `injectable`. Otherwise if it detects that the value is still a factory it
    * instantiates the `injectable` and caches the value.
    */
    function getNodeInjectable(tData, lData, index, tNode) {
        var value = lData[index];
        if (isFactory(value)) {
            var factory = value;
            if (factory.resolving) {
                throw new Error("Circular dep for " + stringifyForError(tData[index]));
            }
            var previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);
            factory.resolving = true;
            var previousInjectImplementation = void 0;
            if (factory.injectImpl) {
                previousInjectImplementation = setInjectImplementation(factory.injectImpl);
            }
            var savePreviousOrParentTNode = getPreviousOrParentTNode();
            var saveLView = getLView();
            setTNodeAndViewData(tNode, lData);
            try {
                value = lData[index] = factory.factory(undefined, tData, lData, tNode);
            }
            finally {
                if (factory.injectImpl)
                    setInjectImplementation(previousInjectImplementation);
                setIncludeViewProviders(previousIncludeViewProviders);
                factory.resolving = false;
                setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
            }
        }
        return value;
    }
    /**
     * Returns the bit in an injector's bloom filter that should be used to determine whether or not
     * the directive might be provided by the injector.
     *
     * When a directive is public, it is added to the bloom filter and given a unique ID that can be
     * retrieved on the Type. When the directive isn't public or the token is not a directive `null`
     * is returned as the node injector can not possibly provide that token.
     *
     * @param token the injection token
     * @returns the matching bit to check in the bloom filter or `null` if the token is not known.
     *   When the returned value is negative then it represents special values such as `Injector`.
     */
    function bloomHashBitOrFactory(token) {
        ngDevMode && assertDefined(token, 'token must be defined');
        if (typeof token === 'string') {
            return token.charCodeAt(0) || 0;
        }
        var tokenId = token[NG_ELEMENT_ID];
        // Negative token IDs are used for special objects such as `Injector`
        return (typeof tokenId === 'number' && tokenId > 0) ? tokenId & BLOOM_MASK : tokenId;
    }
    function bloomHasToken(bloomHash, injectorIndex, injectorView) {
        // Create a mask that targets the specific bit associated with the directive we're looking for.
        // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
        // to bit positions 0 - 31 in a 32 bit integer.
        var mask = 1 << bloomHash;
        var b7 = bloomHash & 0x80;
        var b6 = bloomHash & 0x40;
        var b5 = bloomHash & 0x20;
        // Our bloom filter size is 256 bits, which is eight 32-bit bloom filter buckets:
        // bf0 = [0 - 31], bf1 = [32 - 63], bf2 = [64 - 95], bf3 = [96 - 127], etc.
        // Get the bloom filter value from the appropriate bucket based on the directive's bloomBit.
        var value;
        if (b7) {
            value = b6 ? (b5 ? injectorView[injectorIndex + 7] : injectorView[injectorIndex + 6]) :
                (b5 ? injectorView[injectorIndex + 5] : injectorView[injectorIndex + 4]);
        }
        else {
            value = b6 ? (b5 ? injectorView[injectorIndex + 3] : injectorView[injectorIndex + 2]) :
                (b5 ? injectorView[injectorIndex + 1] : injectorView[injectorIndex]);
        }
        // If the bloom filter value has the bit corresponding to the directive's bloomBit flipped on,
        // this injector is a potential match.
        return !!(value & mask);
    }
    /** Returns true if flags prevent parent injector from being searched for tokens */
    function shouldSearchParent(flags, isFirstHostTNode) {
        return !(flags & exports.InjectFlags.Self) && !(flags & exports.InjectFlags.Host && isFirstHostTNode);
    }
    var NodeInjector = /** @class */ (function () {
        function NodeInjector(_tNode, _lView) {
            this._tNode = _tNode;
            this._lView = _lView;
        }
        NodeInjector.prototype.get = function (token, notFoundValue) {
            return getOrCreateInjectable(this._tNode, this._lView, token, undefined, notFoundValue);
        };
        return NodeInjector;
    }());
    /**
     * @codeGenApi
     */
    function ɵɵgetFactoryOf(type) {
        var typeAny = type;
        var def = getComponentDef(typeAny) || getDirectiveDef(typeAny) ||
            getPipeDef(typeAny) || getInjectableDef(typeAny) || getInjectorDef(typeAny);
        if (!def || def.factory === undefined) {
            return null;
        }
        return def.factory;
    }
    /**
     * @codeGenApi
     */
    function ɵɵgetInheritedFactory(type) {
        var proto = Object.getPrototypeOf(type.prototype).constructor;
        var factory = ɵɵgetFactoryOf(proto);
        if (factory !== null) {
            return factory;
        }
        else {
            // There is no factory defined. Either this was improper usage of inheritance
            // (no Angular decorator on the superclass) or there is no constructor at all
            // in the inheritance chain. Since the two cases cannot be distinguished, the
            // latter has to be assumed.
            return function (t) { return new t(); };
        }
    }

    /**
     * @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
     */
    var ERROR_TYPE = 'ngType';
    var ERROR_DEBUG_CONTEXT = 'ngDebugContext';
    var ERROR_ORIGINAL_ERROR = 'ngOriginalError';
    var ERROR_LOGGER = 'ngErrorLogger';
    function wrappedError(message, originalError) {
        var msg = message + " caused by: " + (originalError instanceof Error ? originalError.message : originalError);
        var error = Error(msg);
        error[ERROR_ORIGINAL_ERROR] = originalError;
        return error;
    }

    /**
     * @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
     */
    function getType(error) {
        return error[ERROR_TYPE];
    }
    function getDebugContext(error) {
        return error[ERROR_DEBUG_CONTEXT];
    }
    function getOriginalError(error) {
        return error[ERROR_ORIGINAL_ERROR];
    }
    function getErrorLogger(error) {
        return error[ERROR_LOGGER] || defaultErrorLogger;
    }
    function defaultErrorLogger(console) {
        var values = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            values[_i - 1] = arguments[_i];
        }
        console.error.apply(console, __spread(values));
    }

    /**
     * @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
     */
    /**
     * Provides a hook for centralized exception handling.
     *
     * The default implementation of `ErrorHandler` prints error messages to the `console`. To
     * intercept error handling, write a custom exception handler that replaces this default as
     * appropriate for your app.
     *
     * @usageNotes
     * ### Example
     *
     * ```
     * class MyErrorHandler implements ErrorHandler {
     *   handleError(error) {
     *     // do something with the exception
     *   }
     * }
     *
     * @NgModule({
     *   providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
     * })
     * class MyModule {}
     * ```
     *
     * @publicApi
     */
    var ErrorHandler = /** @class */ (function () {
        function ErrorHandler() {
            /**
             * @internal
             */
            this._console = console;
        }
        ErrorHandler.prototype.handleError = function (error) {
            var originalError = this._findOriginalError(error);
            var context = this._findContext(error);
            // Note: Browser consoles show the place from where console.error was called.
            // We can use this to give users additional information about the error.
            var errorLogger = getErrorLogger(error);
            errorLogger(this._console, "ERROR", error);
            if (originalError) {
                errorLogger(this._console, "ORIGINAL ERROR", originalError);
            }
            if (context) {
                errorLogger(this._console, 'ERROR CONTEXT', context);
            }
        };
        /** @internal */
        ErrorHandler.prototype._findContext = function (error) {
            if (error) {
                return getDebugContext(error) ? getDebugContext(error) :
                    this._findContext(getOriginalError(error));
            }
            return null;
        };
        /** @internal */
        ErrorHandler.prototype._findOriginalError = function (error) {
            var e = getOriginalError(error);
            while (e && getOriginalError(e)) {
                e = getOriginalError(e);
            }
            return e;
        };
        return ErrorHandler;
    }());

    /**
     * @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
     */
    /**
     * Defines a schema that allows an NgModule to contain the following:
     * - Non-Angular elements named with dash case (`-`).
     * - Element properties named with dash case (`-`).
     * Dash case is the naming convention for custom elements.
     *
     * @publicApi
     */
    var CUSTOM_ELEMENTS_SCHEMA = {
        name: 'custom-elements'
    };
    /**
     * Defines a schema that allows any property on any element.
     *
     * @publicApi
     */
    var NO_ERRORS_SCHEMA = {
        name: 'no-errors-schema'
    };

    /**
     * @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
     */
    var BRAND = '__SANITIZER_TRUSTED_BRAND__';
    function allowSanitizationBypass(value, type) {
        return (value instanceof String && value[BRAND] === type);
    }
    /**
     * Mark `html` string as trusted.
     *
     * This function wraps the trusted string in `String` and brands it in a way which makes it
     * recognizable to {@link htmlSanitizer} to be trusted implicitly.
     *
     * @param trustedHtml `html` string which needs to be implicitly trusted.
     * @returns a `html` `String` which has been branded to be implicitly trusted.
     */
    function bypassSanitizationTrustHtml(trustedHtml) {
        return bypassSanitizationTrustString(trustedHtml, "Html" /* Html */);
    }
    /**
     * Mark `style` string as trusted.
     *
     * This function wraps the trusted string in `String` and brands it in a way which makes it
     * recognizable to {@link styleSanitizer} to be trusted implicitly.
     *
     * @param trustedStyle `style` string which needs to be implicitly trusted.
     * @returns a `style` `String` which has been branded to be implicitly trusted.
     */
    function bypassSanitizationTrustStyle(trustedStyle) {
        return bypassSanitizationTrustString(trustedStyle, "Style" /* Style */);
    }
    /**
     * Mark `script` string as trusted.
     *
     * This function wraps the trusted string in `String` and brands it in a way which makes it
     * recognizable to {@link scriptSanitizer} to be trusted implicitly.
     *
     * @param trustedScript `script` string which needs to be implicitly trusted.
     * @returns a `script` `String` which has been branded to be implicitly trusted.
     */
    function bypassSanitizationTrustScript(trustedScript) {
        return bypassSanitizationTrustString(trustedScript, "Script" /* Script */);
    }
    /**
     * Mark `url` string as trusted.
     *
     * This function wraps the trusted string in `String` and brands it in a way which makes it
     * recognizable to {@link urlSanitizer} to be trusted implicitly.
     *
     * @param trustedUrl `url` string which needs to be implicitly trusted.
     * @returns a `url` `String` which has been branded to be implicitly trusted.
     */
    function bypassSanitizationTrustUrl(trustedUrl) {
        return bypassSanitizationTrustString(trustedUrl, "Url" /* Url */);
    }
    /**
     * Mark `url` string as trusted.
     *
     * This function wraps the trusted string in `String` and brands it in a way which makes it
     * recognizable to {@link resourceUrlSanitizer} to be trusted implicitly.
     *
     * @param trustedResourceUrl `url` string which needs to be implicitly trusted.
     * @returns a `url` `String` which has been branded to be implicitly trusted.
     */
    function bypassSanitizationTrustResourceUrl(trustedResourceUrl) {
        return bypassSanitizationTrustString(trustedResourceUrl, "ResourceUrl" /* ResourceUrl */);
    }
    function bypassSanitizationTrustString(trustedString, mode) {
        // tslint:disable-next-line
        var trusted = new String(trustedString);
        trusted[BRAND] = mode;
        return trusted;
    }

    /**
     * @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 used to control if the default rendering pipeline should be `ViewEngine` or `Ivy`.
     *
     * For more information on how to run and debug tests with either Ivy or View Engine (legacy),
     * please see [BAZEL.md](./docs/BAZEL.md).
     */
    var _devMode = true;
    var _runModeLocked = false;
    /**
     * Returns whether Angular is in development mode. After called once,
     * the value is locked and won't change any more.
     *
     * By default, this is true, unless a user calls `enableProdMode` before calling this.
     *
     * @publicApi
     */
    function isDevMode() {
        _runModeLocked = true;
        return _devMode;
    }
    /**
     * Disable Angular's development mode, which turns off assertions and other
     * checks within the framework.
     *
     * One important assertion this disables verifies that a change detection pass
     * does not result in additional changes to any bindings (also known as
     * unidirectional data flow).
     *
     * @publicApi
     */
    function enableProdMode() {
        if (_runModeLocked) {
            throw new Error('Cannot enable prod mode after platform setup.');
        }
        _devMode = false;
    }

    /**
     * @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 helper class is used to get hold of an inert tree of DOM elements containing dirty HTML
     * that needs sanitizing.
     * Depending upon browser support we must use one of three strategies for doing this.
     * Support: Safari 10.x -> XHR strategy
     * Support: Firefox -> DomParser strategy
     * Default: InertDocument strategy
     */
    var InertBodyHelper = /** @class */ (function () {
        function InertBodyHelper(defaultDoc) {
            this.defaultDoc = defaultDoc;
            this.inertDocument = this.defaultDoc.implementation.createHTMLDocument('sanitization-inert');
            this.inertBodyElement = this.inertDocument.body;
            if (this.inertBodyElement == null) {
                // usually there should be only one body element in the document, but IE doesn't have any, so
                // we need to create one.
                var inertHtml = this.inertDocument.createElement('html');
                this.inertDocument.appendChild(inertHtml);
                this.inertBodyElement = this.inertDocument.createElement('body');
                inertHtml.appendChild(this.inertBodyElement);
            }
            this.inertBodyElement.innerHTML = '<svg><g onload="this.parentNode.remove()"></g></svg>';
            if (this.inertBodyElement.querySelector && !this.inertBodyElement.querySelector('svg')) {
                // We just hit the Safari 10.1 bug - which allows JS to run inside the SVG G element
                // so use the XHR strategy.
                this.getInertBodyElement = this.getInertBodyElement_XHR;
                return;
            }
            this.inertBodyElement.innerHTML =
                '<svg><p><style><img src="</style><img src=x onerror=alert(1)//">';
            if (this.inertBodyElement.querySelector && this.inertBodyElement.querySelector('svg img')) {
                // We just hit the Firefox bug - which prevents the inner img JS from being sanitized
                // so use the DOMParser strategy, if it is available.
                // If the DOMParser is not available then we are not in Firefox (Server/WebWorker?) so we
                // fall through to the default strategy below.
                if (isDOMParserAvailable()) {
                    this.getInertBodyElement = this.getInertBodyElement_DOMParser;
                    return;
                }
            }
            // None of the bugs were hit so it is safe for us to use the default InertDocument strategy
            this.getInertBodyElement = this.getInertBodyElement_InertDocument;
        }
        /**
         * Use XHR to create and fill an inert body element (on Safari 10.1)
         * See
         * https://github.com/cure53/DOMPurify/blob/a992d3a75031cb8bb032e5ea8399ba972bdf9a65/src/purify.js#L439-L449
         */
        InertBodyHelper.prototype.getInertBodyElement_XHR = function (html) {
            // We add these extra elements to ensure that the rest of the content is parsed as expected
            // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
            // `<head>` tag.
            html = '<body><remove></remove>' + html + '</body>';
            try {
                html = encodeURI(html);
            }
            catch (_a) {
                return null;
            }
            var xhr = new XMLHttpRequest();
            xhr.responseType = 'document';
            xhr.open('GET', 'data:text/html;charset=utf-8,' + html, false);
            xhr.send(undefined);
            var body = xhr.response.body;
            body.removeChild(body.firstChild);
            return body;
        };
        /**
         * Use DOMParser to create and fill an inert body element (on Firefox)
         * See https://github.com/cure53/DOMPurify/releases/tag/0.6.7
         *
         */
        InertBodyHelper.prototype.getInertBodyElement_DOMParser = function (html) {
            // We add these extra elements to ensure that the rest of the content is parsed as expected
            // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
            // `<head>` tag.
            html = '<body><remove></remove>' + html + '</body>';
            try {
                var body = new window
                    .DOMParser()
                    .parseFromString(html, 'text/html')
                    .body;
                body.removeChild(body.firstChild);
                return body;
            }
            catch (_a) {
                return null;
            }
        };
        /**
         * Use an HTML5 `template` element, if supported, or an inert body element created via
         * `createHtmlDocument` to create and fill an inert DOM element.
         * This is the default sane strategy to use if the browser does not require one of the specialised
         * strategies above.
         */
        InertBodyHelper.prototype.getInertBodyElement_InertDocument = function (html) {
            // Prefer using <template> element if supported.
            var templateEl = this.inertDocument.createElement('template');
            if ('content' in templateEl) {
                templateEl.innerHTML = html;
                return templateEl;
            }
            this.inertBodyElement.innerHTML = html;
            // Support: IE 9-11 only
            // strip custom-namespaced attributes on IE<=11
            if (this.defaultDoc.documentMode) {
                this.stripCustomNsAttrs(this.inertBodyElement);
            }
            return this.inertBodyElement;
        };
        /**
         * When IE9-11 comes across an unknown namespaced attribute e.g. 'xlink:foo' it adds 'xmlns:ns1'
         * attribute to declare ns1 namespace and prefixes the attribute with 'ns1' (e.g.
         * 'ns1:xlink:foo').
         *
         * This is undesirable since we don't want to allow any of these custom attributes. This method
         * strips them all.
         */
        InertBodyHelper.prototype.stripCustomNsAttrs = function (el) {
            var elAttrs = el.attributes;
            // loop backwards so that we can support removals.
            for (var i = elAttrs.length - 1; 0 < i; i--) {
                var attrib = elAttrs.item(i);
                var attrName = attrib.name;
                if (attrName === 'xmlns:ns1' || attrName.indexOf('ns1:') === 0) {
                    el.removeAttribute(attrName);
                }
            }
            var childNode = el.firstChild;
            while (childNode) {
                if (childNode.nodeType === Node.ELEMENT_NODE)
                    this.stripCustomNsAttrs(childNode);
                childNode = childNode.nextSibling;
            }
        };
        return InertBodyHelper;
    }());
    /**
     * We need to determine whether the DOMParser exists in the global context.
     * The try-catch is because, on some browsers, trying to access this property
     * on window can actually throw an error.
     *
     * @suppress {uselessCode}
     */
    function isDOMParserAvailable() {
        try {
            return !!window.DOMParser;
        }
        catch (_a) {
            return false;
        }
    }

    /**
     * @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
     */
    /**
     * A pattern that recognizes a commonly useful subset of URLs that are safe.
     *
     * This regular expression matches a subset of URLs that will not cause script
     * execution if used in URL context within a HTML document. Specifically, this
     * regular expression matches if (comment from here on and regex copied from
     * Soy's EscapingConventions):
     * (1) Either an allowed protocol (http, https, mailto or ftp).
     * (2) or no protocol.  A protocol must be followed by a colon. The below
     *     allows that by allowing colons only after one of the characters [/?#].
     *     A colon after a hash (#) must be in the fragment.
     *     Otherwise, a colon after a (?) must be in a query.
     *     Otherwise, a colon after a single solidus (/) must be in a path.
     *     Otherwise, a colon after a double solidus (//) must be in the authority
     *     (before port).
     *
     * The pattern disallows &, used in HTML entity declarations before
     * one of the characters in [/?#]. This disallows HTML entities used in the
     * protocol name, which should never happen, e.g. "h&#116;tp" for "http".
     * It also disallows HTML entities in the first path part of a relative path,
     * e.g. "foo&lt;bar/baz".  Our existing escaping functions should not produce
     * that. More importantly, it disallows masking of a colon,
     * e.g. "javascript&#58;...".
     *
     * This regular expression was taken from the Closure sanitization library.
     */
    var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
    /* A pattern that matches safe srcset values */
    var SAFE_SRCSET_PATTERN = /^(?:(?:https?|file):|[^&:/?#]*(?:[/?#]|$))/gi;
    /** A pattern that matches safe data URLs. Only matches image, video and audio types. */
    var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;
    function _sanitizeUrl(url) {
        url = String(url);
        if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN))
            return url;
        if (isDevMode()) {
            console.warn("WARNING: sanitizing unsafe URL value " + url + " (see http://g.co/ng/security#xss)");
        }
        return 'unsafe:' + url;
    }
    function sanitizeSrcset(srcset) {
        srcset = String(srcset);
        return srcset.split(',').map(function (srcset) { return _sanitizeUrl(srcset.trim()); }).join(', ');
    }

    /**
     * @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
     */
    function tagSet(tags) {
        var e_1, _a;
        var res = {};
        try {
            for (var _b = __values(tags.split(',')), _c = _b.next(); !_c.done; _c = _b.next()) {
                var t = _c.value;
                res[t] = true;
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
            }
            finally { if (e_1) throw e_1.error; }
        }
        return res;
    }
    function merge() {
        var e_2, _a;
        var sets = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            sets[_i] = arguments[_i];
        }
        var res = {};
        try {
            for (var sets_1 = __values(sets), sets_1_1 = sets_1.next(); !sets_1_1.done; sets_1_1 = sets_1.next()) {
                var s = sets_1_1.value;
                for (var v in s) {
                    if (s.hasOwnProperty(v))
                        res[v] = true;
                }
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (sets_1_1 && !sets_1_1.done && (_a = sets_1.return)) _a.call(sets_1);
            }
            finally { if (e_2) throw e_2.error; }
        }
        return res;
    }
    // Good source of info about elements and attributes
    // http://dev.w3.org/html5/spec/Overview.html#semantics
    // http://simon.html5.org/html-elements
    // Safe Void Elements - HTML5
    // http://dev.w3.org/html5/spec/Overview.html#void-elements
    var VOID_ELEMENTS = tagSet('area,br,col,hr,img,wbr');
    // Elements that you can, intentionally, leave open (and which close themselves)
    // http://dev.w3.org/html5/spec/Overview.html#optional-tags
    var OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr');
    var OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet('rp,rt');
    var OPTIONAL_END_TAG_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS);
    // Safe Block Elements - HTML5
    var BLOCK_ELEMENTS = merge(OPTIONAL_END_TAG_BLOCK_ELEMENTS, tagSet('address,article,' +
        'aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
        'h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul'));
    // Inline Elements - HTML5
    var INLINE_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,acronym,audio,b,' +
        'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' +
        'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video'));
    var VALID_ELEMENTS = merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
    // Attributes that have href and hence need to be sanitized
    var URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
    // Attributes that have special href set hence need to be sanitized
    var SRCSET_ATTRS = tagSet('srcset');
    var HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' +
        'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' +
        'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' +
        'scope,scrolling,shape,size,sizes,span,srclang,start,summary,tabindex,target,title,translate,type,usemap,' +
        'valign,value,vspace,width');
    // Accessibility attributes as per WAI-ARIA 1.1 (W3C Working Draft 14 December 2018)
    var ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,' +
        'aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,' +
        'aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,' +
        'aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,' +
        'aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,' +
        'aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,' +
        'aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext');
    // NB: This currently consciously doesn't support SVG. SVG sanitization has had several security
    // issues in the past, so it seems safer to leave it out if possible. If support for binding SVG via
    // innerHTML is required, SVG attributes should be added here.
    // NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
    // can be sanitized, but they increase security surface area without a legitimate use case, so they
    // are left out here.
    var VALID_ATTRS = merge(URI_ATTRS, SRCSET_ATTRS, HTML_ATTRS, ARIA_ATTRS);
    // Elements whose content should not be traversed/preserved, if the elements themselves are invalid.
    //
    // Typically, `<invalid>Some content</invalid>` would traverse (and in this case preserve)
    // `Some content`, but strip `invalid-element` opening/closing tags. For some elements, though, we
    // don't want to preserve the content, if the elements themselves are going to be removed.
    var SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS = tagSet('script,style,template');
    /**
     * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
     * attributes.
     */
    var SanitizingHtmlSerializer = /** @class */ (function () {
        function SanitizingHtmlSerializer() {
            // Explicitly track if something was stripped, to avoid accidentally warning of sanitization just
            // because characters were re-encoded.
            this.sanitizedSomething = false;
            this.buf = [];
        }
        SanitizingHtmlSerializer.prototype.sanitizeChildren = function (el) {
            // This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
            // However this code never accesses properties off of `document` before deleting its contents
            // again, so it shouldn't be vulnerable to DOM clobbering.
            var current = el.firstChild;
            var traverseContent = true;
            while (current) {
                if (current.nodeType === Node.ELEMENT_NODE) {
                    traverseContent = this.startElement(current);
                }
                else if (current.nodeType === Node.TEXT_NODE) {
                    this.chars(current.nodeValue);
                }
                else {
                    // Strip non-element, non-text nodes.
                    this.sanitizedSomething = true;
                }
                if (traverseContent && current.firstChild) {
                    current = current.firstChild;
                    continue;
                }
                while (current) {
                    // Leaving the element. Walk up and to the right, closing tags as we go.
                    if (current.nodeType === Node.ELEMENT_NODE) {
                        this.endElement(current);
                    }
                    var next = this.checkClobberedElement(current, current.nextSibling);
                    if (next) {
                        current = next;
                        break;
                    }
                    current = this.checkClobberedElement(current, current.parentNode);
                }
            }
            return this.buf.join('');
        };
        /**
         * Sanitizes an opening element tag (if valid) and returns whether the element's contents should
         * be traversed. Element content must always be traversed (even if the element itself is not
         * valid/safe), unless the element is one of `SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS`.
         *
         * @param element The element to sanitize.
         * @return True if the element's contents should be traversed.
         */
        SanitizingHtmlSerializer.prototype.startElement = function (element) {
            var tagName = element.nodeName.toLowerCase();
            if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
                this.sanitizedSomething = true;
                return !SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS.hasOwnProperty(tagName);
            }
            this.buf.push('<');
            this.buf.push(tagName);
            var elAttrs = element.attributes;
            for (var i = 0; i < elAttrs.length; i++) {
                var elAttr = elAttrs.item(i);
                var attrName = elAttr.name;
                var lower = attrName.toLowerCase();
                if (!VALID_ATTRS.hasOwnProperty(lower)) {
                    this.sanitizedSomething = true;
                    continue;
                }
                var value = elAttr.value;
                // TODO(martinprobst): Special case image URIs for data:image/...
                if (URI_ATTRS[lower])
                    value = _sanitizeUrl(value);
                if (SRCSET_ATTRS[lower])
                    value = sanitizeSrcset(value);
                this.buf.push(' ', attrName, '="', encodeEntities(value), '"');
            }
            this.buf.push('>');
            return true;
        };
        SanitizingHtmlSerializer.prototype.endElement = function (current) {
            var tagName = current.nodeName.toLowerCase();
            if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
                this.buf.push('</');
                this.buf.push(tagName);
                this.buf.push('>');
            }
        };
        SanitizingHtmlSerializer.prototype.chars = function (chars) { this.buf.push(encodeEntities(chars)); };
        SanitizingHtmlSerializer.prototype.checkClobberedElement = function (node, nextNode) {
            if (nextNode &&
                (node.compareDocumentPosition(nextNode) &
                    Node.DOCUMENT_POSITION_CONTAINED_BY) === Node.DOCUMENT_POSITION_CONTAINED_BY) {
                throw new Error("Failed to sanitize html because the element is clobbered: " + node.outerHTML);
            }
            return nextNode;
        };
        return SanitizingHtmlSerializer;
    }());
    // Regular Expressions for parsing tags and attributes
    var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
    // ! to ~ is the ASCII range.
    var NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
    /**
     * Escapes all potentially dangerous characters, so that the
     * resulting string can be safely inserted into attribute or
     * element text.
     * @param value
     */
    function encodeEntities(value) {
        return value.replace(/&/g, '&amp;')
            .replace(SURROGATE_PAIR_REGEXP, function (match) {
            var hi = match.charCodeAt(0);
            var low = match.charCodeAt(1);
            return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
        })
            .replace(NON_ALPHANUMERIC_REGEXP, function (match) { return '&#' + match.charCodeAt(0) + ';'; })
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');
    }
    var inertBodyHelper;
    /**
     * Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
     * the DOM in a browser environment.
     */
    function _sanitizeHtml(defaultDoc, unsafeHtmlInput) {
        var inertBodyElement = null;
        try {
            inertBodyHelper = inertBodyHelper || new InertBodyHelper(defaultDoc);
            // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
            var unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
            inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
            // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
            // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
            var mXSSAttempts = 5;
            var parsedHtml = unsafeHtml;
            do {
                if (mXSSAttempts === 0) {
                    throw new Error('Failed to sanitize html because the input is unstable');
                }
                mXSSAttempts--;
                unsafeHtml = parsedHtml;
                parsedHtml = inertBodyElement.innerHTML;
                inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
            } while (unsafeHtml !== parsedHtml);
            var sanitizer = new SanitizingHtmlSerializer();
            var safeHtml = sanitizer.sanitizeChildren(getTemplateContent(inertBodyElement) || inertBodyElement);
            if (isDevMode() && sanitizer.sanitizedSomething) {
                console.warn('WARNING: sanitizing HTML stripped some content, see http://g.co/ng/security#xss');
            }
            return safeHtml;
        }
        finally {
            // In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
            if (inertBodyElement) {
                var parent_1 = getTemplateContent(inertBodyElement) || inertBodyElement;
                while (parent_1.firstChild) {
                    parent_1.removeChild(parent_1.firstChild);
                }
            }
        }
    }
    function getTemplateContent(el) {
        return 'content' in el /** Microsoft/TypeScript#21517 */ && isTemplateElement(el) ?
            el.content :
            null;
    }
    function isTemplateElement(el) {
        return el.nodeType === Node.ELEMENT_NODE && el.nodeName === 'TEMPLATE';
    }

    /**
     * @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
     */
    (function (SecurityContext) {
        SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
        SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
        SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
        SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
        SecurityContext[SecurityContext["URL"] = 4] = "URL";
        SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
    })(exports.SecurityContext || (exports.SecurityContext = {}));
    /**
     * Sanitizer is used by the views to sanitize potentially dangerous values.
     *
     * @publicApi
     */
    var Sanitizer = /** @class */ (function () {
        function Sanitizer() {
        }
        return Sanitizer;
    }());

    /**
     * @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
     */
    /**
     * Regular expression for safe style values.
     *
     * Quotes (" and ') are allowed, but a check must be done elsewhere to ensure they're balanced.
     *
     * ',' allows multiple values to be assigned to the same property (e.g. background-attachment or
     * font-family) and hence could allow multiple values to get injected, but that should pose no risk
     * of XSS.
     *
     * The function expression checks only for XSS safety, not for CSS validity.
     *
     * This regular expression was taken from the Closure sanitization library, and augmented for
     * transformation values.
     */
    var VALUES = '[-,."\'%_!# a-zA-Z0-9]+';
    var TRANSFORMATION_FNS = '(?:matrix|translate|scale|rotate|skew|perspective)(?:X|Y|Z|3d)?';
    var COLOR_FNS = '(?:rgb|hsl)a?';
    var GRADIENTS = '(?:repeating-)?(?:linear|radial)-gradient';
    var CSS3_FNS = '(?:calc|attr)';
    var FN_ARGS = '\\([-0-9.%, #a-zA-Z]+\\)';
    var SAFE_STYLE_VALUE = new RegExp("^(" + VALUES + "|" +
        ("(?:" + TRANSFORMATION_FNS + "|" + COLOR_FNS + "|" + GRADIENTS + "|" + CSS3_FNS + ")") +
        (FN_ARGS + ")$"), 'g');
    /**
     * Matches a `url(...)` value with an arbitrary argument as long as it does
     * not contain parentheses.
     *
     * The URL value still needs to be sanitized separately.
     *
     * `url(...)` values are a very common use case, e.g. for `background-image`. With carefully crafted
     * CSS style rules, it is possible to construct an information leak with `url` values in CSS, e.g.
     * by observing whether scroll bars are displayed, or character ranges used by a font face
     * definition.
     *
     * Angular only allows binding CSS values (as opposed to entire CSS rules), so it is unlikely that
     * binding a URL value without further cooperation from the page will cause an information leak, and
     * if so, it is just a leak, not a full blown XSS vulnerability.
     *
     * Given the common use case, low likelihood of attack vector, and low impact of an attack, this
     * code is permissive and allows URLs that sanitize otherwise.
     */
    var URL_RE = /^url\(([^)]+)\)$/;
    /**
     * Checks that quotes (" and ') are properly balanced inside a string. Assumes
     * that neither escape (\) nor any other character that could result in
     * breaking out of a string parsing context are allowed;
     * see http://www.w3.org/TR/css3-syntax/#string-token-diagram.
     *
     * This code was taken from the Closure sanitization library.
     */
    function hasBalancedQuotes(value) {
        var outsideSingle = true;
        var outsideDouble = true;
        for (var i = 0; i < value.length; i++) {
            var c = value.charAt(i);
            if (c === '\'' && outsideDouble) {
                outsideSingle = !outsideSingle;
            }
            else if (c === '"' && outsideSingle) {
                outsideDouble = !outsideDouble;
            }
        }
        return outsideSingle && outsideDouble;
    }
    /**
     * Sanitizes the given untrusted CSS style property value (i.e. not an entire object, just a single
     * value) and returns a value that is safe to use in a browser environment.
     */
    function _sanitizeStyle(value) {
        value = String(value).trim(); // Make sure it's actually a string.
        if (!value)
            return '';
        // Single url(...) values are supported, but only for URLs that sanitize cleanly. See above for
        // reasoning behind this.
        var urlMatch = value.match(URL_RE);
        if ((urlMatch && _sanitizeUrl(urlMatch[1]) === urlMatch[1]) ||
            value.match(SAFE_STYLE_VALUE) && hasBalancedQuotes(value)) {
            return value; // Safe style values.
        }
        if (isDevMode()) {
            console.warn("WARNING: sanitizing unsafe style value " + value + " (see http://g.co/ng/security#xss).");
        }
        return 'unsafe';
    }

    /**
     * @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
     */
    /**
     * An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
     * dangerous content.
     *
     * This method parses the `html` and locates potentially dangerous content (such as urls and
     * javascript) and removes it.
     *
     * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustHtml}.
     *
     * @param unsafeHtml untrusted `html`, typically from the user.
     * @returns `html` string which is safe to display to user, because all of the dangerous javascript
     * and urls have been removed.
     *
     * @publicApi
     */
    function ɵɵsanitizeHtml(unsafeHtml) {
        var sanitizer = getSanitizer();
        if (sanitizer) {
            return sanitizer.sanitize(exports.SecurityContext.HTML, unsafeHtml) || '';
        }
        if (allowSanitizationBypass(unsafeHtml, "Html" /* Html */)) {
            return unsafeHtml.toString();
        }
        return _sanitizeHtml(document, renderStringify(unsafeHtml));
    }
    /**
     * A `style` sanitizer which converts untrusted `style` **string** into trusted string by removing
     * dangerous content.
     *
     * This method parses the `style` and locates potentially dangerous content (such as urls and
     * javascript) and removes it.
     *
     * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustStyle}.
     *
     * @param unsafeStyle untrusted `style`, typically from the user.
     * @returns `style` string which is safe to bind to the `style` properties, because all of the
     * dangerous javascript and urls have been removed.
     *
     * @publicApi
     */
    function ɵɵsanitizeStyle(unsafeStyle) {
        var sanitizer = getSanitizer();
        if (sanitizer) {
            return sanitizer.sanitize(exports.SecurityContext.STYLE, unsafeStyle) || '';
        }
        if (allowSanitizationBypass(unsafeStyle, "Style" /* Style */)) {
            return unsafeStyle.toString();
        }
        return _sanitizeStyle(renderStringify(unsafeStyle));
    }
    /**
     * A `url` sanitizer which converts untrusted `url` **string** into trusted string by removing
     * dangerous
     * content.
     *
     * This method parses the `url` and locates potentially dangerous content (such as javascript) and
     * removes it.
     *
     * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustUrl}.
     *
     * @param unsafeUrl untrusted `url`, typically from the user.
     * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
     * all of the dangerous javascript has been removed.
     *
     * @publicApi
     */
    function ɵɵsanitizeUrl(unsafeUrl) {
        var sanitizer = getSanitizer();
        if (sanitizer) {
            return sanitizer.sanitize(exports.SecurityContext.URL, unsafeUrl) || '';
        }
        if (allowSanitizationBypass(unsafeUrl, "Url" /* Url */)) {
            return unsafeUrl.toString();
        }
        return _sanitizeUrl(renderStringify(unsafeUrl));
    }
    /**
     * A `url` sanitizer which only lets trusted `url`s through.
     *
     * This passes only `url`s marked trusted by calling {@link bypassSanitizationTrustResourceUrl}.
     *
     * @param unsafeResourceUrl untrusted `url`, typically from the user.
     * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
     * only trusted `url`s have been allowed to pass.
     *
     * @publicApi
     */
    function ɵɵsanitizeResourceUrl(unsafeResourceUrl) {
        var sanitizer = getSanitizer();
        if (sanitizer) {
            return sanitizer.sanitize(exports.SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '';
        }
        if (allowSanitizationBypass(unsafeResourceUrl, "ResourceUrl" /* ResourceUrl */)) {
            return unsafeResourceUrl.toString();
        }
        throw new Error('unsafe value used in a resource URL context (see http://g.co/ng/security#xss)');
    }
    /**
     * A `script` sanitizer which only lets trusted javascript through.
     *
     * This passes only `script`s marked trusted by calling {@link
     * bypassSanitizationTrustScript}.
     *
     * @param unsafeScript untrusted `script`, typically from the user.
     * @returns `url` string which is safe to bind to the `<script>` element such as `<img src>`,
     * because only trusted `scripts` have been allowed to pass.
     *
     * @publicApi
     */
    function ɵɵsanitizeScript(unsafeScript) {
        var sanitizer = getSanitizer();
        if (sanitizer) {
            return sanitizer.sanitize(exports.SecurityContext.SCRIPT, unsafeScript) || '';
        }
        if (allowSanitizationBypass(unsafeScript, "Script" /* Script */)) {
            return unsafeScript.toString();
        }
        throw new Error('unsafe value used in a script context');
    }
    /**
     * Detects which sanitizer to use for URL property, based on tag name and prop name.
     *
     * The rules are based on the RESOURCE_URL context config from
     * `packages/compiler/src/schema/dom_security_schema.ts`.
     * If tag and prop names don't match Resource URL schema, use URL sanitizer.
     */
    function getUrlSanitizer(tag, prop) {
        if ((prop === 'src' && (tag === 'embed' || tag === 'frame' || tag === 'iframe' ||
            tag === 'media' || tag === 'script')) ||
            (prop === 'href' && (tag === 'base' || tag === 'link'))) {
            return ɵɵsanitizeResourceUrl;
        }
        return ɵɵsanitizeUrl;
    }
    /**
     * Sanitizes URL, selecting sanitizer function based on tag and property names.
     *
     * This function is used in case we can't define security context at compile time, when only prop
     * name is available. This happens when we generate host bindings for Directives/Components. The
     * host element is unknown at compile time, so we defer calculation of specific sanitizer to
     * runtime.
     *
     * @param unsafeUrl untrusted `url`, typically from the user.
     * @param tag target element tag name.
     * @param prop name of the property that contains the value.
     * @returns `url` string which is safe to bind.
     *
     * @publicApi
     */
    function ɵɵsanitizeUrlOrResourceUrl(unsafeUrl, tag, prop) {
        return getUrlSanitizer(tag, prop)(unsafeUrl);
    }
    /**
     * The default style sanitizer will handle sanitization for style properties by
     * sanitizing any CSS property that can include a `url` value (usually image-based properties)
     *
     * @publicApi
     */
    var ɵɵdefaultStyleSanitizer = function (prop, value, mode) {
        mode = mode || 3 /* ValidateAndSanitize */;
        var doSanitizeValue = true;
        if (mode & 1 /* ValidateProperty */) {
            doSanitizeValue = prop === 'background-image' || prop === 'background' ||
                prop === 'border-image' || prop === 'filter' || prop === 'list-style' ||
                prop === 'list-style-image' || prop === 'clip-path';
        }
        if (mode & 2 /* SanitizeOnly */) {
            return doSanitizeValue ? ɵɵsanitizeStyle(value) : value;
        }
        else {
            return doSanitizeValue;
        }
    };
    function validateAgainstEventProperties(name) {
        if (name.toLowerCase().startsWith('on')) {
            var msg = "Binding to event property '" + name + "' is disallowed for security reasons, " +
                ("please use (" + name.slice(2) + ")=...") +
                ("\nIf '" + name + "' is a directive input, make sure the directive is imported by the") +
                " current module.";
            throw new Error(msg);
        }
    }
    function validateAgainstEventAttributes(name) {
        if (name.toLowerCase().startsWith('on')) {
            var msg = "Binding to event attribute '" + name + "' is disallowed for security reasons, " +
                ("please use (" + name.slice(2) + ")=...");
            throw new Error(msg);
        }
    }
    function getSanitizer() {
        var lView = getLView();
        return lView && lView[SANITIZER];
    }

    /**
     * @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 CONTAINS CODE WHICH SHOULD BE TREE SHAKEN AND NEVER CALLED FROM PRODUCTION CODE!!!
     */
    /**
     * Creates an `Array` construction with a given name. This is useful when
     * looking for memory consumption to see what time of array it is.
     *
     *
     * @param name Name to give to the constructor
     * @returns A subclass of `Array` if possible. This can only be done in
     *          environments which support `class` construct.
     */
    function createNamedArrayType(name) {
        // This should never be called in prod mode, so let's verify that is the case.
        if (ngDevMode) {
            try {
                // We need to do it this way so that TypeScript does not down-level the below code.
                var FunctionConstructor = createNamedArrayType.constructor;
                return (new FunctionConstructor('Array', "return class ABC extends Array{}"))(Array);
            }
            catch (e) {
                // If it does not work just give up and fall back to regular Array.
                return Array;
            }
        }
        else {
            throw new Error('Looks like we are in \'prod mode\', but we are creating a named Array type, which is wrong! Check your code');
        }
    }

    /**
     * @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
     */
    function normalizeDebugBindingName(name) {
        // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
        name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
        return "ng-reflect-" + name;
    }
    var CAMEL_CASE_REGEXP = /([A-Z])/g;
    function camelCaseToDashCase(input) {
        return input.replace(CAMEL_CASE_REGEXP, function () {
            var m = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                m[_i] = arguments[_i];
            }
            return '-' + m[1].toLowerCase();
        });
    }
    function normalizeDebugBindingValue(value) {
        try {
            // Limit the size of the value as otherwise the DOM just gets polluted.
            return value != null ? value.toString().slice(0, 30) : value;
        }
        catch (e) {
            return '[ERROR] Exception while trying to serialize the value';
        }
    }

    /**
     * @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
     */
    /** Returns the matching `LContext` data for a given DOM node, directive or component instance.
     *
     * This function will examine the provided DOM element, component, or directive instance\'s
     * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
     * value will be that of the newly created `LContext`.
     *
     * If the monkey-patched value is the `LView` instance then the context value for that
     * target will be created and the monkey-patch reference will be updated. Therefore when this
     * function is called it may mutate the provided element\'s, component\'s or any of the associated
     * directive\'s monkey-patch values.
     *
     * If the monkey-patch value is not detected then the code will walk up the DOM until an element
     * is found which contains a monkey-patch reference. When that occurs then the provided element
     * will be updated with a new context (which is then returned). If the monkey-patch value is not
     * detected for a component/directive instance then it will throw an error (all components and
     * directives should be automatically monkey-patched by ivy).
     *
     * @param target Component, Directive or DOM Node.
     */
    function getLContext(target) {
        var mpValue = readPatchedData(target);
        if (mpValue) {
            // only when it's an array is it considered an LView instance
            // ... otherwise it's an already constructed LContext instance
            if (Array.isArray(mpValue)) {
                var lView = mpValue;
                var nodeIndex = void 0;
                var component = undefined;
                var directives = undefined;
                if (isComponentInstance(target)) {
                    nodeIndex = findViaComponent(lView, target);
                    if (nodeIndex == -1) {
                        throw new Error('The provided component was not found in the application');
                    }
                    component = target;
                }
                else if (isDirectiveInstance(target)) {
                    nodeIndex = findViaDirective(lView, target);
                    if (nodeIndex == -1) {
                        throw new Error('The provided directive was not found in the application');
                    }
                    directives = getDirectivesAtNodeIndex(nodeIndex, lView, false);
                }
                else {
                    nodeIndex = findViaNativeElement(lView, target);
                    if (nodeIndex == -1) {
                        return null;
                    }
                }
                // the goal is not to fill the entire context full of data because the lookups
                // are expensive. Instead, only the target data (the element, component, container, ICU
                // expression or directive details) are filled into the context. If called multiple times
                // with different target values then the missing target data will be filled in.
                var native = unwrapRNode(lView[nodeIndex]);
                var existingCtx = readPatchedData(native);
                var context = (existingCtx && !Array.isArray(existingCtx)) ?
                    existingCtx :
                    createLContext(lView, nodeIndex, native);
                // only when the component has been discovered then update the monkey-patch
                if (component && context.component === undefined) {
                    context.component = component;
                    attachPatchData(context.component, context);
                }
                // only when the directives have been discovered then update the monkey-patch
                if (directives && context.directives === undefined) {
                    context.directives = directives;
                    for (var i = 0; i < directives.length; i++) {
                        attachPatchData(directives[i], context);
                    }
                }
                attachPatchData(context.native, context);
                mpValue = context;
            }
        }
        else {
            var rElement = target;
            ngDevMode && assertDomNode(rElement);
            // if the context is not found then we need to traverse upwards up the DOM
            // to find the nearest element that has already been monkey patched with data
            var parent_1 = rElement;
            while (parent_1 = parent_1.parentNode) {
                var parentContext = readPatchedData(parent_1);
                if (parentContext) {
                    var lView = void 0;
                    if (Array.isArray(parentContext)) {
                        lView = parentContext;
                    }
                    else {
                        lView = parentContext.lView;
                    }
                    // the edge of the app was also reached here through another means
                    // (maybe because the DOM was changed manually).
                    if (!lView) {
                        return null;
                    }
                    var index = findViaNativeElement(lView, rElement);
                    if (index >= 0) {
                        var native = unwrapRNode(lView[index]);
                        var context = createLContext(lView, index, native);
                        attachPatchData(native, context);
                        mpValue = context;
                        break;
                    }
                }
            }
        }
        return mpValue || null;
    }
    /**
     * Creates an empty instance of a `LContext` context
     */
    function createLContext(lView, nodeIndex, native) {
        return {
            lView: lView,
            nodeIndex: nodeIndex,
            native: native,
            component: undefined,
            directives: undefined,
            localRefs: undefined,
        };
    }
    /**
     * Takes a component instance and returns the view for that component.
     *
     * @param componentInstance
     * @returns The component's view
     */
    function getComponentViewByInstance(componentInstance) {
        var lView = readPatchedData(componentInstance);
        var view;
        if (Array.isArray(lView)) {
            var nodeIndex = findViaComponent(lView, componentInstance);
            view = getComponentViewByIndex(nodeIndex, lView);
            var context = createLContext(lView, nodeIndex, view[HOST]);
            context.component = componentInstance;
            attachPatchData(componentInstance, context);
            attachPatchData(context.native, context);
        }
        else {
            var context = lView;
            view = getComponentViewByIndex(context.nodeIndex, context.lView);
        }
        return view;
    }
    /**
     * Assigns the given data to the given target (which could be a component,
     * directive or DOM node instance) using monkey-patching.
     */
    function attachPatchData(target, data) {
        target[MONKEY_PATCH_KEY_NAME] = data;
    }
    function isComponentInstance(instance) {
        return instance && instance.constructor && instance.constructor.ngComponentDef;
    }
    function isDirectiveInstance(instance) {
        return instance && instance.constructor && instance.constructor.ngDirectiveDef;
    }
    /**
     * Locates the element within the given LView and returns the matching index
     */
    function findViaNativeElement(lView, target) {
        var tNode = lView[TVIEW].firstChild;
        while (tNode) {
            var native = getNativeByTNodeOrNull(tNode, lView);
            if (native === target) {
                return tNode.index;
            }
            tNode = traverseNextElement(tNode);
        }
        return -1;
    }
    /**
     * Locates the next tNode (child, sibling or parent).
     */
    function traverseNextElement(tNode) {
        if (tNode.child) {
            return tNode.child;
        }
        else if (tNode.next) {
            return tNode.next;
        }
        else {
            // Let's take the following template: <div><span>text</span></div><component/>
            // After checking the text node, we need to find the next parent that has a "next" TNode,
            // in this case the parent `div`, so that we can find the component.
            while (tNode.parent && !tNode.parent.next) {
                tNode = tNode.parent;
            }
            return tNode.parent && tNode.parent.next;
        }
    }
    /**
     * Locates the component within the given LView and returns the matching index
     */
    function findViaComponent(lView, componentInstance) {
        var componentIndices = lView[TVIEW].components;
        if (componentIndices) {
            for (var i = 0; i < componentIndices.length; i++) {
                var elementComponentIndex = componentIndices[i];
                var componentView = getComponentViewByIndex(elementComponentIndex, lView);
                if (componentView[CONTEXT] === componentInstance) {
                    return elementComponentIndex;
                }
            }
        }
        else {
            var rootComponentView = getComponentViewByIndex(HEADER_OFFSET, lView);
            var rootComponent = rootComponentView[CONTEXT];
            if (rootComponent === componentInstance) {
                // we are dealing with the root element here therefore we know that the
                // element is the very first element after the HEADER data in the lView
                return HEADER_OFFSET;
            }
        }
        return -1;
    }
    /**
     * Locates the directive within the given LView and returns the matching index
     */
    function findViaDirective(lView, directiveInstance) {
        // if a directive is monkey patched then it will (by default)
        // have a reference to the LView of the current view. The
        // element bound to the directive being search lives somewhere
        // in the view data. We loop through the nodes and check their
        // list of directives for the instance.
        var tNode = lView[TVIEW].firstChild;
        while (tNode) {
            var directiveIndexStart = tNode.directiveStart;
            var directiveIndexEnd = tNode.directiveEnd;
            for (var i = directiveIndexStart; i < directiveIndexEnd; i++) {
                if (lView[i] === directiveInstance) {
                    return tNode.index;
                }
            }
            tNode = traverseNextElement(tNode);
        }
        return -1;
    }
    /**
     * Returns a list of directives extracted from the given view based on the
     * provided list of directive index values.
     *
     * @param nodeIndex The node index
     * @param lView The target view data
     * @param includeComponents Whether or not to include components in returned directives
     */
    function getDirectivesAtNodeIndex(nodeIndex, lView, includeComponents) {
        var tNode = lView[TVIEW].data[nodeIndex];
        var directiveStartIndex = tNode.directiveStart;
        if (directiveStartIndex == 0)
            return EMPTY_ARRAY;
        var directiveEndIndex = tNode.directiveEnd;
        if (!includeComponents && tNode.flags & 1 /* isComponent */)
            directiveStartIndex++;
        return lView.slice(directiveStartIndex, directiveEndIndex);
    }
    function getComponentAtNodeIndex(nodeIndex, lView) {
        var tNode = lView[TVIEW].data[nodeIndex];
        var directiveStartIndex = tNode.directiveStart;
        return tNode.flags & 1 /* isComponent */ ? lView[directiveStartIndex] : null;
    }
    /**
     * Returns a map of local references (local reference name => element or directive instance) that
     * exist on a given element.
     */
    function discoverLocalRefs(lView, nodeIndex) {
        var tNode = lView[TVIEW].data[nodeIndex];
        if (tNode && tNode.localNames) {
            var result = {};
            var localIndex = tNode.index + 1;
            for (var i = 0; i < tNode.localNames.length; i += 2) {
                result[tNode.localNames[i]] = lView[localIndex];
                localIndex++;
            }
            return result;
        }
        return null;
    }

    /** Called when directives inject each other (creating a circular dependency) */
    function throwCyclicDependencyError(token) {
        throw new Error("Cannot instantiate cyclic dependency! " + token);
    }
    /** Called when there are multiple component selectors that match a given node */
    function throwMultipleComponentError(tNode) {
        throw new Error("Multiple components match node with tagname " + tNode.tagName);
    }
    /** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
    function throwErrorIfNoChangesMode(creationMode, oldValue, currValue) {
        var msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
        if (creationMode) {
            msg +=
                " It seems like the view has been created after its parent and its children have been dirty checked." +
                    " Has it been created in a change detection hook ?";
        }
        // TODO: include debug context
        throw new Error(msg);
    }
    function throwMixedMultiProviderError() {
        throw new Error("Cannot mix multi providers and regular providers");
    }
    function throwInvalidProviderError(ngModuleType, providers, provider) {
        var ngModuleDetail = '';
        if (ngModuleType && providers) {
            var providerDetail = providers.map(function (v) { return v == provider ? '?' + provider + '?' : '...'; });
            ngModuleDetail =
                " - only instances of Provider and Type are allowed, got: [" + providerDetail.join(', ') + "]";
        }
        throw new Error("Invalid provider for the NgModule '" + stringify(ngModuleType) + "'" + ngModuleDetail);
    }

    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$4 = 1;

    /**
     * @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
     */
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$5 = 1;

    /**
     * @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
     */
    var unusedValueToPlacateAjd = unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$5;
    var NG_TEMPLATE_SELECTOR = 'ng-template';
    function isCssClassMatching(nodeClassAttrVal, cssClassToMatch) {
        var nodeClassesLen = nodeClassAttrVal.length;
        var matchIndex = nodeClassAttrVal.indexOf(cssClassToMatch);
        var matchEndIdx = matchIndex + cssClassToMatch.length;
        if (matchIndex === -1 // no match
            || (matchIndex > 0 && nodeClassAttrVal[matchIndex - 1] !== ' ') // no space before
            ||
                (matchEndIdx < nodeClassesLen && nodeClassAttrVal[matchEndIdx] !== ' ')) // no space after
         {
            return false;
        }
        return true;
    }
    /**
     * Function that checks whether a given tNode matches tag-based selector and has a valid type.
     *
     * Matching can be performed in 2 modes: projection mode (when we project nodes) and regular
     * directive matching mode:
     * - in the "directive matching" mode we do _not_ take TContainer's tagName into account if it is
     * different from NG_TEMPLATE_SELECTOR (value different from NG_TEMPLATE_SELECTOR indicates that a
     * tag name was extracted from * syntax so we would match the same directive twice);
     * - in the "projection" mode, we use a tag name potentially extracted from the * syntax processing
     * (applicable to TNodeType.Container only).
     */
    function hasTagAndTypeMatch(tNode, currentSelector, isProjectionMode) {
        var tagNameToCompare = tNode.type === 0 /* Container */ && !isProjectionMode ?
            NG_TEMPLATE_SELECTOR :
            tNode.tagName;
        return currentSelector === tagNameToCompare;
    }
    /**
     * A utility function to match an Ivy node static data against a simple CSS selector
     *
     * @param node static data of the node to match
     * @param selector The selector to try matching against the node.
     * @param isProjectionMode if `true` we are matching for content projection, otherwise we are doing
     * directive matching.
     * @returns true if node matches the selector.
     */
    function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
        ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
        var mode = 4 /* ELEMENT */;
        var nodeAttrs = tNode.attrs || [];
        // Find the index of first attribute that has no value, only a name.
        var nameOnlyMarkerIdx = getNameOnlyMarkerIndex(nodeAttrs);
        // When processing ":not" selectors, we skip to the next ":not" if the
        // current one doesn't match
        var skipToNextSelector = false;
        for (var i = 0; i < selector.length; i++) {
            var current = selector[i];
            if (typeof current === 'number') {
                // If we finish processing a :not selector and it hasn't failed, return false
                if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {
                    return false;
                }
                // If we are skipping to the next :not() and this mode flag is positive,
                // it's a part of the current :not() selector, and we should keep skipping
                if (skipToNextSelector && isPositive(current))
                    continue;
                skipToNextSelector = false;
                mode = current | (mode & 1 /* NOT */);
                continue;
            }
            if (skipToNextSelector)
                continue;
            if (mode & 4 /* ELEMENT */) {
                mode = 2 /* ATTRIBUTE */ | mode & 1 /* NOT */;
                if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) ||
                    current === '' && selector.length === 1) {
                    if (isPositive(mode))
                        return false;
                    skipToNextSelector = true;
                }
            }
            else {
                var selectorAttrValue = mode & 8 /* CLASS */ ? current : selector[++i];
                // special case for matching against classes when a tNode has been instantiated with
                // class and style values as separate attribute values (e.g. ['title', CLASS, 'foo'])
                if ((mode & 8 /* CLASS */) && tNode.classes) {
                    if (!isCssClassMatching(getInitialStylingValue(tNode.classes), selectorAttrValue)) {
                        if (isPositive(mode))
                            return false;
                        skipToNextSelector = true;
                    }
                    continue;
                }
                var isInlineTemplate = tNode.type == 0 /* Container */ && tNode.tagName !== NG_TEMPLATE_SELECTOR;
                var attrName = (mode & 8 /* CLASS */) ? 'class' : current;
                var attrIndexInNode = findAttrIndexInNode(attrName, nodeAttrs, isInlineTemplate, isProjectionMode);
                if (attrIndexInNode === -1) {
                    if (isPositive(mode))
                        return false;
                    skipToNextSelector = true;
                    continue;
                }
                if (selectorAttrValue !== '') {
                    var nodeAttrValue = void 0;
                    if (attrIndexInNode > nameOnlyMarkerIdx) {
                        nodeAttrValue = '';
                    }
                    else {
                        ngDevMode && assertNotEqual(nodeAttrs[attrIndexInNode], 0 /* NamespaceURI */, 'We do not match directives on namespaced attributes');
                        nodeAttrValue = nodeAttrs[attrIndexInNode + 1];
                    }
                    var compareAgainstClassName = mode & 8 /* CLASS */ ? nodeAttrValue : null;
                    if (compareAgainstClassName &&
                        !isCssClassMatching(compareAgainstClassName, selectorAttrValue) ||
                        mode & 2 /* ATTRIBUTE */ && selectorAttrValue !== nodeAttrValue) {
                        if (isPositive(mode))
                            return false;
                        skipToNextSelector = true;
                    }
                }
            }
        }
        return isPositive(mode) || skipToNextSelector;
    }
    function isPositive(mode) {
        return (mode & 1 /* NOT */) === 0;
    }
    /**
     * Examines the attribute's definition array for a node to find the index of the
     * attribute that matches the given `name`.
     *
     * NOTE: This will not match namespaced attributes.
     *
     * Attribute matching depends upon `isInlineTemplate` and `isProjectionMode`.
     * The following table summarizes which types of attributes we attempt to match:
     *
     * ===========================================================================================================
     * Modes                   | Normal Attributes | Bindings Attributes | Template Attributes | I18n
     * Attributes
     * ===========================================================================================================
     * Inline + Projection     | YES               | YES                 | NO                  | YES
     * -----------------------------------------------------------------------------------------------------------
     * Inline + Directive      | NO                | NO                  | YES                 | NO
     * -----------------------------------------------------------------------------------------------------------
     * Non-inline + Projection | YES               | YES                 | NO                  | YES
     * -----------------------------------------------------------------------------------------------------------
     * Non-inline + Directive  | YES               | YES                 | NO                  | YES
     * ===========================================================================================================
     *
     * @param name the name of the attribute to find
     * @param attrs the attribute array to examine
     * @param isInlineTemplate true if the node being matched is an inline template (e.g. `*ngFor`)
     * rather than a manually expanded template node (e.g `<ng-template>`).
     * @param isProjectionMode true if we are matching against content projection otherwise we are
     * matching against directives.
     */
    function findAttrIndexInNode(name, attrs, isInlineTemplate, isProjectionMode) {
        if (attrs === null)
            return -1;
        var i = 0;
        if (isProjectionMode || !isInlineTemplate) {
            var bindingsMode = false;
            while (i < attrs.length) {
                var maybeAttrName = attrs[i];
                if (maybeAttrName === name) {
                    return i;
                }
                else if (maybeAttrName === 3 /* Bindings */ || maybeAttrName === 6 /* I18n */) {
                    bindingsMode = true;
                }
                else if (maybeAttrName === 1 /* Classes */) {
                    var value = attrs[++i];
                    // We should skip classes here because we have a separate mechanism for
                    // matching classes in projection mode.
                    while (typeof value === 'string') {
                        value = attrs[++i];
                    }
                    continue;
                }
                else if (maybeAttrName === 4 /* Template */) {
                    // We do not care about Template attributes in this scenario.
                    break;
                }
                else if (maybeAttrName === 0 /* NamespaceURI */) {
                    // Skip the whole namespaced attribute and value. This is by design.
                    i += 4;
                    continue;
                }
                // In binding mode there are only names, rather than name-value pairs.
                i += bindingsMode ? 1 : 2;
            }
            // We did not match the attribute
            return -1;
        }
        else {
            return matchTemplateAttribute(attrs, name);
        }
    }
    function isNodeMatchingSelectorList(tNode, selector, isProjectionMode) {
        if (isProjectionMode === void 0) { isProjectionMode = false; }
        for (var i = 0; i < selector.length; i++) {
            if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) {
                return true;
            }
        }
        return false;
    }
    function getProjectAsAttrValue(tNode) {
        var nodeAttrs = tNode.attrs;
        if (nodeAttrs != null) {
            var ngProjectAsAttrIdx = nodeAttrs.indexOf(5 /* ProjectAs */);
            // only check for ngProjectAs in attribute names, don't accidentally match attribute's value
            // (attribute names are stored at even indexes)
            if ((ngProjectAsAttrIdx & 1) === 0) {
                return nodeAttrs[ngProjectAsAttrIdx + 1];
            }
        }
        return null;
    }
    function getNameOnlyMarkerIndex(nodeAttrs) {
        for (var i = 0; i < nodeAttrs.length; i++) {
            var nodeAttr = nodeAttrs[i];
            if (isNameOnlyAttributeMarker(nodeAttr)) {
                return i;
            }
        }
        return nodeAttrs.length;
    }
    function matchTemplateAttribute(attrs, name) {
        var i = attrs.indexOf(4 /* Template */);
        if (i > -1) {
            i++;
            while (i < attrs.length) {
                if (attrs[i] === name)
                    return i;
                i++;
            }
        }
        return -1;
    }
    /**
     * Checks whether a selector is inside a CssSelectorList
     * @param selector Selector to be checked.
     * @param list List in which to look for the selector.
     */
    function isSelectorInSelectorList(selector, list) {
        selectorListLoop: for (var i = 0; i < list.length; i++) {
            var currentSelectorInList = list[i];
            if (selector.length !== currentSelectorInList.length) {
                continue;
            }
            for (var j = 0; j < selector.length; j++) {
                if (selector[j] !== currentSelectorInList[j]) {
                    continue selectorListLoop;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * --------
     *
     * This file contains the core logic for styling in Angular.
     *
     * All styling bindings (i.e. `[style]`, `[style.prop]`, `[class]` and `[class.name]`)
     * will have their values be applied through the logic in this file.
     *
     * When a binding is encountered (e.g. `<div [style.width]="w">`) then
     * the binding data will be populated into a `TStylingContext` data-structure.
     * There is only one `TStylingContext` per `TNode` and each element instance
     * will update its style/class binding values in concert with the styling
     * context.
     *
     * To learn more about the algorithm see `TStylingContext`.
     *
     * --------
     */
    // The first bit value reflects a map-based binding value's bit.
    // The reason why it's always activated for every entry in the map
    // is so that if any map-binding values update then all other prop
    // based bindings will pass the guard check automatically without
    // any extra code or flags.
    var DEFAULT_GUARD_MASK_VALUE = 1;
    /**
     * The guard/update mask bit index location for map-based bindings.
     *
     * All map-based bindings (i.e. `[style]` and `[class]` )
     */
    var STYLING_INDEX_FOR_MAP_BINDING = 0;
    /**
     * Default fallback value for a styling binding.
     *
     * A value of `null` is used here which signals to the styling algorithm that
     * the styling value is not present. This way if there are no other values
     * detected then it will be removed once the style/class property is dirty and
     * diffed within the styling algorithm present in `flushStyling`.
     */
    var DEFAULT_BINDING_VALUE = null;
    /**
     * Default size count value for a new entry in a context.
     *
     * A value of `1` is used here because each entry in the context has a default
     * property.
     */
    var DEFAULT_SIZE_VALUE = 1;
    var deferredBindingQueue = [];
    /**
     * Visits a class-based binding and updates the new value (if changed).
     *
     * This function is called each time a class-based styling instruction
     * is executed. It's important that it's always called (even if the value
     * has not changed) so that the inner counter index value is incremented.
     * This way, each instruction is always guaranteed to get the same counter
     * state each time it's called (which then allows the `TStylingContext`
     * and the bit mask values to be in sync).
     */
    function updateClassBinding(context, data, element, prop, bindingIndex, value, deferRegistration, forceUpdate) {
        var isMapBased = !prop;
        var state = getStylingState(element, stateIsPersisted(context));
        var index = isMapBased ? STYLING_INDEX_FOR_MAP_BINDING : state.classesIndex++;
        var updated = updateBindingData(context, data, index, prop, bindingIndex, value, deferRegistration, forceUpdate, false);
        if (updated || forceUpdate) {
            // We flip the bit in the bitMask to reflect that the binding
            // at the `index` slot has changed. This identifies to the flushing
            // phase that the bindings for this particular CSS class need to be
            // applied again because on or more of the bindings for the CSS
            // class have changed.
            state.classesBitMask |= 1 << index;
            return true;
        }
        return false;
    }
    /**
     * Visits a style-based binding and updates the new value (if changed).
     *
     * This function is called each time a style-based styling instruction
     * is executed. It's important that it's always called (even if the value
     * has not changed) so that the inner counter index value is incremented.
     * This way, each instruction is always guaranteed to get the same counter
     * state each time it's called (which then allows the `TStylingContext`
     * and the bit mask values to be in sync).
     */
    function updateStyleBinding(context, data, element, prop, bindingIndex, value, sanitizer, deferRegistration, forceUpdate) {
        var isMapBased = !prop;
        var state = getStylingState(element, stateIsPersisted(context));
        var index = isMapBased ? STYLING_INDEX_FOR_MAP_BINDING : state.stylesIndex++;
        var sanitizationRequired = isMapBased ?
            true :
            (sanitizer ? sanitizer(prop, null, 1 /* ValidateProperty */) : false);
        var updated = updateBindingData(context, data, index, prop, bindingIndex, value, deferRegistration, forceUpdate, sanitizationRequired);
        if (updated || forceUpdate) {
            // We flip the bit in the bitMask to reflect that the binding
            // at the `index` slot has changed. This identifies to the flushing
            // phase that the bindings for this particular property need to be
            // applied again because on or more of the bindings for the CSS
            // property have changed.
            state.stylesBitMask |= 1 << index;
            return true;
        }
        return false;
    }
    /**
     * Called each time a binding value has changed within the provided `TStylingContext`.
     *
     * This function is designed to be called from `updateStyleBinding` and `updateClassBinding`.
     * If called during the first update pass, the binding will be registered in the context.
     * If the binding does get registered and the `deferRegistration` flag is true then the
     * binding data will be queued up until the context is later flushed in `applyStyling`.
     *
     * This function will also update binding slot in the provided `LStylingData` with the
     * new binding entry (if it has changed).
     *
     * @returns whether or not the binding value was updated in the `LStylingData`.
     */
    function updateBindingData(context, data, counterIndex, prop, bindingIndex, value, deferRegistration, forceUpdate, sanitizationRequired) {
        if (!isContextLocked(context)) {
            if (deferRegistration) {
                deferBindingRegistration(context, counterIndex, prop, bindingIndex, sanitizationRequired);
            }
            else {
                deferredBindingQueue.length && flushDeferredBindings();
                // this will only happen during the first update pass of the
                // context. The reason why we can't use `tNode.firstTemplatePass`
                // here is because its not guaranteed to be true when the first
                // update pass is executed (remember that all styling instructions
                // are run in the update phase, and, as a result, are no more
                // styling instructions that are run in the creation phase).
                registerBinding(context, counterIndex, prop, bindingIndex, sanitizationRequired);
            }
        }
        var changed = forceUpdate || hasValueChanged(data[bindingIndex], value);
        if (changed) {
            data[bindingIndex] = value;
        }
        return changed;
    }
    /**
     * Schedules a binding registration to be run at a later point.
     *
     * The reasoning for this feature is to ensure that styling
     * bindings are registered in the correct order for when
     * directives/components have a super/sub class inheritance
     * chains. Each directive's styling bindings must be
     * registered into the context in reverse order. Therefore all
     * bindings will be buffered in reverse order and then applied
     * after the inheritance chain exits.
     */
    function deferBindingRegistration(context, counterIndex, prop, bindingIndex, sanitizationRequired) {
        deferredBindingQueue.unshift(context, counterIndex, prop, bindingIndex, sanitizationRequired);
    }
    /**
     * Flushes the collection of deferred bindings and causes each entry
     * to be registered into the context.
     */
    function flushDeferredBindings() {
        var i = 0;
        while (i < deferredBindingQueue.length) {
            var context = deferredBindingQueue[i++];
            var count = deferredBindingQueue[i++];
            var prop = deferredBindingQueue[i++];
            var bindingIndex = deferredBindingQueue[i++];
            var sanitizationRequired = deferredBindingQueue[i++];
            registerBinding(context, count, prop, bindingIndex, sanitizationRequired);
        }
        deferredBindingQueue.length = 0;
    }
    /**
     * Registers the provided binding (prop + bindingIndex) into the context.
     *
     * This function is shared between bindings that are assigned immediately
     * (via `updateBindingData`) and at a deferred stage. When called, it will
     * figure out exactly where to place the binding data in the context.
     *
     * It is needed because it will either update or insert a styling property
     * into the context at the correct spot.
     *
     * When called, one of two things will happen:
     *
     * 1) If the property already exists in the context then it will just add
     *    the provided `bindingValue` to the end of the binding sources region
     *    for that particular property.
     *
     *    - If the binding value is a number then it will be added as a new
     *      binding index source next to the other binding sources for the property.
     *
     *    - Otherwise, if the binding value is a string/boolean/null type then it will
     *      replace the default value for the property if the default value is `null`.
     *
     * 2) If the property does not exist then it will be inserted into the context.
     *    The styling context relies on all properties being stored in alphabetical
     *    order, so it knows exactly where to store it.
     *
     *    When inserted, a default `null` value is created for the property which exists
     *    as the default value for the binding. If the bindingValue property is inserted
     *    and it is either a string, number or null value then that will replace the default
     *    value.
     *
     * Note that this function is also used for map-based styling bindings. They are treated
     * much the same as prop-based bindings, but, because they do not have a property value
     * (since it's a map), all map-based entries are stored in an already populated area of
     * the context at the top (which is reserved for map-based entries).
     */
    function registerBinding(context, countId, prop, bindingValue, sanitizationRequired) {
        var registered = false;
        if (prop) {
            // prop-based bindings (e.g `<div [style.width]="w" [class.foo]="f">`)
            var found = false;
            var i = getPropValuesStartPosition(context);
            while (i < context.length) {
                var valuesCount = getValuesCount(context, i);
                var p = getProp(context, i);
                found = prop <= p;
                if (found) {
                    // all style/class bindings are sorted by property name
                    if (prop < p) {
                        allocateNewContextEntry(context, i, prop, sanitizationRequired);
                    }
                    addBindingIntoContext(context, false, i, bindingValue, countId);
                    break;
                }
                i += 3 /* BindingsStartOffset */ + valuesCount;
            }
            if (!found) {
                allocateNewContextEntry(context, context.length, prop, sanitizationRequired);
                addBindingIntoContext(context, false, i, bindingValue, countId);
                registered = true;
            }
        }
        else {
            // map-based bindings (e.g `<div [style]="s" [class]="{className:true}">`)
            // there is no need to allocate the map-based binding region into the context
            // since it is already there when the context is first created.
            addBindingIntoContext(context, true, 3 /* MapBindingsPosition */, bindingValue, countId);
            registered = true;
        }
        return registered;
    }
    function allocateNewContextEntry(context, index, prop, sanitizationRequired) {
        // 1,2: splice index locations
        // 3: each entry gets a config value (guard mask + flags)
        // 4. each entry gets a size value (which is always one because there is always a default binding
        // value)
        // 5. the property that is getting allocated into the context
        // 6. the default binding value (usually `null`)
        var config = sanitizationRequired ? 1 /* SanitizationRequired */ :
            0 /* Default */;
        context.splice(index, 0, config, DEFAULT_SIZE_VALUE, prop, DEFAULT_BINDING_VALUE);
        setGuardMask(context, index, DEFAULT_GUARD_MASK_VALUE);
    }
    /**
     * Inserts a new binding value into a styling property tuple in the `TStylingContext`.
     *
     * A bindingValue is inserted into a context during the first update pass
     * of a template or host bindings function. When this occurs, two things
     * happen:
     *
     * - If the bindingValue value is a number then it is treated as a bindingIndex
     *   value (a index in the `LView`) and it will be inserted next to the other
     *   binding index entries.
     *
     * - Otherwise the binding value will update the default value for the property
     *   and this will only happen if the default value is `null`.
     *
     * Note that this function also handles map-based bindings and will insert them
     * at the top of the context.
     */
    function addBindingIntoContext(context, isMapBased, index, bindingValue, countId) {
        var valuesCount = getValuesCount(context, index);
        var firstValueIndex = index + 3 /* BindingsStartOffset */;
        var lastValueIndex = firstValueIndex + valuesCount;
        if (!isMapBased) {
            // prop-based values all have default values, but map-based entries do not.
            // we want to access the index for the default value in this case and not just
            // the bindings...
            lastValueIndex--;
        }
        if (typeof bindingValue === 'number') {
            // the loop here will check to see if the binding already exists
            // for the property in the context. Why? The reason for this is
            // because the styling context is not "locked" until the first
            // flush has occurred. This means that if a repeated element
            // registers its styling bindings then it will register each
            // binding more than once (since its duplicated). This check
            // will prevent that from happening. Note that this only happens
            // when a binding is first encountered and not each time it is
            // updated.
            for (var i = firstValueIndex; i <= lastValueIndex; i++) {
                var indexAtPosition = context[i];
                if (indexAtPosition === bindingValue)
                    return;
            }
            context.splice(lastValueIndex, 0, bindingValue);
            context[index + 1 /* ValuesCountOffset */]++;
            // now that a new binding index has been added to the property
            // the guard mask bit value (at the `countId` position) needs
            // to be included into the existing mask value.
            var guardMask = getGuardMask(context, index) | (1 << countId);
            setGuardMask(context, index, guardMask);
        }
        else if (bindingValue !== null && context[lastValueIndex] == null) {
            context[lastValueIndex] = bindingValue;
        }
    }
    /**
     * Applies all pending style and class bindings to the provided element.
     *
     * This function will attempt to flush styling via the provided `classesContext`
     * and `stylesContext` context values. This function is designed to be run from
     * the `stylingApply()` instruction (which is run at the very end of styling
     * change detection) and will rely on any state values that are set from when
     * any styling bindings update.
     *
     * This function may be called multiple times on the same element because it can
     * be called from the template code as well as from host bindings. In order for
     * styling to be successfully flushed to the element (which will only happen once
     * despite this being called multiple times), the following criteria must be met:
     *
     * - `flushStyling` is called from the very last directive that has styling for
     *    the element (see `allowStylingFlush()`).
     * - one or more bindings for classes or styles has updated (this is checked by
     *   examining the classes or styles bit mask).
     *
     * If the style and class values are successfully applied to the element then
     * the temporary state values for the element will be cleared. Otherwise, if
     * this did not occur then the styling state is persisted (see `state.ts` for
     * more information on how this works).
     */
    function flushStyling(renderer, data, classesContext, stylesContext, element, directiveIndex, styleSanitizer) {
        ngDevMode && ngDevMode.flushStyling++;
        var persistState = classesContext ? stateIsPersisted(classesContext) :
            (stylesContext ? stateIsPersisted(stylesContext) : false);
        var allowFlushClasses = allowStylingFlush(classesContext, directiveIndex);
        var allowFlushStyles = allowStylingFlush(stylesContext, directiveIndex);
        // deferred bindings are bindings which are scheduled to register with
        // the context at a later point. These bindings can only registered when
        // the context will be 100% flushed to the element.
        if (deferredBindingQueue.length && (allowFlushClasses || allowFlushStyles)) {
            flushDeferredBindings();
        }
        var state = getStylingState(element, persistState);
        var classesFlushed = maybeApplyStyling(renderer, element, data, classesContext, allowFlushClasses, state.classesBitMask, setClass, null);
        var stylesFlushed = maybeApplyStyling(renderer, element, data, stylesContext, allowFlushStyles, state.stylesBitMask, setStyle, styleSanitizer);
        if (classesFlushed && stylesFlushed) {
            resetStylingState();
            if (persistState) {
                deleteStylingStateFromStorage(element);
            }
        }
        else if (persistState) {
            storeStylingState(element, state);
        }
    }
    function maybeApplyStyling(renderer, element, data, context, allowFlush, bitMask, styleSetter, styleSanitizer) {
        if (allowFlush && context) {
            lockAndFinalizeContext(context);
            if (contextHasUpdates(context, bitMask)) {
                ngDevMode && (styleSanitizer ? ngDevMode.stylesApplied++ : ngDevMode.classesApplied++);
                applyStyling(context, renderer, element, data, bitMask, styleSetter, styleSanitizer);
                return true;
            }
        }
        return allowFlush;
    }
    function contextHasUpdates(context, bitMask) {
        return context && bitMask > BIT_MASK_START_VALUE;
    }
    /**
     * Locks the context (so no more bindings can be added) and also copies over initial class/style
     * values into their binding areas.
     *
     * There are two main actions that take place in this function:
     *
     * - Locking the context:
     *   Locking the context is required so that the style/class instructions know NOT to
     *   register a binding again after the first update pass has run. If a locking bit was
     *   not used then it would need to scan over the context each time an instruction is run
     *   (which is expensive).
     *
     * - Patching initial values:
     *   Directives and component host bindings may include static class/style values which are
     *   bound to the host element. When this happens, the styling context will need to be informed
     *   so it can use these static styling values as defaults when a matching binding is falsy.
     *   These initial styling values are read from the initial styling values slot within the
     *   provided `TStylingContext` (which is an instance of a `StylingMapArray`). This inner map will
     *   be updated each time a host binding applies its static styling values (via `elementHostAttrs`)
     *   so these values are only read at this point because this is the very last point before the
     *   first style/class values are flushed to the element.
     */
    function lockAndFinalizeContext(context) {
        if (!isContextLocked(context)) {
            var initialValues = getStylingMapArray(context);
            if (initialValues) {
                updateInitialStylingOnContext(context, initialValues);
            }
            lockContext(context);
        }
    }
    /**
     * Runs through the provided styling context and applies each value to
     * the provided element (via the renderer) if one or more values are present.
     *
     * This function will iterate over all entries present in the provided
     * `TStylingContext` array (both prop-based and map-based bindings).-
     *
     * Each entry, within the `TStylingContext` array, is stored alphabetically
     * and this means that each prop/value entry will be applied in order
     * (so long as it is marked dirty in the provided `bitMask` value).
     *
     * If there are any map-based entries present (which are applied to the
     * element via the `[style]` and `[class]` bindings) then those entries
     * will be applied as well. However, the code for that is not a part of
     * this function. Instead, each time a property is visited, then the
     * code below will call an external function called `stylingMapsSyncFn`
     * and, if present, it will keep the application of styling values in
     * map-based bindings up to sync with the application of prop-based
     * bindings.
     *
     * Visit `styling_next/map_based_bindings.ts` to learn more about how the
     * algorithm works for map-based styling bindings.
     *
     * Note that this function is not designed to be called in isolation (use
     * `applyClasses` and `applyStyles` to actually apply styling values).
     */
    function applyStyling(context, renderer, element, bindingData, bitMaskValue, applyStylingFn, sanitizer) {
        var bitMask = normalizeBitMaskValue(bitMaskValue);
        var stylingMapsSyncFn = getStylingMapsSyncFn();
        var mapsGuardMask = getGuardMask(context, 3 /* MapBindingsPosition */);
        var applyAllValues = (bitMask & mapsGuardMask) > 0;
        var mapsMode = applyAllValues ? 1 /* ApplyAllValues */ : 0 /* TraverseValues */;
        var i = getPropValuesStartPosition(context);
        while (i < context.length) {
            var valuesCount = getValuesCount(context, i);
            var guardMask = getGuardMask(context, i);
            if (bitMask & guardMask) {
                var valueApplied = false;
                var prop = getProp(context, i);
                var valuesCountUpToDefault = valuesCount - 1;
                var defaultValue = getBindingValue(context, i, valuesCountUpToDefault);
                // case 1: apply prop-based values
                // try to apply the binding values and see if a non-null
                // value gets set for the styling binding
                for (var j = 0; j < valuesCountUpToDefault; j++) {
                    var bindingIndex = getBindingValue(context, i, j);
                    var value = bindingData[bindingIndex];
                    if (isStylingValueDefined(value)) {
                        var finalValue = sanitizer && isSanitizationRequired(context, i) ?
                            sanitizer(prop, value, 2 /* SanitizeOnly */) :
                            value;
                        applyStylingFn(renderer, element, prop, finalValue, bindingIndex);
                        valueApplied = true;
                        break;
                    }
                }
                // case 2: apply map-based values
                // traverse through each map-based styling binding and update all values up to
                // the provided `prop` value. If the property was not applied in the loop above
                // then it will be attempted to be applied in the maps sync code below.
                if (stylingMapsSyncFn) {
                    // determine whether or not to apply the target property or to skip it
                    var mode = mapsMode | (valueApplied ? 4 /* SkipTargetProp */ :
                        2 /* ApplyTargetProp */);
                    var valueAppliedWithinMap = stylingMapsSyncFn(context, renderer, element, bindingData, applyStylingFn, sanitizer, mode, prop, defaultValue);
                    valueApplied = valueApplied || valueAppliedWithinMap;
                }
                // case 3: apply the default value
                // if the value has not yet been applied then a truthy value does not exist in the
                // prop-based or map-based bindings code. If and when this happens, just apply the
                // default value (even if the default value is `null`).
                if (!valueApplied) {
                    applyStylingFn(renderer, element, prop, defaultValue);
                }
            }
            i += 3 /* BindingsStartOffset */ + valuesCount;
        }
        // the map-based styling entries may have not applied all their
        // values. For this reason, one more call to the sync function
        // needs to be issued at the end.
        if (stylingMapsSyncFn) {
            stylingMapsSyncFn(context, renderer, element, bindingData, applyStylingFn, sanitizer, mapsMode);
        }
    }
    function normalizeBitMaskValue(value) {
        // if pass => apply all values (-1 implies that all bits are flipped to true)
        if (value === true)
            return -1;
        // if pass => skip all values
        if (value === false)
            return 0;
        // return the bit mask value as is
        return value;
    }
    var _activeStylingMapApplyFn = null;
    function getStylingMapsSyncFn() {
        return _activeStylingMapApplyFn;
    }
    function setStylingMapsSyncFn(fn) {
        _activeStylingMapApplyFn = fn;
    }
    /**
     * Assigns a style value to a style property for the given element.
     */
    var setStyle = function (renderer, native, prop, value) {
        // the reason why this may be `null` is either because
        // it's a container element or it's a part of a test
        // environment that doesn't have styling. In either
        // case it's safe not to apply styling to the element.
        var nativeStyle = native.style;
        if (value) {
            // opacity, z-index and flexbox all have number values
            // and these need to be converted into strings so that
            // they can be assigned properly.
            value = value.toString();
            ngDevMode && ngDevMode.rendererSetStyle++;
            renderer && isProceduralRenderer(renderer) ?
                renderer.setStyle(native, prop, value, RendererStyleFlags3.DashCase) :
                (nativeStyle && nativeStyle.setProperty(prop, value));
        }
        else {
            ngDevMode && ngDevMode.rendererRemoveStyle++;
            renderer && isProceduralRenderer(renderer) ?
                renderer.removeStyle(native, prop, RendererStyleFlags3.DashCase) :
                (nativeStyle && nativeStyle.removeProperty(prop));
        }
    };
    var ɵ0$4 = setStyle;
    /**
     * Adds/removes the provided className value to the provided element.
     */
    var setClass = function (renderer, native, className, value) {
        if (className !== '') {
            // the reason why this may be `null` is either because
            // it's a container element or it's a part of a test
            // environment that doesn't have styling. In either
            // case it's safe not to apply styling to the element.
            var classList = native.classList;
            if (value) {
                ngDevMode && ngDevMode.rendererAddClass++;
                renderer && isProceduralRenderer(renderer) ? renderer.addClass(native, className) :
                    (classList && classList.add(className));
            }
            else {
                ngDevMode && ngDevMode.rendererRemoveClass++;
                renderer && isProceduralRenderer(renderer) ? renderer.removeClass(native, className) :
                    (classList && classList.remove(className));
            }
        }
    };
    var ɵ1$1 = setClass;
    /**
     * Iterates over all provided styling entries and renders them on the element.
     *
     * This function is used alongside a `StylingMapArray` entry. This entry is not
     * the same as the `TStylingContext` and is only really used when an element contains
     * initial styling values (e.g. `<div style="width:200px">`), but no style/class bindings
     * are present. If and when that happens then this function will be called to render all
     * initial styling values on an element.
     */
    function renderStylingMap(renderer, element, stylingValues, isClassBased) {
        var stylingMapArr = getStylingMapArray(stylingValues);
        if (stylingMapArr) {
            for (var i = 1 /* ValuesStartPosition */; i < stylingMapArr.length; i += 2 /* TupleSize */) {
                var prop = getMapProp(stylingMapArr, i);
                var value = getMapValue(stylingMapArr, i);
                if (isClassBased) {
                    setClass(renderer, element, prop, value, null);
                }
                else {
                    setStyle(renderer, element, prop, value, null);
                }
            }
        }
    }
    /**
     * Registers all initial styling entries into the provided context.
     *
     * This function will iterate over all entries in the provided `initialStyling` ar}ray and register
     * them as default (initial) values in the provided context. Initial styling values in a context are
     * the default values that are to be applied unless overwritten by a binding.
     *
     * The reason why this function exists and isn't a part of the context construction is because
     * host binding is evaluated at a later stage after the element is created. This means that
     * if a directive or component contains any initial styling code (i.e. `<div class="foo">`)
     * then that initial styling data can only be applied once the styling for that element
     * is first applied (at the end of the update phase). Once that happens then the context will
     * update itself with the complete initial styling for the element.
     */
    function updateInitialStylingOnContext(context, initialStyling) {
        // `-1` is used here because all initial styling data is not a spart
        // of a binding (since it's static)
        var INITIAL_STYLING_COUNT_ID = -1;
        for (var i = 1 /* ValuesStartPosition */; i < initialStyling.length; i += 2 /* TupleSize */) {
            var value = getMapValue(initialStyling, i);
            if (value) {
                var prop = getMapProp(initialStyling, i);
                registerBinding(context, INITIAL_STYLING_COUNT_ID, prop, value, false);
            }
        }
    }

    /**
     * @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
     */
    /** A special value which designates that a value has not changed. */
    var NO_CHANGE = {};

    /**
     * @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
     */
    /**
     * Marks that the next string is for element.
     *
     * See `I18nMutateOpCodes` documentation.
     */
    var ELEMENT_MARKER = {
        marker: 'element'
    };
    /**
     * Marks that the next string is for comment.
     *
     * See `I18nMutateOpCodes` documentation.
     */
    var COMMENT_MARKER = {
        marker: 'comment'
    };
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$6 = 1;

    /**
     * @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
     */
    function attachDebugObject(obj, debug) {
        Object.defineProperty(obj, 'debug', { value: debug, enumerable: false });
    }

    /**
     * --------
     *
     * This file contains the algorithm logic for applying map-based bindings
     * such as `[style]` and `[class]`.
     *
     * --------
     */
    /**
     * Used to apply styling values presently within any map-based bindings on an element.
     *
     * Angular supports map-based styling bindings which can be applied via the
     * `[style]` and `[class]` bindings which can be placed on any HTML element.
     * These bindings can work independently, together or alongside prop-based
     * styling bindings (e.g. `<div [style]="x" [style.width]="w">`).
     *
     * If a map-based styling binding is detected by the compiler, the following
     * AOT code is produced:
     *
     * ```typescript
     * styleMap(ctx.styles); // styles = {key:value}
     * classMap(ctx.classes); // classes = {key:value}|string
     * ```
     *
     * If and when either of the instructions above are evaluated, then the code
     * present in this file is included into the bundle. The mechanism used, to
     * activate support for map-based bindings at runtime is possible via the
     * `activeStylingMapFeature` function (which is also present in this file).
     *
     * # The Algorithm
     * Whenever a map-based binding updates (which is when the identity of the
     * map-value changes) then the map is iterated over and a `StylingMapArray` array
     * is produced. The `StylingMapArray` instance is stored in the binding location
     * where the `BINDING_INDEX` is situated when the `styleMap()` or `classMap()`
     * instruction were called. Once the binding changes, then the internal `bitMask`
     * value is marked as dirty.
     *
     * Styling values are applied once CD exits the element (which happens when
     * the `select(n)` instruction is called or the template function exits). When
     * this occurs, all prop-based bindings are applied. If a map-based binding is
     * present then a special flushing function (called a sync function) is made
     * available and it will be called each time a styling property is flushed.
     *
     * The flushing algorithm is designed to apply styling for a property (which is
     * a CSS property or a className value) one by one. If map-based bindings
     * are present, then the flushing algorithm will keep calling the maps styling
     * sync function each time a property is visited. This way, the flushing
     * behavior of map-based bindings will always be at the same property level
     * as the current prop-based property being iterated over (because everything
     * is alphabetically sorted).
     *
     * Let's imagine we have the following HTML template code:
     *
     * ```html
     * <div [style]="{width:'100px', height:'200px', 'z-index':'10'}"
     *      [style.width.px]="200">...</div>
     * ```
     *
     * When CD occurs, both the `[style]` and `[style.width]` bindings
     * are evaluated. Then when the styles are flushed on screen, the
     * following operations happen:
     *
     * 1. `[style.width]` is attempted to be written to the element.
     *
     * 2.  Once that happens, the algorithm instructs the map-based
     *     entries (`[style]` in this case) to "catch up" and apply
     *     all values up to the `width` value. When this happens the
     *     `height` value is applied to the element (since it is
     *     alphabetically situated before the `width` property).
     *
     * 3. Since there are no more prop-based entries anymore, the
     *    loop exits and then, just before the flushing ends, it
     *    instructs all map-based bindings to "finish up" applying
     *    their values.
     *
     * 4. The only remaining value within the map-based entries is
     *    the `z-index` value (`width` got skipped because it was
     *    successfully applied via the prop-based `[style.width]`
     *    binding). Since all map-based entries are told to "finish up",
     *    the `z-index` value is iterated over and it is then applied
     *    to the element.
     *
     * The most important thing to take note of here is that prop-based
     * bindings are evaluated in order alongside map-based bindings.
     * This allows all styling across an element to be applied in O(n)
     * time (a similar algorithm is that of the array merge algorithm
     * in merge sort).
     */
    var syncStylingMap = function (context, renderer, element, data, applyStylingFn, sanitizer, mode, targetProp, defaultValue) {
        var targetPropValueWasApplied = false;
        // once the map-based styling code is activate it is never deactivated. For this reason a
        // check to see if the current styling context has any map based bindings is required.
        var totalMaps = getValuesCount(context, 3 /* MapBindingsPosition */);
        if (totalMaps) {
            var runTheSyncAlgorithm = true;
            var loopUntilEnd = !targetProp;
            // If the code is told to finish up (run until the end), but the mode
            // hasn't been flagged to apply values (it only traverses values) then
            // there is no point in iterating over the array because nothing will
            // be applied to the element.
            if (loopUntilEnd && (mode & ~1 /* ApplyAllValues */)) {
                runTheSyncAlgorithm = false;
                targetPropValueWasApplied = true;
            }
            if (runTheSyncAlgorithm) {
                targetPropValueWasApplied = innerSyncStylingMap(context, renderer, element, data, applyStylingFn, sanitizer, mode, targetProp || null, 0, defaultValue || null);
            }
            if (loopUntilEnd) {
                resetSyncCursors();
            }
        }
        return targetPropValueWasApplied;
    };
    /**
     * Recursive function designed to apply map-based styling to an element one map at a time.
     *
     * This function is designed to be called from the `syncStylingMap` function and will
     * apply map-based styling data one map at a time to the provided `element`.
     *
     * This function is recursive and it will call itself if a follow-up map value is to be
     * processed. To learn more about how the algorithm works, see `syncStylingMap`.
     */
    function innerSyncStylingMap(context, renderer, element, data, applyStylingFn, sanitizer, mode, targetProp, currentMapIndex, defaultValue) {
        var targetPropValueWasApplied = false;
        var totalMaps = getValuesCount(context, 3 /* MapBindingsPosition */);
        if (currentMapIndex < totalMaps) {
            var bindingIndex = getBindingValue(context, 3 /* MapBindingsPosition */, currentMapIndex);
            var stylingMapArr = data[bindingIndex];
            var cursor = getCurrentSyncCursor(currentMapIndex);
            while (cursor < stylingMapArr.length) {
                var prop = getMapProp(stylingMapArr, cursor);
                var iteratedTooFar = targetProp && prop > targetProp;
                var isTargetPropMatched = !iteratedTooFar && prop === targetProp;
                var value = getMapValue(stylingMapArr, cursor);
                var valueIsDefined = isStylingValueDefined(value);
                // the recursive code is designed to keep applying until
                // it reaches or goes past the target prop. If and when
                // this happens then it will stop processing values, but
                // all other map values must also catch up to the same
                // point. This is why a recursive call is still issued
                // even if the code has iterated too far.
                var innerMode = iteratedTooFar ? mode : resolveInnerMapMode(mode, valueIsDefined, isTargetPropMatched);
                var innerProp = iteratedTooFar ? targetProp : prop;
                var valueApplied = innerSyncStylingMap(context, renderer, element, data, applyStylingFn, sanitizer, innerMode, innerProp, currentMapIndex + 1, defaultValue);
                if (iteratedTooFar) {
                    if (!targetPropValueWasApplied) {
                        targetPropValueWasApplied = valueApplied;
                    }
                    break;
                }
                if (!valueApplied && isValueAllowedToBeApplied(mode, isTargetPropMatched)) {
                    var useDefault = isTargetPropMatched && !valueIsDefined;
                    var valueToApply = useDefault ? defaultValue : value;
                    var bindingIndexToApply = useDefault ? bindingIndex : null;
                    var finalValue = sanitizer ?
                        sanitizer(prop, valueToApply, 3 /* ValidateAndSanitize */) :
                        valueToApply;
                    applyStylingFn(renderer, element, prop, finalValue, bindingIndexToApply);
                    valueApplied = true;
                }
                targetPropValueWasApplied = valueApplied && isTargetPropMatched;
                cursor += 2 /* TupleSize */;
            }
            setCurrentSyncCursor(currentMapIndex, cursor);
            // this is a fallback case in the event that the styling map is `null` for this
            // binding but there are other map-based bindings that need to be evaluated
            // afterwards. If the `prop` value is falsy then the intention is to cycle
            // through all of the properties in the remaining maps as well. If the current
            // styling map is too short then there are no values to iterate over. In either
            // case the follow-up maps need to be iterated over.
            if (stylingMapArr.length === 1 /* ValuesStartPosition */ || !targetProp) {
                return innerSyncStylingMap(context, renderer, element, data, applyStylingFn, sanitizer, mode, targetProp, currentMapIndex + 1, defaultValue);
            }
        }
        return targetPropValueWasApplied;
    }
    /**
     * Enables support for map-based styling bindings (e.g. `[style]` and `[class]` bindings).
     */
    function activateStylingMapFeature() {
        setStylingMapsSyncFn(syncStylingMap);
    }
    /**
     * Used to determine the mode for the inner recursive call.
     *
     * If an inner map is iterated on then this is done so for one
     * of two reasons:
     *
     * - value is being applied:
     *   if the value is being applied from this current styling
     *   map then there is no need to apply it in a deeper map.
     *
     * - value is being not applied:
     *   apply the value if it is found in a deeper map.
     *
     * When these reasons are encountered the flags will for the
     * inner map mode will be configured.
     */
    function resolveInnerMapMode(currentMode, valueIsDefined, isExactMatch) {
        var innerMode = currentMode;
        if (!valueIsDefined && !(currentMode & 4 /* SkipTargetProp */) &&
            (isExactMatch || (currentMode & 1 /* ApplyAllValues */))) {
            // case 1: set the mode to apply the targeted prop value if it
            // ends up being encountered in another map value
            innerMode |= 2 /* ApplyTargetProp */;
            innerMode &= ~4 /* SkipTargetProp */;
        }
        else {
            // case 2: set the mode to skip the targeted prop value if it
            // ends up being encountered in another map value
            innerMode |= 4 /* SkipTargetProp */;
            innerMode &= ~2 /* ApplyTargetProp */;
        }
        return innerMode;
    }
    /**
     * Decides whether or not a prop/value entry will be applied to an element.
     *
     * To determine whether or not a value is to be applied,
     * the following procedure is evaluated:
     *
     * First check to see the current `mode` status:
     *  1. If the mode value permits all props to be applied then allow.
     *    - But do not allow if the current prop is set to be skipped.
     *  2. Otherwise if the current prop is permitted then allow.
     */
    function isValueAllowedToBeApplied(mode, isTargetPropMatched) {
        var doApplyValue = (mode & 1 /* ApplyAllValues */) > 0;
        if (!doApplyValue) {
            if (mode & 2 /* ApplyTargetProp */) {
                doApplyValue = isTargetPropMatched;
            }
        }
        else if ((mode & 4 /* SkipTargetProp */) && isTargetPropMatched) {
            doApplyValue = false;
        }
        return doApplyValue;
    }
    /**
     * Used to keep track of concurrent cursor values for multiple map-based styling bindings present on
     * an element.
     */
    var MAP_CURSORS = [];
    /**
     * Used to reset the state of each cursor value being used to iterate over map-based styling
     * bindings.
     */
    function resetSyncCursors() {
        for (var i = 0; i < MAP_CURSORS.length; i++) {
            MAP_CURSORS[i] = 1 /* ValuesStartPosition */;
        }
    }
    /**
     * Returns an active cursor value at a given mapIndex location.
     */
    function getCurrentSyncCursor(mapIndex) {
        if (mapIndex >= MAP_CURSORS.length) {
            MAP_CURSORS.push(1 /* ValuesStartPosition */);
        }
        return MAP_CURSORS[mapIndex];
    }
    /**
     * Sets a cursor value at a given mapIndex location.
     */
    function setCurrentSyncCursor(mapIndex, indexValue) {
        MAP_CURSORS[mapIndex] = indexValue;
    }
    /**
     * Used to convert a {key:value} map into a `StylingMapArray` array.
     *
     * This function will either generate a new `StylingMapArray` instance
     * or it will patch the provided `newValues` map value into an
     * existing `StylingMapArray` value (this only happens if `bindingValue`
     * is an instance of `StylingMapArray`).
     *
     * If a new key/value map is provided with an old `StylingMapArray`
     * value then all properties will be overwritten with their new
     * values or with `null`. This means that the array will never
     * shrink in size (but it will also not be created and thrown
     * away whenever the {key:value} map entries change).
     */
    function normalizeIntoStylingMap(bindingValue, newValues, normalizeProps) {
        var stylingMapArr = Array.isArray(bindingValue) ? bindingValue : [null];
        stylingMapArr[0 /* RawValuePosition */] = newValues || null;
        // because the new values may not include all the properties
        // that the old ones had, all values are set to `null` before
        // the new values are applied. This way, when flushed, the
        // styling algorithm knows exactly what style/class values
        // to remove from the element (since they are `null`).
        for (var j = 1 /* ValuesStartPosition */; j < stylingMapArr.length; j += 2 /* TupleSize */) {
            setMapValue(stylingMapArr, j, null);
        }
        var props = null;
        var map;
        var allValuesTrue = false;
        if (typeof newValues === 'string') { // [class] bindings allow string values
            if (newValues.length) {
                props = newValues.split(/\s+/);
                allValuesTrue = true;
            }
        }
        else {
            props = newValues ? Object.keys(newValues) : null;
            map = newValues;
        }
        if (props) {
            for (var i = 0; i < props.length; i++) {
                var prop = props[i];
                var newProp = normalizeProps ? hyphenate(prop) : prop;
                var value = allValuesTrue ? true : map[prop];
                addItemToStylingMap(stylingMapArr, newProp, value, true);
            }
        }
        return stylingMapArr;
    }
    /**
     * Inserts the provided item into the provided styling array at the right spot.
     *
     * The `StylingMapArray` type is a sorted key/value array of entries. This means
     * that when a new entry is inserted it must be placed at the right spot in the
     * array. This function figures out exactly where to place it.
     */
    function addItemToStylingMap(stylingMapArr, prop, value, allowOverwrite) {
        for (var j = 1 /* ValuesStartPosition */; j < stylingMapArr.length; j += 2 /* TupleSize */) {
            var propAtIndex = getMapProp(stylingMapArr, j);
            if (prop <= propAtIndex) {
                var applied = false;
                if (propAtIndex === prop) {
                    var valueAtIndex = stylingMapArr[j];
                    if (allowOverwrite || !isStylingValueDefined(valueAtIndex)) {
                        applied = true;
                        setMapValue(stylingMapArr, j, value);
                    }
                }
                else {
                    applied = true;
                    stylingMapArr.splice(j, 0, prop, value);
                }
                return applied;
            }
        }
        stylingMapArr.push(prop, value);
        return true;
    }
    /**
     * Converts the provided styling map array into a string.
     *
     * Classes => `one two three`
     * Styles => `prop:value; prop2:value2`
     */
    function stylingMapToString(map, isClassBased) {
        var str = '';
        for (var i = 1 /* ValuesStartPosition */; i < map.length; i += 2 /* TupleSize */) {
            var prop = getMapProp(map, i);
            var value = getMapValue(map, i);
            var attrValue = concatString(prop, isClassBased ? '' : value, ':');
            str = concatString(str, attrValue, isClassBased ? ' ' : '; ');
        }
        return str;
    }
    /**
     * Converts the provided styling map array into a key value map.
     */
    function stylingMapToStringMap(map) {
        var stringMap = {};
        if (map) {
            for (var i = 1 /* ValuesStartPosition */; i < map.length; i += 2 /* TupleSize */) {
                var prop = getMapProp(map, i);
                var value = getMapValue(map, i);
                stringMap[prop] = value;
            }
        }
        return stringMap;
    }

    /**
     * Instantiates and attaches an instance of `TStylingContextDebug` to the provided context.
     */
    function attachStylingDebugObject(context) {
        var debug = new TStylingContextDebug(context);
        attachDebugObject(context, debug);
        return debug;
    }
    /**
     * A human-readable debug summary of the styling data present within `TStylingContext`.
     *
     * This class is designed to be used within testing code or when an
     * application has `ngDevMode` activated.
     */
    var TStylingContextDebug = /** @class */ (function () {
        function TStylingContextDebug(context) {
            this.context = context;
        }
        Object.defineProperty(TStylingContextDebug.prototype, "isLocked", {
            get: function () { return isContextLocked(this.context); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TStylingContextDebug.prototype, "entries", {
            /**
             * Returns a detailed summary of each styling entry in the context.
             *
             * See `TStylingTupleSummary`.
             */
            get: function () {
                var context = this.context;
                var entries = {};
                var start = 3 /* MapBindingsPosition */;
                var i = start;
                while (i < context.length) {
                    var valuesCount = getValuesCount(context, i);
                    // the context may contain placeholder values which are populated ahead of time,
                    // but contain no actual binding values. In this situation there is no point in
                    // classifying this as an "entry" since no real data is stored here yet.
                    if (valuesCount) {
                        var prop = getProp(context, i);
                        var guardMask = getGuardMask(context, i);
                        var defaultValue = getDefaultValue(context, i);
                        var sanitizationRequired = isSanitizationRequired(context, i);
                        var bindingsStartPosition = i + 3 /* BindingsStartOffset */;
                        var sources = [];
                        for (var j = 0; j < valuesCount; j++) {
                            sources.push(context[bindingsStartPosition + j]);
                        }
                        entries[prop] = { prop: prop, guardMask: guardMask, sanitizationRequired: sanitizationRequired, valuesCount: valuesCount, defaultValue: defaultValue, sources: sources };
                    }
                    i += 3 /* BindingsStartOffset */ + valuesCount;
                }
                return entries;
            },
            enumerable: true,
            configurable: true
        });
        return TStylingContextDebug;
    }());
    /**
     * A human-readable debug summary of the styling data present for a `DebugNode` instance.
     *
     * This class is designed to be used within testing code or when an
     * application has `ngDevMode` activated.
     */
    var NodeStylingDebug = /** @class */ (function () {
        function NodeStylingDebug(context, _data, _isClassBased) {
            this.context = context;
            this._data = _data;
            this._isClassBased = _isClassBased;
            this._sanitizer = null;
        }
        /**
         * Overrides the sanitizer used to process styles.
         */
        NodeStylingDebug.prototype.overrideSanitizer = function (sanitizer) { this._sanitizer = sanitizer; };
        Object.defineProperty(NodeStylingDebug.prototype, "summary", {
            /**
             * Returns a detailed summary of each styling entry in the context and
             * what their runtime representation is.
             *
             * See `LStylingSummary`.
             */
            get: function () {
                var entries = {};
                this._mapValues(function (prop, value, bindingIndex) {
                    entries[prop] = { prop: prop, value: value, bindingIndex: bindingIndex };
                });
                return entries;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NodeStylingDebug.prototype, "values", {
            /**
             * Returns a key/value map of all the styles/classes that were last applied to the element.
             */
            get: function () {
                var entries = {};
                this._mapValues(function (prop, value) { entries[prop] = value; });
                return entries;
            },
            enumerable: true,
            configurable: true
        });
        NodeStylingDebug.prototype._mapValues = function (fn) {
            // there is no need to store/track an element instance. The
            // element is only used when the styling algorithm attempts to
            // style the value (and we mock out the stylingApplyFn anyway).
            var mockElement = {};
            var hasMaps = getValuesCount(this.context, 3 /* MapBindingsPosition */) > 0;
            if (hasMaps) {
                activateStylingMapFeature();
            }
            var mapFn = function (renderer, element, prop, value, bindingIndex) { fn(prop, value, bindingIndex || null); };
            var sanitizer = this._isClassBased ? null : (this._sanitizer || getCurrentStyleSanitizer());
            applyStyling(this.context, null, mockElement, this._data, true, mapFn, sanitizer);
        };
        return NodeStylingDebug;
    }());

    /**
     * @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 contains conditionally attached classes which provide human readable (debug) level
     * information for `LView`, `LContainer` and other internal data structures. These data structures
     * are stored internally as array which makes it very difficult during debugging to reason about the
     * current state of the system.
     *
     * Patching the array with extra property does change the array's hidden class' but it does not
     * change the cost of access, therefore this patching should not have significant if any impact in
     * `ngDevMode` mode. (see: https://jsperf.com/array-vs-monkey-patch-array)
     *
     * So instead of seeing:
     * ```
     * Array(30) [Object, 659, null, …]
     * ```
     *
     * You get to see:
     * ```
     * LViewDebug {
     *   views: [...],
     *   flags: {attached: true, ...}
     *   nodes: [
     *     {html: '<div id="123">', ..., nodes: [
     *       {html: '<span>', ..., nodes: null}
     *     ]}
     *   ]
     * }
     * ```
     */
    var LViewArray = ngDevMode && createNamedArrayType('LView');
    var LVIEW_EMPTY; // can't initialize here or it will not be tree shaken, because `LView`
    // constructor could have side-effects.
    /**
     * This function clones a blueprint and creates LView.
     *
     * Simple slice will keep the same type, and we need it to be LView
     */
    function cloneToLView(list) {
        if (LVIEW_EMPTY === undefined)
            LVIEW_EMPTY = new LViewArray();
        return LVIEW_EMPTY.concat(list);
    }
    /**
     * This class is a debug version of Object literal so that we can have constructor name show up in
     * debug tools in ngDevMode.
     */
    var TViewConstructor = /** @class */ (function () {
        function TView(id, //
        blueprint, //
        template, //
        queries, //
        viewQuery, //
        node, //
        data, //
        bindingStartIndex, //
        expandoStartIndex, //
        expandoInstructions, //
        firstTemplatePass, //
        staticViewQueries, //
        staticContentQueries, //
        preOrderHooks, //
        preOrderCheckHooks, //
        contentHooks, //
        contentCheckHooks, //
        viewHooks, //
        viewCheckHooks, //
        destroyHooks, //
        cleanup, //
        contentQueries, //
        components, //
        directiveRegistry, //
        pipeRegistry, //
        firstChild, //
        schemas) {
            this.id = id;
            this.blueprint = blueprint;
            this.template = template;
            this.queries = queries;
            this.viewQuery = viewQuery;
            this.node = node;
            this.data = data;
            this.bindingStartIndex = bindingStartIndex;
            this.expandoStartIndex = expandoStartIndex;
            this.expandoInstructions = expandoInstructions;
            this.firstTemplatePass = firstTemplatePass;
            this.staticViewQueries = staticViewQueries;
            this.staticContentQueries = staticContentQueries;
            this.preOrderHooks = preOrderHooks;
            this.preOrderCheckHooks = preOrderCheckHooks;
            this.contentHooks = contentHooks;
            this.contentCheckHooks = contentCheckHooks;
            this.viewHooks = viewHooks;
            this.viewCheckHooks = viewCheckHooks;
            this.destroyHooks = destroyHooks;
            this.cleanup = cleanup;
            this.contentQueries = contentQueries;
            this.components = components;
            this.directiveRegistry = directiveRegistry;
            this.pipeRegistry = pipeRegistry;
            this.firstChild = firstChild;
            this.schemas = schemas;
        }
        return TView;
    }());
    var TNodeConstructor = /** @class */ (function () {
        function TNode(tView_, //
        type, //
        index, //
        injectorIndex, //
        directiveStart, //
        directiveEnd, //
        propertyMetadataStartIndex, //
        propertyMetadataEndIndex, //
        flags, //
        providerIndexes, //
        tagName, //
        attrs, //
        localNames, //
        initialInputs, //
        inputs, //
        outputs, //
        tViews, //
        next, //
        projectionNext, //
        child, //
        parent, //
        projection, //
        styles, //
        classes) {
            this.tView_ = tView_;
            this.type = type;
            this.index = index;
            this.injectorIndex = injectorIndex;
            this.directiveStart = directiveStart;
            this.directiveEnd = directiveEnd;
            this.propertyMetadataStartIndex = propertyMetadataStartIndex;
            this.propertyMetadataEndIndex = propertyMetadataEndIndex;
            this.flags = flags;
            this.providerIndexes = providerIndexes;
            this.tagName = tagName;
            this.attrs = attrs;
            this.localNames = localNames;
            this.initialInputs = initialInputs;
            this.inputs = inputs;
            this.outputs = outputs;
            this.tViews = tViews;
            this.next = next;
            this.projectionNext = projectionNext;
            this.child = child;
            this.parent = parent;
            this.projection = projection;
            this.styles = styles;
            this.classes = classes;
        }
        Object.defineProperty(TNode.prototype, "type_", {
            get: function () {
                switch (this.type) {
                    case 0 /* Container */:
                        return 'TNodeType.Container';
                    case 3 /* Element */:
                        return 'TNodeType.Element';
                    case 4 /* ElementContainer */:
                        return 'TNodeType.ElementContainer';
                    case 5 /* IcuContainer */:
                        return 'TNodeType.IcuContainer';
                    case 1 /* Projection */:
                        return 'TNodeType.Projection';
                    case 2 /* View */:
                        return 'TNodeType.View';
                    default:
                        return 'TNodeType.???';
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TNode.prototype, "flags_", {
            get: function () {
                var flags = [];
                if (this.flags & 8 /* hasClassInput */)
                    flags.push('TNodeFlags.hasClassInput');
                if (this.flags & 4 /* hasContentQuery */)
                    flags.push('TNodeFlags.hasContentQuery');
                if (this.flags & 16 /* hasStyleInput */)
                    flags.push('TNodeFlags.hasStyleInput');
                if (this.flags & 1 /* isComponent */)
                    flags.push('TNodeFlags.isComponent');
                if (this.flags & 32 /* isDetached */)
                    flags.push('TNodeFlags.isDetached');
                if (this.flags & 2 /* isProjected */)
                    flags.push('TNodeFlags.isProjected');
                return flags.join('|');
            },
            enumerable: true,
            configurable: true
        });
        return TNode;
    }());
    var TViewData = ngDevMode && createNamedArrayType('TViewData');
    var TVIEWDATA_EMPTY; // can't initialize here or it will not be tree shaken, because `LView`
    // constructor could have side-effects.
    /**
     * This function clones a blueprint and creates TData.
     *
     * Simple slice will keep the same type, and we need it to be TData
     */
    function cloneToTViewData(list) {
        if (TVIEWDATA_EMPTY === undefined)
            TVIEWDATA_EMPTY = new TViewData();
        return TVIEWDATA_EMPTY.concat(list);
    }
    var LViewBlueprint = ngDevMode && createNamedArrayType('LViewBlueprint');
    var MatchesArray = ngDevMode && createNamedArrayType('MatchesArray');
    var TViewComponents = ngDevMode && createNamedArrayType('TViewComponents');
    var TNodeLocalNames = ngDevMode && createNamedArrayType('TNodeLocalNames');
    var TNodeInitialInputs = ngDevMode && createNamedArrayType('TNodeInitialInputs');
    var TNodeInitialData = ngDevMode && createNamedArrayType('TNodeInitialData');
    var LCleanup = ngDevMode && createNamedArrayType('LCleanup');
    var TCleanup = ngDevMode && createNamedArrayType('TCleanup');
    function attachLViewDebug(lView) {
        attachDebugObject(lView, new LViewDebug(lView));
    }
    function attachLContainerDebug(lContainer) {
        attachDebugObject(lContainer, new LContainerDebug(lContainer));
    }
    function toDebug(obj) {
        if (obj) {
            var debug = obj.debug;
            assertDefined(debug, 'Object does not have a debug representation.');
            return debug;
        }
        else {
            return obj;
        }
    }
    /**
     * Use this method to unwrap a native element in `LView` and convert it into HTML for easier
     * reading.
     *
     * @param value possibly wrapped native DOM node.
     * @param includeChildren If `true` then the serialized HTML form will include child elements (same
     * as `outerHTML`). If `false` then the serialized HTML form will only contain the element itself
     * (will not serialize child elements).
     */
    function toHtml(value, includeChildren) {
        if (includeChildren === void 0) { includeChildren = false; }
        var node = unwrapRNode(value);
        if (node) {
            var isTextNode = node.nodeType === Node.TEXT_NODE;
            var outerHTML = (isTextNode ? node.textContent : node.outerHTML) || '';
            if (includeChildren || isTextNode) {
                return outerHTML;
            }
            else {
                var innerHTML = node.innerHTML;
                return outerHTML.split(innerHTML)[0] || null;
            }
        }
        else {
            return null;
        }
    }
    var LViewDebug = /** @class */ (function () {
        function LViewDebug(_raw_lView) {
            this._raw_lView = _raw_lView;
        }
        Object.defineProperty(LViewDebug.prototype, "flags", {
            /**
             * Flags associated with the `LView` unpacked into a more readable state.
             */
            get: function () {
                var flags = this._raw_lView[FLAGS];
                return {
                    __raw__flags__: flags,
                    initPhaseState: flags & 3 /* InitPhaseStateMask */,
                    creationMode: !!(flags & 4 /* CreationMode */),
                    firstViewPass: !!(flags & 8 /* FirstLViewPass */),
                    checkAlways: !!(flags & 16 /* CheckAlways */),
                    dirty: !!(flags & 64 /* Dirty */),
                    attached: !!(flags & 128 /* Attached */),
                    destroyed: !!(flags & 256 /* Destroyed */),
                    isRoot: !!(flags & 512 /* IsRoot */),
                    indexWithinInitPhase: flags >> 10 /* IndexWithinInitPhaseShift */,
                };
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LViewDebug.prototype, "parent", {
            get: function () { return toDebug(this._raw_lView[PARENT]); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LViewDebug.prototype, "host", {
            get: function () { return toHtml(this._raw_lView[HOST], true); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LViewDebug.prototype, "context", {
            get: function () { return this._raw_lView[CONTEXT]; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LViewDebug.prototype, "nodes", {
            /**
             * The tree of nodes associated with the current `LView`. The nodes have been normalized into a
             * tree structure with relevant details pulled out for readability.
             */
            get: function () {
                var lView = this._raw_lView;
                var tNode = lView[TVIEW].firstChild;
                return toDebugNodes(tNode, lView);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LViewDebug.prototype, "__other__", {
            /**
             * Additional information which is hidden behind a property. The extra level of indirection is
             * done so that the debug view would not be cluttered with properties which are only rarely
             * relevant to the developer.
             */
            get: function () {
                return {
                    tView: this._raw_lView[TVIEW],
                    cleanup: this._raw_lView[CLEANUP],
                    injector: this._raw_lView[INJECTOR$1],
                    rendererFactory: this._raw_lView[RENDERER_FACTORY],
                    renderer: this._raw_lView[RENDERER],
                    sanitizer: this._raw_lView[SANITIZER],
                    childHead: toDebug(this._raw_lView[CHILD_HEAD]),
                    next: toDebug(this._raw_lView[NEXT]),
                    childTail: toDebug(this._raw_lView[CHILD_TAIL]),
                    declarationView: toDebug(this._raw_lView[DECLARATION_VIEW]),
                    queries: null,
                    tHost: this._raw_lView[T_HOST],
                    bindingIndex: this._raw_lView[BINDING_INDEX],
                };
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LViewDebug.prototype, "childViews", {
            /**
             * Normalized view of child views (and containers) attached at this location.
             */
            get: function () {
                var childViews = [];
                var child = this.__other__.childHead;
                while (child) {
                    childViews.push(child);
                    child = child.__other__.next;
                }
                return childViews;
            },
            enumerable: true,
            configurable: true
        });
        return LViewDebug;
    }());
    /**
     * Turns a flat list of nodes into a tree by walking the associated `TNode` tree.
     *
     * @param tNode
     * @param lView
     */
    function toDebugNodes(tNode, lView) {
        if (tNode) {
            var debugNodes = [];
            var tNodeCursor = tNode;
            while (tNodeCursor) {
                var rawValue = lView[tNode.index];
                var native = unwrapRNode(rawValue);
                var componentLViewDebug = toDebug(readLViewValue(rawValue));
                var styles = isStylingContext(tNode.styles) ?
                    new NodeStylingDebug(tNode.styles, lView) :
                    null;
                var classes = isStylingContext(tNode.classes) ?
                    new NodeStylingDebug(tNode.classes, lView, true) :
                    null;
                debugNodes.push({
                    html: toHtml(native),
                    native: native, styles: styles, classes: classes,
                    nodes: toDebugNodes(tNode.child, lView),
                    component: componentLViewDebug,
                });
                tNodeCursor = tNodeCursor.next;
            }
            return debugNodes;
        }
        else {
            return null;
        }
    }
    var LContainerDebug = /** @class */ (function () {
        function LContainerDebug(_raw_lContainer) {
            this._raw_lContainer = _raw_lContainer;
        }
        Object.defineProperty(LContainerDebug.prototype, "activeIndex", {
            get: function () { return this._raw_lContainer[ACTIVE_INDEX]; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LContainerDebug.prototype, "views", {
            get: function () {
                return this._raw_lContainer.slice(CONTAINER_HEADER_OFFSET)
                    .map(toDebug);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LContainerDebug.prototype, "parent", {
            get: function () { return toDebug(this._raw_lContainer[PARENT]); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LContainerDebug.prototype, "movedViews", {
            get: function () { return this._raw_lContainer[MOVED_VIEWS]; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LContainerDebug.prototype, "host", {
            get: function () { return this._raw_lContainer[HOST]; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LContainerDebug.prototype, "native", {
            get: function () { return this._raw_lContainer[NATIVE]; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(LContainerDebug.prototype, "__other__", {
            get: function () {
                return {
                    next: toDebug(this._raw_lContainer[NEXT]),
                };
            },
            enumerable: true,
            configurable: true
        });
        return LContainerDebug;
    }());
    /**
     * Return an `LView` value if found.
     *
     * @param value `LView` if any
     */
    function readLViewValue(value) {
        while (Array.isArray(value)) {
            // This check is not quite right, as it does not take into account `StylingContext`
            // This is why it is in debug, not in util.ts
            if (value.length >= HEADER_OFFSET - 1)
                return value;
            value = value[HOST];
        }
        return null;
    }
    var I18NDebugItem = /** @class */ (function () {
        function I18NDebugItem(__raw_opCode, _lView, nodeIndex, type) {
            this.__raw_opCode = __raw_opCode;
            this._lView = _lView;
            this.nodeIndex = nodeIndex;
            this.type = type;
        }
        Object.defineProperty(I18NDebugItem.prototype, "tNode", {
            get: function () { return getTNode(this.nodeIndex, this._lView); },
            enumerable: true,
            configurable: true
        });
        return I18NDebugItem;
    }());
    /**
     * Turns a list of "Create" & "Update" OpCodes into a human-readable list of operations for
     * debugging purposes.
     * @param mutateOpCodes mutation opCodes to read
     * @param updateOpCodes update opCodes to read
     * @param icus list of ICU expressions
     * @param lView The view the opCodes are acting on
     */
    function attachI18nOpCodesDebug(mutateOpCodes, updateOpCodes, icus, lView) {
        attachDebugObject(mutateOpCodes, new I18nMutateOpCodesDebug(mutateOpCodes, lView));
        attachDebugObject(updateOpCodes, new I18nUpdateOpCodesDebug(updateOpCodes, icus, lView));
        if (icus) {
            icus.forEach(function (icu) {
                icu.create.forEach(function (icuCase) { attachDebugObject(icuCase, new I18nMutateOpCodesDebug(icuCase, lView)); });
                icu.update.forEach(function (icuCase) {
                    attachDebugObject(icuCase, new I18nUpdateOpCodesDebug(icuCase, icus, lView));
                });
            });
        }
    }
    var I18nMutateOpCodesDebug = /** @class */ (function () {
        function I18nMutateOpCodesDebug(__raw_opCodes, __lView) {
            this.__raw_opCodes = __raw_opCodes;
            this.__lView = __lView;
        }
        Object.defineProperty(I18nMutateOpCodesDebug.prototype, "operations", {
            /**
             * A list of operation information about how the OpCodes will act on the view.
             */
            get: function () {
                var _a = this, __lView = _a.__lView, __raw_opCodes = _a.__raw_opCodes;
                var results = [];
                for (var i = 0; i < __raw_opCodes.length; i++) {
                    var opCode = __raw_opCodes[i];
                    var result = void 0;
                    if (typeof opCode === 'string') {
                        result = {
                            __raw_opCode: opCode,
                            type: 'Create Text Node',
                            nodeIndex: __raw_opCodes[++i],
                            text: opCode,
                        };
                    }
                    if (typeof opCode === 'number') {
                        switch (opCode & 7 /* MASK_OPCODE */) {
                            case 1 /* AppendChild */:
                                var destinationNodeIndex = opCode >>> 17 /* SHIFT_PARENT */;
                                result = new I18NDebugItem(opCode, __lView, destinationNodeIndex, 'AppendChild');
                                break;
                            case 0 /* Select */:
                                var nodeIndex = opCode >>> 3 /* SHIFT_REF */;
                                result = new I18NDebugItem(opCode, __lView, nodeIndex, 'Select');
                                break;
                            case 5 /* ElementEnd */:
                                var elementIndex = opCode >>> 3 /* SHIFT_REF */;
                                result = new I18NDebugItem(opCode, __lView, elementIndex, 'ElementEnd');
                                break;
                            case 4 /* Attr */:
                                elementIndex = opCode >>> 3 /* SHIFT_REF */;
                                result = new I18NDebugItem(opCode, __lView, elementIndex, 'Attr');
                                result['attrName'] = __raw_opCodes[++i];
                                result['attrValue'] = __raw_opCodes[++i];
                                break;
                        }
                    }
                    if (!result) {
                        switch (opCode) {
                            case COMMENT_MARKER:
                                result = {
                                    __raw_opCode: opCode,
                                    type: 'COMMENT_MARKER',
                                    commentValue: __raw_opCodes[++i],
                                    nodeIndex: __raw_opCodes[++i],
                                };
                                break;
                            case ELEMENT_MARKER:
                                result = {
                                    __raw_opCode: opCode,
                                    type: 'ELEMENT_MARKER',
                                };
                                break;
                        }
                    }
                    if (!result) {
                        result = {
                            __raw_opCode: opCode,
                            type: 'Unknown Op Code',
                            code: opCode,
                        };
                    }
                    results.push(result);
                }
                return results;
            },
            enumerable: true,
            configurable: true
        });
        return I18nMutateOpCodesDebug;
    }());
    var I18nUpdateOpCodesDebug = /** @class */ (function () {
        function I18nUpdateOpCodesDebug(__raw_opCodes, icus, __lView) {
            this.__raw_opCodes = __raw_opCodes;
            this.icus = icus;
            this.__lView = __lView;
        }
        Object.defineProperty(I18nUpdateOpCodesDebug.prototype, "operations", {
            /**
             * A list of operation information about how the OpCodes will act on the view.
             */
            get: function () {
                var _a = this, __lView = _a.__lView, __raw_opCodes = _a.__raw_opCodes, icus = _a.icus;
                var results = [];
                for (var i = 0; i < __raw_opCodes.length; i++) {
                    // bit code to check if we should apply the next update
                    var checkBit = __raw_opCodes[i];
                    // Number of opCodes to skip until next set of update codes
                    var skipCodes = __raw_opCodes[++i];
                    var value = '';
                    for (var j = i + 1; j <= (i + skipCodes); j++) {
                        var opCode = __raw_opCodes[j];
                        if (typeof opCode === 'string') {
                            value += opCode;
                        }
                        else if (typeof opCode == 'number') {
                            if (opCode < 0) {
                                // It's a binding index whose value is negative
                                // We cannot know the value of the binding so we only show the index
                                value += "\uFFFD" + (-opCode - 1) + "\uFFFD";
                            }
                            else {
                                var nodeIndex = opCode >>> 2 /* SHIFT_REF */;
                                var tIcuIndex = void 0;
                                var tIcu = void 0;
                                switch (opCode & 3 /* MASK_OPCODE */) {
                                    case 1 /* Attr */:
                                        var attrName = __raw_opCodes[++j];
                                        var sanitizeFn = __raw_opCodes[++j];
                                        results.push({
                                            __raw_opCode: opCode,
                                            checkBit: checkBit,
                                            type: 'Attr',
                                            attrValue: value, attrName: attrName, sanitizeFn: sanitizeFn,
                                        });
                                        break;
                                    case 0 /* Text */:
                                        results.push({
                                            __raw_opCode: opCode,
                                            checkBit: checkBit,
                                            type: 'Text', nodeIndex: nodeIndex,
                                            text: value,
                                        });
                                        break;
                                    case 2 /* IcuSwitch */:
                                        tIcuIndex = __raw_opCodes[++j];
                                        tIcu = icus[tIcuIndex];
                                        var result = new I18NDebugItem(opCode, __lView, nodeIndex, 'IcuSwitch');
                                        result['tIcuIndex'] = tIcuIndex;
                                        result['checkBit'] = checkBit;
                                        result['mainBinding'] = value;
                                        result['tIcu'] = tIcu;
                                        results.push(result);
                                        break;
                                    case 3 /* IcuUpdate */:
                                        tIcuIndex = __raw_opCodes[++j];
                                        tIcu = icus[tIcuIndex];
                                        result = new I18NDebugItem(opCode, __lView, nodeIndex, 'IcuUpdate');
                                        result['tIcuIndex'] = tIcuIndex;
                                        result['checkBit'] = checkBit;
                                        result['tIcu'] = tIcu;
                                        results.push(result);
                                        break;
                                }
                            }
                        }
                    }
                    i += skipCodes;
                }
                return results;
            },
            enumerable: true,
            configurable: true
        });
        return I18nUpdateOpCodesDebug;
    }());

    /**
     * @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
     */
    /**
     * Selects an element for later binding instructions.
     *
     * Used in conjunction with instructions like {@link property} to act on elements with specified
     * indices, for example those created with {@link element} or {@link elementStart}.
     *
     * ```ts
     * (rf: RenderFlags, ctx: any) => {
     *   if (rf & 1) {
     *     element(0, 'div');
     *   }
     *   if (rf & 2) {
     *     select(0); // Select the <div/> created above.
     *     property('title', 'test');
     *   }
     *  }
     * ```
     * @param index the index of the item to act on with the following instructions
     *
     * @codeGenApi
     */
    function ɵɵselect(index) {
        ngDevMode && assertGreaterThan(index, -1, 'Invalid index');
        ngDevMode &&
            assertLessThan(index, getLView().length - HEADER_OFFSET, 'Should be within range for the view data');
        var lView = getLView();
        selectInternal(lView, index);
    }
    function selectInternal(lView, index) {
        // Flush the initial hooks for elements in the view that have been added up to this point.
        executePreOrderHooks(lView, lView[TVIEW], getCheckNoChangesMode(), index);
        // We must set the selected index *after* running the hooks, because hooks may have side-effects
        // that cause other template functions to run, thus updating the selected index, which is global
        // state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
        // will be altered by the time we leave the `ɵɵselect` instruction.
        setSelectedIndex(index);
    }

    var ɵ0$5 = function () { return Promise.resolve(null); };
    /**
     * A permanent marker promise which signifies that the current CD tree is
     * clean.
     */
    var _CLEAN_PROMISE = (ɵ0$5)();
    /**
     * Refreshes the view, executing the following steps in that order:
     * triggers init hooks, refreshes dynamic embedded views, triggers content hooks, sets host
     * bindings, refreshes child components.
     * Note: view hooks are triggered later when leaving the view.
     */
    function refreshDescendantViews(lView) {
        var tView = lView[TVIEW];
        var creationMode = isCreationMode(lView);
        // This needs to be set before children are processed to support recursive components
        tView.firstTemplatePass = false;
        // Resetting the bindingIndex of the current LView as the next steps may trigger change detection.
        lView[BINDING_INDEX] = tView.bindingStartIndex;
        // If this is a creation pass, we should not call lifecycle hooks or evaluate bindings.
        // This will be done in the update pass.
        if (!creationMode) {
            var checkNoChangesMode = getCheckNoChangesMode();
            executePreOrderHooks(lView, tView, checkNoChangesMode, undefined);
            refreshDynamicEmbeddedViews(lView);
            // Content query results must be refreshed before content hooks are called.
            refreshContentQueries(tView, lView);
            resetPreOrderHookFlags(lView);
            executeHooks(lView, tView.contentHooks, tView.contentCheckHooks, checkNoChangesMode, 1 /* AfterContentInitHooksToBeRun */, undefined);
            setHostBindings(tView, lView);
        }
        // We resolve content queries specifically marked as `static` in creation mode. Dynamic
        // content queries are resolved during change detection (i.e. update mode), after embedded
        // views are refreshed (see block above).
        if (creationMode && tView.staticContentQueries) {
            refreshContentQueries(tView, lView);
        }
        // We must materialize query results before child components are processed
        // in case a child component has projected a container. The LContainer needs
        // to exist so the embedded views are properly attached by the container.
        if (!creationMode || tView.staticViewQueries) {
            executeViewQueryFn(2 /* Update */, tView, lView[CONTEXT]);
        }
        refreshChildComponents(lView, tView.components);
    }
    /** Sets the host bindings for the current view. */
    function setHostBindings(tView, viewData) {
        var selectedIndex = getSelectedIndex();
        try {
            if (tView.expandoInstructions) {
                var bindingRootIndex = viewData[BINDING_INDEX] = tView.expandoStartIndex;
                setBindingRoot(bindingRootIndex);
                var currentDirectiveIndex = -1;
                var currentElementIndex = -1;
                for (var i = 0; i < tView.expandoInstructions.length; i++) {
                    var instruction = tView.expandoInstructions[i];
                    if (typeof instruction === 'number') {
                        if (instruction <= 0) {
                            // Negative numbers mean that we are starting new EXPANDO block and need to update
                            // the current element and directive index.
                            currentElementIndex = -instruction;
                            setActiveHostElement(currentElementIndex);
                            // Injector block and providers are taken into account.
                            var providerCount = tView.expandoInstructions[++i];
                            bindingRootIndex += INJECTOR_BLOOM_PARENT_SIZE + providerCount;
                            currentDirectiveIndex = bindingRootIndex;
                        }
                        else {
                            // This is either the injector size (so the binding root can skip over directives
                            // and get to the first set of host bindings on this node) or the host var count
                            // (to get to the next set of host bindings on this node).
                            bindingRootIndex += instruction;
                        }
                        setBindingRoot(bindingRootIndex);
                    }
                    else {
                        // If it's not a number, it's a host binding function that needs to be executed.
                        if (instruction !== null) {
                            viewData[BINDING_INDEX] = bindingRootIndex;
                            var hostCtx = unwrapRNode(viewData[currentDirectiveIndex]);
                            instruction(2 /* Update */, hostCtx, currentElementIndex);
                            // Each directive gets a uniqueId value that is the same for both
                            // create and update calls when the hostBindings function is called. The
                            // directive uniqueId is not set anywhere--it is just incremented between
                            // each hostBindings call and is useful for helping instruction code
                            // uniquely determine which directive is currently active when executed.
                            incrementActiveDirectiveId();
                        }
                        currentDirectiveIndex++;
                    }
                }
            }
        }
        finally {
            setActiveHostElement(selectedIndex);
        }
    }
    /** Refreshes all content queries declared by directives in a given view */
    function refreshContentQueries(tView, lView) {
        var contentQueries = tView.contentQueries;
        if (contentQueries !== null) {
            for (var i = 0; i < contentQueries.length; i += 2) {
                var queryStartIdx = contentQueries[i];
                var directiveDefIdx = contentQueries[i + 1];
                if (directiveDefIdx !== -1) {
                    var directiveDef = tView.data[directiveDefIdx];
                    ngDevMode &&
                        assertDefined(directiveDef.contentQueries, 'contentQueries function should be defined');
                    setCurrentQueryIndex(queryStartIdx);
                    directiveDef.contentQueries(2 /* Update */, lView[directiveDefIdx], directiveDefIdx);
                }
            }
        }
    }
    /** Refreshes child components in the current view. */
    function refreshChildComponents(hostLView, components) {
        if (components != null) {
            for (var i = 0; i < components.length; i++) {
                componentRefresh(hostLView, components[i]);
            }
        }
    }
    /**
     * Creates a native element from a tag name, using a renderer.
     * @param name the tag name
     * @param overriddenRenderer Optional A renderer to override the default one
     * @returns the element created
     */
    function elementCreate(name, overriddenRenderer) {
        var native;
        var rendererToUse = overriddenRenderer || getLView()[RENDERER];
        var namespace = getNamespace();
        if (isProceduralRenderer(rendererToUse)) {
            native = rendererToUse.createElement(name, namespace);
        }
        else {
            if (namespace === null) {
                native = rendererToUse.createElement(name);
            }
            else {
                native = rendererToUse.createElementNS(namespace, name);
            }
        }
        return native;
    }
    function createLView(parentLView, tView, context, flags, host, tHostNode, rendererFactory, renderer, sanitizer, injector) {
        var lView = ngDevMode ? cloneToLView(tView.blueprint) : tView.blueprint.slice();
        lView[HOST] = host;
        lView[FLAGS] = flags | 4 /* CreationMode */ | 128 /* Attached */ | 8 /* FirstLViewPass */;
        resetPreOrderHookFlags(lView);
        lView[PARENT] = lView[DECLARATION_VIEW] = parentLView;
        lView[CONTEXT] = context;
        lView[RENDERER_FACTORY] = (rendererFactory || parentLView && parentLView[RENDERER_FACTORY]);
        ngDevMode && assertDefined(lView[RENDERER_FACTORY], 'RendererFactory is required');
        lView[RENDERER] = (renderer || parentLView && parentLView[RENDERER]);
        ngDevMode && assertDefined(lView[RENDERER], 'Renderer is required');
        lView[SANITIZER] = sanitizer || parentLView && parentLView[SANITIZER] || null;
        lView[INJECTOR$1] = injector || parentLView && parentLView[INJECTOR$1] || null;
        lView[T_HOST] = tHostNode;
        ngDevMode && attachLViewDebug(lView);
        return lView;
    }
    function getOrCreateTNode(tView, tHostNode, index, type, name, attrs) {
        // Keep this function short, so that the VM will inline it.
        var adjustedIndex = index + HEADER_OFFSET;
        var tNode = tView.data[adjustedIndex] ||
            createTNodeAtIndex(tView, tHostNode, adjustedIndex, type, name, attrs, index);
        setPreviousOrParentTNode(tNode, true);
        return tNode;
    }
    function createTNodeAtIndex(tView, tHostNode, adjustedIndex, type, name, attrs, index) {
        var previousOrParentTNode = getPreviousOrParentTNode();
        var isParent = getIsParent();
        var parent = isParent ? previousOrParentTNode : previousOrParentTNode && previousOrParentTNode.parent;
        // Parents cannot cross component boundaries because components will be used in multiple places,
        // so it's only set if the view is the same.
        var parentInSameView = parent && parent !== tHostNode;
        var tParentNode = parentInSameView ? parent : null;
        var tNode = tView.data[adjustedIndex] =
            createTNode(tView, tParentNode, type, adjustedIndex, name, attrs);
        // The first node is not always the one at index 0, in case of i18n, index 0 can be the
        // instruction `i18nStart` and the first node has the index 1 or more
        if (index === 0 || !tView.firstChild) {
            tView.firstChild = tNode;
        }
        // Now link ourselves into the tree.
        if (previousOrParentTNode) {
            if (isParent && previousOrParentTNode.child == null &&
                (tNode.parent !== null || previousOrParentTNode.type === 2 /* View */)) {
                // We are in the same view, which means we are adding content node to the parent view.
                previousOrParentTNode.child = tNode;
            }
            else if (!isParent) {
                previousOrParentTNode.next = tNode;
            }
        }
        return tNode;
    }
    function assignTViewNodeToLView(tView, tParentNode, index, lView) {
        // View nodes are not stored in data because they can be added / removed at runtime (which
        // would cause indices to change). Their TNodes are instead stored in tView.node.
        var tNode = tView.node;
        if (tNode == null) {
            ngDevMode && tParentNode &&
                assertNodeOfPossibleTypes(tParentNode, 3 /* Element */, 0 /* Container */);
            tView.node = tNode = createTNode(tView, tParentNode, //
            2 /* View */, index, null, null);
        }
        return lView[T_HOST] = tNode;
    }
    /**
     * When elements are created dynamically after a view blueprint is created (e.g. through
     * i18nApply() or ComponentFactory.create), we need to adjust the blueprint for future
     * template passes.
     *
     * @param view The LView containing the blueprint to adjust
     * @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0
     */
    function allocExpando(view, numSlotsToAlloc) {
        ngDevMode && assertGreaterThan(numSlotsToAlloc, 0, 'The number of slots to alloc should be greater than 0');
        if (numSlotsToAlloc > 0) {
            var tView = view[TVIEW];
            if (tView.firstTemplatePass) {
                for (var i = 0; i < numSlotsToAlloc; i++) {
                    tView.blueprint.push(null);
                    tView.data.push(null);
                    view.push(null);
                }
                // We should only increment the expando start index if there aren't already directives
                // and injectors saved in the "expando" section
                if (!tView.expandoInstructions) {
                    tView.expandoStartIndex += numSlotsToAlloc;
                }
                else {
                    // Since we're adding the dynamic nodes into the expando section, we need to let the host
                    // bindings know that they should skip x slots
                    tView.expandoInstructions.push(numSlotsToAlloc);
                }
            }
        }
    }
    //////////////////////////
    //// Render
    //////////////////////////
    /**
     * Used for creating the LViewNode of a dynamic embedded view,
     * either through ViewContainerRef.createEmbeddedView() or TemplateRef.createEmbeddedView().
     * Such lViewNode will then be renderer with renderEmbeddedTemplate() (see below).
     */
    function createEmbeddedViewAndNode(tView, context, declarationView, injectorIndex) {
        var _isParent = getIsParent();
        var _previousOrParentTNode = getPreviousOrParentTNode();
        setPreviousOrParentTNode(null, true);
        var lView = createLView(declarationView, tView, context, 16 /* CheckAlways */, null, null);
        lView[DECLARATION_VIEW] = declarationView;
        assignTViewNodeToLView(tView, null, -1, lView);
        if (tView.firstTemplatePass) {
            tView.node.injectorIndex = injectorIndex;
        }
        setPreviousOrParentTNode(_previousOrParentTNode, _isParent);
        return lView;
    }
    /**
     * Used for rendering embedded views (e.g. dynamically created views)
     *
     * Dynamically created views must store/retrieve their TViews differently from component views
     * because their template functions are nested in the template functions of their hosts, creating
     * closures. If their host template happens to be an embedded template in a loop (e.g. ngFor
     * inside
     * an ngFor), the nesting would mean we'd have multiple instances of the template function, so we
     * can't store TViews in the template function itself (as we do for comps). Instead, we store the
     * TView for dynamically created views on their host TNode, which only has one instance.
     */
    function renderEmbeddedTemplate(viewToRender, tView, context) {
        var _isParent = getIsParent();
        var _previousOrParentTNode = getPreviousOrParentTNode();
        var oldView;
        if (viewToRender[FLAGS] & 512 /* IsRoot */) {
            // This is a root view inside the view tree
            tickRootContext(getRootContext(viewToRender));
        }
        else {
            // Will become true if the `try` block executes with no errors.
            var safeToRunHooks = false;
            try {
                setPreviousOrParentTNode(null, true);
                oldView = enterView(viewToRender, viewToRender[T_HOST]);
                resetPreOrderHookFlags(viewToRender);
                executeTemplate(viewToRender, tView.template, getRenderFlags(viewToRender), context);
                // This must be set to false immediately after the first creation run because in an
                // ngFor loop, all the views will be created together before update mode runs and turns
                // off firstTemplatePass. If we don't set it here, instances will perform directive
                // matching, etc again and again.
                tView.firstTemplatePass = false;
                refreshDescendantViews(viewToRender);
                safeToRunHooks = true;
            }
            finally {
                leaveView(oldView, safeToRunHooks);
                setPreviousOrParentTNode(_previousOrParentTNode, _isParent);
            }
        }
    }
    function renderComponentOrTemplate(hostView, context, templateFn) {
        var rendererFactory = hostView[RENDERER_FACTORY];
        var oldView = enterView(hostView, hostView[T_HOST]);
        var normalExecutionPath = !getCheckNoChangesMode();
        var creationModeIsActive = isCreationMode(hostView);
        // Will become true if the `try` block executes with no errors.
        var safeToRunHooks = false;
        try {
            if (normalExecutionPath && !creationModeIsActive && rendererFactory.begin) {
                rendererFactory.begin();
            }
            if (creationModeIsActive) {
                // creation mode pass
                templateFn && executeTemplate(hostView, templateFn, 1 /* Create */, context);
                refreshDescendantViews(hostView);
                hostView[FLAGS] &= ~4 /* CreationMode */;
            }
            // update mode pass
            resetPreOrderHookFlags(hostView);
            templateFn && executeTemplate(hostView, templateFn, 2 /* Update */, context);
            refreshDescendantViews(hostView);
            safeToRunHooks = true;
        }
        finally {
            if (normalExecutionPath && !creationModeIsActive && rendererFactory.end) {
                rendererFactory.end();
            }
            leaveView(oldView, safeToRunHooks);
        }
    }
    function executeTemplate(lView, templateFn, rf, context) {
        namespaceHTMLInternal();
        var prevSelectedIndex = getSelectedIndex();
        try {
            setActiveHostElement(null);
            if (rf & 2 /* Update */) {
                // When we're updating, have an inherent ɵɵselect(0) so we don't have to generate that
                // instruction for most update blocks
                selectInternal(lView, 0);
            }
            templateFn(rf, context);
        }
        finally {
            setSelectedIndex(prevSelectedIndex);
        }
    }
    /**
     * This function returns the default configuration of rendering flags depending on when the
     * template is in creation mode or update mode. Update block and create block are
     * always run separately.
     */
    function getRenderFlags(view) {
        return isCreationMode(view) ? 1 /* Create */ : 2 /* Update */;
    }
    //////////////////////////
    //// Element
    //////////////////////////
    function executeContentQueries(tView, tNode, lView) {
        if (isContentQueryHost(tNode)) {
            var start = tNode.directiveStart;
            var end = tNode.directiveEnd;
            for (var directiveIndex = start; directiveIndex < end; directiveIndex++) {
                var def = tView.data[directiveIndex];
                if (def.contentQueries) {
                    def.contentQueries(1 /* Create */, lView[directiveIndex], directiveIndex);
                }
            }
        }
    }
    /**
     * Creates directive instances and populates local refs.
     *
     * @param localRefs Local refs of the node in question
     * @param localRefExtractor mapping function that extracts local ref value from TNode
     */
    function createDirectivesAndLocals(tView, lView, tNode, localRefExtractor) {
        if (localRefExtractor === void 0) { localRefExtractor = getNativeByTNode; }
        if (!getBindingsEnabled())
            return;
        instantiateAllDirectives(tView, lView, tNode);
        invokeDirectivesHostBindings(tView, lView, tNode);
        saveResolvedLocalsInData(lView, tNode, localRefExtractor);
        setActiveHostElement(null);
    }
    /**
     * Takes a list of local names and indices and pushes the resolved local variable values
     * to LView in the same order as they are loaded in the template with load().
     */
    function saveResolvedLocalsInData(viewData, tNode, localRefExtractor) {
        var localNames = tNode.localNames;
        if (localNames) {
            var localIndex = tNode.index + 1;
            for (var i = 0; i < localNames.length; i += 2) {
                var index = localNames[i + 1];
                var value = index === -1 ?
                    localRefExtractor(tNode, viewData) :
                    viewData[index];
                viewData[localIndex++] = value;
            }
        }
    }
    /**
     * Gets TView from a template function or creates a new TView
     * if it doesn't already exist.
     *
     * @param def ComponentDef
     * @returns TView
     */
    function getOrCreateTView(def) {
        return def.tView || (def.tView = createTView(-1, def.template, def.consts, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery, def.schemas));
    }
    /**
     * Creates a TView instance
     *
     * @param viewIndex The viewBlockId for inline views, or -1 if it's a component/dynamic
     * @param templateFn Template function
     * @param consts The number of nodes, local refs, and pipes in this template
     * @param directives Registry of directives for this view
     * @param pipes Registry of pipes for this view
     * @param viewQuery View queries for this view
     * @param schemas Schemas for this view
     */
    function createTView(viewIndex, templateFn, consts, vars, directives, pipes, viewQuery, schemas) {
        ngDevMode && ngDevMode.tView++;
        var bindingStartIndex = HEADER_OFFSET + consts;
        // This length does not yet contain host bindings from child directives because at this point,
        // we don't know which directives are active on this template. As soon as a directive is matched
        // that has a host binding, we will update the blueprint with that def's hostVars count.
        var initialViewLength = bindingStartIndex + vars;
        var blueprint = createViewBlueprint(bindingStartIndex, initialViewLength);
        return blueprint[TVIEW] = ngDevMode ?
            new TViewConstructor(viewIndex, // id: number,
            blueprint, // blueprint: LView,
            templateFn, // template: ComponentTemplate<{}>|null,
            null, // queries: TQueries|null
            viewQuery, // viewQuery: ViewQueriesFunction<{}>|null,
            null, // node: TViewNode|TElementNode|null,
            cloneToTViewData(blueprint).fill(null, bindingStartIndex), // data: TData,
            bindingStartIndex, // bindingStartIndex: number,
            initialViewLength, // expandoStartIndex: number,
            null, // expandoInstructions: ExpandoInstructions|null,
            true, // firstTemplatePass: boolean,
            false, // staticViewQueries: boolean,
            false, // staticContentQueries: boolean,
            null, // preOrderHooks: HookData|null,
            null, // preOrderCheckHooks: HookData|null,
            null, // contentHooks: HookData|null,
            null, // contentCheckHooks: HookData|null,
            null, // viewHooks: HookData|null,
            null, // viewCheckHooks: HookData|null,
            null, // destroyHooks: HookData|null,
            null, // cleanup: any[]|null,
            null, // contentQueries: number[]|null,
            null, // components: number[]|null,
            typeof directives === 'function' ?
                directives() :
                directives, // directiveRegistry: DirectiveDefList|null,
            typeof pipes === 'function' ? pipes() : pipes, // pipeRegistry: PipeDefList|null,
            null, // firstChild: TNode|null,
            schemas) :
            {
                id: viewIndex,
                blueprint: blueprint,
                template: templateFn,
                queries: null,
                viewQuery: viewQuery,
                node: null,
                data: blueprint.slice().fill(null, bindingStartIndex),
                bindingStartIndex: bindingStartIndex,
                expandoStartIndex: initialViewLength,
                expandoInstructions: null,
                firstTemplatePass: true,
                staticViewQueries: false,
                staticContentQueries: false,
                preOrderHooks: null,
                preOrderCheckHooks: null,
                contentHooks: null,
                contentCheckHooks: null,
                viewHooks: null,
                viewCheckHooks: null,
                destroyHooks: null,
                cleanup: null,
                contentQueries: null,
                components: null,
                directiveRegistry: typeof directives === 'function' ? directives() : directives,
                pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
                firstChild: null,
                schemas: schemas,
            };
    }
    function createViewBlueprint(bindingStartIndex, initialViewLength) {
        var blueprint = new (ngDevMode ? LViewBlueprint : Array)(initialViewLength)
            .fill(null, 0, bindingStartIndex)
            .fill(NO_CHANGE, bindingStartIndex);
        blueprint[BINDING_INDEX] = bindingStartIndex;
        return blueprint;
    }
    function createError(text, token) {
        return new Error("Renderer: " + text + " [" + stringifyForError(token) + "]");
    }
    /**
     * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
     *
     * @param elementOrSelector Render element or CSS selector to locate the element.
     */
    function locateHostElement(factory, elementOrSelector) {
        var defaultRenderer = factory.createRenderer(null, null);
        var rNode = typeof elementOrSelector === 'string' ?
            (isProceduralRenderer(defaultRenderer) ?
                defaultRenderer.selectRootElement(elementOrSelector) :
                defaultRenderer.querySelector(elementOrSelector)) :
            elementOrSelector;
        if (ngDevMode && !rNode) {
            if (typeof elementOrSelector === 'string') {
                throw createError('Host node with selector not found:', elementOrSelector);
            }
            else {
                throw createError('Host node is required:', elementOrSelector);
            }
        }
        return rNode;
    }
    /**
     * Saves context for this cleanup function in LView.cleanupInstances.
     *
     * On the first template pass, saves in TView:
     * - Cleanup function
     * - Index of context we just saved in LView.cleanupInstances
     */
    function storeCleanupWithContext(lView, context, cleanupFn) {
        var lCleanup = getCleanup(lView);
        lCleanup.push(context);
        if (lView[TVIEW].firstTemplatePass) {
            getTViewCleanup(lView).push(cleanupFn, lCleanup.length - 1);
        }
    }
    /**
     * Saves the cleanup function itself in LView.cleanupInstances.
     *
     * This is necessary for functions that are wrapped with their contexts, like in renderer2
     * listeners.
     *
     * On the first template pass, the index of the cleanup function is saved in TView.
     */
    function storeCleanupFn(view, cleanupFn) {
        getCleanup(view).push(cleanupFn);
        if (view[TVIEW].firstTemplatePass) {
            getTViewCleanup(view).push(view[CLEANUP].length - 1, null);
        }
    }
    /**
     * Constructs a TNode object from the arguments.
     *
     * @param tView `TView` to which this `TNode` belongs (used only in `ngDevMode`)
     * @param type The type of the node
     * @param adjustedIndex The index of the TNode in TView.data, adjusted for HEADER_OFFSET
     * @param tagName The tag name of the node
     * @param attrs The attributes defined on this node
     * @param tViews Any TViews attached to this node
     * @returns the TNode object
     */
    function createTNode(tView, tParent, type, adjustedIndex, tagName, attrs) {
        ngDevMode && ngDevMode.tNode++;
        var injectorIndex = tParent ? tParent.injectorIndex : -1;
        return ngDevMode ? new TNodeConstructor(tView, // tView_: TView
        type, // type: TNodeType
        adjustedIndex, // index: number
        injectorIndex, // injectorIndex: number
        -1, // directiveStart: number
        -1, // directiveEnd: number
        -1, // propertyMetadataStartIndex: number
        -1, // propertyMetadataEndIndex: number
        0, // flags: TNodeFlags
        0, // providerIndexes: TNodeProviderIndexes
        tagName, // tagName: string|null
        attrs, // attrs: (string|AttributeMarker|(string|SelectorFlags)[])[]|null
        null, // localNames: (string|number)[]|null
        undefined, // initialInputs: (string[]|null)[]|null|undefined
        undefined, // inputs: PropertyAliases|null|undefined
        undefined, // outputs: PropertyAliases|null|undefined
        null, // tViews: ITView|ITView[]|null
        null, // next: ITNode|null
        null, // projectionNext: ITNode|null
        null, // child: ITNode|null
        tParent, // parent: TElementNode|TContainerNode|null
        null, // projection: number|(ITNode|RNode[])[]|null
        null, // styles: TStylingContext|null
        null) :
            {
                type: type,
                index: adjustedIndex,
                injectorIndex: injectorIndex,
                directiveStart: -1,
                directiveEnd: -1,
                propertyMetadataStartIndex: -1,
                propertyMetadataEndIndex: -1,
                flags: 0,
                providerIndexes: 0,
                tagName: tagName,
                attrs: attrs,
                localNames: null,
                initialInputs: undefined,
                inputs: undefined,
                outputs: undefined,
                tViews: null,
                next: null,
                projectionNext: null,
                child: null,
                parent: tParent,
                projection: null,
                styles: null,
                classes: null,
            };
    }
    /**
     * Consolidates all inputs or outputs of all directives on this logical node.
     *
     * @param tNode
     * @param direction whether to consider inputs or outputs
     * @returns PropertyAliases|null aggregate of all properties if any, `null` otherwise
     */
    function generatePropertyAliases(tNode, direction) {
        var tView = getLView()[TVIEW];
        var propStore = null;
        var start = tNode.directiveStart;
        var end = tNode.directiveEnd;
        if (end > start) {
            var isInput = direction === 0 /* Input */;
            var defs = tView.data;
            for (var i = start; i < end; i++) {
                var directiveDef = defs[i];
                var propertyAliasMap = isInput ? directiveDef.inputs : directiveDef.outputs;
                for (var publicName in propertyAliasMap) {
                    if (propertyAliasMap.hasOwnProperty(publicName)) {
                        propStore = propStore || {};
                        var internalName = propertyAliasMap[publicName];
                        var hasProperty = propStore.hasOwnProperty(publicName);
                        hasProperty ? propStore[publicName].push(i, publicName, internalName) :
                            (propStore[publicName] = [i, publicName, internalName]);
                    }
                }
            }
        }
        return propStore;
    }
    /**
     * Mapping between attributes names that don't correspond to their element property names.
     * Note: this mapping has to be kept in sync with the equally named mapping in the template
     * type-checking machinery of ngtsc.
     */
    var ATTR_TO_PROP = {
        'class': 'className',
        'for': 'htmlFor',
        'formaction': 'formAction',
        'innerHtml': 'innerHTML',
        'readonly': 'readOnly',
        'tabindex': 'tabIndex',
    };
    function elementPropertyInternal(index, propName, value, sanitizer, nativeOnly, loadRendererFn) {
        ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
        var lView = getLView();
        var element = getNativeByIndex(index, lView);
        var tNode = getTNode(index, lView);
        var inputData;
        var dataValue;
        if (!nativeOnly && (inputData = initializeTNodeInputs(tNode)) &&
            (dataValue = inputData[propName])) {
            setInputsForProperty(lView, dataValue, value);
            if (isComponent(tNode))
                markDirtyIfOnPush(lView, index + HEADER_OFFSET);
            if (ngDevMode) {
                if (tNode.type === 3 /* Element */ || tNode.type === 0 /* Container */) {
                    /**
                     * dataValue is an array containing runtime input or output names for the directives:
                     * i+0: directive instance index
                     * i+1: publicName
                     * i+2: privateName
                     *
                     * e.g. [0, 'change', 'change-minified']
                     * we want to set the reflected property with the privateName: dataValue[i+2]
                     */
                    for (var i = 0; i < dataValue.length; i += 3) {
                        setNgReflectProperty(lView, element, tNode.type, dataValue[i + 2], value);
                    }
                }
            }
        }
        else if (tNode.type === 3 /* Element */) {
            propName = ATTR_TO_PROP[propName] || propName;
            if (ngDevMode) {
                validateAgainstEventProperties(propName);
                validateAgainstUnknownProperties(lView, element, propName, tNode);
                ngDevMode.rendererSetProperty++;
            }
            savePropertyDebugData(tNode, lView, propName, lView[TVIEW].data, nativeOnly);
            var renderer = loadRendererFn ? loadRendererFn(tNode, lView) : lView[RENDERER];
            // It is assumed that the sanitizer is only added when the compiler determines that the
            // property
            // is risky, so sanitization can be done without further checks.
            value = sanitizer != null ? sanitizer(value, tNode.tagName || '', propName) : value;
            if (isProceduralRenderer(renderer)) {
                renderer.setProperty(element, propName, value);
            }
            else if (!isAnimationProp(propName)) {
                element.setProperty ? element.setProperty(propName, value) :
                    element[propName] = value;
            }
        }
        else if (tNode.type === 0 /* Container */) {
            // If the node is a container and the property didn't
            // match any of the inputs or schemas we should throw.
            if (ngDevMode && !matchingSchemas(lView, tNode.tagName)) {
                throw createUnknownPropertyError(propName, tNode);
            }
        }
    }
    /** If node is an OnPush component, marks its LView dirty. */
    function markDirtyIfOnPush(lView, viewIndex) {
        ngDevMode && assertLView(lView);
        var childComponentLView = getComponentViewByIndex(viewIndex, lView);
        if (!(childComponentLView[FLAGS] & 16 /* CheckAlways */)) {
            childComponentLView[FLAGS] |= 64 /* Dirty */;
        }
    }
    function setNgReflectProperty(lView, element, type, attrName, value) {
        var _a;
        var renderer = lView[RENDERER];
        attrName = normalizeDebugBindingName(attrName);
        var debugValue = normalizeDebugBindingValue(value);
        if (type === 3 /* Element */) {
            if (value == null) {
                isProceduralRenderer(renderer) ? renderer.removeAttribute(element, attrName) :
                    element.removeAttribute(attrName);
            }
            else {
                isProceduralRenderer(renderer) ?
                    renderer.setAttribute(element, attrName, debugValue) :
                    element.setAttribute(attrName, debugValue);
            }
        }
        else {
            var textContent = "bindings=" + JSON.stringify((_a = {}, _a[attrName] = debugValue, _a), null, 2);
            if (isProceduralRenderer(renderer)) {
                renderer.setValue(element, textContent);
            }
            else {
                element.textContent = textContent;
            }
        }
    }
    function validateAgainstUnknownProperties(hostView, element, propName, tNode) {
        // If the tag matches any of the schemas we shouldn't throw.
        if (matchingSchemas(hostView, tNode.tagName)) {
            return;
        }
        // If prop is not a known property of the HTML element...
        if (!(propName in element) &&
            // and we are in a browser context... (web worker nodes should be skipped)
            typeof Node === 'function' && element instanceof Node &&
            // and isn't a synthetic animation property...
            propName[0] !== ANIMATION_PROP_PREFIX) {
            // ... it is probably a user error and we should throw.
            throw createUnknownPropertyError(propName, tNode);
        }
    }
    function matchingSchemas(hostView, tagName) {
        var schemas = hostView[TVIEW].schemas;
        if (schemas !== null) {
            for (var i = 0; i < schemas.length; i++) {
                var schema = schemas[i];
                if (schema === NO_ERRORS_SCHEMA ||
                    schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
    * Stores debugging data for this property binding on first template pass.
    * This enables features like DebugElement.properties.
    */
    function savePropertyDebugData(tNode, lView, propName, tData, nativeOnly) {
        var lastBindingIndex = lView[BINDING_INDEX] - 1;
        // Bind/interpolation functions save binding metadata in the last binding index,
        // but leave the property name blank. If the interpolation delimiter is at the 0
        // index, we know that this is our first pass and the property name still needs to
        // be set.
        var bindingMetadata = tData[lastBindingIndex];
        if (bindingMetadata[0] == INTERPOLATION_DELIMITER) {
            tData[lastBindingIndex] = propName + bindingMetadata;
            // We don't want to store indices for host bindings because they are stored in a
            // different part of LView (the expando section).
            if (!nativeOnly) {
                if (tNode.propertyMetadataStartIndex == -1) {
                    tNode.propertyMetadataStartIndex = lastBindingIndex;
                }
                tNode.propertyMetadataEndIndex = lastBindingIndex + 1;
            }
        }
    }
    /**
    * Creates an error that should be thrown when encountering an unknown property on an element.
    * @param propName Name of the invalid property.
    * @param tNode Node on which we encountered the error.
    */
    function createUnknownPropertyError(propName, tNode) {
        return new Error("Template error: Can't bind to '" + propName + "' since it isn't a known property of '" + tNode.tagName + "'.");
    }
    /**
     * Instantiate a root component.
     */
    function instantiateRootComponent(tView, viewData, def) {
        var rootTNode = getPreviousOrParentTNode();
        if (tView.firstTemplatePass) {
            if (def.providersResolver)
                def.providersResolver(def);
            generateExpandoInstructionBlock(tView, rootTNode, 1);
            baseResolveDirective(tView, viewData, def, def.factory);
        }
        var directive = getNodeInjectable(tView.data, viewData, viewData.length - 1, rootTNode);
        postProcessBaseDirective(viewData, rootTNode, directive);
        return directive;
    }
    /**
     * Resolve the matched directives on a node.
     */
    function resolveDirectives(tView, lView, tNode, localRefs) {
        // Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
        // tsickle.
        ngDevMode && assertEqual(tView.firstTemplatePass, true, 'should run on first template pass only');
        if (!getBindingsEnabled())
            return;
        var directives = findDirectiveMatches(tView, lView, tNode);
        var exportsMap = localRefs ? { '': -1 } : null;
        if (directives) {
            initNodeFlags(tNode, tView.data.length, directives.length);
            // When the same token is provided by several directives on the same node, some rules apply in
            // the viewEngine:
            // - viewProviders have priority over providers
            // - the last directive in NgModule.declarations has priority over the previous one
            // So to match these rules, the order in which providers are added in the arrays is very
            // important.
            for (var i = 0; i < directives.length; i++) {
                var def = directives[i];
                if (def.providersResolver)
                    def.providersResolver(def);
            }
            generateExpandoInstructionBlock(tView, tNode, directives.length);
            var initialPreOrderHooksLength = (tView.preOrderHooks && tView.preOrderHooks.length) || 0;
            var initialPreOrderCheckHooksLength = (tView.preOrderCheckHooks && tView.preOrderCheckHooks.length) || 0;
            var nodeIndex = tNode.index - HEADER_OFFSET;
            for (var i = 0; i < directives.length; i++) {
                var def = directives[i];
                var directiveDefIdx = tView.data.length;
                baseResolveDirective(tView, lView, def, def.factory);
                saveNameToExportMap(tView.data.length - 1, def, exportsMap);
                // Init hooks are queued now so ngOnInit is called in host components before
                // any projected components.
                registerPreOrderHooks(directiveDefIdx, def, tView, nodeIndex, initialPreOrderHooksLength, initialPreOrderCheckHooksLength);
            }
        }
        if (exportsMap)
            cacheMatchingLocalNames(tNode, localRefs, exportsMap);
    }
    /**
     * Instantiate all the directives that were previously resolved on the current node.
     */
    function instantiateAllDirectives(tView, lView, tNode) {
        var start = tNode.directiveStart;
        var end = tNode.directiveEnd;
        if (!tView.firstTemplatePass && start < end) {
            getOrCreateNodeInjectorForNode(tNode, lView);
        }
        for (var i = start; i < end; i++) {
            var def = tView.data[i];
            if (isComponentDef(def)) {
                addComponentLogic(lView, tNode, def);
            }
            var directive = getNodeInjectable(tView.data, lView, i, tNode);
            postProcessDirective(lView, directive, def, i);
        }
    }
    function invokeDirectivesHostBindings(tView, viewData, tNode) {
        var start = tNode.directiveStart;
        var end = tNode.directiveEnd;
        var expando = tView.expandoInstructions;
        var firstTemplatePass = tView.firstTemplatePass;
        var elementIndex = tNode.index - HEADER_OFFSET;
        var selectedIndex = getSelectedIndex();
        try {
            setActiveHostElement(elementIndex);
            for (var i = start; i < end; i++) {
                var def = tView.data[i];
                var directive = viewData[i];
                if (def.hostBindings) {
                    invokeHostBindingsInCreationMode(def, expando, directive, tNode, firstTemplatePass);
                    // Each directive gets a uniqueId value that is the same for both
                    // create and update calls when the hostBindings function is called. The
                    // directive uniqueId is not set anywhere--it is just incremented between
                    // each hostBindings call and is useful for helping instruction code
                    // uniquely determine which directive is currently active when executed.
                    incrementActiveDirectiveId();
                }
                else if (firstTemplatePass) {
                    expando.push(null);
                }
            }
        }
        finally {
            setActiveHostElement(selectedIndex);
        }
    }
    function invokeHostBindingsInCreationMode(def, expando, directive, tNode, firstTemplatePass) {
        var previousExpandoLength = expando.length;
        setCurrentDirectiveDef(def);
        var elementIndex = tNode.index - HEADER_OFFSET;
        def.hostBindings(1 /* Create */, directive, elementIndex);
        setCurrentDirectiveDef(null);
        // `hostBindings` function may or may not contain `allocHostVars` call
        // (e.g. it may not if it only contains host listeners), so we need to check whether
        // `expandoInstructions` has changed and if not - we still push `hostBindings` to
        // expando block, to make sure we execute it for DI cycle
        if (previousExpandoLength === expando.length && firstTemplatePass) {
            expando.push(def.hostBindings);
        }
    }
    /**
    * Generates a new block in TView.expandoInstructions for this node.
    *
    * Each expando block starts with the element index (turned negative so we can distinguish
    * it from the hostVar count) and the directive count. See more in VIEW_DATA.md.
    */
    function generateExpandoInstructionBlock(tView, tNode, directiveCount) {
        ngDevMode && assertEqual(tView.firstTemplatePass, true, 'Expando block should only be generated on first template pass.');
        var elementIndex = -(tNode.index - HEADER_OFFSET);
        var providerStartIndex = tNode.providerIndexes & 65535 /* ProvidersStartIndexMask */;
        var providerCount = tView.data.length - providerStartIndex;
        (tView.expandoInstructions || (tView.expandoInstructions = [])).push(elementIndex, providerCount, directiveCount);
    }
    /**
     * Process a directive on the current node after its creation.
     */
    function postProcessDirective(viewData, directive, def, directiveDefIdx) {
        var previousOrParentTNode = getPreviousOrParentTNode();
        postProcessBaseDirective(viewData, previousOrParentTNode, directive);
        ngDevMode && assertDefined(previousOrParentTNode, 'previousOrParentTNode');
        if (previousOrParentTNode && previousOrParentTNode.attrs) {
            setInputsFromAttrs(directiveDefIdx, directive, def, previousOrParentTNode);
        }
        if (viewData[TVIEW].firstTemplatePass && def.contentQueries) {
            previousOrParentTNode.flags |= 4 /* hasContentQuery */;
        }
        if (isComponentDef(def)) {
            var componentView = getComponentViewByIndex(previousOrParentTNode.index, viewData);
            componentView[CONTEXT] = directive;
        }
    }
    /**
     * A lighter version of postProcessDirective() that is used for the root component.
     */
    function postProcessBaseDirective(lView, previousOrParentTNode, directive) {
        var native = getNativeByTNode(previousOrParentTNode, lView);
        ngDevMode && assertEqual(lView[BINDING_INDEX], lView[TVIEW].bindingStartIndex, 'directives should be created before any bindings');
        ngDevMode && assertPreviousIsParent(getIsParent());
        attachPatchData(directive, lView);
        if (native) {
            attachPatchData(native, lView);
        }
    }
    /**
    * Matches the current node against all available selectors.
    * If a component is matched (at most one), it is returned in first position in the array.
    */
    function findDirectiveMatches(tView, viewData, tNode) {
        ngDevMode && assertEqual(tView.firstTemplatePass, true, 'should run on first template pass only');
        var registry = tView.directiveRegistry;
        var matches = null;
        if (registry) {
            for (var i = 0; i < registry.length; i++) {
                var def = registry[i];
                if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */ false)) {
                    matches || (matches = ngDevMode ? new MatchesArray() : []);
                    diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, viewData), tView, def.type);
                    if (isComponentDef(def)) {
                        if (tNode.flags & 1 /* isComponent */)
                            throwMultipleComponentError(tNode);
                        tNode.flags = 1 /* isComponent */;
                        // The component is always stored first with directives after.
                        matches.unshift(def);
                    }
                    else {
                        matches.push(def);
                    }
                }
            }
        }
        return matches;
    }
    /** Stores index of component's host element so it will be queued for view refresh during CD. */
    function queueComponentIndexForCheck(previousOrParentTNode) {
        var tView = getLView()[TVIEW];
        ngDevMode &&
            assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
        (tView.components || (tView.components = ngDevMode ? new TViewComponents() : [])).push(previousOrParentTNode.index);
    }
    /** Caches local names and their matching directive indices for query and template lookups. */
    function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
        if (localRefs) {
            var localNames = tNode.localNames =
                ngDevMode ? new TNodeLocalNames() : [];
            // Local names must be stored in tNode in the same order that localRefs are defined
            // in the template to ensure the data is loaded in the same slots as their refs
            // in the template (for template queries).
            for (var i = 0; i < localRefs.length; i += 2) {
                var index = exportsMap[localRefs[i + 1]];
                if (index == null)
                    throw new Error("Export of name '" + localRefs[i + 1] + "' not found!");
                localNames.push(localRefs[i], index);
            }
        }
    }
    /**
    * Builds up an export map as directives are created, so local refs can be quickly mapped
    * to their directive instances.
    */
    function saveNameToExportMap(index, def, exportsMap) {
        if (exportsMap) {
            if (def.exportAs) {
                for (var i = 0; i < def.exportAs.length; i++) {
                    exportsMap[def.exportAs[i]] = index;
                }
            }
            if (def.template)
                exportsMap[''] = index;
        }
    }
    /**
     * Initializes the flags on the current node, setting all indices to the initial index,
     * the directive count to 0, and adding the isComponent flag.
     * @param index the initial index
     */
    function initNodeFlags(tNode, index, numberOfDirectives) {
        var flags = tNode.flags;
        ngDevMode && assertEqual(flags === 0 || flags === 1 /* isComponent */, true, 'expected node flags to not be initialized');
        ngDevMode && assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
        // When the first directive is created on a node, save the index
        tNode.flags = flags & 1 /* isComponent */;
        tNode.directiveStart = index;
        tNode.directiveEnd = index + numberOfDirectives;
        tNode.providerIndexes = index;
    }
    function baseResolveDirective(tView, viewData, def, directiveFactory) {
        tView.data.push(def);
        var nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), null);
        tView.blueprint.push(nodeInjectorFactory);
        viewData.push(nodeInjectorFactory);
    }
    function addComponentLogic(lView, previousOrParentTNode, def) {
        var native = getNativeByTNode(previousOrParentTNode, lView);
        var tView = getOrCreateTView(def);
        // Only component views should be added to the view tree directly. Embedded views are
        // accessed through their containers because they may be removed / re-added later.
        var rendererFactory = lView[RENDERER_FACTORY];
        var componentView = addToViewTree(lView, createLView(lView, tView, null, def.onPush ? 64 /* Dirty */ : 16 /* CheckAlways */, lView[previousOrParentTNode.index], previousOrParentTNode, rendererFactory, rendererFactory.createRenderer(native, def)));
        componentView[T_HOST] = previousOrParentTNode;
        // Component view will always be created before any injected LContainers,
        // so this is a regular element, wrap it with the component view
        lView[previousOrParentTNode.index] = componentView;
        if (lView[TVIEW].firstTemplatePass) {
            queueComponentIndexForCheck(previousOrParentTNode);
        }
    }
    function elementAttributeInternal(index, name, value, lView, sanitizer, namespace) {
        ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
        ngDevMode && validateAgainstEventAttributes(name);
        var element = getNativeByIndex(index, lView);
        var renderer = lView[RENDERER];
        if (value == null) {
            ngDevMode && ngDevMode.rendererRemoveAttribute++;
            isProceduralRenderer(renderer) ? renderer.removeAttribute(element, name, namespace) :
                element.removeAttribute(name);
        }
        else {
            ngDevMode && ngDevMode.rendererSetAttribute++;
            var tNode = getTNode(index, lView);
            var strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tNode.tagName || '', name);
            if (isProceduralRenderer(renderer)) {
                renderer.setAttribute(element, name, strValue, namespace);
            }
            else {
                namespace ? element.setAttributeNS(namespace, name, strValue) :
                    element.setAttribute(name, strValue);
            }
        }
    }
    /**
     * Sets initial input properties on directive instances from attribute data
     *
     * @param directiveIndex Index of the directive in directives array
     * @param instance Instance of the directive on which to set the initial inputs
     * @param def The directive def that contains the list of inputs
     * @param tNode The static data for this node
     */
    function setInputsFromAttrs(directiveIndex, instance, def, tNode) {
        var initialInputData = tNode.initialInputs;
        if (initialInputData === undefined || directiveIndex >= initialInputData.length) {
            initialInputData = generateInitialInputs(directiveIndex, def.inputs, tNode);
        }
        var initialInputs = initialInputData[directiveIndex];
        if (initialInputs) {
            var setInput = def.setInput;
            for (var i = 0; i < initialInputs.length;) {
                var publicName = initialInputs[i++];
                var privateName = initialInputs[i++];
                var value = initialInputs[i++];
                if (setInput) {
                    def.setInput(instance, value, publicName, privateName);
                }
                else {
                    instance[privateName] = value;
                }
                if (ngDevMode) {
                    var lView = getLView();
                    var nativeElement = getNativeByTNode(tNode, lView);
                    setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value);
                }
            }
        }
    }
    /**
     * Generates initialInputData for a node and stores it in the template's static storage
     * so subsequent template invocations don't have to recalculate it.
     *
     * initialInputData is an array containing values that need to be set as input properties
     * for directives on this node, but only once on creation. We need this array to support
     * the case where you set an @Input property of a directive using attribute-like syntax.
     * e.g. if you have a `name` @Input, you can set it once like this:
     *
     * <my-component name="Bess"></my-component>
     *
     * @param directiveIndex Index to store the initial input data
     * @param inputs The list of inputs from the directive def
     * @param tNode The static data on this node
     */
    function generateInitialInputs(directiveIndex, inputs, tNode) {
        var initialInputData = tNode.initialInputs || (tNode.initialInputs = ngDevMode ? new TNodeInitialInputs() : []);
        // Ensure that we don't create sparse arrays
        for (var i_1 = initialInputData.length; i_1 <= directiveIndex; i_1++) {
            initialInputData.push(null);
        }
        var attrs = tNode.attrs;
        var i = 0;
        while (i < attrs.length) {
            var attrName = attrs[i];
            if (attrName === 0 /* NamespaceURI */) {
                // We do not allow inputs on namespaced attributes.
                i += 4;
                continue;
            }
            else if (attrName === 5 /* ProjectAs */) {
                // Skip over the `ngProjectAs` value.
                i += 2;
                continue;
            }
            // If we hit any other attribute markers, we're done anyway. None of those are valid inputs.
            if (typeof attrName === 'number')
                break;
            var minifiedInputName = inputs[attrName];
            var attrValue = attrs[i + 1];
            if (minifiedInputName !== undefined) {
                var inputsToStore = initialInputData[directiveIndex] ||
                    (initialInputData[directiveIndex] = ngDevMode ? new TNodeInitialData() : []);
                inputsToStore.push(attrName, minifiedInputName, attrValue);
            }
            i += 2;
        }
        return initialInputData;
    }
    //////////////////////////
    //// ViewContainer & View
    //////////////////////////
    // Not sure why I need to do `any` here but TS complains later.
    var LContainerArray = ngDevMode && createNamedArrayType('LContainer');
    /**
     * Creates a LContainer, either from a container instruction, or for a ViewContainerRef.
     *
     * @param hostNative The host element for the LContainer
     * @param hostTNode The host TNode for the LContainer
     * @param currentView The parent view of the LContainer
     * @param native The native comment element
     * @param isForViewContainerRef Optional a flag indicating the ViewContainerRef case
     * @returns LContainer
     */
    function createLContainer(hostNative, currentView, native, tNode, isForViewContainerRef) {
        ngDevMode && assertDomNode(native);
        ngDevMode && assertLView(currentView);
        // https://jsperf.com/array-literal-vs-new-array-really
        var lContainer = new (ngDevMode ? LContainerArray : Array)(hostNative, // host native
        true, // Boolean `true` in this position signifies that this is an `LContainer`
        isForViewContainerRef ? -1 : 0, // active index
        currentView, // parent
        null, // next
        null, // queries
        tNode, // t_host
        native, // native,
        null);
        ngDevMode && attachLContainerDebug(lContainer);
        return lContainer;
    }
    /**
     * Goes over dynamic embedded views (ones created through ViewContainerRef APIs) and refreshes
     * them
     * by executing an associated template function.
     */
    function refreshDynamicEmbeddedViews(lView) {
        for (var current = lView[CHILD_HEAD]; current !== null; current = current[NEXT]) {
            // Note: current can be an LView or an LContainer instance, but here we are only interested
            // in LContainer. We can tell it's an LContainer because its length is less than the LView
            // header.
            if (current[ACTIVE_INDEX] === -1 && isLContainer(current)) {
                for (var i = CONTAINER_HEADER_OFFSET; i < current.length; i++) {
                    var dynamicViewData = current[i];
                    // The directives and pipes are not needed here as an existing view is only being
                    // refreshed.
                    ngDevMode && assertDefined(dynamicViewData[TVIEW], 'TView must be allocated');
                    renderEmbeddedTemplate(dynamicViewData, dynamicViewData[TVIEW], dynamicViewData[CONTEXT]);
                }
            }
        }
    }
    /////////////
    /**
     * Refreshes components by entering the component view and processing its bindings, queries, etc.
     *
     * @param adjustedElementIndex  Element index in LView[] (adjusted for HEADER_OFFSET)
     */
    function componentRefresh(hostLView, adjustedElementIndex) {
        ngDevMode && assertDataInRange(hostLView, adjustedElementIndex);
        var componentView = getComponentViewByIndex(adjustedElementIndex, hostLView);
        ngDevMode &&
            assertNodeType(hostLView[TVIEW].data[adjustedElementIndex], 3 /* Element */);
        // Only components in creation mode, attached CheckAlways
        // components or attached, dirty OnPush components should be checked
        if ((viewAttachedToChangeDetector(componentView) || isCreationMode(hostLView)) &&
            componentView[FLAGS] & (16 /* CheckAlways */ | 64 /* Dirty */)) {
            syncViewWithBlueprint(componentView);
            checkView(componentView, componentView[CONTEXT]);
        }
    }
    /**
     * Syncs an LView instance with its blueprint if they have gotten out of sync.
     *
     * Typically, blueprints and their view instances should always be in sync, so the loop here
     * will be skipped. However, consider this case of two components side-by-side:
     *
     * App template:
     * ```
     * <comp></comp>
     * <comp></comp>
     * ```
     *
     * The following will happen:
     * 1. App template begins processing.
     * 2. First <comp> is matched as a component and its LView is created.
     * 3. Second <comp> is matched as a component and its LView is created.
     * 4. App template completes processing, so it's time to check child templates.
     * 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
     * 6. Second <comp> template is checked. Its blueprint has been updated by the first
     * <comp> template, but its LView was created before this update, so it is out of sync.
     *
     * Note that embedded views inside ngFor loops will never be out of sync because these views
     * are processed as soon as they are created.
     *
     * @param componentView The view to sync
     */
    function syncViewWithBlueprint(componentView) {
        var componentTView = componentView[TVIEW];
        for (var i = componentView.length; i < componentTView.blueprint.length; i++) {
            componentView[i] = componentTView.blueprint[i];
        }
    }
    /**
     * Adds LView or LContainer to the end of the current view tree.
     *
     * This structure will be used to traverse through nested views to remove listeners
     * and call onDestroy callbacks.
     *
     * @param lView The view where LView or LContainer should be added
     * @param adjustedHostIndex Index of the view's host node in LView[], adjusted for header
     * @param lViewOrLContainer The LView or LContainer to add to the view tree
     * @returns The state passed in
     */
    function addToViewTree(lView, lViewOrLContainer) {
        // TODO(benlesh/misko): This implementation is incorrect, because it always adds the LContainer
        // to
        // the end of the queue, which means if the developer retrieves the LContainers from RNodes out
        // of
        // order, the change detection will run out of order, as the act of retrieving the the
        // LContainer
        // from the RNode is what adds it to the queue.
        if (lView[CHILD_HEAD]) {
            lView[CHILD_TAIL][NEXT] = lViewOrLContainer;
        }
        else {
            lView[CHILD_HEAD] = lViewOrLContainer;
        }
        lView[CHILD_TAIL] = lViewOrLContainer;
        return lViewOrLContainer;
    }
    ///////////////////////////////
    //// Change detection
    ///////////////////////////////
    /**
     * Marks current view and all ancestors dirty.
     *
     * Returns the root view because it is found as a byproduct of marking the view tree
     * dirty, and can be used by methods that consume markViewDirty() to easily schedule
     * change detection. Otherwise, such methods would need to traverse up the view tree
     * an additional time to get the root view and schedule a tick on it.
     *
     * @param lView The starting LView to mark dirty
     * @returns the root LView
     */
    function markViewDirty(lView) {
        while (lView) {
            lView[FLAGS] |= 64 /* Dirty */;
            var parent_1 = getLViewParent(lView);
            // Stop traversing up as soon as you find a root view that wasn't attached to any container
            if (isRootView(lView) && !parent_1) {
                return lView;
            }
            // continue otherwise
            lView = parent_1;
        }
        return null;
    }
    /**
     * Used to schedule change detection on the whole application.
     *
     * Unlike `tick`, `scheduleTick` coalesces multiple calls into one change detection run.
     * It is usually called indirectly by calling `markDirty` when the view needs to be
     * re-rendered.
     *
     * Typically `scheduleTick` uses `requestAnimationFrame` to coalesce multiple
     * `scheduleTick` requests. The scheduling function can be overridden in
     * `renderComponent`'s `scheduler` option.
     */
    function scheduleTick(rootContext, flags) {
        var nothingScheduled = rootContext.flags === 0 /* Empty */;
        rootContext.flags |= flags;
        if (nothingScheduled && rootContext.clean == _CLEAN_PROMISE) {
            var res_1;
            rootContext.clean = new Promise(function (r) { return res_1 = r; });
            rootContext.scheduler(function () {
                if (rootContext.flags & 1 /* DetectChanges */) {
                    rootContext.flags &= ~1 /* DetectChanges */;
                    tickRootContext(rootContext);
                }
                if (rootContext.flags & 2 /* FlushPlayers */) {
                    rootContext.flags &= ~2 /* FlushPlayers */;
                    var playerHandler = rootContext.playerHandler;
                    if (playerHandler) {
                        playerHandler.flushPlayers();
                    }
                }
                rootContext.clean = _CLEAN_PROMISE;
                res_1(null);
            });
        }
    }
    function tickRootContext(rootContext) {
        for (var i = 0; i < rootContext.components.length; i++) {
            var rootComponent = rootContext.components[i];
            renderComponentOrTemplate(readPatchedLView(rootComponent), rootComponent);
        }
    }
    function detectChangesInternal(view, context) {
        var rendererFactory = view[RENDERER_FACTORY];
        if (rendererFactory.begin)
            rendererFactory.begin();
        try {
            if (isCreationMode(view)) {
                checkView(view, context); // creation mode pass
            }
            checkView(view, context); // update mode pass
        }
        catch (error) {
            handleError(view, error);
            throw error;
        }
        finally {
            if (rendererFactory.end)
                rendererFactory.end();
        }
    }
    /**
     * Synchronously perform change detection on a root view and its components.
     *
     * @param lView The view which the change detection should be performed on.
     */
    function detectChangesInRootView(lView) {
        tickRootContext(lView[CONTEXT]);
    }
    /**
     * Checks the change detector and its children, and throws if any changes are detected.
     *
     * This is used in development mode to verify that running change detection doesn't
     * introduce other changes.
     */
    function checkNoChanges(component) {
        var view = getComponentViewByInstance(component);
        checkNoChangesInternal(view, component);
    }
    function checkNoChangesInternal(view, context) {
        setCheckNoChangesMode(true);
        try {
            detectChangesInternal(view, context);
        }
        finally {
            setCheckNoChangesMode(false);
        }
    }
    /**
     * Checks the change detector on a root view and its components, and throws if any changes are
     * detected.
     *
     * This is used in development mode to verify that running change detection doesn't
     * introduce other changes.
     *
     * @param lView The view which the change detection should be checked on.
     */
    function checkNoChangesInRootView(lView) {
        setCheckNoChangesMode(true);
        try {
            detectChangesInRootView(lView);
        }
        finally {
            setCheckNoChangesMode(false);
        }
    }
    /** Checks the view of the component provided. Does not gate on dirty checks or execute doCheck.
     */
    function checkView(hostView, component) {
        var hostTView = hostView[TVIEW];
        var oldView = enterView(hostView, hostView[T_HOST]);
        var templateFn = hostTView.template;
        var creationMode = isCreationMode(hostView);
        // Will become true if the `try` block executes with no errors.
        var safeToRunHooks = false;
        try {
            resetPreOrderHookFlags(hostView);
            creationMode && executeViewQueryFn(1 /* Create */, hostTView, component);
            executeTemplate(hostView, templateFn, getRenderFlags(hostView), component);
            refreshDescendantViews(hostView);
            safeToRunHooks = true;
        }
        finally {
            leaveView(oldView, safeToRunHooks);
        }
    }
    function executeViewQueryFn(flags, tView, component) {
        var viewQuery = tView.viewQuery;
        if (viewQuery !== null) {
            setCurrentQueryIndex(0);
            viewQuery(flags, component);
        }
    }
    ///////////////////////////////
    //// Bindings & interpolations
    ///////////////////////////////
    /**
     * Creates binding metadata for a particular binding and stores it in
     * TView.data. These are generated in order to support DebugElement.properties.
     *
     * Each binding / interpolation will have one (including attribute bindings)
     * because at the time of binding, we don't know to which instruction the binding
     * belongs. It is always stored in TView.data at the index of the last binding
     * value in LView (e.g. for interpolation8, it would be stored at the index of
     * the 8th value).
     *
     * @param lView The LView that contains the current binding index.
     * @param prefix The static prefix string
     * @param suffix The static suffix string
     *
     * @returns Newly created binding metadata string for this binding or null
     */
    function storeBindingMetadata(lView, prefix, suffix) {
        if (prefix === void 0) { prefix = ''; }
        if (suffix === void 0) { suffix = ''; }
        var tData = lView[TVIEW].data;
        var lastBindingIndex = lView[BINDING_INDEX] - 1;
        var value = INTERPOLATION_DELIMITER + prefix + INTERPOLATION_DELIMITER + suffix;
        return tData[lastBindingIndex] == null ? (tData[lastBindingIndex] = value) : null;
    }
    var CLEAN_PROMISE = _CLEAN_PROMISE;
    function initializeTNodeInputs(tNode) {
        // If tNode.inputs is undefined, a listener has created outputs, but inputs haven't
        // yet been checked.
        if (tNode.inputs === undefined) {
            // mark inputs as checked
            tNode.inputs = generatePropertyAliases(tNode, 0 /* Input */);
        }
        return tNode.inputs;
    }
    function getCleanup(view) {
        // top level variables should not be exported for performance reasons (PERF_NOTES.md)
        return view[CLEANUP] || (view[CLEANUP] = ngDevMode ? new LCleanup() : []);
    }
    function getTViewCleanup(view) {
        return view[TVIEW].cleanup || (view[TVIEW].cleanup = ngDevMode ? new TCleanup() : []);
    }
    /**
     * There are cases where the sub component's renderer needs to be included
     * instead of the current renderer (see the componentSyntheticHost* instructions).
     */
    function loadComponentRenderer(tNode, lView) {
        var componentLView = lView[tNode.index];
        return componentLView[RENDERER];
    }
    /** Handles an error thrown in an LView. */
    function handleError(lView, error) {
        var injector = lView[INJECTOR$1];
        var errorHandler = injector ? injector.get(ErrorHandler, null) : null;
        errorHandler && errorHandler.handleError(error);
    }
    /**
     * Set the inputs of directives at the current node to corresponding value.
     *
     * @param lView the `LView` which contains the directives.
     * @param inputs mapping between the public "input" name and privately-known,
     * possibly minified, property names to write to.
     * @param value Value to set.
     */
    function setInputsForProperty(lView, inputs, value) {
        var tView = lView[TVIEW];
        for (var i = 0; i < inputs.length;) {
            var index = inputs[i++];
            var publicName = inputs[i++];
            var privateName = inputs[i++];
            var instance = lView[index];
            ngDevMode && assertDataInRange(lView, index);
            var def = tView.data[index];
            var setInput = def.setInput;
            if (setInput) {
                def.setInput(instance, value, publicName, privateName);
            }
            else {
                instance[privateName] = value;
            }
        }
    }
    /**
     * Updates a text binding at a given index in a given LView.
     */
    function textBindingInternal(lView, index, value) {
        ngDevMode && assertNotSame(value, NO_CHANGE, 'value should not be NO_CHANGE');
        ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
        var element = getNativeByIndex(index, lView);
        ngDevMode && assertDefined(element, 'native element should exist');
        ngDevMode && ngDevMode.rendererSetText++;
        var renderer = lView[RENDERER];
        isProceduralRenderer(renderer) ? renderer.setValue(element, value) : element.textContent = value;
    }
    /**
     * Renders all initial styling (class and style values) on to the element from the tNode.
     *
     * All initial styling data (i.e. any values extracted from the `style` or `class` attributes
     * on an element) are collected into the `tNode.styles` and `tNode.classes` data structures.
     * These values are populated during the creation phase of an element and are then later
     * applied once the element is instantiated. This function applies each of the static
     * style and class entries to the element.
     */
    function renderInitialStyling(renderer, native, tNode) {
        renderStylingMap(renderer, native, tNode.classes, true);
        renderStylingMap(renderer, native, tNode.styles, false);
    }

    /**
     * @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
     */
    var unusedValueToPlacateAjd$1 = unusedValueExportToPlacateAjd$1 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$5 + unusedValueExportToPlacateAjd$3 + unusedValueExportToPlacateAjd;
    function getLContainer(tNode, embeddedView) {
        ngDevMode && assertLView(embeddedView);
        var container = embeddedView[PARENT];
        if (tNode.index === -1) {
            // This is a dynamically created view inside a dynamic container.
            // The parent isn't an LContainer if the embedded view hasn't been attached yet.
            return isLContainer(container) ? container : null;
        }
        else {
            ngDevMode && assertLContainer(container);
            // This is a inline view node (e.g. embeddedViewStart)
            return container;
        }
    }
    /**
     * Retrieves render parent for a given view.
     * Might be null if a view is not yet attached to any container.
     */
    function getContainerRenderParent(tViewNode, view) {
        var container = getLContainer(tViewNode, view);
        return container ? nativeParentNode(view[RENDERER], container[NATIVE]) : null;
    }
    /**
     * NOTE: for performance reasons, the possible actions are inlined within the function instead of
     * being passed as an argument.
     */
    function executeActionOnElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
        // If this slot was allocated for a text node dynamically created by i18n, the text node itself
        // won't be created until i18nApply() in the update block, so this node should be skipped.
        // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
        // in `i18n_spec.ts`.
        if (lNodeToHandle != null) {
            var lContainer = void 0;
            var isComponent = false;
            // We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
            // wrapped
            // in an array which needs to be unwrapped. We need to know if it is a component and if
            // it has LContainer so that we can process all of those cases appropriately.
            if (isLContainer(lNodeToHandle)) {
                lContainer = lNodeToHandle;
            }
            else if (isLView(lNodeToHandle)) {
                isComponent = true;
                ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
                lNodeToHandle = lNodeToHandle[HOST];
            }
            var rNode = unwrapRNode(lNodeToHandle);
            ngDevMode && assertDomNode(rNode);
            if (action === 0 /* Insert */) {
                nativeInsertBefore(renderer, parent, rNode, beforeNode || null);
            }
            else if (action === 1 /* Detach */) {
                nativeRemoveNode(renderer, rNode, isComponent);
            }
            else if (action === 2 /* Destroy */) {
                ngDevMode && ngDevMode.rendererDestroyNode++;
                renderer.destroyNode(rNode);
            }
            if (lContainer != null) {
                executeActionOnContainer(renderer, action, lContainer, parent, beforeNode);
            }
        }
    }
    function createTextNode(value, renderer) {
        return isProceduralRenderer(renderer) ? renderer.createText(renderStringify(value)) :
            renderer.createTextNode(renderStringify(value));
    }
    function addRemoveViewFromContainer(lView, insertMode, beforeNode) {
        var renderParent = getContainerRenderParent(lView[TVIEW].node, lView);
        ngDevMode && assertNodeType(lView[TVIEW].node, 2 /* View */);
        if (renderParent) {
            var renderer = lView[RENDERER];
            var action = insertMode ? 0 /* Insert */ : 1 /* Detach */;
            executeActionOnView(renderer, action, lView, renderParent, beforeNode);
        }
    }
    /**
     * Detach a `LView` from the DOM by detaching its nodes.
     *
     * @param lView the `LView` to be detached.
     */
    function renderDetachView(lView) {
        executeActionOnView(lView[RENDERER], 1 /* Detach */, lView, null, null);
    }
    /**
     * Traverses down and up the tree of views and containers to remove listeners and
     * call onDestroy callbacks.
     *
     * Notes:
     *  - Because it's used for onDestroy calls, it needs to be bottom-up.
     *  - Must process containers instead of their views to avoid splicing
     *  when views are destroyed and re-added.
     *  - Using a while loop because it's faster than recursion
     *  - Destroy only called on movement to sibling or movement to parent (laterally or up)
     *
     *  @param rootView The view to destroy
     */
    function destroyViewTree(rootView) {
        // If the view has no children, we can clean it up and return early.
        var lViewOrLContainer = rootView[CHILD_HEAD];
        if (!lViewOrLContainer) {
            return cleanUpView(rootView);
        }
        while (lViewOrLContainer) {
            var next = null;
            if (isLView(lViewOrLContainer)) {
                // If LView, traverse down to child.
                next = lViewOrLContainer[CHILD_HEAD];
            }
            else {
                ngDevMode && assertLContainer(lViewOrLContainer);
                // If container, traverse down to its first LView.
                var firstView = lViewOrLContainer[CONTAINER_HEADER_OFFSET];
                if (firstView)
                    next = firstView;
            }
            if (!next) {
                // Only clean up view when moving to the side or up, as destroy hooks
                // should be called in order from the bottom up.
                while (lViewOrLContainer && !lViewOrLContainer[NEXT] && lViewOrLContainer !== rootView) {
                    cleanUpView(lViewOrLContainer);
                    lViewOrLContainer = getParentState(lViewOrLContainer, rootView);
                }
                cleanUpView(lViewOrLContainer || rootView);
                next = lViewOrLContainer && lViewOrLContainer[NEXT];
            }
            lViewOrLContainer = next;
        }
    }
    /**
     * Inserts a view into a container.
     *
     * This adds the view to the container's array of active views in the correct
     * position. It also adds the view's elements to the DOM if the container isn't a
     * root node of another view (in that case, the view's elements will be added when
     * the container's parent view is added later).
     *
     * @param lView The view to insert
     * @param lContainer The container into which the view should be inserted
     * @param index Which index in the container to insert the child view into
     */
    function insertView(lView, lContainer, index) {
        ngDevMode && assertLView(lView);
        ngDevMode && assertLContainer(lContainer);
        var indexInContainer = CONTAINER_HEADER_OFFSET + index;
        var containerLength = lContainer.length;
        if (index > 0) {
            // This is a new view, we need to add it to the children.
            lContainer[indexInContainer - 1][NEXT] = lView;
        }
        if (index < containerLength - CONTAINER_HEADER_OFFSET) {
            lView[NEXT] = lContainer[indexInContainer];
            addToArray(lContainer, CONTAINER_HEADER_OFFSET + index, lView);
        }
        else {
            lContainer.push(lView);
            lView[NEXT] = null;
        }
        lView[PARENT] = lContainer;
        // track views where declaration and insertion points are different
        var declarationLContainer = lView[DECLARATION_LCONTAINER];
        if (declarationLContainer !== null && lContainer !== declarationLContainer) {
            trackMovedView(declarationLContainer, lView);
        }
        // notify query that a new view has been added
        var lQueries = lView[QUERIES];
        if (lQueries !== null) {
            lQueries.insertView(lView[TVIEW]);
        }
        // Sets the attached flag
        lView[FLAGS] |= 128 /* Attached */;
    }
    /**
     * Track views created from the declaration container (TemplateRef) and inserted into a
     * different LContainer.
     */
    function trackMovedView(declarationContainer, lView) {
        ngDevMode && assertLContainer(declarationContainer);
        var declaredViews = declarationContainer[MOVED_VIEWS];
        if (declaredViews === null) {
            declarationContainer[MOVED_VIEWS] = [lView];
        }
        else {
            declaredViews.push(lView);
        }
    }
    function detachMovedView(declarationContainer, lView) {
        ngDevMode && assertLContainer(declarationContainer);
        ngDevMode && assertDefined(declarationContainer[MOVED_VIEWS], 'A projected view should belong to a non-empty projected views collection');
        var projectedViews = declarationContainer[MOVED_VIEWS];
        var declaredViewIndex = projectedViews.indexOf(lView);
        projectedViews.splice(declaredViewIndex, 1);
    }
    /**
     * Detaches a view from a container.
     *
     * This method removes the view from the container's array of active views. It also
     * removes the view's elements from the DOM.
     *
     * @param lContainer The container from which to detach a view
     * @param removeIndex The index of the view to detach
     * @returns Detached LView instance.
     */
    function detachView(lContainer, removeIndex) {
        if (lContainer.length <= CONTAINER_HEADER_OFFSET)
            return;
        var indexInContainer = CONTAINER_HEADER_OFFSET + removeIndex;
        var viewToDetach = lContainer[indexInContainer];
        if (viewToDetach) {
            var declarationLContainer = viewToDetach[DECLARATION_LCONTAINER];
            if (declarationLContainer !== null && declarationLContainer !== lContainer) {
                detachMovedView(declarationLContainer, viewToDetach);
            }
            if (removeIndex > 0) {
                lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT];
            }
            var removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);
            addRemoveViewFromContainer(viewToDetach, false);
            // notify query that a view has been removed
            var lQueries = removedLView[QUERIES];
            if (lQueries !== null) {
                lQueries.detachView(removedLView[TVIEW]);
            }
            viewToDetach[PARENT] = null;
            viewToDetach[NEXT] = null;
            // Unsets the attached flag
            viewToDetach[FLAGS] &= ~128 /* Attached */;
        }
        return viewToDetach;
    }
    /**
     * Removes a view from a container, i.e. detaches it and then destroys the underlying LView.
     *
     * @param lContainer The container from which to remove a view
     * @param removeIndex The index of the view to remove
     */
    function removeView(lContainer, removeIndex) {
        var detachedView = detachView(lContainer, removeIndex);
        detachedView && destroyLView(detachedView);
    }
    /**
     * A standalone function which destroys an LView,
     * conducting cleanup (e.g. removing listeners, calling onDestroys).
     *
     * @param lView The view to be destroyed.
     */
    function destroyLView(lView) {
        if (!(lView[FLAGS] & 256 /* Destroyed */)) {
            var renderer = lView[RENDERER];
            if (isProceduralRenderer(renderer) && renderer.destroyNode) {
                executeActionOnView(renderer, 2 /* Destroy */, lView, null, null);
            }
            destroyViewTree(lView);
        }
    }
    /**
     * Determines which LViewOrLContainer to jump to when traversing back up the
     * tree in destroyViewTree.
     *
     * Normally, the view's parent LView should be checked, but in the case of
     * embedded views, the container (which is the view node's parent, but not the
     * LView's parent) needs to be checked for a possible next property.
     *
     * @param lViewOrLContainer The LViewOrLContainer for which we need a parent state
     * @param rootView The rootView, so we don't propagate too far up the view tree
     * @returns The correct parent LViewOrLContainer
     */
    function getParentState(lViewOrLContainer, rootView) {
        var tNode;
        if (isLView(lViewOrLContainer) && (tNode = lViewOrLContainer[T_HOST]) &&
            tNode.type === 2 /* View */) {
            // if it's an embedded view, the state needs to go up to the container, in case the
            // container has a next
            return getLContainer(tNode, lViewOrLContainer);
        }
        else {
            // otherwise, use parent view for containers or component views
            return lViewOrLContainer[PARENT] === rootView ? null : lViewOrLContainer[PARENT];
        }
    }
    /**
     * Calls onDestroys hooks for all directives and pipes in a given view and then removes all
     * listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
     * can be propagated to @Output listeners.
     *
     * @param view The LView to clean up
     */
    function cleanUpView(view) {
        if (isLView(view) && !(view[FLAGS] & 256 /* Destroyed */)) {
            // Usually the Attached flag is removed when the view is detached from its parent, however
            // if it's a root view, the flag won't be unset hence why we're also removing on destroy.
            view[FLAGS] &= ~128 /* Attached */;
            // Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook
            // runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If
            // We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.
            // This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
            // really more of an "afterDestroy" hook if you think about it.
            view[FLAGS] |= 256 /* Destroyed */;
            executeOnDestroys(view);
            removeListeners(view);
            var hostTNode = view[T_HOST];
            // For component views only, the local renderer is destroyed as clean up time.
            if (hostTNode && hostTNode.type === 3 /* Element */ && isProceduralRenderer(view[RENDERER])) {
                ngDevMode && ngDevMode.rendererDestroy++;
                view[RENDERER].destroy();
            }
            var declarationContainer = view[DECLARATION_LCONTAINER];
            // we are dealing with an embedded view that is still inserted into a container
            if (declarationContainer !== null && isLContainer(view[PARENT])) {
                // and this is a projected view
                if (declarationContainer !== view[PARENT]) {
                    detachMovedView(declarationContainer, view);
                }
                // For embedded views still attached to a container: remove query result from this view.
                var lQueries = view[QUERIES];
                if (lQueries !== null) {
                    lQueries.detachView(view[TVIEW]);
                }
            }
        }
    }
    /** Removes listeners and unsubscribes from output subscriptions */
    function removeListeners(lView) {
        var tCleanup = lView[TVIEW].cleanup;
        if (tCleanup !== null) {
            var lCleanup = lView[CLEANUP];
            for (var i = 0; i < tCleanup.length - 1; i += 2) {
                if (typeof tCleanup[i] === 'string') {
                    // This is a native DOM listener
                    var idxOrTargetGetter = tCleanup[i + 1];
                    var target = typeof idxOrTargetGetter === 'function' ?
                        idxOrTargetGetter(lView) :
                        unwrapRNode(lView[idxOrTargetGetter]);
                    var listener = lCleanup[tCleanup[i + 2]];
                    var useCaptureOrSubIdx = tCleanup[i + 3];
                    if (typeof useCaptureOrSubIdx === 'boolean') {
                        // native DOM listener registered with Renderer3
                        target.removeEventListener(tCleanup[i], listener, useCaptureOrSubIdx);
                    }
                    else {
                        if (useCaptureOrSubIdx >= 0) {
                            // unregister
                            lCleanup[useCaptureOrSubIdx]();
                        }
                        else {
                            // Subscription
                            lCleanup[-useCaptureOrSubIdx].unsubscribe();
                        }
                    }
                    i += 2;
                }
                else {
                    // This is a cleanup function that is grouped with the index of its context
                    var context = lCleanup[tCleanup[i + 1]];
                    tCleanup[i].call(context);
                }
            }
            lView[CLEANUP] = null;
        }
    }
    /** Calls onDestroy hooks for this view */
    function executeOnDestroys(view) {
        var tView = view[TVIEW];
        var destroyHooks;
        if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
            for (var i = 0; i < destroyHooks.length; i += 2) {
                var context = view[destroyHooks[i]];
                // Only call the destroy hook if the context has been requested.
                if (!(context instanceof NodeInjectorFactory)) {
                    destroyHooks[i + 1].call(context);
                }
            }
        }
    }
    /**
     * Returns a native element if a node can be inserted into the given parent.
     *
     * There are two reasons why we may not be able to insert a element immediately.
     * - Projection: When creating a child content element of a component, we have to skip the
     *   insertion because the content of a component will be projected.
     *   `<component><content>delayed due to projection</content></component>`
     * - Parent container is disconnected: This can happen when we are inserting a view into
     *   parent container, which itself is disconnected. For example the parent container is part
     *   of a View which has not be inserted or is made for projection but has not been inserted
     *   into destination.
     */
    function getRenderParent(tNode, currentView) {
        // Nodes of the top-most view can be inserted eagerly.
        if (isRootView(currentView)) {
            return nativeParentNode(currentView[RENDERER], getNativeByTNode(tNode, currentView));
        }
        // Skip over element and ICU containers as those are represented by a comment node and
        // can't be used as a render parent.
        var parent = getHighestElementOrICUContainer(tNode);
        var renderParent = parent.parent;
        // If the parent is null, then we are inserting across views: either into an embedded view or a
        // component view.
        if (renderParent == null) {
            var hostTNode = currentView[T_HOST];
            if (hostTNode.type === 2 /* View */) {
                // We are inserting a root element of an embedded view We might delay insertion of children
                // for a given view if it is disconnected. This might happen for 2 main reasons:
                // - view is not inserted into any container(view was created but not inserted yet)
                // - view is inserted into a container but the container itself is not inserted into the DOM
                // (container might be part of projection or child of a view that is not inserted yet).
                // In other words we can insert children of a given view if this view was inserted into a
                // container and the container itself has its render parent determined.
                return getContainerRenderParent(hostTNode, currentView);
            }
            else {
                // We are inserting a root element of the component view into the component host element and
                // it should always be eager.
                return getHostNative(currentView);
            }
        }
        else {
            var isIcuCase = parent && parent.type === 5 /* IcuContainer */;
            // If the parent of this node is an ICU container, then it is represented by comment node and we
            // need to use it as an anchor. If it is projected then its direct parent node is the renderer.
            if (isIcuCase && parent.flags & 2 /* isProjected */) {
                return getNativeByTNode(parent, currentView).parentNode;
            }
            ngDevMode && assertNodeType(renderParent, 3 /* Element */);
            if (renderParent.flags & 1 /* isComponent */ && !isIcuCase) {
                var tData = currentView[TVIEW].data;
                var tNode_1 = tData[renderParent.index];
                var encapsulation = tData[tNode_1.directiveStart].encapsulation;
                // We've got a parent which is an element in the current view. We just need to verify if the
                // parent element is not a component. Component's content nodes are not inserted immediately
                // because they will be projected, and so doing insert at this point would be wasteful.
                // Since the projection would then move it to its final destination. Note that we can't
                // make this assumption when using the Shadow DOM, because the native projection placeholders
                // (<content> or <slot>) have to be in place as elements are being inserted.
                if (encapsulation !== exports.ViewEncapsulation.ShadowDom &&
                    encapsulation !== exports.ViewEncapsulation.Native) {
                    return null;
                }
            }
            return getNativeByTNode(renderParent, currentView);
        }
    }
    /**
     * Gets the native host element for a given view. Will return null if the current view does not have
     * a host element.
     */
    function getHostNative(currentView) {
        ngDevMode && assertLView(currentView);
        var hostTNode = currentView[T_HOST];
        return hostTNode && hostTNode.type === 3 /* Element */ ?
            getNativeByTNode(hostTNode, getLViewParent(currentView)) :
            null;
    }
    /**
     * Inserts a native node before another native node for a given parent using {@link Renderer3}.
     * This is a utility function that can be used when native nodes were determined - it abstracts an
     * actual renderer being used.
     */
    function nativeInsertBefore(renderer, parent, child, beforeNode) {
        ngDevMode && ngDevMode.rendererInsertBefore++;
        if (isProceduralRenderer(renderer)) {
            renderer.insertBefore(parent, child, beforeNode);
        }
        else {
            parent.insertBefore(child, beforeNode, true);
        }
    }
    function nativeAppendChild(renderer, parent, child) {
        ngDevMode && ngDevMode.rendererAppendChild++;
        if (isProceduralRenderer(renderer)) {
            renderer.appendChild(parent, child);
        }
        else {
            parent.appendChild(child);
        }
    }
    function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode) {
        if (beforeNode !== null) {
            nativeInsertBefore(renderer, parent, child, beforeNode);
        }
        else {
            nativeAppendChild(renderer, parent, child);
        }
    }
    /** Removes a node from the DOM given its native parent. */
    function nativeRemoveChild(renderer, parent, child, isHostElement) {
        if (isProceduralRenderer(renderer)) {
            renderer.removeChild(parent, child, isHostElement);
        }
        else {
            parent.removeChild(child);
        }
    }
    /**
     * Returns a native parent of a given native node.
     */
    function nativeParentNode(renderer, node) {
        return (isProceduralRenderer(renderer) ? renderer.parentNode(node) : node.parentNode);
    }
    /**
     * Returns a native sibling of a given native node.
     */
    function nativeNextSibling(renderer, node) {
        return isProceduralRenderer(renderer) ? renderer.nextSibling(node) : node.nextSibling;
    }
    /**
     * Finds a native "anchor" node for cases where we can't append a native child directly
     * (`appendChild`) and need to use a reference (anchor) node for the `insertBefore` operation.
     * @param parentTNode
     * @param lView
     */
    function getNativeAnchorNode(parentTNode, lView) {
        if (parentTNode.type === 2 /* View */) {
            var lContainer = getLContainer(parentTNode, lView);
            var index = lContainer.indexOf(lView, CONTAINER_HEADER_OFFSET) - CONTAINER_HEADER_OFFSET;
            return getBeforeNodeForView(index, lContainer);
        }
        else if (parentTNode.type === 4 /* ElementContainer */ ||
            parentTNode.type === 5 /* IcuContainer */) {
            return getNativeByTNode(parentTNode, lView);
        }
        return null;
    }
    /**
     * Appends the `child` native node (or a collection of nodes) to the `parent`.
     *
     * The element insertion might be delayed {@link canInsertNativeNode}.
     *
     * @param childEl The native child (or children) that should be appended
     * @param childTNode The TNode of the child element
     * @param currentView The current LView
     * @returns Whether or not the child was appended
     */
    function appendChild(childEl, childTNode, currentView) {
        var e_1, _a;
        var renderParent = getRenderParent(childTNode, currentView);
        if (renderParent != null) {
            var renderer = currentView[RENDERER];
            var parentTNode = childTNode.parent || currentView[T_HOST];
            var anchorNode = getNativeAnchorNode(parentTNode, currentView);
            if (Array.isArray(childEl)) {
                try {
                    for (var childEl_1 = __values(childEl), childEl_1_1 = childEl_1.next(); !childEl_1_1.done; childEl_1_1 = childEl_1.next()) {
                        var nativeNode = childEl_1_1.value;
                        nativeAppendOrInsertBefore(renderer, renderParent, nativeNode, anchorNode);
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (childEl_1_1 && !childEl_1_1.done && (_a = childEl_1.return)) _a.call(childEl_1);
                    }
                    finally { if (e_1) throw e_1.error; }
                }
            }
            else {
                nativeAppendOrInsertBefore(renderer, renderParent, childEl, anchorNode);
            }
        }
    }
    /**
     * Gets the top-level element or an ICU container if those containers are nested.
     *
     * @param tNode The starting TNode for which we should skip element and ICU containers
     * @returns The TNode of the highest level ICU container or element container
     */
    function getHighestElementOrICUContainer(tNode) {
        while (tNode.parent != null && (tNode.parent.type === 4 /* ElementContainer */ ||
            tNode.parent.type === 5 /* IcuContainer */)) {
            tNode = tNode.parent;
        }
        return tNode;
    }
    function getBeforeNodeForView(viewIndexInContainer, lContainer) {
        var nextViewIndex = CONTAINER_HEADER_OFFSET + viewIndexInContainer + 1;
        if (nextViewIndex < lContainer.length) {
            var lView = lContainer[nextViewIndex];
            ngDevMode && assertDefined(lView[T_HOST], 'Missing Host TNode');
            var tViewNodeChild = lView[T_HOST].child;
            return tViewNodeChild !== null ? getNativeByTNodeOrNull(tViewNodeChild, lView) :
                lContainer[NATIVE];
        }
        else {
            return lContainer[NATIVE];
        }
    }
    /**
     * Removes a native node itself using a given renderer. To remove the node we are looking up its
     * parent from the native tree as not all platforms / browsers support the equivalent of
     * node.remove().
     *
     * @param renderer A renderer to be used
     * @param rNode The native node that should be removed
     * @param isHostElement A flag indicating if a node to be removed is a host of a component.
     */
    function nativeRemoveNode(renderer, rNode, isHostElement) {
        var nativeParent = nativeParentNode(renderer, rNode);
        if (nativeParent) {
            nativeRemoveChild(renderer, nativeParent, rNode, isHostElement);
        }
    }
    /**
     * Appends nodes to a target projection place. Nodes to insert were previously re-distribution and
     * stored on a component host level.
     * @param lView A LView where nodes are inserted (target LView)
     * @param tProjectionNode A projection node where previously re-distribution should be appended
     * (target insertion place)
     * @param selectorIndex A bucket from where nodes to project should be taken
     * @param componentView A where projectable nodes were initially created (source view)
     */
    function appendProjectedNodes(lView, tProjectionNode, selectorIndex, componentView) {
        var projectedView = componentView[PARENT];
        var componentNode = componentView[T_HOST];
        var nodeToProject = componentNode.projection[selectorIndex];
        if (Array.isArray(nodeToProject)) {
            appendChild(nodeToProject, tProjectionNode, lView);
        }
        else {
            while (nodeToProject) {
                if (!(nodeToProject.flags & 32 /* isDetached */)) {
                    if (nodeToProject.type === 1 /* Projection */) {
                        appendProjectedNodes(lView, tProjectionNode, nodeToProject.projection, findComponentView(projectedView));
                    }
                    else {
                        // This flag must be set now or we won't know that this node is projected
                        // if the nodes are inserted into a container later.
                        nodeToProject.flags |= 2 /* isProjected */;
                        appendProjectedNode(nodeToProject, tProjectionNode, lView, projectedView);
                    }
                }
                nodeToProject = nodeToProject.projectionNext;
            }
        }
    }
    /**
     * Loops over all children of a TNode container and appends them to the DOM
     *
     * @param ngContainerChildTNode The first child of the TNode container
     * @param tProjectionNode The projection (ng-content) TNode
     * @param currentView Current LView
     * @param projectionView Projection view (view above current)
     */
    function appendProjectedChildren(ngContainerChildTNode, tProjectionNode, currentView, projectionView) {
        while (ngContainerChildTNode) {
            appendProjectedNode(ngContainerChildTNode, tProjectionNode, currentView, projectionView);
            ngContainerChildTNode = ngContainerChildTNode.next;
        }
    }
    /**
     * Appends a projected node to the DOM, or in the case of a projected container,
     * appends the nodes from all of the container's active views to the DOM.
     *
     * @param projectedTNode The TNode to be projected
     * @param tProjectionNode The projection (ng-content) TNode
     * @param currentView Current LView
     * @param projectionView Projection view (view above current)
     */
    function appendProjectedNode(projectedTNode, tProjectionNode, currentView, projectionView) {
        var native = getNativeByTNode(projectedTNode, projectionView);
        appendChild(native, tProjectionNode, currentView);
        // the projected contents are processed while in the shadow view (which is the currentView)
        // therefore we need to extract the view where the host element lives since it's the
        // logical container of the content projected views
        attachPatchData(native, projectionView);
        var nodeOrContainer = projectionView[projectedTNode.index];
        if (projectedTNode.type === 0 /* Container */) {
            // The node we are adding is a container and we are adding it to an element which
            // is not a component (no more re-projection).
            // Alternatively a container is projected at the root of a component's template
            // and can't be re-projected (as not content of any component).
            // Assign the final projection location in those cases.
            for (var i = CONTAINER_HEADER_OFFSET; i < nodeOrContainer.length; i++) {
                addRemoveViewFromContainer(nodeOrContainer[i], true, nodeOrContainer[NATIVE]);
            }
        }
        else if (projectedTNode.type === 5 /* IcuContainer */) {
            // The node we are adding is an ICU container which is why we also need to project all the
            // children nodes that might have been created previously and are linked to this anchor
            var ngContainerChildTNode = projectedTNode.child;
            appendProjectedChildren(ngContainerChildTNode, ngContainerChildTNode, projectionView, projectionView);
        }
        else {
            if (projectedTNode.type === 4 /* ElementContainer */) {
                appendProjectedChildren(projectedTNode.child, tProjectionNode, currentView, projectionView);
            }
            if (isLContainer(nodeOrContainer)) {
                appendChild(nodeOrContainer[NATIVE], tProjectionNode, currentView);
            }
        }
    }
    /**
     * `executeActionOnView` performs an operation on the view as specified in `action` (insert, detach,
     * destroy)
     *
     * Inserting a view without projection or containers at top level is simple. Just iterate over the
     * root nodes of the View, and for each node perform the `action`.
     *
     * Things get more complicated with containers and projections. That is because coming across:
     * - Container: implies that we have to insert/remove/destroy the views of that container as well
     *              which in turn can have their own Containers at the View roots.
     * - Projection: implies that we have to insert/remove/destroy the nodes of the projection. The
     *               complication is that the nodes we are projecting can themselves have Containers
     *               or other Projections.
     *
     * As you can see this is a very recursive problem. While the recursive implementation is not the
     * most efficient one, trying to unroll the nodes non-recursively results in very complex code that
     * is very hard (to maintain). We are sacrificing a bit of performance for readability using a
     * recursive implementation.
     *
     * @param renderer Renderer to use
     * @param action action to perform (insert, detach, destroy)
     * @param lView The LView which needs to be inserted, detached, destroyed.
     * @param renderParent parent DOM element for insertion/removal.
     * @param beforeNode Before which node the insertions should happen.
     */
    function executeActionOnView(renderer, action, lView, renderParent, beforeNode) {
        var tView = lView[TVIEW];
        ngDevMode && assertNodeType(tView.node, 2 /* View */);
        var viewRootTNode = tView.node.child;
        while (viewRootTNode !== null) {
            executeActionOnNode(renderer, action, lView, viewRootTNode, renderParent, beforeNode);
            viewRootTNode = viewRootTNode.next;
        }
    }
    /**
     * `executeActionOnProjection` performs an operation on the projection specified by `action`
     * (insert, detach, destroy).
     *
     * Inserting a projection requires us to locate the projected nodes from the parent component. The
     * complication is that those nodes themselves could be re-projected from their parent component.
     *
     * @param renderer Renderer to use
     * @param action action to perform (insert, detach, destroy)
     * @param lView The LView which needs to be inserted, detached, destroyed.
     * @param tProjectionNode projection TNode to process
     * @param renderParent parent DOM element for insertion/removal.
     * @param beforeNode Before which node the insertions should happen.
     */
    function executeActionOnProjection(renderer, action, lView, tProjectionNode, renderParent, beforeNode) {
        var componentLView = findComponentView(lView);
        var componentNode = componentLView[T_HOST];
        ngDevMode && assertDefined(componentNode.projection, 'Element nodes for which projection is processed must have projection defined.');
        var nodeToProject = componentNode.projection[tProjectionNode.projection];
        if (nodeToProject !== undefined) {
            if (Array.isArray(nodeToProject)) {
                for (var i = 0; i < nodeToProject.length; i++) {
                    var rNode = nodeToProject[i];
                    ngDevMode && assertDomNode(rNode);
                    executeActionOnElementOrContainer(action, renderer, renderParent, rNode, beforeNode);
                }
            }
            else {
                var projectionTNode = nodeToProject;
                var projectedComponentLView = componentLView[PARENT];
                while (projectionTNode !== null) {
                    executeActionOnNode(renderer, action, projectedComponentLView, projectionTNode, renderParent, beforeNode);
                    projectionTNode = projectionTNode.projectionNext;
                }
            }
        }
    }
    /**
     * `executeActionOnContainer` performs an operation on the container and its views as specified by
     * `action` (insert, detach, destroy)
     *
     * Inserting a Container is complicated by the fact that the container may have Views which
     * themselves have containers or projections.
     *
     * @param renderer Renderer to use
     * @param action action to perform (insert, detach, destroy)
     * @param lContainer The LContainer which needs to be inserted, detached, destroyed.
     * @param renderParent parent DOM element for insertion/removal.
     * @param beforeNode Before which node the insertions should happen.
     */
    function executeActionOnContainer(renderer, action, lContainer, renderParent, beforeNode) {
        ngDevMode && assertLContainer(lContainer);
        var anchor = lContainer[NATIVE]; // LContainer has its own before node.
        var native = unwrapRNode(lContainer);
        // An LContainer can be created dynamically on any node by injecting ViewContainerRef.
        // Asking for a ViewContainerRef on an element will result in a creation of a separate anchor node
        // (comment in the DOM) that will be different from the LContainer's host node. In this particular
        // case we need to execute action on 2 nodes:
        // - container's host node (this is done in the executeNodeAction)
        // - container's host node (this is done here)
        if (anchor !== native) {
            executeActionOnElementOrContainer(action, renderer, renderParent, anchor, beforeNode);
        }
        for (var i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
            var lView = lContainer[i];
            executeActionOnView(renderer, action, lView, renderParent, anchor);
        }
    }
    /**
     * `executeActionOnElementContainerOrIcuContainer` performs an operation on the ng-container node
     * and its child nodes as specified by the `action` (insert, detach, destroy).
     *
     * @param renderer Renderer to use
     * @param action action to perform (insert, detach, destroy)
     * @param lView The LView which needs to be inserted, detached, destroyed.
     * @param tNode The TNode associated with the `ElementContainer` or `IcuContainer`.
     * @param renderParent parent DOM element for insertion/removal.
     * @param beforeNode Before which node the insertions should happen.
     */
    function executeActionOnElementContainerOrIcuContainer(renderer, action, lView, tNode, renderParent, beforeNode) {
        var node = lView[tNode.index];
        executeActionOnElementOrContainer(action, renderer, renderParent, node, beforeNode);
        var childTNode = tNode.child;
        while (childTNode) {
            executeActionOnNode(renderer, action, lView, childTNode, renderParent, beforeNode);
            childTNode = childTNode.next;
        }
    }
    function executeActionOnNode(renderer, action, lView, tNode, renderParent, beforeNode) {
        var nodeType = tNode.type;
        if (!(tNode.flags & 32 /* isDetached */)) {
            if (nodeType === 4 /* ElementContainer */ || nodeType === 5 /* IcuContainer */) {
                executeActionOnElementContainerOrIcuContainer(renderer, action, lView, tNode, renderParent, beforeNode);
            }
            else if (nodeType === 1 /* Projection */) {
                executeActionOnProjection(renderer, action, lView, tNode, renderParent, beforeNode);
            }
            else {
                ngDevMode && assertNodeOfPossibleTypes(tNode, 3 /* Element */, 0 /* Container */);
                executeActionOnElementOrContainer(action, renderer, renderParent, lView[tNode.index], beforeNode);
            }
        }
    }

    /**
     * @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
     */
    /**
     * Unwraps a parent injector location number to find the view offset from the current injector,
     * then walks up the declaration view tree until the TNode of the parent injector is found.
     *
     * @param location The location of the parent injector, which contains the view offset
     * @param startView The LView instance from which to start walking up the view tree
     * @param startTNode The TNode instance of the starting element
     * @returns The TNode of the parent injector
     */
    function getParentInjectorTNode(location, startView, startTNode) {
        if (startTNode.parent && startTNode.parent.injectorIndex !== -1) {
            // view offset is 0
            var injectorIndex = startTNode.parent.injectorIndex;
            var parentTNode_1 = startTNode.parent;
            while (parentTNode_1.parent != null && injectorIndex == parentTNode_1.injectorIndex) {
                parentTNode_1 = parentTNode_1.parent;
            }
            return parentTNode_1;
        }
        var viewOffset = getParentInjectorViewOffset(location);
        // view offset is 1
        var parentView = startView;
        var parentTNode = startView[T_HOST];
        // view offset is superior to 1
        while (viewOffset > 1) {
            parentView = parentView[DECLARATION_VIEW];
            parentTNode = parentView[T_HOST];
            viewOffset--;
        }
        return parentTNode;
    }

    /**
     * @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
     */
    var ViewRef = /** @class */ (function () {
        function ViewRef(_lView, _context, _componentIndex) {
            this._context = _context;
            this._componentIndex = _componentIndex;
            this._appRef = null;
            this._viewContainerRef = null;
            /**
             * @internal
             */
            this._tViewNode = null;
            this._lView = _lView;
        }
        Object.defineProperty(ViewRef.prototype, "rootNodes", {
            get: function () {
                if (this._lView[HOST] == null) {
                    var tView = this._lView[T_HOST];
                    return collectNativeNodes(this._lView, tView, []);
                }
                return [];
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ViewRef.prototype, "context", {
            get: function () { return this._context ? this._context : this._lookUpContext(); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ViewRef.prototype, "destroyed", {
            get: function () {
                return (this._lView[FLAGS] & 256 /* Destroyed */) === 256 /* Destroyed */;
            },
            enumerable: true,
            configurable: true
        });
        ViewRef.prototype.destroy = function () {
            if (this._appRef) {
                this._appRef.detachView(this);
            }
            else if (this._viewContainerRef) {
                var index = this._viewContainerRef.indexOf(this);
                if (index > -1) {
                    this._viewContainerRef.detach(index);
                }
                this._viewContainerRef = null;
            }
            destroyLView(this._lView);
        };
        ViewRef.prototype.onDestroy = function (callback) { storeCleanupFn(this._lView, callback); };
        /**
         * Marks a view and all of its ancestors dirty.
         *
         * It also triggers change detection by calling `scheduleTick` internally, which coalesces
         * multiple `markForCheck` calls to into one change detection run.
         *
         * This can be used to ensure an {@link ChangeDetectionStrategy#OnPush OnPush} component is
         * checked when it needs to be re-rendered but the two normal triggers haven't marked it
         * dirty (i.e. inputs haven't changed and events haven't fired in the view).
         *
         * <!-- TODO: Add a link to a chapter on OnPush components -->
         *
         * @usageNotes
         * ### Example
         *
         * ```typescript
         * @Component({
         *   selector: 'my-app',
         *   template: `Number of ticks: {{numberOfTicks}}`
         *   changeDetection: ChangeDetectionStrategy.OnPush,
         * })
         * class AppComponent {
         *   numberOfTicks = 0;
         *
         *   constructor(private ref: ChangeDetectorRef) {
         *     setInterval(() => {
         *       this.numberOfTicks++;
         *       // the following is required, otherwise the view will not be updated
         *       this.ref.markForCheck();
         *     }, 1000);
         *   }
         * }
         * ```
         */
        ViewRef.prototype.markForCheck = function () { markViewDirty(this._lView); };
        /**
         * Detaches the view from the change detection tree.
         *
         * Detached views will not be checked during change detection runs until they are
         * re-attached, even if they are dirty. `detach` can be used in combination with
         * {@link ChangeDetectorRef#detectChanges detectChanges} to implement local change
         * detection checks.
         *
         * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
         * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
         *
         * @usageNotes
         * ### Example
         *
         * The following example defines a component with a large list of readonly data.
         * Imagine the data changes constantly, many times per second. For performance reasons,
         * we want to check and update the list every five seconds. We can do that by detaching
         * the component's change detector and doing a local check every five seconds.
         *
         * ```typescript
         * class DataProvider {
         *   // in a real application the returned data will be different every time
         *   get data() {
         *     return [1,2,3,4,5];
         *   }
         * }
         *
         * @Component({
         *   selector: 'giant-list',
         *   template: `
         *     <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
         *   `,
         * })
         * class GiantList {
         *   constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {
         *     ref.detach();
         *     setInterval(() => {
         *       this.ref.detectChanges();
         *     }, 5000);
         *   }
         * }
         *
         * @Component({
         *   selector: 'app',
         *   providers: [DataProvider],
         *   template: `
         *     <giant-list><giant-list>
         *   `,
         * })
         * class App {
         * }
         * ```
         */
        ViewRef.prototype.detach = function () { this._lView[FLAGS] &= ~128 /* Attached */; };
        /**
         * Re-attaches a view to the change detection tree.
         *
         * This can be used to re-attach views that were previously detached from the tree
         * using {@link ChangeDetectorRef#detach detach}. Views are attached to the tree by default.
         *
         * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
         *
         * @usageNotes
         * ### Example
         *
         * The following example creates a component displaying `live` data. The component will detach
         * its change detector from the main change detector tree when the component's live property
         * is set to false.
         *
         * ```typescript
         * class DataProvider {
         *   data = 1;
         *
         *   constructor() {
         *     setInterval(() => {
         *       this.data = this.data * 2;
         *     }, 500);
         *   }
         * }
         *
         * @Component({
         *   selector: 'live-data',
         *   inputs: ['live'],
         *   template: 'Data: {{dataProvider.data}}'
         * })
         * class LiveData {
         *   constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
         *
         *   set live(value) {
         *     if (value) {
         *       this.ref.reattach();
         *     } else {
         *       this.ref.detach();
         *     }
         *   }
         * }
         *
         * @Component({
         *   selector: 'my-app',
         *   providers: [DataProvider],
         *   template: `
         *     Live Update: <input type="checkbox" [(ngModel)]="live">
         *     <live-data [live]="live"><live-data>
         *   `,
         * })
         * class AppComponent {
         *   live = true;
         * }
         * ```
         */
        ViewRef.prototype.reattach = function () { this._lView[FLAGS] |= 128 /* Attached */; };
        /**
         * Checks the view and its children.
         *
         * This can also be used in combination with {@link ChangeDetectorRef#detach detach} to implement
         * local change detection checks.
         *
         * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
         * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
         *
         * @usageNotes
         * ### Example
         *
         * The following example defines a component with a large list of readonly data.
         * Imagine, the data changes constantly, many times per second. For performance reasons,
         * we want to check and update the list every five seconds.
         *
         * We can do that by detaching the component's change detector and doing a local change detection
         * check every five seconds.
         *
         * See {@link ChangeDetectorRef#detach detach} for more information.
         */
        ViewRef.prototype.detectChanges = function () { detectChangesInternal(this._lView, this.context); };
        /**
         * Checks the change detector and its children, and throws if any changes are detected.
         *
         * This is used in development mode to verify that running change detection doesn't
         * introduce other changes.
         */
        ViewRef.prototype.checkNoChanges = function () { checkNoChangesInternal(this._lView, this.context); };
        ViewRef.prototype.attachToViewContainerRef = function (vcRef) {
            if (this._appRef) {
                throw new Error('This view is already attached directly to the ApplicationRef!');
            }
            this._viewContainerRef = vcRef;
        };
        ViewRef.prototype.detachFromAppRef = function () {
            this._appRef = null;
            renderDetachView(this._lView);
        };
        ViewRef.prototype.attachToAppRef = function (appRef) {
            if (this._viewContainerRef) {
                throw new Error('This view is already attached to a ViewContainer!');
            }
            this._appRef = appRef;
        };
        ViewRef.prototype._lookUpContext = function () {
            return this._context = getLViewParent(this._lView)[this._componentIndex];
        };
        return ViewRef;
    }());
    /** @internal */
    var RootViewRef = /** @class */ (function (_super) {
        __extends(RootViewRef, _super);
        function RootViewRef(_view) {
            var _this = _super.call(this, _view, null, -1) || this;
            _this._view = _view;
            return _this;
        }
        RootViewRef.prototype.detectChanges = function () { detectChangesInRootView(this._view); };
        RootViewRef.prototype.checkNoChanges = function () { checkNoChangesInRootView(this._view); };
        Object.defineProperty(RootViewRef.prototype, "context", {
            get: function () { return null; },
            enumerable: true,
            configurable: true
        });
        return RootViewRef;
    }(ViewRef));
    function collectNativeNodes(lView, parentTNode, result) {
        var tNodeChild = parentTNode.child;
        while (tNodeChild) {
            var nativeNode = getNativeByTNodeOrNull(tNodeChild, lView);
            nativeNode && result.push(nativeNode);
            if (tNodeChild.type === 4 /* ElementContainer */) {
                collectNativeNodes(lView, tNodeChild, result);
            }
            else if (tNodeChild.type === 1 /* Projection */) {
                var componentView = findComponentView(lView);
                var componentHost = componentView[T_HOST];
                var parentView = getLViewParent(componentView);
                var currentProjectedNode = componentHost.projection[tNodeChild.projection];
                while (currentProjectedNode && parentView) {
                    result.push(getNativeByTNode(currentProjectedNode, parentView));
                    currentProjectedNode = currentProjectedNode.next;
                }
            }
            tNodeChild = tNodeChild.next;
        }
        return result;
    }

    /**
     * @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
     */
    /**
     * Creates an ElementRef from the most recent node.
     *
     * @returns The ElementRef instance to use
     */
    function injectElementRef(ElementRefToken) {
        return createElementRef(ElementRefToken, getPreviousOrParentTNode(), getLView());
    }
    var R3ElementRef;
    /**
     * Creates an ElementRef given a node.
     *
     * @param ElementRefToken The ElementRef type
     * @param tNode The node for which you'd like an ElementRef
     * @param view The view to which the node belongs
     * @returns The ElementRef instance to use
     */
    function createElementRef(ElementRefToken, tNode, view) {
        if (!R3ElementRef) {
            // TODO: Fix class name, should be ElementRef, but there appears to be a rollup bug
            R3ElementRef = /** @class */ (function (_super) {
                __extends(ElementRef_, _super);
                function ElementRef_() {
                    return _super !== null && _super.apply(this, arguments) || this;
                }
                return ElementRef_;
            }(ElementRefToken));
        }
        return new R3ElementRef(getNativeByTNode(tNode, view));
    }
    var R3TemplateRef;
    /**
     * Creates a TemplateRef given a node.
     *
     * @returns The TemplateRef instance to use
     */
    function injectTemplateRef(TemplateRefToken, ElementRefToken) {
        return createTemplateRef(TemplateRefToken, ElementRefToken, getPreviousOrParentTNode(), getLView());
    }
    /**
     * Creates a TemplateRef and stores it on the injector.
     *
     * @param TemplateRefToken The TemplateRef type
     * @param ElementRefToken The ElementRef type
     * @param hostTNode The node on which a TemplateRef is requested
     * @param hostView The view to which the node belongs
     * @returns The TemplateRef instance or null if we can't create a TemplateRef on a given node type
     */
    function createTemplateRef(TemplateRefToken, ElementRefToken, hostTNode, hostView) {
        if (!R3TemplateRef) {
            // TODO: Fix class name, should be TemplateRef, but there appears to be a rollup bug
            R3TemplateRef = /** @class */ (function (_super) {
                __extends(TemplateRef_, _super);
                function TemplateRef_(_declarationView, _declarationTContainer, elementRef) {
                    var _this = _super.call(this) || this;
                    _this._declarationView = _declarationView;
                    _this._declarationTContainer = _declarationTContainer;
                    _this.elementRef = elementRef;
                    return _this;
                }
                TemplateRef_.prototype.createEmbeddedView = function (context) {
                    var embeddedTView = this._declarationTContainer.tViews;
                    var lView = createEmbeddedViewAndNode(embeddedTView, context, this._declarationView, this._declarationTContainer.injectorIndex);
                    var declarationLContainer = this._declarationView[this._declarationTContainer.index];
                    ngDevMode && assertLContainer(declarationLContainer);
                    lView[DECLARATION_LCONTAINER] = declarationLContainer;
                    var declarationViewLQueries = this._declarationView[QUERIES];
                    if (declarationViewLQueries !== null) {
                        lView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
                    }
                    renderEmbeddedTemplate(lView, embeddedTView, context);
                    var viewRef = new ViewRef(lView, context, -1);
                    viewRef._tViewNode = lView[T_HOST];
                    return viewRef;
                };
                return TemplateRef_;
            }(TemplateRefToken));
        }
        if (hostTNode.type === 0 /* Container */) {
            ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
            return new R3TemplateRef(hostView, hostTNode, createElementRef(ElementRefToken, hostTNode, hostView));
        }
        else {
            return null;
        }
    }
    var R3ViewContainerRef;
    /**
     * Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
     * already exists, retrieves the existing ViewContainerRef.
     *
     * @returns The ViewContainerRef instance to use
     */
    function injectViewContainerRef(ViewContainerRefToken, ElementRefToken) {
        var previousTNode = getPreviousOrParentTNode();
        return createContainerRef(ViewContainerRefToken, ElementRefToken, previousTNode, getLView());
    }
    /**
     * Creates a ViewContainerRef and stores it on the injector.
     *
     * @param ViewContainerRefToken The ViewContainerRef type
     * @param ElementRefToken The ElementRef type
     * @param hostTNode The node that is requesting a ViewContainerRef
     * @param hostView The view to which the node belongs
     * @returns The ViewContainerRef instance to use
     */
    function createContainerRef(ViewContainerRefToken, ElementRefToken, hostTNode, hostView) {
        if (!R3ViewContainerRef) {
            // TODO: Fix class name, should be ViewContainerRef, but there appears to be a rollup bug
            R3ViewContainerRef = /** @class */ (function (_super) {
                __extends(ViewContainerRef_, _super);
                function ViewContainerRef_(_lContainer, _hostTNode, _hostView) {
                    var _this = _super.call(this) || this;
                    _this._lContainer = _lContainer;
                    _this._hostTNode = _hostTNode;
                    _this._hostView = _hostView;
                    return _this;
                }
                Object.defineProperty(ViewContainerRef_.prototype, "element", {
                    get: function () {
                        return createElementRef(ElementRefToken, this._hostTNode, this._hostView);
                    },
                    enumerable: true,
                    configurable: true
                });
                Object.defineProperty(ViewContainerRef_.prototype, "injector", {
                    get: function () { return new NodeInjector(this._hostTNode, this._hostView); },
                    enumerable: true,
                    configurable: true
                });
                Object.defineProperty(ViewContainerRef_.prototype, "parentInjector", {
                    /** @deprecated No replacement */
                    get: function () {
                        var parentLocation = getParentInjectorLocation(this._hostTNode, this._hostView);
                        var parentView = getParentInjectorView(parentLocation, this._hostView);
                        var parentTNode = getParentInjectorTNode(parentLocation, this._hostView, this._hostTNode);
                        return !hasParentInjector(parentLocation) || parentTNode == null ?
                            new NodeInjector(null, this._hostView) :
                            new NodeInjector(parentTNode, parentView);
                    },
                    enumerable: true,
                    configurable: true
                });
                ViewContainerRef_.prototype.clear = function () {
                    while (this.length > 0) {
                        this.remove(this.length - 1);
                    }
                };
                ViewContainerRef_.prototype.get = function (index) {
                    return this._lContainer[VIEW_REFS] !== null && this._lContainer[VIEW_REFS][index] || null;
                };
                Object.defineProperty(ViewContainerRef_.prototype, "length", {
                    get: function () { return this._lContainer.length - CONTAINER_HEADER_OFFSET; },
                    enumerable: true,
                    configurable: true
                });
                ViewContainerRef_.prototype.createEmbeddedView = function (templateRef, context, index) {
                    var viewRef = templateRef.createEmbeddedView(context || {});
                    this.insert(viewRef, index);
                    return viewRef;
                };
                ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
                    var contextInjector = injector || this.parentInjector;
                    if (!ngModuleRef && componentFactory.ngModule == null && contextInjector) {
                        ngModuleRef = contextInjector.get(NgModuleRef, null);
                    }
                    var componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
                    this.insert(componentRef.hostView, index);
                    return componentRef;
                };
                ViewContainerRef_.prototype.insert = function (viewRef, index) {
                    if (viewRef.destroyed) {
                        throw new Error('Cannot insert a destroyed View in a ViewContainer!');
                    }
                    this.allocateContainerIfNeeded();
                    var lView = viewRef._lView;
                    var adjustedIdx = this._adjustIndex(index);
                    if (viewAttachedToContainer(lView)) {
                        // If view is already attached, fall back to move() so we clean up
                        // references appropriately.
                        return this.move(viewRef, adjustedIdx);
                    }
                    insertView(lView, this._lContainer, adjustedIdx);
                    var beforeNode = getBeforeNodeForView(adjustedIdx, this._lContainer);
                    addRemoveViewFromContainer(lView, true, beforeNode);
                    viewRef.attachToViewContainerRef(this);
                    addToArray(this._lContainer[VIEW_REFS], adjustedIdx, viewRef);
                    return viewRef;
                };
                ViewContainerRef_.prototype.move = function (viewRef, newIndex) {
                    if (viewRef.destroyed) {
                        throw new Error('Cannot move a destroyed View in a ViewContainer!');
                    }
                    var index = this.indexOf(viewRef);
                    if (index !== -1)
                        this.detach(index);
                    this.insert(viewRef, newIndex);
                    return viewRef;
                };
                ViewContainerRef_.prototype.indexOf = function (viewRef) {
                    return this._lContainer[VIEW_REFS] !== null ?
                        this._lContainer[VIEW_REFS].indexOf(viewRef) :
                        0;
                };
                ViewContainerRef_.prototype.remove = function (index) {
                    this.allocateContainerIfNeeded();
                    var adjustedIdx = this._adjustIndex(index, -1);
                    removeView(this._lContainer, adjustedIdx);
                    removeFromArray(this._lContainer[VIEW_REFS], adjustedIdx);
                };
                ViewContainerRef_.prototype.detach = function (index) {
                    this.allocateContainerIfNeeded();
                    var adjustedIdx = this._adjustIndex(index, -1);
                    var view = detachView(this._lContainer, adjustedIdx);
                    var wasDetached = view && removeFromArray(this._lContainer[VIEW_REFS], adjustedIdx) != null;
                    return wasDetached ? new ViewRef(view, view[CONTEXT], -1) : null;
                };
                ViewContainerRef_.prototype._adjustIndex = function (index, shift) {
                    if (shift === void 0) { shift = 0; }
                    if (index == null) {
                        return this.length + shift;
                    }
                    if (ngDevMode) {
                        assertGreaterThan(index, -1, 'index must be positive');
                        // +1 because it's legal to insert at the end.
                        assertLessThan(index, this.length + 1 + shift, 'index');
                    }
                    return index;
                };
                ViewContainerRef_.prototype.allocateContainerIfNeeded = function () {
                    if (this._lContainer[VIEW_REFS] === null) {
                        this._lContainer[VIEW_REFS] = [];
                    }
                };
                return ViewContainerRef_;
            }(ViewContainerRefToken));
        }
        ngDevMode && assertNodeOfPossibleTypes(hostTNode, 0 /* Container */, 3 /* Element */, 4 /* ElementContainer */);
        var lContainer;
        var slotValue = hostView[hostTNode.index];
        if (isLContainer(slotValue)) {
            // If the host is a container, we don't need to create a new LContainer
            lContainer = slotValue;
            lContainer[ACTIVE_INDEX] = -1;
        }
        else {
            var commentNode = void 0;
            // If the host is an element container, the native host element is guaranteed to be a
            // comment and we can reuse that comment as anchor element for the new LContainer.
            if (hostTNode.type === 4 /* ElementContainer */) {
                commentNode = unwrapRNode(slotValue);
            }
            else {
                ngDevMode && ngDevMode.rendererCreateComment++;
                commentNode = hostView[RENDERER].createComment(ngDevMode ? 'container' : '');
            }
            // A container can be created on the root (topmost / bootstrapped) component and in this case we
            // can't use LTree to insert container's marker node (both parent of a comment node and the
            // commend node itself is located outside of elements hold by LTree). In this specific case we
            // use low-level DOM manipulation to insert container's marker (comment) node.
            if (isRootView(hostView)) {
                var renderer = hostView[RENDERER];
                var hostNative = getNativeByTNode(hostTNode, hostView);
                var parentOfHostNative = nativeParentNode(renderer, hostNative);
                nativeInsertBefore(renderer, parentOfHostNative, commentNode, nativeNextSibling(renderer, hostNative));
            }
            else {
                appendChild(commentNode, hostTNode, hostView);
            }
            hostView[hostTNode.index] = lContainer =
                createLContainer(slotValue, hostView, commentNode, hostTNode, true);
            addToViewTree(hostView, lContainer);
        }
        return new R3ViewContainerRef(lContainer, hostTNode, hostView);
    }
    /** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
    function injectChangeDetectorRef(isPipe) {
        if (isPipe === void 0) { isPipe = false; }
        return createViewRef(getPreviousOrParentTNode(), getLView(), isPipe);
    }
    /**
     * Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
     *
     * @param hostTNode The node that is requesting a ChangeDetectorRef
     * @param hostView The view to which the node belongs
     * @param isPipe Whether the view is being injected into a pipe.
     * @returns The ChangeDetectorRef to use
     */
    function createViewRef(hostTNode, hostView, isPipe) {
        if (isComponent(hostTNode) && !isPipe) {
            var componentIndex = hostTNode.directiveStart;
            var componentView = getComponentViewByIndex(hostTNode.index, hostView);
            return new ViewRef(componentView, null, componentIndex);
        }
        else if (hostTNode.type === 3 /* Element */ || hostTNode.type === 0 /* Container */ ||
            hostTNode.type === 4 /* ElementContainer */) {
            var hostComponentView = findComponentView(hostView);
            return new ViewRef(hostComponentView, hostComponentView[CONTEXT], -1);
        }
        return null;
    }
    /** Returns a Renderer2 (or throws when application was bootstrapped with Renderer3) */
    function getOrCreateRenderer2(view) {
        var renderer = view[RENDERER];
        if (isProceduralRenderer(renderer)) {
            return renderer;
        }
        else {
            throw new Error('Cannot inject Renderer2 when the application uses Renderer3!');
        }
    }
    /** Injects a Renderer2 for the current component. */
    function injectRenderer2() {
        // We need the Renderer to be based on the component that it's being injected into, however since
        // DI happens before we've entered its view, `getLView` will return the parent view instead.
        var lView = getLView();
        var tNode = getPreviousOrParentTNode();
        var nodeAtIndex = getComponentViewByIndex(tNode.index, lView);
        return getOrCreateRenderer2(isLView(nodeAtIndex) ? nodeAtIndex : lView);
    }

    /**
     * @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
     */
    /**
     * Base class for Angular Views, provides change detection functionality.
     * A change-detection tree collects all views that are to be checked for changes.
     * Use the methods to add and remove views from the tree, initiate change-detection,
     * and explicitly mark views as _dirty_, meaning that they have changed and need to be rerendered.
     *
     * @usageNotes
     *
     * The following examples demonstrate how to modify default change-detection behavior
     * to perform explicit detection when needed.
     *
     * ### Use `markForCheck()` with `CheckOnce` strategy
     *
     * The following example sets the `OnPush` change-detection strategy for a component
     * (`CheckOnce`, rather than the default `CheckAlways`), then forces a second check
     * after an interval. See [live demo](http://plnkr.co/edit/GC512b?p=preview).
     *
     * <code-example path="core/ts/change_detect/change-detection.ts"
     * region="mark-for-check"></code-example>
     *
     * ### Detach change detector to limit how often check occurs
     *
     * The following example defines a component with a large list of read-only data
     * that is expected to change constantly, many times per second.
     * To improve performance, we want to check and update the list
     * less often than the changes actually occur. To do that, we detach
     * the component's change detector and perform an explicit local check every five seconds.
     *
     * <code-example path="core/ts/change_detect/change-detection.ts" region="detach"></code-example>
     *
     *
     * ### Reattaching a detached component
     *
     * The following example creates a component displaying live data.
     * The component detaches its change detector from the main change detector tree
     * when the `live` property is set to false, and reattaches it when the property
     * becomes true.
     *
     * <code-example path="core/ts/change_detect/change-detection.ts" region="reattach"></code-example>
     *
     * @publicApi
     */
    var ChangeDetectorRef = /** @class */ (function () {
        function ChangeDetectorRef() {
        }
        /**
         * @internal
         * @nocollapse
         */
        ChangeDetectorRef.__NG_ELEMENT_ID__ = function () { return SWITCH_CHANGE_DETECTOR_REF_FACTORY(); };
        return ChangeDetectorRef;
    }());
    var SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__ = injectChangeDetectorRef;
    var SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__ = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
    };
    var ɵ0$6 = SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__;
    var SWITCH_CHANGE_DETECTOR_REF_FACTORY = SWITCH_CHANGE_DETECTOR_REF_FACTORY__PRE_R3__;

    /**
     * @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
     */
    /**
     * @description
     *
     * Represents a type that a Component or other object is instances of.
     *
     * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by
     * the `MyCustomComponent` constructor function.
     *
     * @publicApi
     */
    var Type = Function;
    function isType(v) {
        return typeof v === 'function';
    }

    /**
     * @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
     */
    /**
     * Attention: These regex has to hold even if the code is minified!
     */
    var DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*arguments\)/;
    var INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{/;
    var INHERITED_CLASS_WITH_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(/;
    var INHERITED_CLASS_WITH_DELEGATE_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(\)\s*{\s+super\(\.\.\.arguments\)/;
    /**
     * Determine whether a stringified type is a class which delegates its constructor
     * to its parent.
     *
     * This is not trivial since compiled code can actually contain a constructor function
     * even if the original source code did not. For instance, when the child class contains
     * an initialized instance property.
     */
    function isDelegateCtor(typeStr) {
        return DELEGATE_CTOR.test(typeStr) || INHERITED_CLASS_WITH_DELEGATE_CTOR.test(typeStr) ||
            (INHERITED_CLASS.test(typeStr) && !INHERITED_CLASS_WITH_CTOR.test(typeStr));
    }
    var ReflectionCapabilities = /** @class */ (function () {
        function ReflectionCapabilities(reflect) {
            this._reflect = reflect || _global['Reflect'];
        }
        ReflectionCapabilities.prototype.isReflectionEnabled = function () { return true; };
        ReflectionCapabilities.prototype.factory = function (t) { return function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return new (t.bind.apply(t, __spread([void 0], args)))();
        }; };
        /** @internal */
        ReflectionCapabilities.prototype._zipTypesAndAnnotations = function (paramTypes, paramAnnotations) {
            var result;
            if (typeof paramTypes === 'undefined') {
                result = new Array(paramAnnotations.length);
            }
            else {
                result = new Array(paramTypes.length);
            }
            for (var i = 0; i < result.length; i++) {
                // TS outputs Object for parameters without types, while Traceur omits
                // the annotations. For now we preserve the Traceur behavior to aid
                // migration, but this can be revisited.
                if (typeof paramTypes === 'undefined') {
                    result[i] = [];
                }
                else if (paramTypes[i] && paramTypes[i] != Object) {
                    result[i] = [paramTypes[i]];
                }
                else {
                    result[i] = [];
                }
                if (paramAnnotations && paramAnnotations[i] != null) {
                    result[i] = result[i].concat(paramAnnotations[i]);
                }
            }
            return result;
        };
        ReflectionCapabilities.prototype._ownParameters = function (type, parentCtor) {
            var typeStr = type.toString();
            // If we have no decorators, we only have function.length as metadata.
            // In that case, to detect whether a child class declared an own constructor or not,
            // we need to look inside of that constructor to check whether it is
            // just calling the parent.
            // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
            // that sets 'design:paramtypes' to []
            // if a class inherits from another class but has no ctor declared itself.
            if (isDelegateCtor(typeStr)) {
                return null;
            }
            // Prefer the direct API.
            if (type.parameters && type.parameters !== parentCtor.parameters) {
                return type.parameters;
            }
            // API of tsickle for lowering decorators to properties on the class.
            var tsickleCtorParams = type.ctorParameters;
            if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
                // Newer tsickle uses a function closure
                // Retain the non-function case for compatibility with older tsickle
                var ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
                var paramTypes_1 = ctorParameters.map(function (ctorParam) { return ctorParam && ctorParam.type; });
                var paramAnnotations_1 = ctorParameters.map(function (ctorParam) {
                    return ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators);
                });
                return this._zipTypesAndAnnotations(paramTypes_1, paramAnnotations_1);
            }
            // API for metadata created by invoking the decorators.
            var paramAnnotations = type.hasOwnProperty(PARAMETERS) && type[PARAMETERS];
            var paramTypes = this._reflect && this._reflect.getOwnMetadata &&
                this._reflect.getOwnMetadata('design:paramtypes', type);
            if (paramTypes || paramAnnotations) {
                return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
            }
            // If a class has no decorators, at least create metadata
            // based on function.length.
            // Note: We know that this is a real constructor as we checked
            // the content of the constructor above.
            return new Array(type.length).fill(undefined);
        };
        ReflectionCapabilities.prototype.parameters = function (type) {
            // Note: only report metadata if we have at least one class decorator
            // to stay in sync with the static reflector.
            if (!isType(type)) {
                return [];
            }
            var parentCtor = getParentCtor(type);
            var parameters = this._ownParameters(type, parentCtor);
            if (!parameters && parentCtor !== Object) {
                parameters = this.parameters(parentCtor);
            }
            return parameters || [];
        };
        ReflectionCapabilities.prototype._ownAnnotations = function (typeOrFunc, parentCtor) {
            // Prefer the direct API.
            if (typeOrFunc.annotations && typeOrFunc.annotations !== parentCtor.annotations) {
                var annotations = typeOrFunc.annotations;
                if (typeof annotations === 'function' && annotations.annotations) {
                    annotations = annotations.annotations;
                }
                return annotations;
            }
            // API of tsickle for lowering decorators to properties on the class.
            if (typeOrFunc.decorators && typeOrFunc.decorators !== parentCtor.decorators) {
                return convertTsickleDecoratorIntoMetadata(typeOrFunc.decorators);
            }
            // API for metadata created by invoking the decorators.
            if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
                return typeOrFunc[ANNOTATIONS];
            }
            return null;
        };
        ReflectionCapabilities.prototype.annotations = function (typeOrFunc) {
            if (!isType(typeOrFunc)) {
                return [];
            }
            var parentCtor = getParentCtor(typeOrFunc);
            var ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
            var parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
            return parentAnnotations.concat(ownAnnotations);
        };
        ReflectionCapabilities.prototype._ownPropMetadata = function (typeOrFunc, parentCtor) {
            // Prefer the direct API.
            if (typeOrFunc.propMetadata &&
                typeOrFunc.propMetadata !== parentCtor.propMetadata) {
                var propMetadata = typeOrFunc.propMetadata;
                if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
                    propMetadata = propMetadata.propMetadata;
                }
                return propMetadata;
            }
            // API of tsickle for lowering decorators to properties on the class.
            if (typeOrFunc.propDecorators &&
                typeOrFunc.propDecorators !== parentCtor.propDecorators) {
                var propDecorators_1 = typeOrFunc.propDecorators;
                var propMetadata_1 = {};
                Object.keys(propDecorators_1).forEach(function (prop) {
                    propMetadata_1[prop] = convertTsickleDecoratorIntoMetadata(propDecorators_1[prop]);
                });
                return propMetadata_1;
            }
            // API for metadata created by invoking the decorators.
            if (typeOrFunc.hasOwnProperty(PROP_METADATA)) {
                return typeOrFunc[PROP_METADATA];
            }
            return null;
        };
        ReflectionCapabilities.prototype.propMetadata = function (typeOrFunc) {
            if (!isType(typeOrFunc)) {
                return {};
            }
            var parentCtor = getParentCtor(typeOrFunc);
            var propMetadata = {};
            if (parentCtor !== Object) {
                var parentPropMetadata_1 = this.propMetadata(parentCtor);
                Object.keys(parentPropMetadata_1).forEach(function (propName) {
                    propMetadata[propName] = parentPropMetadata_1[propName];
                });
            }
            var ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
            if (ownPropMetadata) {
                Object.keys(ownPropMetadata).forEach(function (propName) {
                    var decorators = [];
                    if (propMetadata.hasOwnProperty(propName)) {
                        decorators.push.apply(decorators, __spread(propMetadata[propName]));
                    }
                    decorators.push.apply(decorators, __spread(ownPropMetadata[propName]));
                    propMetadata[propName] = decorators;
                });
            }
            return propMetadata;
        };
        ReflectionCapabilities.prototype.ownPropMetadata = function (typeOrFunc) {
            if (!isType(typeOrFunc)) {
                return {};
            }
            return this._ownPropMetadata(typeOrFunc, getParentCtor(typeOrFunc)) || {};
        };
        ReflectionCapabilities.prototype.hasLifecycleHook = function (type, lcProperty) {
            return type instanceof Type && lcProperty in type.prototype;
        };
        ReflectionCapabilities.prototype.guards = function (type) { return {}; };
        ReflectionCapabilities.prototype.getter = function (name) { return new Function('o', 'return o.' + name + ';'); };
        ReflectionCapabilities.prototype.setter = function (name) {
            return new Function('o', 'v', 'return o.' + name + ' = v;');
        };
        ReflectionCapabilities.prototype.method = function (name) {
            var functionBody = "if (!o." + name + ") throw new Error('\"" + name + "\" is undefined');\n        return o." + name + ".apply(o, args);";
            return new Function('o', 'args', functionBody);
        };
        // There is not a concept of import uri in Js, but this is useful in developing Dart applications.
        ReflectionCapabilities.prototype.importUri = function (type) {
            // StaticSymbol
            if (typeof type === 'object' && type['filePath']) {
                return type['filePath'];
            }
            // Runtime type
            return "./" + stringify(type);
        };
        ReflectionCapabilities.prototype.resourceUri = function (type) { return "./" + stringify(type); };
        ReflectionCapabilities.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
            return runtime;
        };
        ReflectionCapabilities.prototype.resolveEnum = function (enumIdentifier, name) { return enumIdentifier[name]; };
        return ReflectionCapabilities;
    }());
    function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
        if (!decoratorInvocations) {
            return [];
        }
        return decoratorInvocations.map(function (decoratorInvocation) {
            var decoratorType = decoratorInvocation.type;
            var annotationCls = decoratorType.annotationCls;
            var annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
            return new (annotationCls.bind.apply(annotationCls, __spread([void 0], annotationArgs)))();
        });
    }
    function getParentCtor(ctor) {
        var parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
        var parentCtor = parentProto ? parentProto.constructor : null;
        // Note: We always use `Object` as the null value
        // to simplify checking later on.
        return parentCtor || Object;
    }

    /**
     * @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
     */
    var _reflect = null;
    function getReflect() {
        return (_reflect = _reflect || new ReflectionCapabilities());
    }
    function reflectDependencies(type) {
        return convertDependencies(getReflect().parameters(type));
    }
    function convertDependencies(deps) {
        var compiler = getCompilerFacade();
        return deps.map(function (dep) { return reflectDependency(compiler, dep); });
    }
    function reflectDependency(compiler, dep) {
        var meta = {
            token: null,
            host: false,
            optional: false,
            resolved: compiler.R3ResolvedDependencyType.Token,
            self: false,
            skipSelf: false,
        };
        function setTokenAndResolvedType(token) {
            meta.resolved = compiler.R3ResolvedDependencyType.Token;
            meta.token = token;
        }
        if (Array.isArray(dep)) {
            if (dep.length === 0) {
                throw new Error('Dependency array must have arguments.');
            }
            for (var j = 0; j < dep.length; j++) {
                var param = dep[j];
                if (param === undefined) {
                    // param may be undefined if type of dep is not set by ngtsc
                    continue;
                }
                else if (param instanceof Optional || param.__proto__.ngMetadataName === 'Optional') {
                    meta.optional = true;
                }
                else if (param instanceof SkipSelf || param.__proto__.ngMetadataName === 'SkipSelf') {
                    meta.skipSelf = true;
                }
                else if (param instanceof Self || param.__proto__.ngMetadataName === 'Self') {
                    meta.self = true;
                }
                else if (param instanceof Host || param.__proto__.ngMetadataName === 'Host') {
                    meta.host = true;
                }
                else if (param instanceof Inject) {
                    meta.token = param.token;
                }
                else if (param instanceof Attribute) {
                    if (param.attributeName === undefined) {
                        throw new Error("Attribute name must be defined.");
                    }
                    meta.token = param.attributeName;
                    meta.resolved = compiler.R3ResolvedDependencyType.Attribute;
                }
                else if (param === ChangeDetectorRef) {
                    meta.token = param;
                    meta.resolved = compiler.R3ResolvedDependencyType.ChangeDetectorRef;
                }
                else {
                    setTokenAndResolvedType(param);
                }
            }
        }
        else {
            setTokenAndResolvedType(dep);
        }
        return meta;
    }

    /**
     * @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
     */
    /**
     * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
     * `ngInjectableDef` onto the injectable type.
     */
    function compileInjectable(type, srcMeta) {
        var def = null;
        // if NG_INJECTABLE_DEF is already defined on this class then don't overwrite it
        if (type.hasOwnProperty(NG_INJECTABLE_DEF))
            return;
        Object.defineProperty(type, NG_INJECTABLE_DEF, {
            get: function () {
                if (def === null) {
                    // Allow the compilation of a class with a `@Injectable()` decorator without parameters
                    var meta = srcMeta || { providedIn: null };
                    var hasAProvider = isUseClassProvider(meta) || isUseFactoryProvider(meta) ||
                        isUseValueProvider(meta) || isUseExistingProvider(meta);
                    var compilerMeta = {
                        name: type.name,
                        type: type,
                        typeArgumentCount: 0,
                        providedIn: meta.providedIn,
                        ctorDeps: reflectDependencies(type),
                        userDeps: undefined,
                    };
                    if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
                        compilerMeta.userDeps = convertDependencies(meta.deps);
                    }
                    if (!hasAProvider) {
                        // In the case the user specifies a type provider, treat it as {provide: X, useClass: X}.
                        // The deps will have been reflected above, causing the factory to create the class by
                        // calling
                        // its constructor with injected deps.
                        compilerMeta.useClass = type;
                    }
                    else if (isUseClassProvider(meta)) {
                        // The user explicitly specified useClass, and may or may not have provided deps.
                        compilerMeta.useClass = meta.useClass;
                    }
                    else if (isUseValueProvider(meta)) {
                        // The user explicitly specified useValue.
                        compilerMeta.useValue = meta.useValue;
                    }
                    else if (isUseFactoryProvider(meta)) {
                        // The user explicitly specified useFactory.
                        compilerMeta.useFactory = meta.useFactory;
                    }
                    else if (isUseExistingProvider(meta)) {
                        // The user explicitly specified useExisting.
                        compilerMeta.useExisting = meta.useExisting;
                    }
                    else {
                        // Can't happen - either hasAProvider will be false, or one of the providers will be set.
                        throw new Error("Unreachable state.");
                    }
                    def = getCompilerFacade().compileInjectable(angularCoreDiEnv, "ng:///" + type.name + "/ngInjectableDef.js", compilerMeta);
                }
                return def;
            },
        });
    }
    var ɵ0$7 = getClosureSafeProperty;
    var USE_VALUE$1 = getClosureSafeProperty({ provide: String, useValue: ɵ0$7 });
    function isUseClassProvider(meta) {
        return meta.useClass !== undefined;
    }
    function isUseValueProvider(meta) {
        return USE_VALUE$1 in meta;
    }
    function isUseFactoryProvider(meta) {
        return meta.useFactory !== undefined;
    }
    function isUseExistingProvider(meta) {
        return meta.useExisting !== undefined;
    }

    /**
     * @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
     */
    var ɵ0$8 = getClosureSafeProperty;
    var USE_VALUE$2 = getClosureSafeProperty({ provide: String, useValue: ɵ0$8 });
    var EMPTY_ARRAY$1 = [];
    function convertInjectableProviderToFactory(type, provider) {
        if (!provider) {
            var reflectionCapabilities = new ReflectionCapabilities();
            var deps_1 = reflectionCapabilities.parameters(type);
            // TODO - convert to flags.
            return function () { return new (type.bind.apply(type, __spread([void 0], injectArgs(deps_1))))(); };
        }
        if (USE_VALUE$2 in provider) {
            var valueProvider_1 = provider;
            return function () { return valueProvider_1.useValue; };
        }
        else if (provider.useExisting) {
            var existingProvider_1 = provider;
            return function () { return ɵɵinject(existingProvider_1.useExisting); };
        }
        else if (provider.useFactory) {
            var factoryProvider_1 = provider;
            return function () { return factoryProvider_1.useFactory.apply(factoryProvider_1, __spread(injectArgs(factoryProvider_1.deps || EMPTY_ARRAY$1))); };
        }
        else if (provider.useClass) {
            var classProvider_1 = provider;
            var deps_2 = provider.deps;
            if (!deps_2) {
                var reflectionCapabilities = new ReflectionCapabilities();
                deps_2 = reflectionCapabilities.parameters(type);
            }
            return function () {
                var _a;
                return new ((_a = classProvider_1.useClass).bind.apply(_a, __spread([void 0], injectArgs(deps_2))))();
            };
        }
        else {
            var deps_3 = provider.deps;
            if (!deps_3) {
                var reflectionCapabilities = new ReflectionCapabilities();
                deps_3 = reflectionCapabilities.parameters(type);
            }
            return function () { return new (type.bind.apply(type, __spread([void 0], injectArgs(deps_3))))(); };
        }
    }

    /**
     * @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
     */
    var ɵ0$9 = function (type, meta) { return SWITCH_COMPILE_INJECTABLE(type, meta); };
    /**
     * Injectable decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var Injectable = makeDecorator('Injectable', undefined, undefined, undefined, ɵ0$9);
    /**
     * Supports @Injectable() in JIT mode for Render2.
     */
    function render2CompileInjectable(injectableType, options) {
        if (options && options.providedIn !== undefined && !getInjectableDef(injectableType)) {
            injectableType.ngInjectableDef = ɵɵdefineInjectable({
                token: injectableType,
                providedIn: options.providedIn,
                factory: convertInjectableProviderToFactory(injectableType, options),
            });
        }
    }
    var SWITCH_COMPILE_INJECTABLE__POST_R3__ = compileInjectable;
    var SWITCH_COMPILE_INJECTABLE__PRE_R3__ = render2CompileInjectable;
    var SWITCH_COMPILE_INJECTABLE = SWITCH_COMPILE_INJECTABLE__PRE_R3__;

    /**
     * @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
     */
    /**
     * An internal token whose presence in an injector indicates that the injector should treat itself
     * as a root scoped injector when processing requests for unknown tokens which may indicate
     * they are provided in the root scope.
     */
    var APP_ROOT = new InjectionToken('The presence of this token marks an injector as being the root injector.');

    /**
     * @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
     */
    /**
     * Marker which indicates that a value has not yet been created from the factory function.
     */
    var NOT_YET = {};
    /**
     * Marker which indicates that the factory function for a token is in the process of being called.
     *
     * If the injector is asked to inject a token with its value set to CIRCULAR, that indicates
     * injection of a dependency has recursively attempted to inject the original token, and there is
     * a circular dependency among the providers.
     */
    var CIRCULAR = {};
    var EMPTY_ARRAY$2 = [];
    /**
     * A lazily initialized NullInjector.
     */
    var NULL_INJECTOR = undefined;
    function getNullInjector() {
        if (NULL_INJECTOR === undefined) {
            NULL_INJECTOR = new NullInjector();
        }
        return NULL_INJECTOR;
    }
    /**
     * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
     *
     * @publicApi
     */
    function createInjector(defType, parent, additionalProviders, name) {
        if (parent === void 0) { parent = null; }
        if (additionalProviders === void 0) { additionalProviders = null; }
        parent = parent || getNullInjector();
        return new R3Injector(defType, additionalProviders, parent, name);
    }
    var R3Injector = /** @class */ (function () {
        function R3Injector(def, additionalProviders, parent, source) {
            var _this = this;
            if (source === void 0) { source = null; }
            this.parent = parent;
            /**
             * Map of tokens to records which contain the instances of those tokens.
             */
            this.records = new Map();
            /**
             * The transitive set of `InjectorType`s which define this injector.
             */
            this.injectorDefTypes = new Set();
            /**
             * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
             */
            this.onDestroy = new Set();
            this._destroyed = false;
            // Start off by creating Records for every provider declared in every InjectorType
            // included transitively in `def`.
            var dedupStack = [];
            deepForEach([def], function (injectorDef) { return _this.processInjectorType(injectorDef, [], dedupStack); });
            additionalProviders && deepForEach(additionalProviders, function (provider) { return _this.processProvider(provider, def, additionalProviders); });
            // Make sure the INJECTOR token provides this injector.
            this.records.set(INJECTOR, makeRecord(undefined, this));
            // Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide
            // any injectable scoped to APP_ROOT_SCOPE.
            this.isRootInjector = this.records.has(APP_ROOT);
            // Eagerly instantiate the InjectorType classes themselves.
            this.injectorDefTypes.forEach(function (defType) { return _this.get(defType); });
            // Source name, used for debugging
            this.source = source || (typeof def === 'object' ? null : stringify(def));
        }
        Object.defineProperty(R3Injector.prototype, "destroyed", {
            /**
             * Flag indicating that this injector was previously destroyed.
             */
            get: function () { return this._destroyed; },
            enumerable: true,
            configurable: true
        });
        /**
         * Destroy the injector and release references to every instance or provider associated with it.
         *
         * Also calls the `OnDestroy` lifecycle hooks of every instance that was created for which a
         * hook was found.
         */
        R3Injector.prototype.destroy = function () {
            this.assertNotDestroyed();
            // Set destroyed = true first, in case lifecycle hooks re-enter destroy().
            this._destroyed = true;
            try {
                // Call all the lifecycle hooks.
                this.onDestroy.forEach(function (service) { return service.ngOnDestroy(); });
            }
            finally {
                // Release all references.
                this.records.clear();
                this.onDestroy.clear();
                this.injectorDefTypes.clear();
            }
        };
        R3Injector.prototype.get = function (token, notFoundValue, flags) {
            if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
            if (flags === void 0) { flags = exports.InjectFlags.Default; }
            this.assertNotDestroyed();
            // Set the injection context.
            var previousInjector = setCurrentInjector(this);
            try {
                // Check for the SkipSelf flag.
                if (!(flags & exports.InjectFlags.SkipSelf)) {
                    // SkipSelf isn't set, check if the record belongs to this injector.
                    var record = this.records.get(token);
                    if (record === undefined) {
                        // No record, but maybe the token is scoped to this injector. Look for an ngInjectableDef
                        // with a scope matching this injector.
                        var def = couldBeInjectableType(token) && getInjectableDef(token);
                        if (def && this.injectableDefInScope(def)) {
                            // Found an ngInjectableDef and it's scoped to this injector. Pretend as if it was here
                            // all along.
                            record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
                            this.records.set(token, record);
                        }
                    }
                    // If a record was found, get the instance for it and return it.
                    if (record !== undefined) {
                        return this.hydrate(token, record);
                    }
                }
                // Select the next injector based on the Self flag - if self is set, the next injector is
                // the NullInjector, otherwise it's the parent.
                var nextInjector = !(flags & exports.InjectFlags.Self) ? this.parent : getNullInjector();
                return nextInjector.get(token, flags & exports.InjectFlags.Optional ? null : notFoundValue);
            }
            catch (e) {
                if (e.name === 'NullInjectorError') {
                    var path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
                    path.unshift(stringify(token));
                    if (previousInjector) {
                        // We still have a parent injector, keep throwing
                        throw e;
                    }
                    else {
                        // Format & throw the final error message when we don't have any previous injector
                        return catchInjectorError(e, token, 'R3InjectorError', this.source);
                    }
                }
                else {
                    throw e;
                }
            }
            finally {
                // Lastly, clean up the state by restoring the previous injector.
                setCurrentInjector(previousInjector);
            }
        };
        R3Injector.prototype.toString = function () {
            var tokens = [], records = this.records;
            records.forEach(function (v, token) { return tokens.push(stringify(token)); });
            return "R3Injector[" + tokens.join(', ') + "]";
        };
        R3Injector.prototype.assertNotDestroyed = function () {
            if (this._destroyed) {
                throw new Error('Injector has already been destroyed.');
            }
        };
        /**
         * Add an `InjectorType` or `InjectorTypeWithProviders` and all of its transitive providers
         * to this injector.
         *
         * If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
         * the function will return "true" to indicate that the providers of the type definition need
         * to be processed. This allows us to process providers of injector types after all imports of
         * an injector definition are processed. (following View Engine semantics: see FW-1349)
         */
        R3Injector.prototype.processInjectorType = function (defOrWrappedDef, parents, dedupStack) {
            var _this = this;
            defOrWrappedDef = resolveForwardRef(defOrWrappedDef);
            if (!defOrWrappedDef)
                return false;
            // Either the defOrWrappedDef is an InjectorType (with ngInjectorDef) or an
            // InjectorDefTypeWithProviders (aka ModuleWithProviders). Detecting either is a megamorphic
            // read, so care is taken to only do the read once.
            // First attempt to read the ngInjectorDef.
            var def = getInjectorDef(defOrWrappedDef);
            // If that's not present, then attempt to read ngModule from the InjectorDefTypeWithProviders.
            var ngModule = (def == null) && defOrWrappedDef.ngModule || undefined;
            // Determine the InjectorType. In the case where `defOrWrappedDef` is an `InjectorType`,
            // then this is easy. In the case of an InjectorDefTypeWithProviders, then the definition type
            // is the `ngModule`.
            var defType = (ngModule === undefined) ? defOrWrappedDef : ngModule;
            // Check for circular dependencies.
            if (ngDevMode && parents.indexOf(defType) !== -1) {
                var defName = stringify(defType);
                throw new Error("Circular dependency in DI detected for type " + defName + ". Dependency path: " + parents.map(function (defType) { return stringify(defType); }).join(' > ') + " > " + defName + ".");
            }
            // Check for multiple imports of the same module
            var isDuplicate = dedupStack.indexOf(defType) !== -1;
            // Finally, if defOrWrappedType was an `InjectorDefTypeWithProviders`, then the actual
            // `InjectorDef` is on its `ngModule`.
            if (ngModule !== undefined) {
                def = getInjectorDef(ngModule);
            }
            // If no definition was found, it might be from exports. Remove it.
            if (def == null) {
                return false;
            }
            // Track the InjectorType and add a provider for it.
            this.injectorDefTypes.add(defType);
            this.records.set(defType, makeRecord(def.factory, NOT_YET));
            // Add providers in the same way that @NgModule resolution did:
            // First, include providers from any imports.
            if (def.imports != null && !isDuplicate) {
                // Before processing defType's imports, add it to the set of parents. This way, if it ends
                // up deeply importing itself, this can be detected.
                ngDevMode && parents.push(defType);
                // Add it to the set of dedups. This way we can detect multiple imports of the same module
                dedupStack.push(defType);
                var importTypesWithProviders_1;
                try {
                    deepForEach(def.imports, function (imported) {
                        if (_this.processInjectorType(imported, parents, dedupStack)) {
                            if (importTypesWithProviders_1 === undefined)
                                importTypesWithProviders_1 = [];
                            // If the processed import is an injector type with providers, we store it in the
                            // list of import types with providers, so that we can process those afterwards.
                            importTypesWithProviders_1.push(imported);
                        }
                    });
                }
                finally {
                    // Remove it from the parents set when finished.
                    ngDevMode && parents.pop();
                }
                // Imports which are declared with providers (TypeWithProviders) need to be processed
                // after all imported modules are processed. This is similar to how View Engine
                // processes/merges module imports in the metadata resolver. See: FW-1349.
                if (importTypesWithProviders_1 !== undefined) {
                    var _loop_1 = function (i) {
                        var _a = importTypesWithProviders_1[i], ngModule_1 = _a.ngModule, providers = _a.providers;
                        deepForEach(providers, function (provider) { return _this.processProvider(provider, ngModule_1, providers || EMPTY_ARRAY$2); });
                    };
                    for (var i = 0; i < importTypesWithProviders_1.length; i++) {
                        _loop_1(i);
                    }
                }
            }
            // Next, include providers listed on the definition itself.
            var defProviders = def.providers;
            if (defProviders != null && !isDuplicate) {
                var injectorType_1 = defOrWrappedDef;
                deepForEach(defProviders, function (provider) { return _this.processProvider(provider, injectorType_1, defProviders); });
            }
            return (ngModule !== undefined &&
                defOrWrappedDef.providers !== undefined);
        };
        /**
         * Process a `SingleProvider` and add it.
         */
        R3Injector.prototype.processProvider = function (provider, ngModuleType, providers) {
            // Determine the token from the provider. Either it's its own token, or has a {provide: ...}
            // property.
            provider = resolveForwardRef(provider);
            var token = isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide);
            // Construct a `Record` for the provider.
            var record = providerToRecord(provider, ngModuleType, providers);
            if (!isTypeProvider(provider) && provider.multi === true) {
                // If the provider indicates that it's a multi-provider, process it specially.
                // First check whether it's been defined already.
                var multiRecord_1 = this.records.get(token);
                if (multiRecord_1) {
                    // It has. Throw a nice error if
                    if (multiRecord_1.multi === undefined) {
                        throwMixedMultiProviderError();
                    }
                }
                else {
                    multiRecord_1 = makeRecord(undefined, NOT_YET, true);
                    multiRecord_1.factory = function () { return injectArgs(multiRecord_1.multi); };
                    this.records.set(token, multiRecord_1);
                }
                token = provider;
                multiRecord_1.multi.push(provider);
            }
            else {
                var existing = this.records.get(token);
                if (existing && existing.multi !== undefined) {
                    throwMixedMultiProviderError();
                }
            }
            this.records.set(token, record);
        };
        R3Injector.prototype.hydrate = function (token, record) {
            if (record.value === CIRCULAR) {
                throwCyclicDependencyError(stringify(token));
            }
            else if (record.value === NOT_YET) {
                record.value = CIRCULAR;
                record.value = record.factory();
            }
            if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {
                this.onDestroy.add(record.value);
            }
            return record.value;
        };
        R3Injector.prototype.injectableDefInScope = function (def) {
            if (!def.providedIn) {
                return false;
            }
            else if (typeof def.providedIn === 'string') {
                return def.providedIn === 'any' || (def.providedIn === 'root' && this.isRootInjector);
            }
            else {
                return this.injectorDefTypes.has(def.providedIn);
            }
        };
        return R3Injector;
    }());
    function injectableDefOrInjectorDefFactory(token) {
        // Most tokens will have an ngInjectableDef directly on them, which specifies a factory directly.
        var injectableDef = getInjectableDef(token);
        if (injectableDef !== null) {
            return injectableDef.factory;
        }
        // If the token is an NgModule, it's also injectable but the factory is on its ngInjectorDef.
        var injectorDef = getInjectorDef(token);
        if (injectorDef !== null) {
            return injectorDef.factory;
        }
        // InjectionTokens should have an ngInjectableDef and thus should be handled above.
        // If it's missing that, it's an error.
        if (token instanceof InjectionToken) {
            throw new Error("Token " + stringify(token) + " is missing an ngInjectableDef definition.");
        }
        // Undecorated types can sometimes be created if they have no constructor arguments.
        if (token instanceof Function) {
            return getUndecoratedInjectableFactory(token);
        }
        // There was no way to resolve a factory for this token.
        throw new Error('unreachable');
    }
    function getUndecoratedInjectableFactory(token) {
        // If the token has parameters then it has dependencies that we cannot resolve implicitly.
        var paramLength = token.length;
        if (paramLength > 0) {
            var args = new Array(paramLength).fill('?');
            throw new Error("Can't resolve all parameters for " + stringify(token) + ": (" + args.join(', ') + ").");
        }
        // The constructor function appears to have no parameters.
        // This might be because it inherits from a super-class. In which case, use an ngInjectableDef
        // from an ancestor if there is one.
        // Otherwise this really is a simple class with no dependencies, so return a factory that
        // just instantiates the zero-arg constructor.
        var inheritedInjectableDef = getInheritedInjectableDef(token);
        if (inheritedInjectableDef !== null) {
            return function () { return inheritedInjectableDef.factory(token); };
        }
        else {
            return function () { return new token(); };
        }
    }
    function providerToRecord(provider, ngModuleType, providers) {
        var factory = providerToFactory(provider, ngModuleType, providers);
        if (isValueProvider(provider)) {
            return makeRecord(undefined, provider.useValue);
        }
        else {
            return makeRecord(factory, NOT_YET);
        }
    }
    /**
     * Converts a `SingleProvider` into a factory function.
     *
     * @param provider provider to convert to factory
     */
    function providerToFactory(provider, ngModuleType, providers) {
        var factory = undefined;
        if (isTypeProvider(provider)) {
            return injectableDefOrInjectorDefFactory(resolveForwardRef(provider));
        }
        else {
            if (isValueProvider(provider)) {
                factory = function () { return resolveForwardRef(provider.useValue); };
            }
            else if (isExistingProvider(provider)) {
                factory = function () { return ɵɵinject(resolveForwardRef(provider.useExisting)); };
            }
            else if (isFactoryProvider(provider)) {
                factory = function () { return provider.useFactory.apply(provider, __spread(injectArgs(provider.deps || []))); };
            }
            else {
                var classRef_1 = resolveForwardRef(provider &&
                    (provider.useClass || provider.provide));
                if (!classRef_1) {
                    throwInvalidProviderError(ngModuleType, providers, provider);
                }
                if (hasDeps(provider)) {
                    factory = function () { return new ((classRef_1).bind.apply((classRef_1), __spread([void 0], injectArgs(provider.deps))))(); };
                }
                else {
                    return injectableDefOrInjectorDefFactory(classRef_1);
                }
            }
        }
        return factory;
    }
    function makeRecord(factory, value, multi) {
        if (multi === void 0) { multi = false; }
        return {
            factory: factory,
            value: value,
            multi: multi ? [] : undefined,
        };
    }
    function isValueProvider(value) {
        return value !== null && typeof value == 'object' && USE_VALUE in value;
    }
    function isExistingProvider(value) {
        return !!(value && value.useExisting);
    }
    function isFactoryProvider(value) {
        return !!(value && value.useFactory);
    }
    function isTypeProvider(value) {
        return typeof value === 'function';
    }
    function isClassProvider(value) {
        return !!value.useClass;
    }
    function hasDeps(value) {
        return !!value.deps;
    }
    function hasOnDestroy(value) {
        return value !== null && typeof value === 'object' &&
            typeof value.ngOnDestroy === 'function';
    }
    function couldBeInjectableType(value) {
        return (typeof value === 'function') ||
            (typeof value === 'object' && value instanceof InjectionToken);
    }

    /**
     * @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
     */
    function INJECTOR_IMPL__PRE_R3__(providers, parent, name) {
        return new StaticInjector(providers, parent, name);
    }
    function INJECTOR_IMPL__POST_R3__(providers, parent, name) {
        return createInjector({ name: name }, parent, providers, name);
    }
    var INJECTOR_IMPL = INJECTOR_IMPL__PRE_R3__;
    /**
     * Concrete injectors implement this interface.
     *
     * For more details, see the ["Dependency Injection Guide"](guide/dependency-injection).
     *
     * @usageNotes
     * ### Example
     *
     * {@example core/di/ts/injector_spec.ts region='Injector'}
     *
     * `Injector` returns itself when given `Injector` as a token:
     *
     * {@example core/di/ts/injector_spec.ts region='injectInjector'}
     *
     * @publicApi
     */
    var Injector = /** @class */ (function () {
        function Injector() {
        }
        /**
         * Create a new Injector which is configure using `StaticProvider`s.
         *
         * @usageNotes
         * ### Example
         *
         * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
         */
        Injector.create = function (options, parent) {
            if (Array.isArray(options)) {
                return INJECTOR_IMPL(options, parent, '');
            }
            else {
                return INJECTOR_IMPL(options.providers, options.parent, options.name || '');
            }
        };
        Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
        Injector.NULL = new NullInjector();
        /** @nocollapse */
        Injector.ngInjectableDef = ɵɵdefineInjectable({
            token: Injector,
            providedIn: 'any',
            factory: function () { return ɵɵinject(INJECTOR); },
        });
        /**
         * @internal
         * @nocollapse
         */
        Injector.__NG_ELEMENT_ID__ = -1;
        return Injector;
    }());
    var IDENT = function (value) {
        return value;
    };
    var ɵ0$a = IDENT;
    var EMPTY = [];
    var CIRCULAR$1 = IDENT;
    var MULTI_PROVIDER_FN = function () {
        return Array.prototype.slice.call(arguments);
    };
    var ɵ1$2 = MULTI_PROVIDER_FN;
    var NO_NEW_LINE$1 = 'ɵ';
    var StaticInjector = /** @class */ (function () {
        function StaticInjector(providers, parent, source) {
            if (parent === void 0) { parent = Injector.NULL; }
            if (source === void 0) { source = null; }
            this.parent = parent;
            this.source = source;
            var records = this._records = new Map();
            records.set(Injector, { token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false });
            records.set(INJECTOR, { token: INJECTOR, fn: IDENT, deps: EMPTY, value: this, useNew: false });
            recursivelyProcessProviders(records, providers);
        }
        StaticInjector.prototype.get = function (token, notFoundValue, flags) {
            if (flags === void 0) { flags = exports.InjectFlags.Default; }
            var record = this._records.get(token);
            try {
                return tryResolveToken(token, record, this._records, this.parent, notFoundValue, flags);
            }
            catch (e) {
                return catchInjectorError(e, token, 'StaticInjectorError', this.source);
            }
        };
        StaticInjector.prototype.toString = function () {
            var tokens = [], records = this._records;
            records.forEach(function (v, token) { return tokens.push(stringify(token)); });
            return "StaticInjector[" + tokens.join(', ') + "]";
        };
        return StaticInjector;
    }());
    function resolveProvider(provider) {
        var deps = computeDeps(provider);
        var fn = IDENT;
        var value = EMPTY;
        var useNew = false;
        var provide = resolveForwardRef(provider.provide);
        if (USE_VALUE in provider) {
            // We need to use USE_VALUE in provider since provider.useValue could be defined as undefined.
            value = provider.useValue;
        }
        else if (provider.useFactory) {
            fn = provider.useFactory;
        }
        else if (provider.useExisting) {
            // Just use IDENT
        }
        else if (provider.useClass) {
            useNew = true;
            fn = resolveForwardRef(provider.useClass);
        }
        else if (typeof provide == 'function') {
            useNew = true;
            fn = provide;
        }
        else {
            throw staticError('StaticProvider does not have [useValue|useFactory|useExisting|useClass] or [provide] is not newable', provider);
        }
        return { deps: deps, fn: fn, useNew: useNew, value: value };
    }
    function multiProviderMixError(token) {
        return staticError('Cannot mix multi providers and regular providers', token);
    }
    function recursivelyProcessProviders(records, provider) {
        if (provider) {
            provider = resolveForwardRef(provider);
            if (provider instanceof Array) {
                // if we have an array recurse into the array
                for (var i = 0; i < provider.length; i++) {
                    recursivelyProcessProviders(records, provider[i]);
                }
            }
            else if (typeof provider === 'function') {
                // Functions were supported in ReflectiveInjector, but are not here. For safety give useful
                // error messages
                throw staticError('Function/Class not supported', provider);
            }
            else if (provider && typeof provider === 'object' && provider.provide) {
                // At this point we have what looks like a provider: {provide: ?, ....}
                var token = resolveForwardRef(provider.provide);
                var resolvedProvider = resolveProvider(provider);
                if (provider.multi === true) {
                    // This is a multi provider.
                    var multiProvider = records.get(token);
                    if (multiProvider) {
                        if (multiProvider.fn !== MULTI_PROVIDER_FN) {
                            throw multiProviderMixError(token);
                        }
                    }
                    else {
                        // Create a placeholder factory which will look up the constituents of the multi provider.
                        records.set(token, multiProvider = {
                            token: provider.provide,
                            deps: [],
                            useNew: false,
                            fn: MULTI_PROVIDER_FN,
                            value: EMPTY
                        });
                    }
                    // Treat the provider as the token.
                    token = provider;
                    multiProvider.deps.push({ token: token, options: 6 /* Default */ });
                }
                var record = records.get(token);
                if (record && record.fn == MULTI_PROVIDER_FN) {
                    throw multiProviderMixError(token);
                }
                records.set(token, resolvedProvider);
            }
            else {
                throw staticError('Unexpected provider', provider);
            }
        }
    }
    function tryResolveToken(token, record, records, parent, notFoundValue, flags) {
        try {
            return resolveToken(token, record, records, parent, notFoundValue, flags);
        }
        catch (e) {
            // ensure that 'e' is of type Error.
            if (!(e instanceof Error)) {
                e = new Error(e);
            }
            var path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
            path.unshift(token);
            if (record && record.value == CIRCULAR$1) {
                // Reset the Circular flag.
                record.value = EMPTY;
            }
            throw e;
        }
    }
    function resolveToken(token, record, records, parent, notFoundValue, flags) {
        var _a;
        var value;
        if (record && !(flags & exports.InjectFlags.SkipSelf)) {
            // If we don't have a record, this implies that we don't own the provider hence don't know how
            // to resolve it.
            value = record.value;
            if (value == CIRCULAR$1) {
                throw Error(NO_NEW_LINE$1 + 'Circular dependency');
            }
            else if (value === EMPTY) {
                record.value = CIRCULAR$1;
                var obj = undefined;
                var useNew = record.useNew;
                var fn = record.fn;
                var depRecords = record.deps;
                var deps = EMPTY;
                if (depRecords.length) {
                    deps = [];
                    for (var i = 0; i < depRecords.length; i++) {
                        var depRecord = depRecords[i];
                        var options = depRecord.options;
                        var childRecord = options & 2 /* CheckSelf */ ? records.get(depRecord.token) : undefined;
                        deps.push(tryResolveToken(
                        // Current Token to resolve
                        depRecord.token, 
                        // A record which describes how to resolve the token.
                        // If undefined, this means we don't have such a record
                        childRecord, 
                        // Other records we know about.
                        records, 
                        // If we don't know how to resolve dependency and we should not check parent for it,
                        // than pass in Null injector.
                        !childRecord && !(options & 4 /* CheckParent */) ? Injector.NULL : parent, options & 1 /* Optional */ ? null : Injector.THROW_IF_NOT_FOUND, exports.InjectFlags.Default));
                    }
                }
                record.value = value = useNew ? new ((_a = fn).bind.apply(_a, __spread([void 0], deps)))() : fn.apply(obj, deps);
            }
        }
        else if (!(flags & exports.InjectFlags.Self)) {
            value = parent.get(token, notFoundValue, exports.InjectFlags.Default);
        }
        return value;
    }
    function computeDeps(provider) {
        var deps = EMPTY;
        var providerDeps = provider.deps;
        if (providerDeps && providerDeps.length) {
            deps = [];
            for (var i = 0; i < providerDeps.length; i++) {
                var options = 6 /* Default */;
                var token = resolveForwardRef(providerDeps[i]);
                if (token instanceof Array) {
                    for (var j = 0, annotations = token; j < annotations.length; j++) {
                        var annotation = annotations[j];
                        if (annotation instanceof Optional || annotation == Optional) {
                            options = options | 1 /* Optional */;
                        }
                        else if (annotation instanceof SkipSelf || annotation == SkipSelf) {
                            options = options & ~2 /* CheckSelf */;
                        }
                        else if (annotation instanceof Self || annotation == Self) {
                            options = options & ~4 /* CheckParent */;
                        }
                        else if (annotation instanceof Inject) {
                            token = annotation.token;
                        }
                        else {
                            token = resolveForwardRef(annotation);
                        }
                    }
                }
                deps.push({ token: token, options: options });
            }
        }
        else if (provider.useExisting) {
            var token = resolveForwardRef(provider.useExisting);
            deps = [{ token: token, options: 6 /* Default */ }];
        }
        else if (!providerDeps && !(USE_VALUE in provider)) {
            // useValue & useExisting are the only ones which are exempt from deps all others need it.
            throw staticError('\'deps\' required', provider);
        }
        return deps;
    }
    function staticError(text, obj) {
        return new Error(formatError(text, obj, 'StaticInjectorError'));
    }

    /**
     * @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
     */
    function findFirstClosedCycle(keys) {
        var res = [];
        for (var i = 0; i < keys.length; ++i) {
            if (res.indexOf(keys[i]) > -1) {
                res.push(keys[i]);
                return res;
            }
            res.push(keys[i]);
        }
        return res;
    }
    function constructResolvingPath(keys) {
        if (keys.length > 1) {
            var reversed = findFirstClosedCycle(keys.slice().reverse());
            var tokenStrs = reversed.map(function (k) { return stringify(k.token); });
            return ' (' + tokenStrs.join(' -> ') + ')';
        }
        return '';
    }
    function injectionError(injector, key, constructResolvingMessage, originalError) {
        var keys = [key];
        var errMsg = constructResolvingMessage(keys);
        var error = (originalError ? wrappedError(errMsg, originalError) : Error(errMsg));
        error.addKey = addKey;
        error.keys = keys;
        error.injectors = [injector];
        error.constructResolvingMessage = constructResolvingMessage;
        error[ERROR_ORIGINAL_ERROR] = originalError;
        return error;
    }
    function addKey(injector, key) {
        this.injectors.push(injector);
        this.keys.push(key);
        // Note: This updated message won't be reflected in the `.stack` property
        this.message = this.constructResolvingMessage(this.keys);
    }
    /**
     * Thrown when trying to retrieve a dependency by key from {@link Injector}, but the
     * {@link Injector} does not have a {@link Provider} for the given key.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * class A {
     *   constructor(b:B) {}
     * }
     *
     * expect(() => Injector.resolveAndCreate([A])).toThrowError();
     * ```
     */
    function noProviderError(injector, key) {
        return injectionError(injector, key, function (keys) {
            var first = stringify(keys[0].token);
            return "No provider for " + first + "!" + constructResolvingPath(keys);
        });
    }
    /**
     * Thrown when dependencies form a cycle.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * var injector = Injector.resolveAndCreate([
     *   {provide: "one", useFactory: (two) => "two", deps: [[new Inject("two")]]},
     *   {provide: "two", useFactory: (one) => "one", deps: [[new Inject("one")]]}
     * ]);
     *
     * expect(() => injector.get("one")).toThrowError();
     * ```
     *
     * Retrieving `A` or `B` throws a `CyclicDependencyError` as the graph above cannot be constructed.
     */
    function cyclicDependencyError(injector, key) {
        return injectionError(injector, key, function (keys) {
            return "Cannot instantiate cyclic dependency!" + constructResolvingPath(keys);
        });
    }
    /**
     * Thrown when a constructing type returns with an Error.
     *
     * The `InstantiationError` class contains the original error plus the dependency graph which caused
     * this object to be instantiated.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * class A {
     *   constructor() {
     *     throw new Error('message');
     *   }
     * }
     *
     * var injector = Injector.resolveAndCreate([A]);

     * try {
     *   injector.get(A);
     * } catch (e) {
     *   expect(e instanceof InstantiationError).toBe(true);
     *   expect(e.originalException.message).toEqual("message");
     *   expect(e.originalStack).toBeDefined();
     * }
     * ```
     */
    function instantiationError(injector, originalException, originalStack, key) {
        return injectionError(injector, key, function (keys) {
            var first = stringify(keys[0].token);
            return originalException.message + ": Error during instantiation of " + first + "!" + constructResolvingPath(keys) + ".";
        }, originalException);
    }
    /**
     * Thrown when an object other then {@link Provider} (or `Type`) is passed to {@link Injector}
     * creation.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * expect(() => Injector.resolveAndCreate(["not a type"])).toThrowError();
     * ```
     */
    function invalidProviderError(provider) {
        return Error("Invalid provider - only instances of Provider and Type are allowed, got: " + provider);
    }
    /**
     * Thrown when the class has no annotation information.
     *
     * Lack of annotation information prevents the {@link Injector} from determining which dependencies
     * need to be injected into the constructor.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * class A {
     *   constructor(b) {}
     * }
     *
     * expect(() => Injector.resolveAndCreate([A])).toThrowError();
     * ```
     *
     * This error is also thrown when the class not marked with {@link Injectable} has parameter types.
     *
     * ```typescript
     * class B {}
     *
     * class A {
     *   constructor(b:B) {} // no information about the parameter types of A is available at runtime.
     * }
     *
     * expect(() => Injector.resolveAndCreate([A,B])).toThrowError();
     * ```
     *
     */
    function noAnnotationError(typeOrFunc, params) {
        var signature = [];
        for (var i = 0, ii = params.length; i < ii; i++) {
            var parameter = params[i];
            if (!parameter || parameter.length == 0) {
                signature.push('?');
            }
            else {
                signature.push(parameter.map(stringify).join(' '));
            }
        }
        return Error('Cannot resolve all parameters for \'' + stringify(typeOrFunc) + '\'(' +
            signature.join(', ') + '). ' +
            'Make sure that all the parameters are decorated with Inject or have valid type annotations and that \'' +
            stringify(typeOrFunc) + '\' is decorated with Injectable.');
    }
    /**
     * Thrown when getting an object by index.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * class A {}
     *
     * var injector = Injector.resolveAndCreate([A]);
     *
     * expect(() => injector.getAt(100)).toThrowError();
     * ```
     *
     */
    function outOfBoundsError(index) {
        return Error("Index " + index + " is out-of-bounds.");
    }
    // TODO: add a working example after alpha38 is released
    /**
     * Thrown when a multi provider and a regular provider are bound to the same token.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * expect(() => Injector.resolveAndCreate([
     *   { provide: "Strings", useValue: "string1", multi: true},
     *   { provide: "Strings", useValue: "string2", multi: false}
     * ])).toThrowError();
     * ```
     */
    function mixingMultiProvidersWithRegularProvidersError(provider1, provider2) {
        return Error("Cannot mix multi providers and regular providers, got: " + provider1 + " " + provider2);
    }

    /**
     * @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
     */
    /**
     * A unique object used for retrieving items from the {@link ReflectiveInjector}.
     *
     * Keys have:
     * - a system-wide unique `id`.
     * - a `token`.
     *
     * `Key` is used internally by {@link ReflectiveInjector} because its system-wide unique `id` allows
     * the
     * injector to store created objects in a more efficient way.
     *
     * `Key` should not be created directly. {@link ReflectiveInjector} creates keys automatically when
     * resolving
     * providers.
     *
     * @deprecated No replacement
     * @publicApi
     */
    var ReflectiveKey = /** @class */ (function () {
        /**
         * Private
         */
        function ReflectiveKey(token, id) {
            this.token = token;
            this.id = id;
            if (!token) {
                throw new Error('Token must be defined!');
            }
            this.displayName = stringify(this.token);
        }
        /**
         * Retrieves a `Key` for a token.
         */
        ReflectiveKey.get = function (token) {
            return _globalKeyRegistry.get(resolveForwardRef(token));
        };
        Object.defineProperty(ReflectiveKey, "numberOfKeys", {
            /**
             * @returns the number of keys registered in the system.
             */
            get: function () { return _globalKeyRegistry.numberOfKeys; },
            enumerable: true,
            configurable: true
        });
        return ReflectiveKey;
    }());
    var KeyRegistry = /** @class */ (function () {
        function KeyRegistry() {
            this._allKeys = new Map();
        }
        KeyRegistry.prototype.get = function (token) {
            if (token instanceof ReflectiveKey)
                return token;
            if (this._allKeys.has(token)) {
                return this._allKeys.get(token);
            }
            var newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);
            this._allKeys.set(token, newKey);
            return newKey;
        };
        Object.defineProperty(KeyRegistry.prototype, "numberOfKeys", {
            get: function () { return this._allKeys.size; },
            enumerable: true,
            configurable: true
        });
        return KeyRegistry;
    }());
    var _globalKeyRegistry = new KeyRegistry();

    /**
     * @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
     */
    /**
     * Provides access to reflection data about symbols. Used internally by Angular
     * to power dependency injection and compilation.
     */
    var Reflector = /** @class */ (function () {
        function Reflector(reflectionCapabilities) {
            this.reflectionCapabilities = reflectionCapabilities;
        }
        Reflector.prototype.updateCapabilities = function (caps) { this.reflectionCapabilities = caps; };
        Reflector.prototype.factory = function (type) { return this.reflectionCapabilities.factory(type); };
        Reflector.prototype.parameters = function (typeOrFunc) {
            return this.reflectionCapabilities.parameters(typeOrFunc);
        };
        Reflector.prototype.annotations = function (typeOrFunc) {
            return this.reflectionCapabilities.annotations(typeOrFunc);
        };
        Reflector.prototype.propMetadata = function (typeOrFunc) {
            return this.reflectionCapabilities.propMetadata(typeOrFunc);
        };
        Reflector.prototype.hasLifecycleHook = function (type, lcProperty) {
            return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
        };
        Reflector.prototype.getter = function (name) { return this.reflectionCapabilities.getter(name); };
        Reflector.prototype.setter = function (name) { return this.reflectionCapabilities.setter(name); };
        Reflector.prototype.method = function (name) { return this.reflectionCapabilities.method(name); };
        Reflector.prototype.importUri = function (type) { return this.reflectionCapabilities.importUri(type); };
        Reflector.prototype.resourceUri = function (type) { return this.reflectionCapabilities.resourceUri(type); };
        Reflector.prototype.resolveIdentifier = function (name, moduleUrl, members, runtime) {
            return this.reflectionCapabilities.resolveIdentifier(name, moduleUrl, members, runtime);
        };
        Reflector.prototype.resolveEnum = function (identifier, name) {
            return this.reflectionCapabilities.resolveEnum(identifier, name);
        };
        return Reflector;
    }());

    /**
     * @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
     */
    /**
     * The {@link Reflector} used internally in Angular to access metadata
     * about symbols.
     */
    var reflector = new Reflector(new ReflectionCapabilities());

    /**
     * @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
     */
    /**
     * `Dependency` is used by the framework to extend DI.
     * This is internal to Angular and should not be used directly.
     */
    var ReflectiveDependency = /** @class */ (function () {
        function ReflectiveDependency(key, optional, visibility) {
            this.key = key;
            this.optional = optional;
            this.visibility = visibility;
        }
        ReflectiveDependency.fromKey = function (key) {
            return new ReflectiveDependency(key, false, null);
        };
        return ReflectiveDependency;
    }());
    var _EMPTY_LIST = [];
    var ResolvedReflectiveProvider_ = /** @class */ (function () {
        function ResolvedReflectiveProvider_(key, resolvedFactories, multiProvider) {
            this.key = key;
            this.resolvedFactories = resolvedFactories;
            this.multiProvider = multiProvider;
            this.resolvedFactory = this.resolvedFactories[0];
        }
        return ResolvedReflectiveProvider_;
    }());
    /**
     * An internal resolved representation of a factory function created by resolving `Provider`.
     * @publicApi
     */
    var ResolvedReflectiveFactory = /** @class */ (function () {
        function ResolvedReflectiveFactory(
        /**
         * Factory function which can return an instance of an object represented by a key.
         */
        factory, 
        /**
         * Arguments (dependencies) to the `factory` function.
         */
        dependencies) {
            this.factory = factory;
            this.dependencies = dependencies;
        }
        return ResolvedReflectiveFactory;
    }());
    /**
     * Resolve a single provider.
     */
    function resolveReflectiveFactory(provider) {
        var factoryFn;
        var resolvedDeps;
        if (provider.useClass) {
            var useClass = resolveForwardRef(provider.useClass);
            factoryFn = reflector.factory(useClass);
            resolvedDeps = _dependenciesFor(useClass);
        }
        else if (provider.useExisting) {
            factoryFn = function (aliasInstance) { return aliasInstance; };
            resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];
        }
        else if (provider.useFactory) {
            factoryFn = provider.useFactory;
            resolvedDeps = constructDependencies(provider.useFactory, provider.deps);
        }
        else {
            factoryFn = function () { return provider.useValue; };
            resolvedDeps = _EMPTY_LIST;
        }
        return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);
    }
    /**
     * Converts the `Provider` into `ResolvedProvider`.
     *
     * `Injector` internally only uses `ResolvedProvider`, `Provider` contains convenience provider
     * syntax.
     */
    function resolveReflectiveProvider(provider) {
        return new ResolvedReflectiveProvider_(ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)], provider.multi || false);
    }
    /**
     * Resolve a list of Providers.
     */
    function resolveReflectiveProviders(providers) {
        var normalized = _normalizeProviders(providers, []);
        var resolved = normalized.map(resolveReflectiveProvider);
        var resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());
        return Array.from(resolvedProviderMap.values());
    }
    /**
     * Merges a list of ResolvedProviders into a list where each key is contained exactly once and
     * multi providers have been merged.
     */
    function mergeResolvedReflectiveProviders(providers, normalizedProvidersMap) {
        for (var i = 0; i < providers.length; i++) {
            var provider = providers[i];
            var existing = normalizedProvidersMap.get(provider.key.id);
            if (existing) {
                if (provider.multiProvider !== existing.multiProvider) {
                    throw mixingMultiProvidersWithRegularProvidersError(existing, provider);
                }
                if (provider.multiProvider) {
                    for (var j = 0; j < provider.resolvedFactories.length; j++) {
                        existing.resolvedFactories.push(provider.resolvedFactories[j]);
                    }
                }
                else {
                    normalizedProvidersMap.set(provider.key.id, provider);
                }
            }
            else {
                var resolvedProvider = void 0;
                if (provider.multiProvider) {
                    resolvedProvider = new ResolvedReflectiveProvider_(provider.key, provider.resolvedFactories.slice(), provider.multiProvider);
                }
                else {
                    resolvedProvider = provider;
                }
                normalizedProvidersMap.set(provider.key.id, resolvedProvider);
            }
        }
        return normalizedProvidersMap;
    }
    function _normalizeProviders(providers, res) {
        providers.forEach(function (b) {
            if (b instanceof Type) {
                res.push({ provide: b, useClass: b });
            }
            else if (b && typeof b == 'object' && b.provide !== undefined) {
                res.push(b);
            }
            else if (b instanceof Array) {
                _normalizeProviders(b, res);
            }
            else {
                throw invalidProviderError(b);
            }
        });
        return res;
    }
    function constructDependencies(typeOrFunc, dependencies) {
        if (!dependencies) {
            return _dependenciesFor(typeOrFunc);
        }
        else {
            var params_1 = dependencies.map(function (t) { return [t]; });
            return dependencies.map(function (t) { return _extractToken(typeOrFunc, t, params_1); });
        }
    }
    function _dependenciesFor(typeOrFunc) {
        var params = reflector.parameters(typeOrFunc);
        if (!params)
            return [];
        if (params.some(function (p) { return p == null; })) {
            throw noAnnotationError(typeOrFunc, params);
        }
        return params.map(function (p) { return _extractToken(typeOrFunc, p, params); });
    }
    function _extractToken(typeOrFunc, metadata, params) {
        var token = null;
        var optional = false;
        if (!Array.isArray(metadata)) {
            if (metadata instanceof Inject) {
                return _createDependency(metadata.token, optional, null);
            }
            else {
                return _createDependency(metadata, optional, null);
            }
        }
        var visibility = null;
        for (var i = 0; i < metadata.length; ++i) {
            var paramMetadata = metadata[i];
            if (paramMetadata instanceof Type) {
                token = paramMetadata;
            }
            else if (paramMetadata instanceof Inject) {
                token = paramMetadata.token;
            }
            else if (paramMetadata instanceof Optional) {
                optional = true;
            }
            else if (paramMetadata instanceof Self || paramMetadata instanceof SkipSelf) {
                visibility = paramMetadata;
            }
            else if (paramMetadata instanceof InjectionToken) {
                token = paramMetadata;
            }
        }
        token = resolveForwardRef(token);
        if (token != null) {
            return _createDependency(token, optional, visibility);
        }
        else {
            throw noAnnotationError(typeOrFunc, params);
        }
    }
    function _createDependency(token, optional, visibility) {
        return new ReflectiveDependency(ReflectiveKey.get(token), optional, visibility);
    }

    /**
     * @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
     */
    // Threshold for the dynamic version
    var UNDEFINED = new Object();
    /**
     * A ReflectiveDependency injection container used for instantiating objects and resolving
     * dependencies.
     *
     * An `Injector` is a replacement for a `new` operator, which can automatically resolve the
     * constructor dependencies.
     *
     * In typical use, application code asks for the dependencies in the constructor and they are
     * resolved by the `Injector`.
     *
     * @usageNotes
     * ### Example
     *
     * The following example creates an `Injector` configured to create `Engine` and `Car`.
     *
     * ```typescript
     * @Injectable()
     * class Engine {
     * }
     *
     * @Injectable()
     * class Car {
     *   constructor(public engine:Engine) {}
     * }
     *
     * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
     * var car = injector.get(Car);
     * expect(car instanceof Car).toBe(true);
     * expect(car.engine instanceof Engine).toBe(true);
     * ```
     *
     * Notice, we don't use the `new` operator because we explicitly want to have the `Injector`
     * resolve all of the object's dependencies automatically.
     *
     * @deprecated from v5 - slow and brings in a lot of code, Use `Injector.create` instead.
     * @publicApi
     */
    var ReflectiveInjector = /** @class */ (function () {
        function ReflectiveInjector() {
        }
        /**
         * Turns an array of provider definitions into an array of resolved providers.
         *
         * A resolution is a process of flattening multiple nested arrays and converting individual
         * providers into an array of `ResolvedReflectiveProvider`s.
         *
         * @usageNotes
         * ### Example
         *
         * ```typescript
         * @Injectable()
         * class Engine {
         * }
         *
         * @Injectable()
         * class Car {
         *   constructor(public engine:Engine) {}
         * }
         *
         * var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);
         *
         * expect(providers.length).toEqual(2);
         *
         * expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);
         * expect(providers[0].key.displayName).toBe("Car");
         * expect(providers[0].dependencies.length).toEqual(1);
         * expect(providers[0].factory).toBeDefined();
         *
         * expect(providers[1].key.displayName).toBe("Engine");
         * });
         * ```
         *
         */
        ReflectiveInjector.resolve = function (providers) {
            return resolveReflectiveProviders(providers);
        };
        /**
         * Resolves an array of providers and creates an injector from those providers.
         *
         * The passed-in providers can be an array of `Type`, `Provider`,
         * or a recursive array of more providers.
         *
         * @usageNotes
         * ### Example
         *
         * ```typescript
         * @Injectable()
         * class Engine {
         * }
         *
         * @Injectable()
         * class Car {
         *   constructor(public engine:Engine) {}
         * }
         *
         * var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);
         * expect(injector.get(Car) instanceof Car).toBe(true);
         * ```
         */
        ReflectiveInjector.resolveAndCreate = function (providers, parent) {
            var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
            return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);
        };
        /**
         * Creates an injector from previously resolved providers.
         *
         * This API is the recommended way to construct injectors in performance-sensitive parts.
         *
         * @usageNotes
         * ### Example
         *
         * ```typescript
         * @Injectable()
         * class Engine {
         * }
         *
         * @Injectable()
         * class Car {
         *   constructor(public engine:Engine) {}
         * }
         *
         * var providers = ReflectiveInjector.resolve([Car, Engine]);
         * var injector = ReflectiveInjector.fromResolvedProviders(providers);
         * expect(injector.get(Car) instanceof Car).toBe(true);
         * ```
         */
        ReflectiveInjector.fromResolvedProviders = function (providers, parent) {
            return new ReflectiveInjector_(providers, parent);
        };
        return ReflectiveInjector;
    }());
    var ReflectiveInjector_ = /** @class */ (function () {
        /**
         * Private
         */
        function ReflectiveInjector_(_providers, _parent) {
            /** @internal */
            this._constructionCounter = 0;
            this._providers = _providers;
            this.parent = _parent || null;
            var len = _providers.length;
            this.keyIds = new Array(len);
            this.objs = new Array(len);
            for (var i = 0; i < len; i++) {
                this.keyIds[i] = _providers[i].key.id;
                this.objs[i] = UNDEFINED;
            }
        }
        ReflectiveInjector_.prototype.get = function (token, notFoundValue) {
            if (notFoundValue === void 0) { notFoundValue = THROW_IF_NOT_FOUND; }
            return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);
        };
        ReflectiveInjector_.prototype.resolveAndCreateChild = function (providers) {
            var ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);
            return this.createChildFromResolved(ResolvedReflectiveProviders);
        };
        ReflectiveInjector_.prototype.createChildFromResolved = function (providers) {
            var inj = new ReflectiveInjector_(providers);
            inj.parent = this;
            return inj;
        };
        ReflectiveInjector_.prototype.resolveAndInstantiate = function (provider) {
            return this.instantiateResolved(ReflectiveInjector.resolve([provider])[0]);
        };
        ReflectiveInjector_.prototype.instantiateResolved = function (provider) {
            return this._instantiateProvider(provider);
        };
        ReflectiveInjector_.prototype.getProviderAtIndex = function (index) {
            if (index < 0 || index >= this._providers.length) {
                throw outOfBoundsError(index);
            }
            return this._providers[index];
        };
        /** @internal */
        ReflectiveInjector_.prototype._new = function (provider) {
            if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {
                throw cyclicDependencyError(this, provider.key);
            }
            return this._instantiateProvider(provider);
        };
        ReflectiveInjector_.prototype._getMaxNumberOfObjects = function () { return this.objs.length; };
        ReflectiveInjector_.prototype._instantiateProvider = function (provider) {
            if (provider.multiProvider) {
                var res = new Array(provider.resolvedFactories.length);
                for (var i = 0; i < provider.resolvedFactories.length; ++i) {
                    res[i] = this._instantiate(provider, provider.resolvedFactories[i]);
                }
                return res;
            }
            else {
                return this._instantiate(provider, provider.resolvedFactories[0]);
            }
        };
        ReflectiveInjector_.prototype._instantiate = function (provider, ResolvedReflectiveFactory) {
            var _this = this;
            var factory = ResolvedReflectiveFactory.factory;
            var deps;
            try {
                deps =
                    ResolvedReflectiveFactory.dependencies.map(function (dep) { return _this._getByReflectiveDependency(dep); });
            }
            catch (e) {
                if (e.addKey) {
                    e.addKey(this, provider.key);
                }
                throw e;
            }
            var obj;
            try {
                obj = factory.apply(void 0, __spread(deps));
            }
            catch (e) {
                throw instantiationError(this, e, e.stack, provider.key);
            }
            return obj;
        };
        ReflectiveInjector_.prototype._getByReflectiveDependency = function (dep) {
            return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);
        };
        ReflectiveInjector_.prototype._getByKey = function (key, visibility, notFoundValue) {
            if (key === ReflectiveInjector_.INJECTOR_KEY) {
                return this;
            }
            if (visibility instanceof Self) {
                return this._getByKeySelf(key, notFoundValue);
            }
            else {
                return this._getByKeyDefault(key, notFoundValue, visibility);
            }
        };
        ReflectiveInjector_.prototype._getObjByKeyId = function (keyId) {
            for (var i = 0; i < this.keyIds.length; i++) {
                if (this.keyIds[i] === keyId) {
                    if (this.objs[i] === UNDEFINED) {
                        this.objs[i] = this._new(this._providers[i]);
                    }
                    return this.objs[i];
                }
            }
            return UNDEFINED;
        };
        /** @internal */
        ReflectiveInjector_.prototype._throwOrNull = function (key, notFoundValue) {
            if (notFoundValue !== THROW_IF_NOT_FOUND) {
                return notFoundValue;
            }
            else {
                throw noProviderError(this, key);
            }
        };
        /** @internal */
        ReflectiveInjector_.prototype._getByKeySelf = function (key, notFoundValue) {
            var obj = this._getObjByKeyId(key.id);
            return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);
        };
        /** @internal */
        ReflectiveInjector_.prototype._getByKeyDefault = function (key, notFoundValue, visibility) {
            var inj;
            if (visibility instanceof SkipSelf) {
                inj = this.parent;
            }
            else {
                inj = this;
            }
            while (inj instanceof ReflectiveInjector_) {
                var inj_ = inj;
                var obj = inj_._getObjByKeyId(key.id);
                if (obj !== UNDEFINED)
                    return obj;
                inj = inj_.parent;
            }
            if (inj !== null) {
                return inj.get(key.token, notFoundValue);
            }
            else {
                return this._throwOrNull(key, notFoundValue);
            }
        };
        Object.defineProperty(ReflectiveInjector_.prototype, "displayName", {
            get: function () {
                var providers = _mapProviders(this, function (b) { return ' "' + b.key.displayName + '" '; })
                    .join(', ');
                return "ReflectiveInjector(providers: [" + providers + "])";
            },
            enumerable: true,
            configurable: true
        });
        ReflectiveInjector_.prototype.toString = function () { return this.displayName; };
        ReflectiveInjector_.INJECTOR_KEY = ReflectiveKey.get(Injector);
        return ReflectiveInjector_;
    }());
    function _mapProviders(injector, fn) {
        var res = new Array(injector._providers.length);
        for (var i = 0; i < injector._providers.length; ++i) {
            res[i] = fn(injector.getProviderAtIndex(i));
        }
        return res;
    }

    /**
     * @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
     */

    /**
     * @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
     */

    /**
     * @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
     */
    /**
     * A DI token that you can use to create a virtual [provider](guide/glossary#provider)
     * that will populate the `entryComponents` field of components and NgModules
     * based on its `useValue` property value.
     * All components that are referenced in the `useValue` value (either directly
     * or in a nested array or map) are added to the `entryComponents` property.
     *
     * @usageNotes
     *
     * The following example shows how the router can populate the `entryComponents`
     * field of an NgModule based on a router configuration that refers
     * to components.
     *
     * ```typescript
     * // helper function inside the router
     * function provideRoutes(routes) {
     *   return [
     *     {provide: ROUTES, useValue: routes},
     *     {provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: routes, multi: true}
     *   ];
     * }
     *
     * // user code
     * let routes = [
     *   {path: '/root', component: RootComp},
     *   {path: '/teams', component: TeamsComp}
     * ];
     *
     * @NgModule({
     *   providers: [provideRoutes(routes)]
     * })
     * class ModuleWithRoutes {}
     * ```
     *
     * @publicApi
     */
    var ANALYZE_FOR_ENTRY_COMPONENTS = new InjectionToken('AnalyzeForEntryComponents');
    /**
     * Base class for query metadata.
     *
     * @see `ContentChildren`.
     * @see `ContentChild`.
     * @see `ViewChildren`.
     * @see `ViewChild`.
     *
     * @publicApi
     */
    var Query = /** @class */ (function () {
        function Query() {
        }
        return Query;
    }());
    var ɵ0$b = function (selector, data) {
        if (data === void 0) { data = {}; }
        return (__assign({ selector: selector, first: false, isViewQuery: false, descendants: false }, data));
    };
    /**
     * ContentChildren decorator and metadata.
     *
     *
     * @Annotation
     * @publicApi
     */
    var ContentChildren = makePropDecorator('ContentChildren', ɵ0$b, Query);
    var ɵ1$3 = function (selector, data) {
        if (data === void 0) { data = {}; }
        return (__assign({ selector: selector, first: true, isViewQuery: false, descendants: true }, data));
    };
    /**
     * ContentChild decorator and metadata.
     *
     *
     * @Annotation
     *
     * @publicApi
     */
    var ContentChild = makePropDecorator('ContentChild', ɵ1$3, Query);
    var ɵ2 = function (selector, data) {
        if (data === void 0) { data = {}; }
        return (__assign({ selector: selector, first: false, isViewQuery: true, descendants: true }, data));
    };
    /**
     * ViewChildren decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var ViewChildren = makePropDecorator('ViewChildren', ɵ2, Query);
    var ɵ3 = function (selector, data) {
        return (__assign({ selector: selector, first: true, isViewQuery: true, descendants: true }, data));
    };
    /**
     * ViewChild decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var ViewChild = makePropDecorator('ViewChild', ɵ3, Query);

    /**
     * @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
     */
    /**
     * Used to resolve resource URLs on `@Component` when used with JIT compilation.
     *
     * Example:
     * ```
     * @Component({
     *   selector: 'my-comp',
     *   templateUrl: 'my-comp.html', // This requires asynchronous resolution
     * })
     * class MyComponent{
     * }
     *
     * // Calling `renderComponent` will fail because `renderComponent` is a synchronous process
     * // and `MyComponent`'s `@Component.templateUrl` needs to be resolved asynchronously.
     *
     * // Calling `resolveComponentResources()` will resolve `@Component.templateUrl` into
     * // `@Component.template`, which allows `renderComponent` to proceed in a synchronous manner.
     *
     * // Use browser's `fetch()` function as the default resource resolution strategy.
     * resolveComponentResources(fetch).then(() => {
     *   // After resolution all URLs have been converted into `template` strings.
     *   renderComponent(MyComponent);
     * });
     *
     * ```
     *
     * NOTE: In AOT the resolution happens during compilation, and so there should be no need
     * to call this method outside JIT mode.
     *
     * @param resourceResolver a function which is responsible for returning a `Promise` to the
     * contents of the resolved URL. Browser's `fetch()` method is a good default implementation.
     */
    function resolveComponentResources(resourceResolver) {
        // Store all promises which are fetching the resources.
        var componentResolved = [];
        // Cache so that we don't fetch the same resource more than once.
        var urlMap = new Map();
        function cachedResourceResolve(url) {
            var promise = urlMap.get(url);
            if (!promise) {
                var resp = resourceResolver(url);
                urlMap.set(url, promise = resp.then(unwrapResponse));
            }
            return promise;
        }
        componentResourceResolutionQueue.forEach(function (component, type) {
            var promises = [];
            if (component.templateUrl) {
                promises.push(cachedResourceResolve(component.templateUrl).then(function (template) {
                    component.template = template;
                }));
            }
            var styleUrls = component.styleUrls;
            var styles = component.styles || (component.styles = []);
            var styleOffset = component.styles.length;
            styleUrls && styleUrls.forEach(function (styleUrl, index) {
                styles.push(''); // pre-allocate array.
                promises.push(cachedResourceResolve(styleUrl).then(function (style) {
                    styles[styleOffset + index] = style;
                    styleUrls.splice(styleUrls.indexOf(styleUrl), 1);
                    if (styleUrls.length == 0) {
                        component.styleUrls = undefined;
                    }
                }));
            });
            var fullyResolved = Promise.all(promises).then(function () { return componentDefResolved(type); });
            componentResolved.push(fullyResolved);
        });
        clearResolutionOfComponentResourcesQueue();
        return Promise.all(componentResolved).then(function () { return undefined; });
    }
    var componentResourceResolutionQueue = new Map();
    // Track when existing ngComponentDef for a Type is waiting on resources.
    var componentDefPendingResolution = new Set();
    function maybeQueueResolutionOfComponentResources(type, metadata) {
        if (componentNeedsResolution(metadata)) {
            componentResourceResolutionQueue.set(type, metadata);
            componentDefPendingResolution.add(type);
        }
    }
    function isComponentDefPendingResolution(type) {
        return componentDefPendingResolution.has(type);
    }
    function componentNeedsResolution(component) {
        return !!((component.templateUrl && !component.hasOwnProperty('template')) ||
            component.styleUrls && component.styleUrls.length);
    }
    function clearResolutionOfComponentResourcesQueue() {
        var old = componentResourceResolutionQueue;
        componentResourceResolutionQueue = new Map();
        return old;
    }
    function restoreComponentResolutionQueue(queue) {
        componentDefPendingResolution.clear();
        queue.forEach(function (_, type) { return componentDefPendingResolution.add(type); });
        componentResourceResolutionQueue = queue;
    }
    function isComponentResourceResolutionQueueEmpty() {
        return componentResourceResolutionQueue.size === 0;
    }
    function unwrapResponse(response) {
        return typeof response == 'string' ? response : response.text();
    }
    function componentDefResolved(type) {
        componentDefPendingResolution.delete(type);
    }

    /**
     * @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
     */
    /**
     * Allocates the necessary amount of slots for host vars.
     *
     * @param count Amount of vars to be allocated
     *
     * @codeGenApi
     */
    function ɵɵallocHostVars(count) {
        var lView = getLView();
        var tView = lView[TVIEW];
        if (!tView.firstTemplatePass)
            return;
        queueHostBindingForCheck(tView, getCurrentDirectiveDef(), count);
        prefillHostVars(tView, lView, count);
    }
    /**
     * Stores host binding fn and number of host vars so it will be queued for binding refresh during
     * CD.
     */
    function queueHostBindingForCheck(tView, def, hostVars) {
        ngDevMode &&
            assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
        var expando = tView.expandoInstructions;
        var length = expando.length;
        // Check whether a given `hostBindings` function already exists in expandoInstructions,
        // which can happen in case directive definition was extended from base definition (as a part of
        // the `InheritDefinitionFeature` logic). If we found the same `hostBindings` function in the
        // list, we just increase the number of host vars associated with that function, but do not add it
        // into the list again.
        if (length >= 2 && expando[length - 2] === def.hostBindings) {
            expando[length - 1] = expando[length - 1] + hostVars;
        }
        else {
            expando.push(def.hostBindings, hostVars);
        }
    }
    /**
     * On the first template pass, we need to reserve space for host binding values
     * after directives are matched (so all directives are saved, then bindings).
     * Because we are updating the blueprint, we only need to do this once.
     */
    function prefillHostVars(tView, lView, totalHostVars) {
        ngDevMode &&
            assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
        for (var i = 0; i < totalHostVars; i++) {
            lView.push(NO_CHANGE);
            tView.blueprint.push(NO_CHANGE);
            tView.data.push(null);
        }
    }

    /**
     * @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
     */
    var _symbolIterator = null;
    function getSymbolIterator() {
        if (!_symbolIterator) {
            var Symbol_1 = _global['Symbol'];
            if (Symbol_1 && Symbol_1.iterator) {
                _symbolIterator = Symbol_1.iterator;
            }
            else {
                // es6-shim specific logic
                var keys = Object.getOwnPropertyNames(Map.prototype);
                for (var i = 0; i < keys.length; ++i) {
                    var key = keys[i];
                    if (key !== 'entries' && key !== 'size' &&
                        Map.prototype[key] === Map.prototype['entries']) {
                        _symbolIterator = key;
                    }
                }
            }
        }
        return _symbolIterator;
    }

    /**
     * @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
     */
    function isListLikeIterable(obj) {
        if (!isJsObject(obj))
            return false;
        return Array.isArray(obj) ||
            (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
                getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
    }
    function areIterablesEqual(a, b, comparator) {
        var iterator1 = a[getSymbolIterator()]();
        var iterator2 = b[getSymbolIterator()]();
        while (true) {
            var item1 = iterator1.next();
            var item2 = iterator2.next();
            if (item1.done && item2.done)
                return true;
            if (item1.done || item2.done)
                return false;
            if (!comparator(item1.value, item2.value))
                return false;
        }
    }
    function iterateListLike(obj, fn) {
        if (Array.isArray(obj)) {
            for (var i = 0; i < obj.length; i++) {
                fn(obj[i]);
            }
        }
        else {
            var iterator = obj[getSymbolIterator()]();
            var item = void 0;
            while (!((item = iterator.next()).done)) {
                fn(item.value);
            }
        }
    }
    function isJsObject(o) {
        return o !== null && (typeof o === 'function' || typeof o === 'object');
    }

    /**
     * @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
     */
    // JS has NaN !== NaN
    function looseIdentical(a, b) {
        return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
    }
    function devModeEqual(a, b) {
        var isListLikeIterableA = isListLikeIterable(a);
        var isListLikeIterableB = isListLikeIterable(b);
        if (isListLikeIterableA && isListLikeIterableB) {
            return areIterablesEqual(a, b, devModeEqual);
        }
        else {
            var isAObject = a && (typeof a === 'object' || typeof a === 'function');
            var isBObject = b && (typeof b === 'object' || typeof b === 'function');
            if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
                return true;
            }
            else {
                return looseIdentical(a, b);
            }
        }
    }

    /**
     * @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
     */
    function devModeEqual$1(a, b) {
        var isListLikeIterableA = isListLikeIterable$1(a);
        var isListLikeIterableB = isListLikeIterable$1(b);
        if (isListLikeIterableA && isListLikeIterableB) {
            return areIterablesEqual$1(a, b, devModeEqual$1);
        }
        else {
            var isAObject = a && (typeof a === 'object' || typeof a === 'function');
            var isBObject = b && (typeof b === 'object' || typeof b === 'function');
            if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
                return true;
            }
            else {
                return looseIdentical(a, b);
            }
        }
    }
    /**
     * Indicates that the result of a {@link Pipe} transformation has changed even though the
     * reference has not changed.
     *
     * Wrapped values are unwrapped automatically during the change detection, and the unwrapped value
     * is stored.
     *
     * Example:
     *
     * ```
     * if (this._latestValue === this._latestReturnedValue) {
     *    return this._latestReturnedValue;
     *  } else {
     *    this._latestReturnedValue = this._latestValue;
     *    return WrappedValue.wrap(this._latestValue); // this will force update
     *  }
     * ```
     *
     * @publicApi
     */
    var WrappedValue = /** @class */ (function () {
        function WrappedValue(value) {
            this.wrapped = value;
        }
        /** Creates a wrapped value. */
        WrappedValue.wrap = function (value) { return new WrappedValue(value); };
        /**
         * Returns the underlying value of a wrapped value.
         * Returns the given `value` when it is not wrapped.
         **/
        WrappedValue.unwrap = function (value) { return WrappedValue.isWrapped(value) ? value.wrapped : value; };
        /** Returns true if `value` is a wrapped value. */
        WrappedValue.isWrapped = function (value) { return value instanceof WrappedValue; };
        return WrappedValue;
    }());
    function isListLikeIterable$1(obj) {
        if (!isJsObject$1(obj))
            return false;
        return Array.isArray(obj) ||
            (!(obj instanceof Map) && // JS Map are iterables but return entries as [k, v]
                getSymbolIterator() in obj); // JS Iterable have a Symbol.iterator prop
    }
    function areIterablesEqual$1(a, b, comparator) {
        var iterator1 = a[getSymbolIterator()]();
        var iterator2 = b[getSymbolIterator()]();
        while (true) {
            var item1 = iterator1.next();
            var item2 = iterator2.next();
            if (item1.done && item2.done)
                return true;
            if (item1.done || item2.done)
                return false;
            if (!comparator(item1.value, item2.value))
                return false;
        }
    }
    function iterateListLike$1(obj, fn) {
        if (Array.isArray(obj)) {
            for (var i = 0; i < obj.length; i++) {
                fn(obj[i]);
            }
        }
        else {
            var iterator = obj[getSymbolIterator()]();
            var item = void 0;
            while (!((item = iterator.next()).done)) {
                fn(item.value);
            }
        }
    }
    function isJsObject$1(o) {
        return o !== null && (typeof o === 'function' || typeof o === 'object');
    }

    /**
     * @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
     */
    // TODO(misko): consider inlining
    /** Updates binding and returns the value. */
    function updateBinding(lView, bindingIndex, value) {
        return lView[bindingIndex] = value;
    }
    /** Gets the current binding value. */
    function getBinding(lView, bindingIndex) {
        ngDevMode && assertDataInRange(lView, bindingIndex);
        ngDevMode &&
            assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
        return lView[bindingIndex];
    }
    /** Updates binding if changed, then returns whether it was updated. */
    function bindingUpdated(lView, bindingIndex, value) {
        ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
        ngDevMode &&
            assertLessThan(bindingIndex, lView.length, "Slot should have been initialized to NO_CHANGE");
        var oldValue = lView[bindingIndex];
        if (isDifferent(oldValue, value)) {
            if (ngDevMode && getCheckNoChangesMode()) {
                // View engine didn't report undefined values as changed on the first checkNoChanges pass
                // (before the change detection was run).
                var oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
                if (!devModeEqual$1(oldValueToCompare, value)) {
                    throwErrorIfNoChangesMode(oldValue === NO_CHANGE, oldValueToCompare, value);
                }
            }
            lView[bindingIndex] = value;
            return true;
        }
        return false;
    }
    /** Updates 2 bindings if changed, then returns whether either was updated. */
    function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
        var different = bindingUpdated(lView, bindingIndex, exp1);
        return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
    }
    /** Updates 3 bindings if changed, then returns whether any was updated. */
    function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
        var different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
        return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
    }
    /** Updates 4 bindings if changed, then returns whether any was updated. */
    function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
        var different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
        return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
    }

    /**
     * @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
     */
    /**
     * Update a property on a selected element.
     *
     * Operates on the element selected by index via the {@link select} instruction.
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled
     *
     * @param propName Name of property. Because it is going to DOM, this is not subject to
     *        renaming as part of minification.
     * @param value New value to write.
     * @param sanitizer An optional function used to sanitize the value.
     * @returns This function returns itself so that it may be chained
     * (e.g. `property('name', ctx.name)('title', ctx.title)`)
     *
     * @codeGenApi
     */
    function ɵɵproperty(propName, value, sanitizer) {
        var index = getSelectedIndex();
        ngDevMode && assertNotEqual(index, -1, 'selected index cannot be -1');
        var lView = getLView();
        var bindReconciledValue = bind(lView, value);
        if (bindReconciledValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, bindReconciledValue, sanitizer);
        }
        return ɵɵproperty;
    }
    /**
     * Creates a single value binding.
     *
     * @param lView Current view
     * @param value Value to diff
     */
    function bind(lView, value) {
        var bindingIndex = lView[BINDING_INDEX]++;
        storeBindingMetadata(lView);
        return bindingUpdated(lView, bindingIndex, value) ? value : NO_CHANGE;
    }

    /**
     * Updates the value of or removes a bound attribute on an Element.
     *
     * Used in the case of `[attr.title]="value"`
     *
     * @param name name The name of the attribute.
     * @param value value The attribute is removed when value is `null` or `undefined`.
     *                  Otherwise the attribute value is set to the stringified value.
     * @param sanitizer An optional function used to sanitize the value.
     * @param namespace Optional namespace to use when setting the attribute.
     *
     * @codeGenApi
     */
    function ɵɵattribute(name, value, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var bound = bind(lView, value);
        if (bound !== NO_CHANGE) {
            elementAttributeInternal(index, name, bound, lView, sanitizer, namespace);
        }
        return ɵɵattribute;
    }

    /**
     * @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
     */
    /**
     * Create interpolation bindings with a variable number of expressions.
     *
     * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
     * Those are faster because there is no need to create an array of expressions and iterate over it.
     *
     * `values`:
     * - has static text at even indexes,
     * - has evaluated expressions at odd indexes.
     *
     * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
     */
    function interpolationV(lView, values) {
        ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
        ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
        var isBindingUpdated = false;
        var tData = lView[TVIEW].data;
        var bindingIndex = lView[BINDING_INDEX];
        if (tData[bindingIndex] == null) {
            // 2 is the index of the first static interstitial value (ie. not prefix)
            for (var i = 2; i < values.length; i += 2) {
                tData[bindingIndex++] = values[i];
            }
            bindingIndex = lView[BINDING_INDEX];
        }
        for (var i = 1; i < values.length; i += 2) {
            // Check if bindings (odd indexes) have changed
            isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
        }
        lView[BINDING_INDEX] = bindingIndex;
        storeBindingMetadata(lView, values[0], values[values.length - 1]);
        if (!isBindingUpdated) {
            return NO_CHANGE;
        }
        // Build the updated content
        var content = values[0];
        for (var i = 1; i < values.length; i += 2) {
            content += renderStringify(values[i]) + values[i + 1];
        }
        return content;
    }
    /**
     * Creates an interpolation binding with 1 expression.
     *
     * @param prefix static value used for concatenation only.
     * @param v0 value checked for change.
     * @param suffix static value used for concatenation only.
     */
    function interpolation1(lView, prefix, v0, suffix) {
        var different = bindingUpdated(lView, lView[BINDING_INDEX]++, v0);
        storeBindingMetadata(lView, prefix, suffix);
        return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
    }
    /**
     * Creates an interpolation binding with 2 expressions.
     */
    function interpolation2(lView, prefix, v0, i0, v1, suffix) {
        var bindingIndex = lView[BINDING_INDEX];
        var different = bindingUpdated2(lView, bindingIndex, v0, v1);
        lView[BINDING_INDEX] += 2;
        // Only set static strings the first time (data will be null subsequent runs).
        var data = storeBindingMetadata(lView, prefix, suffix);
        if (data) {
            lView[TVIEW].data[bindingIndex] = i0;
        }
        return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
    }
    /**
     * Creates an interpolation binding with 3 expressions.
     */
    function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
        var bindingIndex = lView[BINDING_INDEX];
        var different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
        lView[BINDING_INDEX] += 3;
        // Only set static strings the first time (data will be null subsequent runs).
        var data = storeBindingMetadata(lView, prefix, suffix);
        if (data) {
            var tData = lView[TVIEW].data;
            tData[bindingIndex] = i0;
            tData[bindingIndex + 1] = i1;
        }
        return different ?
            prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix :
            NO_CHANGE;
    }
    /**
     * Create an interpolation binding with 4 expressions.
     */
    function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
        var bindingIndex = lView[BINDING_INDEX];
        var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
        lView[BINDING_INDEX] += 4;
        // Only set static strings the first time (data will be null subsequent runs).
        var data = storeBindingMetadata(lView, prefix, suffix);
        if (data) {
            var tData = lView[TVIEW].data;
            tData[bindingIndex] = i0;
            tData[bindingIndex + 1] = i1;
            tData[bindingIndex + 2] = i2;
        }
        return different ?
            prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
                renderStringify(v3) + suffix :
            NO_CHANGE;
    }
    /**
     * Creates an interpolation binding with 5 expressions.
     */
    function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
        var bindingIndex = lView[BINDING_INDEX];
        var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
        different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
        lView[BINDING_INDEX] += 5;
        // Only set static strings the first time (data will be null subsequent runs).
        var data = storeBindingMetadata(lView, prefix, suffix);
        if (data) {
            var tData = lView[TVIEW].data;
            tData[bindingIndex] = i0;
            tData[bindingIndex + 1] = i1;
            tData[bindingIndex + 2] = i2;
            tData[bindingIndex + 3] = i3;
        }
        return different ?
            prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
                renderStringify(v3) + i3 + renderStringify(v4) + suffix :
            NO_CHANGE;
    }
    /**
     * Creates an interpolation binding with 6 expressions.
     */
    function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
        var bindingIndex = lView[BINDING_INDEX];
        var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
        different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
        lView[BINDING_INDEX] += 6;
        // Only set static strings the first time (data will be null subsequent runs).
        var data = storeBindingMetadata(lView, prefix, suffix);
        if (data) {
            var tData = lView[TVIEW].data;
            tData[bindingIndex] = i0;
            tData[bindingIndex + 1] = i1;
            tData[bindingIndex + 2] = i2;
            tData[bindingIndex + 3] = i3;
            tData[bindingIndex + 4] = i4;
        }
        return different ?
            prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
                renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix :
            NO_CHANGE;
    }
    /**
     * Creates an interpolation binding with 7 expressions.
     */
    function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
        var bindingIndex = lView[BINDING_INDEX];
        var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
        different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
        lView[BINDING_INDEX] += 7;
        // Only set static strings the first time (data will be null subsequent runs).
        var data = storeBindingMetadata(lView, prefix, suffix);
        if (data) {
            var tData = lView[TVIEW].data;
            tData[bindingIndex] = i0;
            tData[bindingIndex + 1] = i1;
            tData[bindingIndex + 2] = i2;
            tData[bindingIndex + 3] = i3;
            tData[bindingIndex + 4] = i4;
            tData[bindingIndex + 5] = i5;
        }
        return different ?
            prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
                renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 +
                renderStringify(v6) + suffix :
            NO_CHANGE;
    }
    /**
     * Creates an interpolation binding with 8 expressions.
     */
    function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
        var bindingIndex = lView[BINDING_INDEX];
        var different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
        different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
        lView[BINDING_INDEX] += 8;
        // Only set static strings the first time (data will be null subsequent runs).
        var data = storeBindingMetadata(lView, prefix, suffix);
        if (data) {
            var tData = lView[TVIEW].data;
            tData[bindingIndex] = i0;
            tData[bindingIndex + 1] = i1;
            tData[bindingIndex + 2] = i2;
            tData[bindingIndex + 3] = i3;
            tData[bindingIndex + 4] = i4;
            tData[bindingIndex + 5] = i5;
            tData[bindingIndex + 6] = i6;
        }
        return different ?
            prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 +
                renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 +
                renderStringify(v6) + i6 + renderStringify(v7) + suffix :
            NO_CHANGE;
    }

    /**
     *
     * Update an interpolated attribute on an element with single bound value surrounded by text.
     *
     * Used when the value passed to a property has 1 interpolated value in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate1;
    }
    /**
     *
     * Update an interpolated attribute on an element with 2 bound values surrounded by text.
     *
     * Used when the value passed to a property has 2 interpolated values in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate2;
    }
    /**
     *
     * Update an interpolated attribute on an element with 3 bound values surrounded by text.
     *
     * Used when the value passed to a property has 3 interpolated values in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate3(
     * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate3;
    }
    /**
     *
     * Update an interpolated attribute on an element with 4 bound values surrounded by text.
     *
     * Used when the value passed to a property has 4 interpolated values in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate4(
     * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate4(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate4;
    }
    /**
     *
     * Update an interpolated attribute on an element with 5 bound values surrounded by text.
     *
     * Used when the value passed to a property has 5 interpolated values in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate5(
     * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate5(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate5;
    }
    /**
     *
     * Update an interpolated attribute on an element with 6 bound values surrounded by text.
     *
     * Used when the value passed to a property has 6 interpolated values in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate6(
     *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate6(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate6;
    }
    /**
     *
     * Update an interpolated attribute on an element with 7 bound values surrounded by text.
     *
     * Used when the value passed to a property has 7 interpolated values in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate7(
     *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate7(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate7;
    }
    /**
     *
     * Update an interpolated attribute on an element with 8 bound values surrounded by text.
     *
     * Used when the value passed to a property has 8 interpolated values in it:
     *
     * ```html
     * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolate8(
     *  'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
     * ```
     *
     * @param attrName The name of the attribute to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param i6 Static value used for concatenation only.
     * @param v7 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolate8(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolatedValue, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolate8;
    }
    /**
     * Update an interpolated attribute on an element with 8 or more bound values surrounded by text.
     *
     * Used when the number of interpolated values exceeds 7.
     *
     * ```html
     * <div
     *  title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵattributeInterpolateV(
     *  'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
     *  'suffix']);
     * ```
     *
     * @param attrName The name of the attribute to update.
     * @param values The a collection of values and the strings in-between those values, beginning with
     * a string prefix and ending with a string suffix.
     * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolationV(lView, values);
        if (interpolated !== NO_CHANGE) {
            elementAttributeInternal(index, attrName, interpolated, lView, sanitizer, namespace);
        }
        return ɵɵattributeInterpolateV;
    }

    /**
     * @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
     */
    /**
     * Synchronously perform change detection on a component (and possibly its sub-components).
     *
     * This function triggers change detection in a synchronous way on a component. There should
     * be very little reason to call this function directly since a preferred way to do change
     * detection is to {@link markDirty} the component and wait for the scheduler to call this method
     * at some future point in time. This is because a single user action often results in many
     * components being invalidated and calling change detection on each component synchronously
     * would be inefficient. It is better to wait until all components are marked as dirty and
     * then perform single change detection across all of the components
     *
     * @param component The component which the change detection should be performed on.
     */
    function detectChanges(component) {
        var view = getComponentViewByInstance(component);
        detectChangesInternal(view, component);
    }
    /**
     * Mark the component as dirty (needing change detection).
     *
     * Marking a component dirty will schedule a change detection on this
     * component at some point in the future. Marking an already dirty
     * component as dirty is a noop. Only one outstanding change detection
     * can be scheduled per component tree. (Two components bootstrapped with
     * separate `renderComponent` will have separate schedulers)
     *
     * When the root component is bootstrapped with `renderComponent`, a scheduler
     * can be provided.
     *
     * @param component Component to mark as dirty.
     *
     * @publicApi
     */
    function markDirty(component) {
        ngDevMode && assertDefined(component, 'component');
        var rootView = markViewDirty(getComponentViewByInstance(component));
        ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
        scheduleTick(rootView[CONTEXT], 1 /* DetectChanges */);
    }
    /**
     * Used to perform change detection on the whole application.
     *
     * This is equivalent to `detectChanges`, but invoked on root component. Additionally, `tick`
     * executes lifecycle hooks and conditionally checks components based on their
     * `ChangeDetectionStrategy` and dirtiness.
     *
     * The preferred way to trigger change detection is to call `markDirty`. `markDirty` internally
     * schedules `tick` using a scheduler in order to coalesce multiple `markDirty` calls into a
     * single change detection run. By default, the scheduler is `requestAnimationFrame`, but can
     * be changed when calling `renderComponent` and providing the `scheduler` option.
     */
    function tick(component) {
        var rootView = getRootView(component);
        var rootContext = rootView[CONTEXT];
        tickRootContext(rootContext);
    }

    /**
     * @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
     */
    /**
     * Creates an LContainer for inline views, e.g.
     *
     * % if (showing) {
     *   <div></div>
     * % }
     *
     * @param index The index of the container in the data array
     *
     * @codeGenApi
     */
    function ɵɵcontainer(index) {
        var lView = getLView();
        var tNode = containerInternal(lView, index, null, null);
        if (lView[TVIEW].firstTemplatePass) {
            tNode.tViews = [];
        }
        setIsNotParent();
    }
    /**
     * Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
     *
     * <ng-template #foo>
     *    <div></div>
     * </ng-template>
     *
     * @param index The index of the container in the data array
     * @param templateFn Inline template
     * @param consts The number of nodes, local refs, and pipes for this template
     * @param vars The number of bindings for this template
     * @param tagName The name of the container element, if applicable
     * @param attrs The attrs attached to the container, if applicable
     * @param localRefs A set of local reference bindings on the element.
     * @param localRefExtractor A function which extracts local-refs values from the template.
     *        Defaults to the current element associated with the local-ref.
     *
     * @codeGenApi
     */
    function ɵɵtemplate(index, templateFn, consts, vars, tagName, attrs, localRefs, localRefExtractor) {
        var lView = getLView();
        var tView = lView[TVIEW];
        // TODO: consider a separate node type for templates
        var tContainerNode = containerInternal(lView, index, tagName || null, attrs || null);
        if (tView.firstTemplatePass) {
            ngDevMode && ngDevMode.firstTemplatePass++;
            resolveDirectives(tView, lView, tContainerNode, localRefs || null);
            var embeddedTView = tContainerNode.tViews = createTView(-1, templateFn, consts, vars, tView.directiveRegistry, tView.pipeRegistry, null, null);
            if (tView.queries !== null) {
                tView.queries.template(tView, tContainerNode);
                embeddedTView.queries = tView.queries.embeddedTView(tContainerNode);
            }
        }
        createDirectivesAndLocals(tView, lView, tContainerNode, localRefExtractor);
        attachPatchData(getNativeByTNode(tContainerNode, lView), lView);
        registerPostOrderHooks(tView, tContainerNode);
        setIsNotParent();
    }
    /**
     * Sets a container up to receive views.
     *
     * @param index The index of the container in the data array
     *
     * @codeGenApi
     */
    function ɵɵcontainerRefreshStart(index) {
        var lView = getLView();
        var tView = lView[TVIEW];
        var previousOrParentTNode = loadInternal(tView.data, index);
        ngDevMode && assertNodeType(previousOrParentTNode, 0 /* Container */);
        setPreviousOrParentTNode(previousOrParentTNode, true);
        lView[index + HEADER_OFFSET][ACTIVE_INDEX] = 0;
        // We need to execute init hooks here so ngOnInit hooks are called in top level views
        // before they are called in embedded views (for backwards compatibility).
        executePreOrderHooks(lView, tView, getCheckNoChangesMode(), undefined);
    }
    /**
     * Marks the end of the LContainer.
     *
     * Marking the end of LContainer is the time when to child views get inserted or removed.
     *
     * @codeGenApi
     */
    function ɵɵcontainerRefreshEnd() {
        var previousOrParentTNode = getPreviousOrParentTNode();
        if (getIsParent()) {
            setIsNotParent();
        }
        else {
            ngDevMode && assertNodeType(previousOrParentTNode, 2 /* View */);
            ngDevMode && assertHasParent(previousOrParentTNode);
            previousOrParentTNode = previousOrParentTNode.parent;
            setPreviousOrParentTNode(previousOrParentTNode, false);
        }
        ngDevMode && assertNodeType(previousOrParentTNode, 0 /* Container */);
        var lContainer = getLView()[previousOrParentTNode.index];
        var nextIndex = lContainer[ACTIVE_INDEX];
        // remove extra views at the end of the container
        while (nextIndex < lContainer.length - CONTAINER_HEADER_OFFSET) {
            removeView(lContainer, nextIndex);
        }
    }
    function containerInternal(lView, nodeIndex, tagName, attrs) {
        ngDevMode && assertEqual(lView[BINDING_INDEX], lView[TVIEW].bindingStartIndex, 'container nodes should be created before any bindings');
        var adjustedIndex = nodeIndex + HEADER_OFFSET;
        ngDevMode && assertDataInRange(lView, nodeIndex + HEADER_OFFSET);
        ngDevMode && ngDevMode.rendererCreateComment++;
        var comment = lView[adjustedIndex] =
            lView[RENDERER].createComment(ngDevMode ? 'container' : '');
        var tNode = getOrCreateTNode(lView[TVIEW], lView[T_HOST], nodeIndex, 0 /* Container */, tagName, attrs);
        var lContainer = lView[adjustedIndex] = createLContainer(comment, lView, comment, tNode);
        appendChild(comment, tNode, lView);
        // Containers are added to the current view tree instead of their embedded views
        // because views can be removed and re-inserted.
        addToViewTree(lView, lContainer);
        ngDevMode && assertNodeType(getPreviousOrParentTNode(), 0 /* Container */);
        return tNode;
    }

    /**
     * @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
     */
    /** Store a value in the `data` at a given `index`. */
    function store(index, value) {
        var lView = getLView();
        var tView = lView[TVIEW];
        // We don't store any static data for local variables, so the first time
        // we see the template, we should store as null to avoid a sparse array
        var adjustedIndex = index + HEADER_OFFSET;
        if (adjustedIndex >= tView.data.length) {
            tView.data[adjustedIndex] = null;
            tView.blueprint[adjustedIndex] = null;
        }
        lView[adjustedIndex] = value;
    }
    /**
     * Retrieves a local reference from the current contextViewData.
     *
     * If the reference to retrieve is in a parent view, this instruction is used in conjunction
     * with a nextContext() call, which walks up the tree and updates the contextViewData instance.
     *
     * @param index The index of the local ref in contextViewData.
     *
     * @codeGenApi
     */
    function ɵɵreference(index) {
        var contextLView = getContextLView();
        return loadInternal(contextLView, index);
    }
    /**
     * Retrieves a value from current `viewData`.
     *
     * @codeGenApi
     */
    function ɵɵload(index) {
        return loadInternal(getLView(), index);
    }

    /**
     * @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
     */
    function ɵɵdirectiveInject(token, flags) {
        if (flags === void 0) { flags = exports.InjectFlags.Default; }
        token = resolveForwardRef(token);
        var lView = getLView();
        // Fall back to inject() if view hasn't been created. This situation can happen in tests
        // if inject utilities are used before bootstrapping.
        if (lView == null)
            return ɵɵinject(token, flags);
        return getOrCreateInjectable(getPreviousOrParentTNode(), lView, token, flags);
    }
    /**
     * Facade for the attribute injection from DI.
     *
     * @codeGenApi
     */
    function ɵɵinjectAttribute(attrNameToInject) {
        return injectAttributeImpl(getPreviousOrParentTNode(), attrNameToInject);
    }

    /**
     * --------
     *
     * This file contains the core logic for how styling instructions are processed in Angular.
     *
     * To learn more about the algorithm see `TStylingContext`.
     *
     * --------
     */
    /**
     * Temporary function to bridge styling functionality between this new
     * refactor (which is here inside of `styling_next/`) and the old
     * implementation (which lives inside of `styling/`).
     *
     * This function is executed during the creation block of an element.
     * Because the existing styling implementation issues a call to the
     * `styling()` instruction, this instruction will also get run. The
     * central idea here is that the directive index values are bound
     * into the context. The directive index is temporary and is only
     * required until the `select(n)` instruction is fully functional.
     *
     * @codeGenApi
     */
    function ɵɵstyling() {
        var tView = getLView()[TVIEW];
        if (tView.firstTemplatePass) {
            updateLastDirectiveIndex$1(getPreviousOrParentTNode(), getActiveDirectiveStylingIndex());
        }
    }
    /**
     * Sets the current style sanitizer function which will then be used
     * within all follow-up prop and map-based style binding instructions
     * for the given element.
     *
     * Note that once styling has been applied to the element (i.e. once
     * `select(n)` is executed or the hostBindings/template function exits)
     * then the active `sanitizerFn` will be set to `null`. This means that
     * once styling is applied to another element then a another call to
     * `styleSanitizer` will need to be made.
     *
     * @param sanitizerFn The sanitization function that will be used to
     *       process style prop/value entries.
     *
     * @codeGenApi
     */
    function ɵɵstyleSanitizer(sanitizer) {
        setCurrentStyleSanitizer(sanitizer);
    }
    /**
     * Update a style binding on an element with the provided value.
     *
     * If the style value is falsy then it will be removed from the element
     * (or assigned a different value depending if there are any styles placed
     * on the element with `styleMap` or any static styles that are
     * present from when the element was created with `styling`).
     *
     * Note that the styling element is updated as part of `stylingApply`.
     *
     * @param prop A valid CSS property.
     * @param value New value to write (`null` or an empty string to remove).
     * @param suffix Optional suffix. Used with scalar values to add unit such as `px`.
     *        Note that when a suffix is provided then the underlying sanitizer will
     *        be ignored.
     *
     * Note that this will apply the provided style value to the host element if this function is called
     * within a host binding.
     *
     * @codeGenApi
     */
    function ɵɵstyleProp(prop, value, suffix) {
        stylePropInternal(getSelectedIndex(), prop, value, suffix);
    }
    function stylePropInternal(elementIndex, prop, value, suffix) {
        var lView = getLView();
        // if a value is interpolated then it may render a `NO_CHANGE` value.
        // in this case we do not need to do anything, but the binding index
        // still needs to be incremented because all styling binding values
        // are stored inside of the lView.
        var bindingIndex = lView[BINDING_INDEX]++;
        var updated = _stylingProp(elementIndex, bindingIndex, prop, resolveStylePropValue(value, suffix), false, deferStylingUpdate());
        if (ngDevMode) {
            ngDevMode.styleProp++;
            if (updated) {
                ngDevMode.stylePropCacheMiss++;
            }
        }
    }
    /**
     * Update a class binding on an element with the provided value.
     *
     * This instruction is meant to handle the `[class.foo]="exp"` case and,
     * therefore, the class binding itself must already be allocated using
     * `styling` within the creation block.
     *
     * @param prop A valid CSS class (only one).
     * @param value A true/false value which will turn the class on or off.
     *
     * Note that this will apply the provided class value to the host element if this function
     * is called within a host binding.
     *
     * @codeGenApi
     */
    function ɵɵclassProp(className, value) {
        var lView = getLView();
        // if a value is interpolated then it may render a `NO_CHANGE` value.
        // in this case we do not need to do anything, but the binding index
        // still needs to be incremented because all styling binding values
        // are stored inside of the lView.
        var bindingIndex = lView[BINDING_INDEX]++;
        var updated = _stylingProp(getSelectedIndex(), bindingIndex, className, value, true, deferStylingUpdate());
        if (ngDevMode) {
            ngDevMode.classProp++;
            if (updated) {
                ngDevMode.classPropCacheMiss++;
            }
        }
    }
    /**
     * Shared function used to update a prop-based styling binding for an element.
     */
    function _stylingProp(elementIndex, bindingIndex, prop, value, isClassBased, defer) {
        var lView = getLView();
        var tNode = getTNode(elementIndex, lView);
        var native = getNativeByTNode(tNode, lView);
        var updated = false;
        if (value !== NO_CHANGE) {
            if (isClassBased) {
                updated = updateClassBinding(getClassesContext(tNode), lView, native, prop, bindingIndex, value, defer, false);
            }
            else {
                var sanitizer = getCurrentStyleSanitizer();
                updated = updateStyleBinding(getStylesContext(tNode), lView, native, prop, bindingIndex, value, sanitizer, defer, false);
            }
        }
        return updated;
    }
    /**
     * Update style bindings using an object literal on an element.
     *
     * This instruction is meant to apply styling via the `[style]="exp"` template bindings.
     * When styles are applied to the element they will then be updated with respect to
     * any styles/classes set via `styleProp`. If any styles are set to falsy
     * then they will be removed from the element.
     *
     * Note that the styling instruction will not be applied until `stylingApply` is called.
     *
     * @param styles A key/value style map of the styles that will be applied to the given element.
     *        Any missing styles (that have already been applied to the element beforehand) will be
     *        removed (unset) from the element's styling.
     *
     * Note that this will apply the provided styleMap value to the host element if this function
     * is called within a host binding.
     *
     * @codeGenApi
     */
    function ɵɵstyleMap(styles) {
        var index = getSelectedIndex();
        var lView = getLView();
        var tNode = getTNode(index, lView);
        var context = getStylesContext(tNode);
        var directiveIndex = getActiveDirectiveStylingIndex();
        // if a value is interpolated then it may render a `NO_CHANGE` value.
        // in this case we do not need to do anything, but the binding index
        // still needs to be incremented because all styling binding values
        // are stored inside of the lView.
        var bindingIndex = lView[BINDING_INDEX]++;
        // inputs are only evaluated from a template binding into a directive, therefore,
        // there should not be a situation where a directive host bindings function
        // evaluates the inputs (this should only happen in the template function)
        if (!directiveIndex && hasStyleInput(tNode) && styles !== NO_CHANGE) {
            updateDirectiveInputValue(context, lView, tNode, bindingIndex, styles, false);
            styles = NO_CHANGE;
        }
        var updated = _stylingMap(index, context, bindingIndex, styles, false, deferStylingUpdate());
        if (ngDevMode) {
            ngDevMode.styleMap++;
            if (updated) {
                ngDevMode.styleMapCacheMiss++;
            }
        }
    }
    /**
     * Update class bindings using an object literal or class-string on an element.
     *
     * This instruction is meant to apply styling via the `[class]="exp"` template bindings.
     * When classes are applied to the element they will then be updated with
     * respect to any styles/classes set via `classProp`. If any
     * classes are set to falsy then they will be removed from the element.
     *
     * Note that the styling instruction will not be applied until `stylingApply` is called.
     * Note that this will the provided classMap value to the host element if this function is called
     * within a host binding.
     *
     * @param classes A key/value map or string of CSS classes that will be added to the
     *        given element. Any missing classes (that have already been applied to the element
     *        beforehand) will be removed (unset) from the element's list of CSS classes.
     *
     * @codeGenApi
     */
    function ɵɵclassMap(classes) {
        classMapInternal(getSelectedIndex(), classes);
    }
    function classMapInternal(elementIndex, classes) {
        var lView = getLView();
        var tNode = getTNode(elementIndex, lView);
        var context = getClassesContext(tNode);
        var directiveIndex = getActiveDirectiveStylingIndex();
        // if a value is interpolated then it may render a `NO_CHANGE` value.
        // in this case we do not need to do anything, but the binding index
        // still needs to be incremented because all styling binding values
        // are stored inside of the lView.
        var bindingIndex = lView[BINDING_INDEX]++;
        // inputs are only evaluated from a template binding into a directive, therefore,
        // there should not be a situation where a directive host bindings function
        // evaluates the inputs (this should only happen in the template function)
        if (!directiveIndex && hasClassInput(tNode) && classes !== NO_CHANGE) {
            updateDirectiveInputValue(context, lView, tNode, bindingIndex, classes, true);
            classes = NO_CHANGE;
        }
        var updated = _stylingMap(elementIndex, context, bindingIndex, classes, true, deferStylingUpdate());
        if (ngDevMode) {
            ngDevMode.classMap++;
            if (updated) {
                ngDevMode.classMapCacheMiss++;
            }
        }
    }
    /**
     * Shared function used to update a map-based styling binding for an element.
     *
     * When this function is called it will activate support for `[style]` and
     * `[class]` bindings in Angular.
     */
    function _stylingMap(elementIndex, context, bindingIndex, value, isClassBased, defer) {
        activateStylingMapFeature();
        var lView = getLView();
        var valueHasChanged = false;
        if (value !== NO_CHANGE) {
            var tNode = getTNode(elementIndex, lView);
            var native = getNativeByTNode(tNode, lView);
            var oldValue = lView[bindingIndex];
            valueHasChanged = hasValueChanged(oldValue, value);
            var stylingMapArr = normalizeIntoStylingMap(oldValue, value, !isClassBased);
            if (isClassBased) {
                updateClassBinding(context, lView, native, null, bindingIndex, stylingMapArr, defer, valueHasChanged);
            }
            else {
                var sanitizer = getCurrentStyleSanitizer();
                updateStyleBinding(context, lView, native, null, bindingIndex, stylingMapArr, sanitizer, defer, valueHasChanged);
            }
        }
        return valueHasChanged;
    }
    /**
     * Writes a value to a directive's `style` or `class` input binding (if it has changed).
     *
     * If a directive has a `@Input` binding that is set on `style` or `class` then that value
     * will take priority over the underlying style/class styling bindings. This value will
     * be updated for the binding each time during change detection.
     *
     * When this occurs this function will attempt to write the value to the input binding
     * depending on the following situations:
     *
     * - If `oldValue !== newValue`
     * - If `newValue` is `null` (but this is skipped if it is during the first update pass--
     *    which is when the context is not locked yet)
     */
    function updateDirectiveInputValue(context, lView, tNode, bindingIndex, newValue, isClassBased) {
        var oldValue = lView[bindingIndex];
        if (oldValue !== newValue) {
            // even if the value has changed we may not want to emit it to the
            // directive input(s) in the event that it is falsy during the
            // first update pass.
            if (newValue || isContextLocked(context)) {
                var inputs = tNode.inputs[isClassBased ? 'class' : 'style'];
                var initialValue = getInitialStylingValue(context);
                var value = normalizeStylingDirectiveInputValue(initialValue, newValue, isClassBased);
                setInputsForProperty(lView, inputs, value);
            }
            lView[bindingIndex] = newValue;
        }
    }
    /**
     * Returns the appropriate directive input value for `style` or `class`.
     *
     * Earlier versions of Angular expect a binding value to be passed into directive code
     * exactly as it is unless there is a static value present (in which case both values
     * will be stringified and concatenated).
     */
    function normalizeStylingDirectiveInputValue(initialValue, bindingValue, isClassBased) {
        var value = bindingValue;
        // we only concat values if there is an initial value, otherwise we return the value as is.
        // Note that this is to satisfy backwards-compatibility in Angular.
        if (initialValue.length > 0) {
            if (isClassBased) {
                value = concatString(initialValue, forceClassesAsString(bindingValue));
            }
            else {
                value = concatString(initialValue, forceStylesAsString(bindingValue), ';');
            }
        }
        return value;
    }
    /**
     * Flushes all styling code to the element.
     *
     * This function is designed to be called from the template and hostBindings
     * functions and may be called multiple times depending whether multiple
     * sources of styling exist. If called multiple times, only the last call
     * to `stlyingApply()` will render styling to the element.
     *
     * @codeGenApi
     */
    function ɵɵstylingApply() {
        var elementIndex = getSelectedIndex();
        var lView = getLView();
        var tNode = getTNode(elementIndex, lView);
        var renderer = getRenderer(tNode, lView);
        var native = getNativeByTNode(tNode, lView);
        var directiveIndex = getActiveDirectiveStylingIndex();
        var sanitizer = getCurrentStyleSanitizer();
        flushStyling(renderer, lView, getClassesContext(tNode), getStylesContext(tNode), native, directiveIndex, sanitizer);
        setCurrentStyleSanitizer(null);
    }
    function getRenderer(tNode, lView) {
        return tNode.type === 3 /* Element */ ? lView[RENDERER] : null;
    }
    /**
     * Searches and assigns provided all static style/class entries (found in the `attrs` value)
     * and registers them in their respective styling contexts.
     */
    function registerInitialStylingOnTNode(tNode, attrs, startIndex) {
        var hasAdditionalInitialStyling = false;
        var styles = getStylingMapArray(tNode.styles);
        var classes = getStylingMapArray(tNode.classes);
        var mode = -1;
        for (var i = startIndex; i < attrs.length; i++) {
            var attr = attrs[i];
            if (typeof attr == 'number') {
                mode = attr;
            }
            else if (mode == 1 /* Classes */) {
                classes = classes || [''];
                addItemToStylingMap(classes, attr, true);
                hasAdditionalInitialStyling = true;
            }
            else if (mode == 2 /* Styles */) {
                var value = attrs[++i];
                styles = styles || [''];
                addItemToStylingMap(styles, attr, value);
                hasAdditionalInitialStyling = true;
            }
        }
        if (classes && classes.length > 1 /* ValuesStartPosition */) {
            if (!tNode.classes) {
                tNode.classes = classes;
            }
            updateRawValueOnContext(tNode.classes, stylingMapToString(classes, true));
        }
        if (styles && styles.length > 1 /* ValuesStartPosition */) {
            if (!tNode.styles) {
                tNode.styles = styles;
            }
            updateRawValueOnContext(tNode.styles, stylingMapToString(styles, false));
        }
        return hasAdditionalInitialStyling;
    }
    function updateRawValueOnContext(context, value) {
        var stylingMapArr = getStylingMapArray(context);
        stylingMapArr[0 /* RawValuePosition */] = value;
    }
    function getActiveDirectiveStylingIndex() {
        // whenever a directive's hostBindings function is called a uniqueId value
        // is assigned. Normally this is enough to help distinguish one directive
        // from another for the styling context, but there are situations where a
        // sub-class directive could inherit and assign styling in concert with a
        // parent directive. To help the styling code distinguish between a parent
        // sub-classed directive the inheritance depth is taken into account as well.
        return getActiveDirectiveId() + getActiveDirectiveSuperClassDepth();
    }
    /**
     * Temporary function that will update the max directive index value in
     * both the classes and styles contexts present on the provided `tNode`.
     *
     * This code is only used because the `select(n)` code functionality is not
     * yet 100% functional. The `select(n)` instruction cannot yet evaluate host
     * bindings function code in sync with the associated template function code.
     * For this reason the styling algorithm needs to track the last directive index
     * value so that it knows exactly when to render styling to the element since
     * `stylingApply()` is called multiple times per CD (`stylingApply` will be
     * removed once `select(n)` is fixed).
     */
    function updateLastDirectiveIndex$1(tNode, directiveIndex) {
        updateLastDirectiveIndex(getClassesContext(tNode), directiveIndex);
        updateLastDirectiveIndex(getStylesContext(tNode), directiveIndex);
    }
    function getStylesContext(tNode) {
        return getContext(tNode, false);
    }
    function getClassesContext(tNode) {
        return getContext(tNode, true);
    }
    /**
     * Returns/instantiates a styling context from/to a `tNode` instance.
     */
    function getContext(tNode, isClassBased) {
        var context = isClassBased ? tNode.classes : tNode.styles;
        if (!isStylingContext(context)) {
            context = allocTStylingContext(context);
            if (ngDevMode) {
                attachStylingDebugObject(context);
            }
            if (isClassBased) {
                tNode.classes = context;
            }
            else {
                tNode.styles = context;
            }
        }
        return context;
    }
    function resolveStylePropValue(value, suffix) {
        if (value === NO_CHANGE)
            return value;
        var resolvedValue = null;
        if (value !== null) {
            if (suffix) {
                // when a suffix is applied then it will bypass
                // sanitization entirely (b/c a new string is created)
                resolvedValue = renderStringify(value) + suffix;
            }
            else {
                // sanitization happens by dealing with a String value
                // this means that the string value will be passed through
                // into the style rendering later (which is where the value
                // will be sanitized before it is applied)
                resolvedValue = value;
            }
        }
        return resolvedValue;
    }
    /**
     * Whether or not a style/class binding update should be applied later.
     *
     * This function will decide whether a binding should be applied immediately
     * or later (just before the styles/classes are flushed to the element). The
     * reason why this feature exists is because of super/sub directive inheritance.
     * Angular will evaluate host bindings on the super directive first and the sub
     * directive, but the styling bindings on the sub directive are of higher priority
     * than the super directive. For this reason all styling bindings that take place
     * in this circumstance will need to be deferred until later so that they can be
     * applied together and in a different order (the algorithm handles that part).
     */
    function deferStylingUpdate() {
        return getActiveDirectiveSuperClassHeight() > 0;
    }

    /**
     * @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
     */
    /**
     * Create DOM element. The instruction must later be followed by `elementEnd()` call.
     *
     * @param index Index of the element in the LView array
     * @param name Name of the DOM Node
     * @param attrs Statically bound set of attributes, classes, and styles to be written into the DOM
     *              element on creation. Use [AttributeMarker] to denote the meaning of this array.
     * @param localRefs A set of local reference bindings on the element.
     *
     * Attributes and localRefs are passed as an array of strings where elements with an even index
     * hold an attribute name and elements with an odd index hold an attribute value, ex.:
     * ['id', 'warning5', 'class', 'alert']
     *
     * @codeGenApi
     */
    function ɵɵelementStart(index, name, attrs, localRefs) {
        var lView = getLView();
        var tView = lView[TVIEW];
        ngDevMode && assertEqual(lView[BINDING_INDEX], tView.bindingStartIndex, 'elements should be created before any bindings ');
        ngDevMode && ngDevMode.rendererCreateElement++;
        ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
        var native = lView[index + HEADER_OFFSET] = elementCreate(name);
        var renderer = lView[RENDERER];
        var tNode = getOrCreateTNode(tView, lView[T_HOST], index, 3 /* Element */, name, attrs || null);
        if (attrs != null) {
            var lastAttrIndex = setUpAttributes(native, attrs);
            if (tView.firstTemplatePass) {
                registerInitialStylingOnTNode(tNode, attrs, lastAttrIndex);
            }
        }
        renderInitialStyling(renderer, native, tNode);
        appendChild(native, tNode, lView);
        // any immediate children of a component or template container must be pre-emptively
        // monkey-patched with the component view data so that the element can be inspected
        // later on using any element discovery utility methods (see `element_discovery.ts`)
        if (getElementDepthCount() === 0) {
            attachPatchData(native, lView);
        }
        increaseElementDepthCount();
        // if a directive contains a host binding for "class" then all class-based data will
        // flow through that (except for `[class.prop]` bindings). This also includes initial
        // static class values as well. (Note that this will be fixed once map-based `[style]`
        // and `[class]` bindings work for multiple directives.)
        if (tView.firstTemplatePass) {
            ngDevMode && ngDevMode.firstTemplatePass++;
            resolveDirectives(tView, lView, tNode, localRefs || null);
            var inputData = initializeTNodeInputs(tNode);
            if (inputData && inputData.hasOwnProperty('class')) {
                tNode.flags |= 8 /* hasClassInput */;
            }
            if (inputData && inputData.hasOwnProperty('style')) {
                tNode.flags |= 16 /* hasStyleInput */;
            }
            if (tView.queries !== null) {
                tView.queries.elementStart(tView, tNode);
            }
        }
        createDirectivesAndLocals(tView, lView, tNode);
        executeContentQueries(tView, tNode, lView);
    }
    /**
     * Mark the end of the element.
     *
     * @codeGenApi
     */
    function ɵɵelementEnd() {
        var previousOrParentTNode = getPreviousOrParentTNode();
        ngDevMode && assertDefined(previousOrParentTNode, 'No parent node to close.');
        if (getIsParent()) {
            setIsNotParent();
        }
        else {
            ngDevMode && assertHasParent(getPreviousOrParentTNode());
            previousOrParentTNode = previousOrParentTNode.parent;
            setPreviousOrParentTNode(previousOrParentTNode, false);
        }
        var tNode = previousOrParentTNode;
        ngDevMode && assertNodeType(tNode, 3 /* Element */);
        var lView = getLView();
        var tView = lView[TVIEW];
        registerPostOrderHooks(tView, previousOrParentTNode);
        decreaseElementDepthCount();
        if (tView.firstTemplatePass && tView.queries !== null &&
            isContentQueryHost(previousOrParentTNode)) {
            tView.queries.elementEnd(previousOrParentTNode);
        }
        if (hasClassInput(tNode) && tNode.classes) {
            setDirectiveStylingInput(tNode.classes, lView, tNode.inputs['class']);
        }
        if (hasStyleInput(tNode) && tNode.styles) {
            setDirectiveStylingInput(tNode.styles, lView, tNode.inputs['style']);
        }
    }
    /**
     * Creates an empty element using {@link elementStart} and {@link elementEnd}
     *
     * @param index Index of the element in the data array
     * @param name Name of the DOM Node
     * @param attrs Statically bound set of attributes, classes, and styles to be written into the DOM
     *              element on creation. Use [AttributeMarker] to denote the meaning of this array.
     * @param localRefs A set of local reference bindings on the element.
     *
     * @codeGenApi
     */
    function ɵɵelement(index, name, attrs, localRefs) {
        ɵɵelementStart(index, name, attrs, localRefs);
        ɵɵelementEnd();
    }
    /**
     * Assign static attribute values to a host element.
     *
     * This instruction will assign static attribute values as well as class and style
     * values to an element within the host bindings function. Since attribute values
     * can consist of different types of values, the `attrs` array must include the values in
     * the following format:
     *
     * attrs = [
     *   // static attributes (like `title`, `name`, `id`...)
     *   attr1, value1, attr2, value,
     *
     *   // a single namespace value (like `x:id`)
     *   NAMESPACE_MARKER, namespaceUri1, name1, value1,
     *
     *   // another single namespace value (like `x:name`)
     *   NAMESPACE_MARKER, namespaceUri2, name2, value2,
     *
     *   // a series of CSS classes that will be applied to the element (no spaces)
     *   CLASSES_MARKER, class1, class2, class3,
     *
     *   // a series of CSS styles (property + value) that will be applied to the element
     *   STYLES_MARKER, prop1, value1, prop2, value2
     * ]
     *
     * All non-class and non-style attributes must be defined at the start of the list
     * first before all class and style values are set. When there is a change in value
     * type (like when classes and styles are introduced) a marker must be used to separate
     * the entries. The marker values themselves are set via entries found in the
     * [AttributeMarker] enum.
     *
     * NOTE: This instruction is meant to used from `hostBindings` function only.
     *
     * @param directive A directive instance the styling is associated with.
     * @param attrs An array of static values (attributes, classes and styles) with the correct marker
     * values.
     *
     * @codeGenApi
     */
    function ɵɵelementHostAttrs(attrs) {
        var hostElementIndex = getSelectedIndex();
        var lView = getLView();
        var tView = lView[TVIEW];
        var tNode = getTNode(hostElementIndex, lView);
        // non-element nodes (e.g. `<ng-container>`) are not rendered as actual
        // element nodes and adding styles/classes on to them will cause runtime
        // errors...
        if (tNode.type === 3 /* Element */) {
            var native = getNativeByTNode(tNode, lView);
            var lastAttrIndex = setUpAttributes(native, attrs);
            if (tView.firstTemplatePass) {
                var stylingNeedsToBeRendered = registerInitialStylingOnTNode(tNode, attrs, lastAttrIndex);
                // this is only called during the first template pass in the
                // event that this current directive assigned initial style/class
                // host attribute values to the element. Because initial styling
                // values are applied before directives are first rendered (within
                // `createElement`) this means that initial styling for any directives
                // still needs to be applied. Note that this will only happen during
                // the first template pass and not each time a directive applies its
                // attribute values to the element.
                if (stylingNeedsToBeRendered) {
                    var renderer = lView[RENDERER];
                    renderInitialStyling(renderer, native, tNode);
                }
            }
        }
    }
    function setDirectiveStylingInput(context, lView, stylingInputs) {
        // older versions of Angular treat the input as `null` in the
        // event that the value does not exist at all. For this reason
        // we can't have a styling value be an empty string.
        var value = getInitialStylingValue(context) || null;
        // Ivy does an extra `[class]` write with a falsy value since the value
        // is applied during creation mode. This is a deviation from VE and should
        // be (Jira Issue = FW-1467).
        setInputsForProperty(lView, stylingInputs, value);
    }

    /**
     * @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
     */
    /**
     * Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
     * The instruction must later be followed by `elementContainerEnd()` call.
     *
     * @param index Index of the element in the LView array
     * @param attrs Set of attributes to be used when matching directives.
     * @param localRefs A set of local reference bindings on the element.
     *
     * Even if this instruction accepts a set of attributes no actual attribute values are propagated to
     * the DOM (as a comment node can't have attributes). Attributes are here only for directive
     * matching purposes and setting initial inputs of directives.
     *
     * @codeGenApi
     */
    function ɵɵelementContainerStart(index, attrs, localRefs) {
        var lView = getLView();
        var tView = lView[TVIEW];
        var renderer = lView[RENDERER];
        var tagName = 'ng-container';
        ngDevMode && assertEqual(lView[BINDING_INDEX], tView.bindingStartIndex, 'element containers should be created before any bindings');
        ngDevMode && ngDevMode.rendererCreateComment++;
        ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
        var native = lView[index + HEADER_OFFSET] = renderer.createComment(ngDevMode ? tagName : '');
        ngDevMode && assertDataInRange(lView, index - 1);
        var tNode = getOrCreateTNode(tView, lView[T_HOST], index, 4 /* ElementContainer */, tagName, attrs || null);
        if (attrs && tView.firstTemplatePass) {
            // While ng-container doesn't necessarily support styling, we use the style context to identify
            // and execute directives on the ng-container.
            registerInitialStylingOnTNode(tNode, attrs, 0);
        }
        appendChild(native, tNode, lView);
        if (tView.firstTemplatePass) {
            ngDevMode && ngDevMode.firstTemplatePass++;
            resolveDirectives(tView, lView, tNode, localRefs || null);
            if (tView.queries) {
                tView.queries.elementStart(tView, tNode);
            }
        }
        createDirectivesAndLocals(tView, lView, tNode);
        attachPatchData(native, lView);
        executeContentQueries(tView, tNode, lView);
    }
    /**
     * Mark the end of the <ng-container>.
     *
     * @codeGenApi
     */
    function ɵɵelementContainerEnd() {
        var previousOrParentTNode = getPreviousOrParentTNode();
        var lView = getLView();
        var tView = lView[TVIEW];
        if (getIsParent()) {
            setIsNotParent();
        }
        else {
            ngDevMode && assertHasParent(previousOrParentTNode);
            previousOrParentTNode = previousOrParentTNode.parent;
            setPreviousOrParentTNode(previousOrParentTNode, false);
        }
        ngDevMode && assertNodeType(previousOrParentTNode, 4 /* ElementContainer */);
        registerPostOrderHooks(tView, previousOrParentTNode);
        if (tView.firstTemplatePass && tView.queries !== null &&
            isContentQueryHost(previousOrParentTNode)) {
            tView.queries.elementEnd(previousOrParentTNode);
        }
    }
    /**
     * Creates an empty logical container using {@link elementContainerStart}
     * and {@link elementContainerEnd}
     *
     * @param index Index of the element in the LView array
     * @param attrs Set of attributes to be used when matching directives.
     * @param localRefs A set of local reference bindings on the element.
     *
     * @codeGenApi
     */
    function ɵɵelementContainer(index, attrs, localRefs) {
        ɵɵelementContainerStart(index, attrs, localRefs);
        ɵɵelementContainerEnd();
    }

    /**
     * @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
     */
    /**
     * Marks the start of an embedded view.
     *
     * @param viewBlockId The ID of this view
     * @return boolean Whether or not this view is in creation mode
     *
     * @codeGenApi
     */
    function ɵɵembeddedViewStart(viewBlockId, consts, vars) {
        var lView = getLView();
        var previousOrParentTNode = getPreviousOrParentTNode();
        // The previous node can be a view node if we are processing an inline for loop
        var containerTNode = previousOrParentTNode.type === 2 /* View */ ?
            previousOrParentTNode.parent :
            previousOrParentTNode;
        var lContainer = lView[containerTNode.index];
        ngDevMode && assertNodeType(containerTNode, 0 /* Container */);
        var viewToRender = scanForView(lContainer, lContainer[ACTIVE_INDEX], viewBlockId);
        if (viewToRender) {
            setIsParent();
            enterView(viewToRender, viewToRender[TVIEW].node);
        }
        else {
            // When we create a new LView, we always reset the state of the instructions.
            viewToRender = createLView(lView, getOrCreateEmbeddedTView(viewBlockId, consts, vars, containerTNode), null, 16 /* CheckAlways */, null, null);
            var tParentNode = getIsParent() ? previousOrParentTNode :
                previousOrParentTNode && previousOrParentTNode.parent;
            assignTViewNodeToLView(viewToRender[TVIEW], tParentNode, viewBlockId, viewToRender);
            enterView(viewToRender, viewToRender[TVIEW].node);
        }
        if (lContainer) {
            if (isCreationMode(viewToRender)) {
                // it is a new view, insert it into collection of views for a given container
                insertView(viewToRender, lContainer, lContainer[ACTIVE_INDEX]);
            }
            lContainer[ACTIVE_INDEX]++;
        }
        return isCreationMode(viewToRender) ? 1 /* Create */ | 2 /* Update */ :
            2 /* Update */;
    }
    /**
     * Initialize the TView (e.g. static data) for the active embedded view.
     *
     * Each embedded view block must create or retrieve its own TView. Otherwise, the embedded view's
     * static data for a particular node would overwrite the static data for a node in the view above
     * it with the same index (since it's in the same template).
     *
     * @param viewIndex The index of the TView in TNode.tViews
     * @param consts The number of nodes, local refs, and pipes in this template
     * @param vars The number of bindings and pure function bindings in this template
     * @param container The parent container in which to look for the view's static data
     * @returns TView
     */
    function getOrCreateEmbeddedTView(viewIndex, consts, vars, parent) {
        var tView = getLView()[TVIEW];
        ngDevMode && assertNodeType(parent, 0 /* Container */);
        var containerTViews = parent.tViews;
        ngDevMode && assertDefined(containerTViews, 'TView expected');
        ngDevMode && assertEqual(Array.isArray(containerTViews), true, 'TViews should be in an array');
        if (viewIndex >= containerTViews.length || containerTViews[viewIndex] == null) {
            containerTViews[viewIndex] = createTView(viewIndex, null, consts, vars, tView.directiveRegistry, tView.pipeRegistry, null, null);
        }
        return containerTViews[viewIndex];
    }
    /**
     * Looks for a view with a given view block id inside a provided LContainer.
     * Removes views that need to be deleted in the process.
     *
     * @param lContainer to search for views
     * @param startIdx starting index in the views array to search from
     * @param viewBlockId exact view block id to look for
     */
    function scanForView(lContainer, startIdx, viewBlockId) {
        for (var i = startIdx + CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
            var viewAtPositionId = lContainer[i][TVIEW].id;
            if (viewAtPositionId === viewBlockId) {
                return lContainer[i];
            }
            else if (viewAtPositionId < viewBlockId) {
                // found a view that should not be at this position - remove
                removeView(lContainer, i - CONTAINER_HEADER_OFFSET);
            }
            else {
                // found a view with id greater than the one we are searching for
                // which means that required view doesn't exist and can't be found at
                // later positions in the views array - stop the searchdef.cont here
                break;
            }
        }
        return null;
    }
    /**
     * Marks the end of an embedded view.
     *
     * @codeGenApi
     */
    function ɵɵembeddedViewEnd() {
        var lView = getLView();
        var viewHost = lView[T_HOST];
        if (isCreationMode(lView)) {
            refreshDescendantViews(lView); // creation mode pass
            lView[FLAGS] &= ~4 /* CreationMode */;
        }
        resetPreOrderHookFlags(lView);
        refreshDescendantViews(lView); // update mode pass
        var lContainer = lView[PARENT];
        ngDevMode && assertLContainerOrUndefined(lContainer);
        // It's always safe to run hooks here, as `leaveView` is not called during the 'finally' block
        // of a try-catch-finally statement, so it can never be reached while unwinding the stack due to
        // an error being thrown.
        leaveView(lContainer[PARENT], /* safeToRunHooks */ true);
        setPreviousOrParentTNode(viewHost, false);
    }

    /**
     * Returns the current OpaqueViewState instance.
     *
     * Used in conjunction with the restoreView() instruction to save a snapshot
     * of the current view and restore it when listeners are invoked. This allows
     * walking the declaration view tree in listeners to get vars from parent views.
     *
     * @codeGenApi
     */
    function ɵɵgetCurrentView() {
        return getLView();
    }

    /**
     * @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
     */
    /**
     * Determine if the argument is shaped like a Promise
     */
    function isPromise(obj) {
        // allow any Promise/A+ compliant thenable.
        // It's up to the caller to ensure that obj.then conforms to the spec
        return !!obj && typeof obj.then === 'function';
    }
    /**
     * Determine if the argument is an Observable
     */
    function isObservable(obj) {
        // TODO: use isObservable once we update pass rxjs 6.1
        // https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md#610-2018-05-03
        return !!obj && typeof obj.subscribe === 'function';
    }

    /**
     * @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
     */
    /**
     * Adds an event listener to the current node.
     *
     * If an output exists on one of the node's directives, it also subscribes to the output
     * and saves the subscription for later cleanup.
     *
     * @param eventName Name of the event
     * @param listenerFn The function to be called when event emits
     * @param useCapture Whether or not to use capture in event listener
     * @param eventTargetResolver Function that returns global target information in case this listener
     * should be attached to a global object like window, document or body
     *
     * @codeGenApi
     */
    function ɵɵlistener(eventName, listenerFn, useCapture, eventTargetResolver) {
        if (useCapture === void 0) { useCapture = false; }
        listenerInternal(eventName, listenerFn, useCapture, eventTargetResolver);
    }
    /**
    * Registers a synthetic host listener (e.g. `(@foo.start)`) on a component.
    *
    * This instruction is for compatibility purposes and is designed to ensure that a
    * synthetic host listener (e.g. `@HostListener('@foo.start')`) properly gets rendered
    * in the component's renderer. Normally all host listeners are evaluated with the
    * parent component's renderer, but, in the case of animation @triggers, they need
    * to be evaluated with the sub component's renderer (because that's where the
    * animation triggers are defined).
    *
    * Do not use this instruction as a replacement for `listener`. This instruction
    * only exists to ensure compatibility with the ViewEngine's host binding behavior.
    *
    * @param eventName Name of the event
    * @param listenerFn The function to be called when event emits
    * @param useCapture Whether or not to use capture in event listener
    * @param eventTargetResolver Function that returns global target information in case this listener
    * should be attached to a global object like window, document or body
     *
     * @codeGenApi
    */
    function ɵɵcomponentHostSyntheticListener(eventName, listenerFn, useCapture, eventTargetResolver) {
        if (useCapture === void 0) { useCapture = false; }
        listenerInternal(eventName, listenerFn, useCapture, eventTargetResolver, loadComponentRenderer);
    }
    /**
     * A utility function that checks if a given element has already an event handler registered for an
     * event with a specified name. The TView.cleanup data structure is used to find out which events
     * are registered for a given element.
     */
    function findExistingListener(lView, eventName, tNodeIdx) {
        var tView = lView[TVIEW];
        var tCleanup = tView.cleanup;
        if (tCleanup != null) {
            for (var i = 0; i < tCleanup.length - 1; i += 2) {
                var cleanupEventName = tCleanup[i];
                if (cleanupEventName === eventName && tCleanup[i + 1] === tNodeIdx) {
                    // We have found a matching event name on the same node but it might not have been
                    // registered yet, so we must explicitly verify entries in the LView cleanup data
                    // structures.
                    var lCleanup = lView[CLEANUP];
                    var listenerIdxInLCleanup = tCleanup[i + 2];
                    return lCleanup.length > listenerIdxInLCleanup ? lCleanup[listenerIdxInLCleanup] : null;
                }
                // TView.cleanup can have a mix of 4-elements entries (for event handler cleanups) or
                // 2-element entries (for directive and queries destroy hooks). As such we can encounter
                // blocks of 4 or 2 items in the tView.cleanup and this is why we iterate over 2 elements
                // first and jump another 2 elements if we detect listeners cleanup (4 elements). Also check
                // documentation of TView.cleanup for more details of this data structure layout.
                if (typeof cleanupEventName === 'string') {
                    i += 2;
                }
            }
        }
        return null;
    }
    function listenerInternal(eventName, listenerFn, useCapture, eventTargetResolver, loadRendererFn) {
        if (useCapture === void 0) { useCapture = false; }
        var lView = getLView();
        var tNode = getPreviousOrParentTNode();
        var tView = lView[TVIEW];
        var firstTemplatePass = tView.firstTemplatePass;
        var tCleanup = firstTemplatePass && (tView.cleanup || (tView.cleanup = []));
        ngDevMode && assertNodeOfPossibleTypes(tNode, 3 /* Element */, 0 /* Container */, 4 /* ElementContainer */);
        var processOutputs = true;
        // add native event listener - applicable to elements only
        if (tNode.type === 3 /* Element */) {
            var native = getNativeByTNode(tNode, lView);
            var resolved = eventTargetResolver ? eventTargetResolver(native) : EMPTY_OBJ;
            var target = resolved.target || native;
            var renderer = loadRendererFn ? loadRendererFn(tNode, lView) : lView[RENDERER];
            var lCleanup = getCleanup(lView);
            var lCleanupIndex = lCleanup.length;
            var idxOrTargetGetter = eventTargetResolver ?
                function (_lView) { return eventTargetResolver(unwrapRNode(_lView[tNode.index])).target; } :
                tNode.index;
            // In order to match current behavior, native DOM event listeners must be added for all
            // events (including outputs).
            if (isProceduralRenderer(renderer)) {
                // There might be cases where multiple directives on the same element try to register an event
                // handler function for the same event. In this situation we want to avoid registration of
                // several native listeners as each registration would be intercepted by NgZone and
                // trigger change detection. This would mean that a single user action would result in several
                // change detections being invoked. To avoid this situation we want to have only one call to
                // native handler registration (for the same element and same type of event).
                //
                // In order to have just one native event handler in presence of multiple handler functions,
                // we just register a first handler function as a native event listener and then chain
                // (coalesce) other handler functions on top of the first native handler function.
                var existingListener = null;
                // Please note that the coalescing described here doesn't happen for events specifying an
                // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
                // view engine.
                // Also, we don't have to search for existing listeners is there are no directives
                // matching on a given node as we can't register multiple event handlers for the same event in
                // a template (this would mean having duplicate attributes).
                if (!eventTargetResolver && hasDirectives(tNode)) {
                    existingListener = findExistingListener(lView, eventName, tNode.index);
                }
                if (existingListener !== null) {
                    // Attach a new listener at the head of the coalesced listeners list.
                    listenerFn.__ngNextListenerFn__ = existingListener.__ngNextListenerFn__;
                    existingListener.__ngNextListenerFn__ = listenerFn;
                    processOutputs = false;
                }
                else {
                    // The first argument of `listen` function in Procedural Renderer is:
                    // - either a target name (as a string) in case of global target (window, document, body)
                    // - or element reference (in all other cases)
                    listenerFn = wrapListener(tNode, lView, listenerFn, false /** preventDefault */);
                    var cleanupFn = renderer.listen(resolved.name || target, eventName, listenerFn);
                    ngDevMode && ngDevMode.rendererAddEventListener++;
                    lCleanup.push(listenerFn, cleanupFn);
                    tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
                }
            }
            else {
                listenerFn = wrapListener(tNode, lView, listenerFn, true /** preventDefault */);
                target.addEventListener(eventName, listenerFn, useCapture);
                ngDevMode && ngDevMode.rendererAddEventListener++;
                lCleanup.push(listenerFn);
                tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, useCapture);
            }
        }
        // subscribe to directive outputs
        if (tNode.outputs === undefined) {
            // if we create TNode here, inputs must be undefined so we know they still need to be
            // checked
            tNode.outputs = generatePropertyAliases(tNode, 1 /* Output */);
        }
        var outputs = tNode.outputs;
        var props;
        if (processOutputs && outputs && (props = outputs[eventName])) {
            var propsLength = props.length;
            if (propsLength) {
                var lCleanup = getCleanup(lView);
                for (var i = 0; i < propsLength; i += 3) {
                    var index = props[i];
                    ngDevMode && assertDataInRange(lView, index);
                    var minifiedName = props[i + 2];
                    var directiveInstance = lView[index];
                    var output = directiveInstance[minifiedName];
                    if (ngDevMode && !isObservable(output)) {
                        throw new Error("@Output " + minifiedName + " not initialized in '" + directiveInstance.constructor.name + "'.");
                    }
                    var subscription = output.subscribe(listenerFn);
                    var idx = lCleanup.length;
                    lCleanup.push(listenerFn, subscription);
                    tCleanup && tCleanup.push(eventName, tNode.index, idx, -(idx + 1));
                }
            }
        }
    }
    function executeListenerWithErrorHandling(lView, listenerFn, e) {
        try {
            // Only explicitly returning false from a listener should preventDefault
            return listenerFn(e) !== false;
        }
        catch (error) {
            handleError(lView, error);
            return false;
        }
    }
    /**
     * Wraps an event listener with a function that marks ancestors dirty and prevents default behavior,
     * if applicable.
     *
     * @param tNode The TNode associated with this listener
     * @param lView The LView that contains this listener
     * @param listenerFn The listener function to call
     * @param wrapWithPreventDefault Whether or not to prevent default behavior
     * (the procedural renderer does this already, so in those cases, we should skip)
     */
    function wrapListener(tNode, lView, listenerFn, wrapWithPreventDefault) {
        // Note: we are performing most of the work in the listener function itself
        // to optimize listener registration.
        return function wrapListenerIn_markDirtyAndPreventDefault(e) {
            // In order to be backwards compatible with View Engine, events on component host nodes
            // must also mark the component view itself dirty (i.e. the view that it owns).
            var startView = tNode.flags & 1 /* isComponent */ ? getComponentViewByIndex(tNode.index, lView) : lView;
            // See interfaces/view.ts for more on LViewFlags.ManualOnPush
            if ((lView[FLAGS] & 32 /* ManualOnPush */) === 0) {
                markViewDirty(startView);
            }
            var result = executeListenerWithErrorHandling(lView, listenerFn, e);
            // A just-invoked listener function might have coalesced listeners so we need to check for
            // their presence and invoke as needed.
            var nextListenerFn = wrapListenerIn_markDirtyAndPreventDefault.__ngNextListenerFn__;
            while (nextListenerFn) {
                // We should prevent default if any of the listeners explicitly return false
                result = executeListenerWithErrorHandling(lView, nextListenerFn, e) && result;
                nextListenerFn = nextListenerFn.__ngNextListenerFn__;
            }
            if (wrapWithPreventDefault && result === false) {
                e.preventDefault();
                // Necessary for legacy browsers that don't support preventDefault (e.g. IE)
                e.returnValue = false;
            }
            return result;
        };
    }

    /**
     * @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
     */

    /**
     * @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
     */
    /**
     * Retrieves a context at the level specified and saves it as the global, contextViewData.
     * Will get the next level up if level is not specified.
     *
     * This is used to save contexts of parent views so they can be bound in embedded views, or
     * in conjunction with reference() to bind a ref from a parent view.
     *
     * @param level The relative level of the view from which to grab context compared to contextVewData
     * @returns context
     *
     * @codeGenApi
     */
    function ɵɵnextContext(level) {
        if (level === void 0) { level = 1; }
        return nextContextImpl(level);
    }

    /**
     * Checks a given node against matching projection slots and returns the
     * determined slot index. Returns "null" if no slot matched the given node.
     *
     * This function takes into account the parsed ngProjectAs selector from the
     * node's attributes. If present, it will check whether the ngProjectAs selector
     * matches any of the projection slot selectors.
     */
    function matchingProjectionSlotIndex(tNode, projectionSlots) {
        var wildcardNgContentIndex = null;
        var ngProjectAsAttrVal = getProjectAsAttrValue(tNode);
        for (var i = 0; i < projectionSlots.length; i++) {
            var slotValue = projectionSlots[i];
            // The last wildcard projection slot should match all nodes which aren't matching
            // any selector. This is necessary to be backwards compatible with view engine.
            if (slotValue === '*') {
                wildcardNgContentIndex = i;
                continue;
            }
            // If we ran into an `ngProjectAs` attribute, we should match its parsed selector
            // to the list of selectors, otherwise we fall back to matching against the node.
            if (ngProjectAsAttrVal === null ?
                isNodeMatchingSelectorList(tNode, slotValue, /* isProjectionMode */ true) :
                isSelectorInSelectorList(ngProjectAsAttrVal, slotValue)) {
                return i; // first matching selector "captures" a given node
            }
        }
        return wildcardNgContentIndex;
    }
    /**
     * Instruction to distribute projectable nodes among <ng-content> occurrences in a given template.
     * It takes all the selectors from the entire component's template and decides where
     * each projected node belongs (it re-distributes nodes among "buckets" where each "bucket" is
     * backed by a selector).
     *
     * This function requires CSS selectors to be provided in 2 forms: parsed (by a compiler) and text,
     * un-parsed form.
     *
     * The parsed form is needed for efficient matching of a node against a given CSS selector.
     * The un-parsed, textual form is needed for support of the ngProjectAs attribute.
     *
     * Having a CSS selector in 2 different formats is not ideal, but alternatives have even more
     * drawbacks:
     * - having only a textual form would require runtime parsing of CSS selectors;
     * - we can't have only a parsed as we can't re-construct textual form from it (as entered by a
     * template author).
     *
     * @param projectionSlots? A collection of projection slots. A projection slot can be based
     *        on a parsed CSS selectors or set to the wildcard selector ("*") in order to match
     *        all nodes which do not match any selector. If not specified, a single wildcard
     *        selector projection slot will be defined.
     *
     * @codeGenApi
     */
    function ɵɵprojectionDef(projectionSlots) {
        var componentNode = findComponentView(getLView())[T_HOST];
        if (!componentNode.projection) {
            // If no explicit projection slots are defined, fall back to a single
            // projection slot with the wildcard selector.
            var numProjectionSlots = projectionSlots ? projectionSlots.length : 1;
            var projectionHeads = componentNode.projection =
                new Array(numProjectionSlots).fill(null);
            var tails = projectionHeads.slice();
            var componentChild = componentNode.child;
            while (componentChild !== null) {
                var slotIndex = projectionSlots ? matchingProjectionSlotIndex(componentChild, projectionSlots) : 0;
                if (slotIndex !== null) {
                    if (tails[slotIndex]) {
                        tails[slotIndex].projectionNext = componentChild;
                    }
                    else {
                        projectionHeads[slotIndex] = componentChild;
                    }
                    tails[slotIndex] = componentChild;
                }
                componentChild = componentChild.next;
            }
        }
    }
    var delayProjection = false;
    function setDelayProjection(value) {
        delayProjection = value;
    }
    /**
     * Inserts previously re-distributed projected nodes. This instruction must be preceded by a call
     * to the projectionDef instruction.
     *
     * @param nodeIndex
     * @param selectorIndex:
     *        - 0 when the selector is `*` (or unspecified as this is the default value),
     *        - 1 based index of the selector from the {@link projectionDef}
     *
     * @codeGenApi
    */
    function ɵɵprojection(nodeIndex, selectorIndex, attrs) {
        if (selectorIndex === void 0) { selectorIndex = 0; }
        var lView = getLView();
        var tProjectionNode = getOrCreateTNode(lView[TVIEW], lView[T_HOST], nodeIndex, 1 /* Projection */, null, attrs || null);
        // We can't use viewData[HOST_NODE] because projection nodes can be nested in embedded views.
        if (tProjectionNode.projection === null)
            tProjectionNode.projection = selectorIndex;
        // `<ng-content>` has no content
        setIsNotParent();
        // We might need to delay the projection of nodes if they are in the middle of an i18n block
        if (!delayProjection) {
            // re-distribution of projectable nodes is stored on a component's view level
            appendProjectedNodes(lView, tProjectionNode, selectorIndex, findComponentView(lView));
        }
    }

    /**
     *
     * Update an interpolated property on an element with a lone bound value
     *
     * Used when the value passed to a property has 1 interpolated value in it, an no additional text
     * surrounds that interpolated value:
     *
     * ```html
     * <div title="{{v0}}"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate('title', v0);
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate(propName, v0, sanitizer) {
        ɵɵpropertyInterpolate1(propName, '', v0, '', sanitizer);
        return ɵɵpropertyInterpolate;
    }
    /**
     *
     * Update an interpolated property on an element with single bound value surrounded by text.
     *
     * Used when the value passed to a property has 1 interpolated value in it:
     *
     * ```html
     * <div title="prefix{{v0}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate1('title', 'prefix', v0, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate1(propName, prefix, v0, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation1(getLView(), prefix, v0, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate1;
    }
    /**
     *
     * Update an interpolated property on an element with 2 bound values surrounded by text.
     *
     * Used when the value passed to a property has 2 interpolated values in it:
     *
     * ```html
     * <div title="prefix{{v0}}-{{v1}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate2(propName, prefix, v0, i0, v1, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation2(getLView(), prefix, v0, i0, v1, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate2;
    }
    /**
     *
     * Update an interpolated property on an element with 3 bound values surrounded by text.
     *
     * Used when the value passed to a property has 3 interpolated values in it:
     *
     * ```html
     * <div title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate3(
     * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate3(propName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation3(getLView(), prefix, v0, i0, v1, i1, v2, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate3;
    }
    /**
     *
     * Update an interpolated property on an element with 4 bound values surrounded by text.
     *
     * Used when the value passed to a property has 4 interpolated values in it:
     *
     * ```html
     * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate4(
     * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate4(propName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation4(getLView(), prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate4;
    }
    /**
     *
     * Update an interpolated property on an element with 5 bound values surrounded by text.
     *
     * Used when the value passed to a property has 5 interpolated values in it:
     *
     * ```html
     * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate5(
     * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate5(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation5(getLView(), prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate5;
    }
    /**
     *
     * Update an interpolated property on an element with 6 bound values surrounded by text.
     *
     * Used when the value passed to a property has 6 interpolated values in it:
     *
     * ```html
     * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate6(
     *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate6(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation6(getLView(), prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate6;
    }
    /**
     *
     * Update an interpolated property on an element with 7 bound values surrounded by text.
     *
     * Used when the value passed to a property has 7 interpolated values in it:
     *
     * ```html
     * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate7(
     *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate7(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation7(getLView(), prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate7;
    }
    /**
     *
     * Update an interpolated property on an element with 8 bound values surrounded by text.
     *
     * Used when the value passed to a property has 8 interpolated values in it:
     *
     * ```html
     * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolate8(
     *  'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param i6 Static value used for concatenation only.
     * @param v7 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolate8(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolation8(getLView(), prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolate8;
    }
    /**
     * Update an interpolated property on an element with 8 or more bound values surrounded by text.
     *
     * Used when the number of interpolated values exceeds 7.
     *
     * ```html
     * <div
     *  title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
     * ```
     *
     * Its compiled representation is::
     *
     * ```ts
     * ɵɵpropertyInterpolateV(
     *  'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
     *  'suffix']);
     * ```
     *
     * If the property name also exists as an input property on one of the element's directives,
     * the component property will be set instead of the element property. This check must
     * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
     *
     * @param propName The name of the property to update.
     * @param values The a collection of values and the strings inbetween those values, beginning with a
     * string prefix and ending with a string suffix.
     * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
     * @param sanitizer An optional sanitizer function
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵpropertyInterpolateV(propName, values, sanitizer) {
        var index = getSelectedIndex();
        var interpolatedValue = interpolationV(getLView(), values);
        if (interpolatedValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, interpolatedValue, sanitizer);
        }
        return ɵɵpropertyInterpolateV;
    }

    /**
     * @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
     */
    /**
     * Create static text node
     *
     * @param index Index of the node in the data array
     * @param value Value to write. This value will be stringified.
     *
     * @codeGenApi
     */
    function ɵɵtext(index, value) {
        var lView = getLView();
        ngDevMode && assertEqual(lView[BINDING_INDEX], lView[TVIEW].bindingStartIndex, 'text nodes should be created before any bindings');
        ngDevMode && ngDevMode.rendererCreateTextNode++;
        ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
        var textNative = lView[index + HEADER_OFFSET] = createTextNode(value, lView[RENDERER]);
        ngDevMode && ngDevMode.rendererSetText++;
        var tNode = getOrCreateTNode(lView[TVIEW], lView[T_HOST], index, 3 /* Element */, null, null);
        // Text nodes are self closing.
        setIsNotParent();
        appendChild(textNative, tNode, lView);
    }
    /**
     * Create text node with binding
     * Bindings should be handled externally with the proper interpolation(1-8) method
     *
     * @param value Stringified value to write.
     *
     * @codeGenApi
     */
    function ɵɵtextBinding(value) {
        var lView = getLView();
        var index = getSelectedIndex();
        var bound = bind(lView, value);
        if (bound !== NO_CHANGE) {
            textBindingInternal(lView, index, renderStringify(bound));
        }
    }

    /**
     * @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
     */
    /**
     *
     * Update text content with a lone bound value
     *
     * Used when a text node has 1 interpolated value in it, an no additional text
     * surrounds that interpolated value:
     *
     * ```html
     * <div>{{v0}}</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate(v0);
     * ```
     * @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate(v0) {
        ɵɵtextInterpolate1('', v0, '');
        return ɵɵtextInterpolate;
    }
    /**
     *
     * Update text content with single bound value surrounded by other text.
     *
     * Used when a text node has 1 interpolated value in it:
     *
     * ```html
     * <div>prefix{{v0}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate1('prefix', v0, 'suffix');
     * ```
     * @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate1(prefix, v0, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation1(lView, prefix, v0, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate1;
    }
    /**
     *
     * Update text content with 2 bound values surrounded by other text.
     *
     * Used when a text node has 2 interpolated values in it:
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate2('prefix', v0, '-', v1, 'suffix');
     * ```
     * @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate2(prefix, v0, i0, v1, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation2(lView, prefix, v0, i0, v1, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate2;
    }
    /**
     *
     * Update text content with 3 bound values surrounded by other text.
     *
     * Used when a text node has 3 interpolated values in it:
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}-{{v2}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate3(
     * 'prefix', v0, '-', v1, '-', v2, 'suffix');
     * ```
     * @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate3;
    }
    /**
     *
     * Update text content with 4 bound values surrounded by other text.
     *
     * Used when a text node has 4 interpolated values in it:
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate4(
     * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
     * ```
     * @returns itself, so that it may be chained.
     * @see ɵɵtextInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate4;
    }
    /**
     *
     * Update text content with 5 bound values surrounded by other text.
     *
     * Used when a text node has 5 interpolated values in it:
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate5(
     * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
     * ```
     * @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate5;
    }
    /**
     *
     * Update text content with 6 bound values surrounded by other text.
     *
     * Used when a text node has 6 interpolated values in it:
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate6(
     *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
     * ```
     *
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change. @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate6;
    }
    /**
     *
     * Update text content with 7 bound values surrounded by other text.
     *
     * Used when a text node has 7 interpolated values in it:
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate7(
     *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
     * ```
     * @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate7;
    }
    /**
     *
     * Update text content with 8 bound values surrounded by other text.
     *
     * Used when a text node has 8 interpolated values in it:
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolate8(
     *  'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
     * ```
     * @returns itself, so that it may be chained.
     * @see textInterpolateV
     * @codeGenApi
     */
    function ɵɵtextInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolate8;
    }
    /**
     * Update text content with 9 or more bound values other surrounded by text.
     *
     * Used when the number of interpolated values exceeds 8.
     *
     * ```html
     * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix</div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵtextInterpolateV(
     *  ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
     *  'suffix']);
     * ```
     *.
     * @param values The a collection of values and the strings in between those values, beginning with
     * a string prefix and ending with a string suffix.
     * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
     *
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵtextInterpolateV(values) {
        var index = getSelectedIndex();
        var lView = getLView();
        var interpolated = interpolationV(lView, values);
        if (interpolated !== NO_CHANGE) {
            textBindingInternal(lView, index, interpolated);
        }
        return ɵɵtextInterpolateV;
    }

    /**
     * @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
     */
    /**
     *
     * Update an interpolated class on an element with single bound value surrounded by text.
     *
     * Used when the value passed to a property has 1 interpolated value in it:
     *
     * ```html
     * <div class="prefix{{v0}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate1('prefix', v0, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate1(prefix, v0, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     *
     * Update an interpolated class on an element with 2 bound values surrounded by text.
     *
     * Used when the value passed to a property has 2 interpolated values in it:
     *
     * ```html
     * <div class="prefix{{v0}}-{{v1}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate2('prefix', v0, '-', v1, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate2(prefix, v0, i0, v1, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     *
     * Update an interpolated class on an element with 3 bound values surrounded by text.
     *
     * Used when the value passed to a property has 3 interpolated values in it:
     *
     * ```html
     * <div class="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate3(
     * 'prefix', v0, '-', v1, '-', v2, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     *
     * Update an interpolated class on an element with 4 bound values surrounded by text.
     *
     * Used when the value passed to a property has 4 interpolated values in it:
     *
     * ```html
     * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate4(
     * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     *
     * Update an interpolated class on an element with 5 bound values surrounded by text.
     *
     * Used when the value passed to a property has 5 interpolated values in it:
     *
     * ```html
     * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate5(
     * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     *
     * Update an interpolated class on an element with 6 bound values surrounded by text.
     *
     * Used when the value passed to a property has 6 interpolated values in it:
     *
     * ```html
     * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate6(
     *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     *
     * Update an interpolated class on an element with 7 bound values surrounded by text.
     *
     * Used when the value passed to a property has 7 interpolated values in it:
     *
     * ```html
     * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate7(
     *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     *
     * Update an interpolated class on an element with 8 bound values surrounded by text.
     *
     * Used when the value passed to a property has 8 interpolated values in it:
     *
     * ```html
     * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolate8(
     *  'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
     * ```
     *
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param i6 Static value used for concatenation only.
     * @param v7 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @codeGenApi
     */
    function ɵɵclassMapInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
        var lView = getLView();
        var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }
    /**
     * Update an interpolated class on an element with 8 or more bound values surrounded by text.
     *
     * Used when the number of interpolated values exceeds 7.
     *
     * ```html
     * <div
     *  class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵclassMapInterpolateV(
     *  ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
     *  'suffix']);
     * ```
     *.
     * @param values The a collection of values and the strings in-between those values, beginning with
     * a string prefix and ending with a string suffix.
     * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
     * @codeGenApi
     */
    function ɵɵclassMapInterpolateV(values) {
        var lView = getLView();
        var interpolatedValue = interpolationV(lView, values);
        classMapInternal(getSelectedIndex(), interpolatedValue);
    }

    /**
     * @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
     */
    /**
     *
     * Update an interpolated style property on an element with single bound value surrounded by text.
     *
     * Used when the value passed to a property has 1 interpolated value in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate1(0, 'prefix', v0, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate1(prop, prefix, v0, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation1(lView, prefix, v0, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate1;
    }
    /**
     *
     * Update an interpolated style property on an element with 2 bound values surrounded by text.
     *
     * Used when the value passed to a property has 2 interpolated values in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}-{{v1}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate2(0, 'prefix', v0, '-', v1, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate2(prop, prefix, v0, i0, v1, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate2;
    }
    /**
     *
     * Update an interpolated style property on an element with 3 bound values surrounded by text.
     *
     * Used when the value passed to a property has 3 interpolated values in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate3(0, 'prefix', v0, '-', v1, '-', v2, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate3(prop, prefix, v0, i0, v1, i1, v2, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate3;
    }
    /**
     *
     * Update an interpolated style property on an element with 4 bound values surrounded by text.
     *
     * Used when the value passed to a property has 4 interpolated values in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate4(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate4(prop, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate4;
    }
    /**
     *
     * Update an interpolated style property on an element with 5 bound values surrounded by text.
     *
     * Used when the value passed to a property has 5 interpolated values in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate5(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate5(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate5;
    }
    /**
     *
     * Update an interpolated style property on an element with 6 bound values surrounded by text.
     *
     * Used when the value passed to a property has 6 interpolated values in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate6(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate6(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate6;
    }
    /**
     *
     * Update an interpolated style property on an element with 7 bound values surrounded by text.
     *
     * Used when the value passed to a property has 7 interpolated values in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate7(
     *    0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate7(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate7;
    }
    /**
     *
     * Update an interpolated style property on an element with 8 bound values surrounded by text.
     *
     * Used when the value passed to a property has 8 interpolated values in it:
     *
     * ```html
     * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolate8(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6,
     * '-', v7, 'suffix');
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`.
     * @param prefix Static value used for concatenation only.
     * @param v0 Value checked for change.
     * @param i0 Static value used for concatenation only.
     * @param v1 Value checked for change.
     * @param i1 Static value used for concatenation only.
     * @param v2 Value checked for change.
     * @param i2 Static value used for concatenation only.
     * @param v3 Value checked for change.
     * @param i3 Static value used for concatenation only.
     * @param v4 Value checked for change.
     * @param i4 Static value used for concatenation only.
     * @param v5 Value checked for change.
     * @param i5 Static value used for concatenation only.
     * @param v6 Value checked for change.
     * @param i6 Static value used for concatenation only.
     * @param v7 Value checked for change.
     * @param suffix Static value used for concatenation only.
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolate8(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolate8;
    }
    /**
     * Update an interpolated style property on an element with 8 or more bound values surrounded by
     * text.
     *
     * Used when the number of interpolated values exceeds 7.
     *
     * ```html
     * <div
     *  style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix">
     * </div>
     * ```
     *
     * Its compiled representation is:
     *
     * ```ts
     * ɵɵstylePropInterpolateV(
     *  0, ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
     *  'suffix']);
     * ```
     *
     * @param styleIndex Index of style to update. This index value refers to the
     *        index of the style in the style bindings array that was passed into
     *        `styling`..
     * @param values The a collection of values and the strings in-between those values, beginning with
     * a string prefix and ending with a string suffix.
     * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
     * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
     * @returns itself, so that it may be chained.
     * @codeGenApi
     */
    function ɵɵstylePropInterpolateV(prop, values, valueSuffix) {
        var lView = getLView();
        var interpolatedValue = interpolationV(lView, values);
        stylePropInternal(getSelectedIndex(), prop, interpolatedValue, valueSuffix);
        return ɵɵstylePropInterpolateV;
    }

    /**
     * @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
     */
    /**
     * Update a property on a host element. Only applies to native node properties, not inputs.
     *
     * Operates on the element selected by index via the {@link select} instruction.
     *
     * @param propName Name of property. Because it is going to DOM, this is not subject to
     *        renaming as part of minification.
     * @param value New value to write.
     * @param sanitizer An optional function used to sanitize the value.
     * @returns This function returns itself so that it may be chained
     * (e.g. `property('name', ctx.name)('title', ctx.title)`)
     *
     * @codeGenApi
     */
    function ɵɵhostProperty(propName, value, sanitizer) {
        var index = getSelectedIndex();
        ngDevMode && assertNotEqual(index, -1, 'selected index cannot be -1');
        var lView = getLView();
        var bindReconciledValue = bind(lView, value);
        if (bindReconciledValue !== NO_CHANGE) {
            elementPropertyInternal(index, propName, bindReconciledValue, sanitizer, true);
        }
        return ɵɵhostProperty;
    }
    /**
     * Updates a synthetic host binding (e.g. `[@foo]`) on a component.
     *
     * This instruction is for compatibility purposes and is designed to ensure that a
     * synthetic host binding (e.g. `@HostBinding('@foo')`) properly gets rendered in
     * the component's renderer. Normally all host bindings are evaluated with the parent
     * component's renderer, but, in the case of animation @triggers, they need to be
     * evaluated with the sub component's renderer (because that's where the animation
     * triggers are defined).
     *
     * Do not use this instruction as a replacement for `elementProperty`. This instruction
     * only exists to ensure compatibility with the ViewEngine's host binding behavior.
     *
     * @param index The index of the element to update in the data array
     * @param propName Name of property. Because it is going to DOM, this is not subject to
     *        renaming as part of minification.
     * @param value New value to write.
     * @param sanitizer An optional function used to sanitize the value.
     *
     * @codeGenApi
     */
    function ɵɵupdateSyntheticHostBinding(propName, value, sanitizer) {
        var index = getSelectedIndex();
        var lView = getLView();
        // TODO(benlesh): remove bind call here.
        var bound = bind(lView, value);
        if (bound !== NO_CHANGE) {
            elementPropertyInternal(index, propName, bound, sanitizer, true, loadComponentRenderer);
        }
        return ɵɵupdateSyntheticHostBinding;
    }

    /**
     * @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
     */

    /**
     * @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
     */
    /**
     * Returns the component instance associated with a given DOM host element.
     * Elements which don't represent components return `null`.
     *
     * @param element Host DOM element from which the component should be retrieved.
     *
     * ```
     * <my-app>
     *   #VIEW
     *     <div>
     *       <child-comp></child-comp>
     *     </div>
     * </mp-app>
     *
     * expect(getComponent(<child-comp>) instanceof ChildComponent).toBeTruthy();
     * expect(getComponent(<my-app>) instanceof MyApp).toBeTruthy();
     * ```
     *
     * @publicApi
     */
    function getComponent(element) {
        var context = loadLContextFromNode(element);
        if (context.component === undefined) {
            context.component = getComponentAtNodeIndex(context.nodeIndex, context.lView);
        }
        return context.component;
    }
    /**
     * Returns the component instance associated with a given DOM host element.
     * Elements which don't represent components return `null`.
     *
     * @param element Host DOM element from which the component should be retrieved.
     *
     * ```
     * <my-app>
     *   #VIEW
     *     <div>
     *       <child-comp></child-comp>
     *     </div>
     * </mp-app>
     *
     * expect(getComponent(<child-comp>) instanceof ChildComponent).toBeTruthy();
     * expect(getComponent(<my-app>) instanceof MyApp).toBeTruthy();
     * ```
     *
     * @publicApi
     */
    function getContext$1(element) {
        var context = loadLContextFromNode(element);
        return context.lView[CONTEXT];
    }
    /**
     * Returns the component instance associated with view which owns the DOM element (`null`
     * otherwise).
     *
     * @param element DOM element which is owned by an existing component's view.
     *
     * ```
     * <my-app>
     *   #VIEW
     *     <div>
     *       <child-comp></child-comp>
     *     </div>
     * </mp-app>
     *
     * expect(getViewComponent(<child-comp>) instanceof MyApp).toBeTruthy();
     * expect(getViewComponent(<my-app>)).toEqual(null);
     * ```
     *
     * @publicApi
     */
    function getViewComponent(element) {
        var context = loadLContext(element);
        var lView = context.lView;
        var parent;
        ngDevMode && assertLView(lView);
        while (lView[HOST] === null && (parent = getLViewParent(lView))) {
            // As long as lView[HOST] is null we know we are part of sub-template such as `*ngIf`
            lView = parent;
        }
        return lView[FLAGS] & 512 /* IsRoot */ ? null : lView[CONTEXT];
    }
    /**
     * Retrieve all root components.
     *
     * Root components are those which have been bootstrapped by Angular.
     *
     * @param target A DOM element, component or directive instance.
     *
     * @publicApi
     */
    function getRootComponents(target) {
        return __spread(getRootContext(target).components);
    }
    /**
     * Retrieves an `Injector` associated with the element, component or directive.
     *
     * @param target A DOM element, component or directive instance.
     *
     * @publicApi
     */
    function getInjector(target) {
        var context = loadLContext(target);
        var tNode = context.lView[TVIEW].data[context.nodeIndex];
        return new NodeInjector(tNode, context.lView);
    }
    /**
     * Retrieve a set of injection tokens at a given DOM node.
     *
     * @param element Element for which the injection tokens should be retrieved.
     * @publicApi
     */
    function getInjectionTokens(element) {
        var context = loadLContext(element, false);
        if (!context)
            return [];
        var lView = context.lView;
        var tView = lView[TVIEW];
        var tNode = tView.data[context.nodeIndex];
        var providerTokens = [];
        var startIndex = tNode.providerIndexes & 65535 /* ProvidersStartIndexMask */;
        var endIndex = tNode.directiveEnd;
        for (var i = startIndex; i < endIndex; i++) {
            var value = tView.data[i];
            if (isDirectiveDefHack(value)) {
                // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
                // design flaw.  We should always store same type so that we can be monomorphic. The issue
                // is that for Components/Directives we store the def instead the type. The correct behavior
                // is that we should always be storing injectable type in this location.
                value = value.type;
            }
            providerTokens.push(value);
        }
        return providerTokens;
    }
    /**
     * Retrieves directives associated with a given DOM host element.
     *
     * @param target A DOM element, component or directive instance.
     *
     * @publicApi
     */
    function getDirectives(target) {
        var context = loadLContext(target);
        if (context.directives === undefined) {
            context.directives = getDirectivesAtNodeIndex(context.nodeIndex, context.lView, false);
        }
        return context.directives || [];
    }
    function loadLContext(target, throwOnNotFound) {
        if (throwOnNotFound === void 0) { throwOnNotFound = true; }
        var context = getLContext(target);
        if (!context && throwOnNotFound) {
            throw new Error(ngDevMode ? "Unable to find context associated with " + stringifyForError(target) :
                'Invalid ng target');
        }
        return context;
    }
    /**
     * Retrieve map of local references.
     *
     * The references are retrieved as a map of local reference name to element or directive instance.
     *
     * @param target A DOM element, component or directive instance.
     *
     * @publicApi
     */
    function getLocalRefs(target) {
        var context = loadLContext(target);
        if (context.localRefs === undefined) {
            context.localRefs = discoverLocalRefs(context.lView, context.nodeIndex);
        }
        return context.localRefs || {};
    }
    /**
     * Retrieve the host element of the component.
     *
     * Use this function to retrieve the host element of the component. The host
     * element is the element which the component is associated with.
     *
     * @param directive Component or Directive for which the host element should be retrieved.
     *
     * @publicApi
     */
    function getHostElement(directive) {
        return getLContext(directive).native;
    }
    /**
     * Retrieves the rendered text for a given component.
     *
     * This function retrieves the host element of a component and
     * and then returns the `textContent` for that element. This implies
     * that the text returned will include re-projected content of
     * the component as well.
     *
     * @param component The component to return the content text for.
     */
    function getRenderedText(component) {
        var hostElement = getHostElement(component);
        return hostElement.textContent || '';
    }
    function loadLContextFromNode(node) {
        if (!(node instanceof Node))
            throw new Error('Expecting instance of DOM Node');
        return loadLContext(node);
    }
    function isBrowserEvents(listener) {
        // Browser events are those which don't have `useCapture` as boolean.
        return typeof listener.useCapture === 'boolean';
    }
    /**
     * Retrieves a list of DOM listeners.
     *
     * ```
     * <my-app>
     *   #VIEW
     *     <div (click)="doSomething()">
     *     </div>
     * </mp-app>
     *
     * expect(getListeners(<div>)).toEqual({
     *   name: 'click',
     *   element: <div>,
     *   callback: () => doSomething(),
     *   useCapture: false
     * });
     * ```
     *
     * @param element Element for which the DOM listeners should be retrieved.
     * @publicApi
     */
    function getListeners(element) {
        var lContext = loadLContextFromNode(element);
        var lView = lContext.lView;
        var tView = lView[TVIEW];
        var lCleanup = lView[CLEANUP];
        var tCleanup = tView.cleanup;
        var listeners = [];
        if (tCleanup && lCleanup) {
            for (var i = 0; i < tCleanup.length;) {
                var firstParam = tCleanup[i++];
                var secondParam = tCleanup[i++];
                if (typeof firstParam === 'string') {
                    var name_1 = firstParam;
                    var listenerElement = unwrapRNode(lView[secondParam]);
                    var callback = lCleanup[tCleanup[i++]];
                    var useCaptureOrIndx = tCleanup[i++];
                    // if useCaptureOrIndx is boolean then report it as is.
                    // if useCaptureOrIndx is positive number then it in unsubscribe method
                    // if useCaptureOrIndx is negative number then it is a Subscription
                    var useCapture = typeof useCaptureOrIndx === 'boolean' ?
                        useCaptureOrIndx :
                        (useCaptureOrIndx >= 0 ? false : null);
                    if (element == listenerElement) {
                        listeners.push({ element: element, name: name_1, callback: callback, useCapture: useCapture });
                    }
                }
            }
        }
        listeners.sort(sortListeners);
        return listeners;
    }
    function sortListeners(a, b) {
        if (a.name == b.name)
            return 0;
        return a.name < b.name ? -1 : 1;
    }
    /**
     * This function should not exist because it is megamorphic and only mostly correct.
     *
     * See call site for more info.
     */
    function isDirectiveDefHack(obj) {
        return obj.type !== undefined && obj.template !== undefined && obj.declaredInputs !== undefined;
    }

    /**
     * @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
     */

    /**
     * @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 introduces series of globally accessible debug tools
     * to allow for the Angular debugging story to function.
     *
     * To see this in action run the following command:
     *
     *   bazel run --define=compile=aot
     *   //packages/core/test/bundling/todo:devserver
     *
     *  Then load `localhost:5432` and start using the console tools.
     */
    /**
     * This value reflects the property on the window where the dev
     * tools are patched (window.ng).
     * */
    var GLOBAL_PUBLISH_EXPANDO_KEY = 'ng';
    var _published = false;
    /**
     * Publishes a collection of default debug tools onto`window.ng`.
     *
     * These functions are available globally when Angular is in development
     * mode and are automatically stripped away from prod mode is on.
     */
    function publishDefaultGlobalUtils() {
        if (!_published) {
            _published = true;
            publishGlobalUtil('getComponent', getComponent);
            publishGlobalUtil('getContext', getContext$1);
            publishGlobalUtil('getListeners', getListeners);
            publishGlobalUtil('getViewComponent', getViewComponent);
            publishGlobalUtil('getHostElement', getHostElement);
            publishGlobalUtil('getInjector', getInjector);
            publishGlobalUtil('getRootComponents', getRootComponents);
            publishGlobalUtil('getDirectives', getDirectives);
            publishGlobalUtil('markDirty', markDirty);
        }
    }
    /**
     * Publishes the given function to `window.ng` so that it can be
     * used from the browser console when an application is not in production.
     */
    function publishGlobalUtil(name, fn) {
        var w = _global;
        ngDevMode && assertDefined(fn, 'function not defined');
        if (w) {
            var container = w[GLOBAL_PUBLISH_EXPANDO_KEY];
            if (!container) {
                container = w[GLOBAL_PUBLISH_EXPANDO_KEY] = {};
            }
            container[name] = fn;
        }
    }

    /**
     * @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
     */
    var ɵ0$c = function (token, notFoundValue) {
        throw new Error('NullInjector: Not found: ' + stringifyForError(token));
    };
    // TODO: A hack to not pull in the NullInjector from @angular/core.
    var NULL_INJECTOR$1 = {
        get: ɵ0$c
    };
    /**
     * Bootstraps a Component into an existing host element and returns an instance
     * of the component.
     *
     * Use this function to bootstrap a component into the DOM tree. Each invocation
     * of this function will create a separate tree of components, injectors and
     * change detection cycles and lifetimes. To dynamically insert a new component
     * into an existing tree such that it shares the same injection, change detection
     * and object lifetime, use {@link ViewContainer#createComponent}.
     *
     * @param componentType Component to bootstrap
     * @param options Optional parameters which control bootstrapping
     */
    function renderComponent(componentType /* Type as workaround for: Microsoft/TypeScript/issues/4881 */, opts) {
        if (opts === void 0) { opts = {}; }
        ngDevMode && publishDefaultGlobalUtils();
        ngDevMode && assertComponentType(componentType);
        // this is preemptively set to avoid having test and debug code accidentally
        // read data from a previous application state...
        setActiveHostElement(null);
        var rendererFactory = opts.rendererFactory || domRendererFactory3;
        var sanitizer = opts.sanitizer || null;
        var componentDef = getComponentDef(componentType);
        if (componentDef.type != componentType)
            componentDef.type = componentType;
        // The first index of the first selector is the tag name.
        var componentTag = componentDef.selectors[0][0];
        var hostRNode = locateHostElement(rendererFactory, opts.host || componentTag);
        var rootFlags = componentDef.onPush ? 64 /* Dirty */ | 512 /* IsRoot */ :
            16 /* CheckAlways */ | 512 /* IsRoot */;
        var rootContext = createRootContext(opts.scheduler, opts.playerHandler);
        var renderer = rendererFactory.createRenderer(hostRNode, componentDef);
        var rootView = createLView(null, createTView(-1, null, 1, 0, null, null, null, null), rootContext, rootFlags, null, null, rendererFactory, renderer, undefined, opts.injector || null);
        var oldView = enterView(rootView, null);
        var component;
        // Will become true if the `try` block executes with no errors.
        var safeToRunHooks = false;
        try {
            if (rendererFactory.begin)
                rendererFactory.begin();
            var componentView = createRootComponentView(hostRNode, componentDef, rootView, rendererFactory, renderer, sanitizer);
            component = createRootComponent(componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
            addToViewTree(rootView, componentView);
            refreshDescendantViews(rootView); // creation mode pass
            rootView[FLAGS] &= ~4 /* CreationMode */;
            resetPreOrderHookFlags(rootView);
            refreshDescendantViews(rootView); // update mode pass
            safeToRunHooks = true;
        }
        finally {
            leaveView(oldView, safeToRunHooks);
            if (rendererFactory.end)
                rendererFactory.end();
        }
        return component;
    }
    /**
     * Creates the root component view and the root component node.
     *
     * @param rNode Render host element.
     * @param def ComponentDef
     * @param rootView The parent view where the host node is stored
     * @param renderer The current renderer
     * @param sanitizer The sanitizer, if provided
     *
     * @returns Component view created
     */
    function createRootComponentView(rNode, def, rootView, rendererFactory, renderer, sanitizer) {
        resetComponentState();
        var tView = rootView[TVIEW];
        ngDevMode && assertDataInRange(rootView, 0 + HEADER_OFFSET);
        rootView[0 + HEADER_OFFSET] = rNode;
        var tNode = getOrCreateTNode(tView, null, 0, 3 /* Element */, null, null);
        var componentView = createLView(rootView, getOrCreateTView(def), null, def.onPush ? 64 /* Dirty */ : 16 /* CheckAlways */, rootView[HEADER_OFFSET], tNode, rendererFactory, renderer, sanitizer);
        if (tView.firstTemplatePass) {
            diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, rootView), tView, def.type);
            tNode.flags = 1 /* isComponent */;
            initNodeFlags(tNode, rootView.length, 1);
            queueComponentIndexForCheck(tNode);
        }
        // Store component view at node index, with node as the HOST
        return rootView[HEADER_OFFSET] = componentView;
    }
    /**
     * Creates a root component and sets it up with features and host bindings. Shared by
     * renderComponent() and ViewContainerRef.createComponent().
     */
    function createRootComponent(componentView, componentDef, rootView, rootContext, hostFeatures) {
        var tView = rootView[TVIEW];
        // Create directive instance with factory() and store at next index in viewData
        var component = instantiateRootComponent(tView, rootView, componentDef);
        rootContext.components.push(component);
        componentView[CONTEXT] = component;
        hostFeatures && hostFeatures.forEach(function (feature) { return feature(component, componentDef); });
        // We want to generate an empty QueryList for root content queries for backwards
        // compatibility with ViewEngine.
        if (componentDef.contentQueries) {
            componentDef.contentQueries(1 /* Create */, component, rootView.length - 1);
        }
        var rootTNode = getPreviousOrParentTNode();
        if (tView.firstTemplatePass && componentDef.hostBindings) {
            var elementIndex = rootTNode.index - HEADER_OFFSET;
            setActiveHostElement(elementIndex);
            var expando = tView.expandoInstructions;
            invokeHostBindingsInCreationMode(componentDef, expando, component, rootTNode, tView.firstTemplatePass);
            setActiveHostElement(null);
        }
        return component;
    }
    function createRootContext(scheduler, playerHandler) {
        return {
            components: [],
            scheduler: scheduler || defaultScheduler,
            clean: CLEAN_PROMISE,
            playerHandler: playerHandler || null,
            flags: 0 /* Empty */
        };
    }
    /**
     * Used to enable lifecycle hooks on the root component.
     *
     * Include this feature when calling `renderComponent` if the root component
     * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
     * be called properly.
     *
     * Example:
     *
     * ```
     * renderComponent(AppComponent, {features: [RootLifecycleHooks]});
     * ```
     */
    function LifecycleHooksFeature(component, def) {
        var rootTView = readPatchedLView(component)[TVIEW];
        var dirIndex = rootTView.data.length - 1;
        registerPreOrderHooks(dirIndex, def, rootTView, -1, -1, -1);
        // TODO(misko): replace `as TNode` with createTNode call. (needs refactoring to lose dep on
        // LNode).
        registerPostOrderHooks(rootTView, { directiveStart: dirIndex, directiveEnd: dirIndex + 1 });
    }
    /**
     * Wait on component until it is rendered.
     *
     * This function returns a `Promise` which is resolved when the component's
     * change detection is executed. This is determined by finding the scheduler
     * associated with the `component`'s render tree and waiting until the scheduler
     * flushes. If nothing is scheduled, the function returns a resolved promise.
     *
     * Example:
     * ```
     * await whenRendered(myComponent);
     * ```
     *
     * @param component Component to wait upon
     * @returns Promise which resolves when the component is rendered.
     */
    function whenRendered(component) {
        return getRootContext(component).clean;
    }

    /**
     * @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
     */
    /**
     * Represents a basic change from a previous to a new value for a single
     * property on a directive instance. Passed as a value in a
     * {@link SimpleChanges} object to the `ngOnChanges` hook.
     *
     * @see `OnChanges`
     *
     * @publicApi
     */
    var SimpleChange = /** @class */ (function () {
        function SimpleChange(previousValue, currentValue, firstChange) {
            this.previousValue = previousValue;
            this.currentValue = currentValue;
            this.firstChange = firstChange;
        }
        /**
         * Check whether the new value is the first value assigned.
         */
        SimpleChange.prototype.isFirstChange = function () { return this.firstChange; };
        return SimpleChange;
    }());

    /**
     * @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
     */
    var PRIVATE_PREFIX = '__ngOnChanges_';
    /**
     * The NgOnChangesFeature decorates a component with support for the ngOnChanges
     * lifecycle hook, so it should be included in any component that implements
     * that hook.
     *
     * If the component or directive uses inheritance, the NgOnChangesFeature MUST
     * be included as a feature AFTER {@link InheritDefinitionFeature}, otherwise
     * inherited properties will not be propagated to the ngOnChanges lifecycle
     * hook.
     *
     * Example usage:
     *
     * ```
     * static ngComponentDef = defineComponent({
     *   ...
     *   inputs: {name: 'publicName'},
     *   features: [NgOnChangesFeature()]
     * });
     * ```
     *
     * @codeGenApi
     */
    function ɵɵNgOnChangesFeature() {
        // This option ensures that the ngOnChanges lifecycle hook will be inherited
        // from superclasses (in InheritDefinitionFeature).
        NgOnChangesFeatureImpl.ngInherit = true;
        return NgOnChangesFeatureImpl;
    }
    function NgOnChangesFeatureImpl(definition) {
        if (definition.type.prototype.ngOnChanges) {
            definition.setInput = ngOnChangesSetInput;
            definition.onChanges = wrapOnChanges();
        }
    }
    function wrapOnChanges() {
        return function wrapOnChangesHook_inPreviousChangesStorage() {
            var simpleChangesStore = getSimpleChangesStore(this);
            var current = simpleChangesStore && simpleChangesStore.current;
            if (current) {
                var previous = simpleChangesStore.previous;
                if (previous === EMPTY_OBJ) {
                    simpleChangesStore.previous = current;
                }
                else {
                    // New changes are copied to the previous store, so that we don't lose history for inputs
                    // which were not changed this time
                    for (var key in current) {
                        previous[key] = current[key];
                    }
                }
                simpleChangesStore.current = null;
                this.ngOnChanges(current);
            }
        };
    }
    function ngOnChangesSetInput(instance, value, publicName, privateName) {
        var simpleChangesStore = getSimpleChangesStore(instance) ||
            setSimpleChangesStore(instance, { previous: EMPTY_OBJ, current: null });
        var current = simpleChangesStore.current || (simpleChangesStore.current = {});
        var previous = simpleChangesStore.previous;
        var declaredName = this.declaredInputs[publicName];
        var previousChange = previous[declaredName];
        current[declaredName] = new SimpleChange(previousChange && previousChange.currentValue, value, previous === EMPTY_OBJ);
        instance[privateName] = value;
    }
    var SIMPLE_CHANGES_STORE = '__ngSimpleChanges__';
    function getSimpleChangesStore(instance) {
        return instance[SIMPLE_CHANGES_STORE] || null;
    }
    function setSimpleChangesStore(instance, store) {
        return instance[SIMPLE_CHANGES_STORE] = store;
    }

    /**
     * @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
     */
    function getSuperType(type) {
        return Object.getPrototypeOf(type.prototype).constructor;
    }
    /**
     * Merges the definition from a super class to a sub class.
     * @param definition The definition that is a SubClass of another directive of component
     *
     * @codeGenApi
     */
    function ɵɵInheritDefinitionFeature(definition) {
        var e_1, _a;
        var superType = getSuperType(definition.type);
        while (superType) {
            var superDef = undefined;
            if (isComponentDef(definition)) {
                // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
                superDef = superType.ngComponentDef || superType.ngDirectiveDef;
            }
            else {
                if (superType.ngComponentDef) {
                    throw new Error('Directives cannot inherit Components');
                }
                // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
                superDef = superType.ngDirectiveDef;
            }
            var baseDef = superType.ngBaseDef;
            // Some fields in the definition may be empty, if there were no values to put in them that
            // would've justified object creation. Unwrap them if necessary.
            if (baseDef || superDef) {
                var writeableDef = definition;
                writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
                writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
                writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
            }
            if (baseDef) {
                var baseViewQuery = baseDef.viewQuery;
                var baseContentQueries = baseDef.contentQueries;
                var baseHostBindings = baseDef.hostBindings;
                baseHostBindings && inheritHostBindings(definition, baseHostBindings);
                baseViewQuery && inheritViewQuery(definition, baseViewQuery);
                baseContentQueries && inheritContentQueries(definition, baseContentQueries);
                fillProperties(definition.inputs, baseDef.inputs);
                fillProperties(definition.declaredInputs, baseDef.declaredInputs);
                fillProperties(definition.outputs, baseDef.outputs);
            }
            if (superDef) {
                // Merge hostBindings
                var superHostBindings = superDef.hostBindings;
                superHostBindings && inheritHostBindings(definition, superHostBindings);
                // Merge queries
                var superViewQuery = superDef.viewQuery;
                var superContentQueries = superDef.contentQueries;
                superViewQuery && inheritViewQuery(definition, superViewQuery);
                superContentQueries && inheritContentQueries(definition, superContentQueries);
                // Merge inputs and outputs
                fillProperties(definition.inputs, superDef.inputs);
                fillProperties(definition.declaredInputs, superDef.declaredInputs);
                fillProperties(definition.outputs, superDef.outputs);
                // Inherit hooks
                // Assume super class inheritance feature has already run.
                definition.afterContentChecked =
                    definition.afterContentChecked || superDef.afterContentChecked;
                definition.afterContentInit = definition.afterContentInit || superDef.afterContentInit;
                definition.afterViewChecked = definition.afterViewChecked || superDef.afterViewChecked;
                definition.afterViewInit = definition.afterViewInit || superDef.afterViewInit;
                definition.doCheck = definition.doCheck || superDef.doCheck;
                definition.onDestroy = definition.onDestroy || superDef.onDestroy;
                definition.onInit = definition.onInit || superDef.onInit;
                // Run parent features
                var features = superDef.features;
                if (features) {
                    try {
                        for (var features_1 = (e_1 = void 0, __values(features)), features_1_1 = features_1.next(); !features_1_1.done; features_1_1 = features_1.next()) {
                            var feature = features_1_1.value;
                            if (feature && feature.ngInherit) {
                                feature(definition);
                            }
                        }
                    }
                    catch (e_1_1) { e_1 = { error: e_1_1 }; }
                    finally {
                        try {
                            if (features_1_1 && !features_1_1.done && (_a = features_1.return)) _a.call(features_1);
                        }
                        finally { if (e_1) throw e_1.error; }
                    }
                }
            }
            else {
                // Even if we don't have a definition, check the type for the hooks and use those if need be
                var superPrototype = superType.prototype;
                if (superPrototype) {
                    definition.afterContentChecked =
                        definition.afterContentChecked || superPrototype.ngAfterContentChecked;
                    definition.afterContentInit =
                        definition.afterContentInit || superPrototype.ngAfterContentInit;
                    definition.afterViewChecked =
                        definition.afterViewChecked || superPrototype.ngAfterViewChecked;
                    definition.afterViewInit = definition.afterViewInit || superPrototype.ngAfterViewInit;
                    definition.doCheck = definition.doCheck || superPrototype.ngDoCheck;
                    definition.onDestroy = definition.onDestroy || superPrototype.ngOnDestroy;
                    definition.onInit = definition.onInit || superPrototype.ngOnInit;
                    if (superPrototype.ngOnChanges) {
                        ɵɵNgOnChangesFeature()(definition);
                    }
                }
            }
            superType = Object.getPrototypeOf(superType);
        }
    }
    function maybeUnwrapEmpty(value) {
        if (value === EMPTY_OBJ) {
            return {};
        }
        else if (value === EMPTY_ARRAY) {
            return [];
        }
        else {
            return value;
        }
    }
    function inheritViewQuery(definition, superViewQuery) {
        var prevViewQuery = definition.viewQuery;
        if (prevViewQuery) {
            definition.viewQuery = function (rf, ctx) {
                superViewQuery(rf, ctx);
                prevViewQuery(rf, ctx);
            };
        }
        else {
            definition.viewQuery = superViewQuery;
        }
    }
    function inheritContentQueries(definition, superContentQueries) {
        var prevContentQueries = definition.contentQueries;
        if (prevContentQueries) {
            definition.contentQueries = function (rf, ctx, directiveIndex) {
                superContentQueries(rf, ctx, directiveIndex);
                prevContentQueries(rf, ctx, directiveIndex);
            };
        }
        else {
            definition.contentQueries = superContentQueries;
        }
    }
    function inheritHostBindings(definition, superHostBindings) {
        var prevHostBindings = definition.hostBindings;
        // If the subclass does not have a host bindings function, we set the subclass host binding
        // function to be the superclass's (in this feature). We should check if they're the same here
        // to ensure we don't inherit it twice.
        if (superHostBindings !== prevHostBindings) {
            if (prevHostBindings) {
                // because inheritance is unknown during compile time, the runtime code
                // needs to be informed of the super-class depth so that instruction code
                // can distinguish one host bindings function from another. The reason why
                // relying on the directive uniqueId exclusively is not enough is because the
                // uniqueId value and the directive instance stay the same between hostBindings
                // calls throughout the directive inheritance chain. This means that without
                // a super-class depth value, there is no way to know whether a parent or
                // sub-class host bindings function is currently being executed.
                definition.hostBindings = function (rf, ctx, elementIndex) {
                    // The reason why we increment first and then decrement is so that parent
                    // hostBindings calls have a higher id value compared to sub-class hostBindings
                    // calls (this way the leaf directive is always at a super-class depth of 0).
                    adjustActiveDirectiveSuperClassDepthPosition(1);
                    try {
                        superHostBindings(rf, ctx, elementIndex);
                    }
                    finally {
                        adjustActiveDirectiveSuperClassDepthPosition(-1);
                    }
                    prevHostBindings(rf, ctx, elementIndex);
                };
            }
            else {
                definition.hostBindings = superHostBindings;
            }
        }
    }

    /**
     * @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
     */
    /**
     * Resolves the providers which are defined in the DirectiveDef.
     *
     * When inserting the tokens and the factories in their respective arrays, we can assume that
     * this method is called first for the component (if any), and then for other directives on the same
     * node.
     * As a consequence,the providers are always processed in that order:
     * 1) The view providers of the component
     * 2) The providers of the component
     * 3) The providers of the other directives
     * This matches the structure of the injectables arrays of a view (for each node).
     * So the tokens and the factories can be pushed at the end of the arrays, except
     * in one case for multi providers.
     *
     * @param def the directive definition
     * @param providers: Array of `providers`.
     * @param viewProviders: Array of `viewProviders`.
     */
    function providersResolver(def, providers, viewProviders) {
        var lView = getLView();
        var tView = lView[TVIEW];
        if (tView.firstTemplatePass) {
            var isComponent = isComponentDef(def);
            // The list of view providers is processed first, and the flags are updated
            resolveProvider$1(viewProviders, tView.data, tView.blueprint, isComponent, true);
            // Then, the list of providers is processed, and the flags are updated
            resolveProvider$1(providers, tView.data, tView.blueprint, isComponent, false);
        }
    }
    /**
     * Resolves a provider and publishes it to the DI system.
     */
    function resolveProvider$1(provider, tInjectables, lInjectablesBlueprint, isComponent, isViewProvider) {
        provider = resolveForwardRef(provider);
        if (Array.isArray(provider)) {
            // Recursively call `resolveProvider`
            // Recursion is OK in this case because this code will not be in hot-path once we implement
            // cloning of the initial state.
            for (var i = 0; i < provider.length; i++) {
                resolveProvider$1(provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider);
            }
        }
        else {
            var lView = getLView();
            var tView = lView[TVIEW];
            var token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
            var providerFactory = providerToFactory(provider);
            var tNode = getPreviousOrParentTNode();
            var beginIndex = tNode.providerIndexes & 65535 /* ProvidersStartIndexMask */;
            var endIndex = tNode.directiveStart;
            var cptViewProvidersCount = tNode.providerIndexes >> 16 /* CptViewProvidersCountShift */;
            if (isClassProvider(provider) || isTypeProvider(provider)) {
                var prototype = (provider.useClass || provider).prototype;
                var ngOnDestroy = prototype.ngOnDestroy;
                if (ngOnDestroy) {
                    (tView.destroyHooks || (tView.destroyHooks = [])).push(tInjectables.length, ngOnDestroy);
                }
            }
            if (isTypeProvider(provider) || !provider.multi) {
                // Single provider case: the factory is created and pushed immediately
                var factory = new NodeInjectorFactory(providerFactory, isViewProvider, ɵɵdirectiveInject);
                var existingFactoryIndex = indexOf(token, tInjectables, isViewProvider ? beginIndex : beginIndex + cptViewProvidersCount, endIndex);
                if (existingFactoryIndex == -1) {
                    diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
                    tInjectables.push(token);
                    tNode.directiveStart++;
                    tNode.directiveEnd++;
                    if (isViewProvider) {
                        tNode.providerIndexes += 65536 /* CptViewProvidersCountShifter */;
                    }
                    lInjectablesBlueprint.push(factory);
                    lView.push(factory);
                }
                else {
                    lInjectablesBlueprint[existingFactoryIndex] = factory;
                    lView[existingFactoryIndex] = factory;
                }
            }
            else {
                // Multi provider case:
                // We create a multi factory which is going to aggregate all the values.
                // Since the output of such a factory depends on content or view injection,
                // we create two of them, which are linked together.
                //
                // The first one (for view providers) is always in the first block of the injectables array,
                // and the second one (for providers) is always in the second block.
                // This is important because view providers have higher priority. When a multi token
                // is being looked up, the view providers should be found first.
                // Note that it is not possible to have a multi factory in the third block (directive block).
                //
                // The algorithm to process multi providers is as follows:
                // 1) If the multi provider comes from the `viewProviders` of the component:
                //   a) If the special view providers factory doesn't exist, it is created and pushed.
                //   b) Else, the multi provider is added to the existing multi factory.
                // 2) If the multi provider comes from the `providers` of the component or of another
                // directive:
                //   a) If the multi factory doesn't exist, it is created and provider pushed into it.
                //      It is also linked to the multi factory for view providers, if it exists.
                //   b) Else, the multi provider is added to the existing multi factory.
                var existingProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex + cptViewProvidersCount, endIndex);
                var existingViewProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex, beginIndex + cptViewProvidersCount);
                var doesProvidersFactoryExist = existingProvidersFactoryIndex >= 0 &&
                    lInjectablesBlueprint[existingProvidersFactoryIndex];
                var doesViewProvidersFactoryExist = existingViewProvidersFactoryIndex >= 0 &&
                    lInjectablesBlueprint[existingViewProvidersFactoryIndex];
                if (isViewProvider && !doesViewProvidersFactoryExist ||
                    !isViewProvider && !doesProvidersFactoryExist) {
                    // Cases 1.a and 2.a
                    diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
                    var factory = multiFactory(isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver, lInjectablesBlueprint.length, isViewProvider, isComponent, providerFactory);
                    if (!isViewProvider && doesViewProvidersFactoryExist) {
                        lInjectablesBlueprint[existingViewProvidersFactoryIndex].providerFactory = factory;
                    }
                    tInjectables.push(token);
                    tNode.directiveStart++;
                    tNode.directiveEnd++;
                    if (isViewProvider) {
                        tNode.providerIndexes += 65536 /* CptViewProvidersCountShifter */;
                    }
                    lInjectablesBlueprint.push(factory);
                    lView.push(factory);
                }
                else {
                    // Cases 1.b and 2.b
                    multiFactoryAdd(lInjectablesBlueprint[isViewProvider ? existingViewProvidersFactoryIndex : existingProvidersFactoryIndex], providerFactory, !isViewProvider && isComponent);
                }
                if (!isViewProvider && isComponent && doesViewProvidersFactoryExist) {
                    lInjectablesBlueprint[existingViewProvidersFactoryIndex].componentProviders++;
                }
            }
        }
    }
    /**
     * Add a factory in a multi factory.
     */
    function multiFactoryAdd(multiFactory, factory, isComponentProvider) {
        multiFactory.multi.push(factory);
        if (isComponentProvider) {
            multiFactory.componentProviders++;
        }
    }
    /**
     * Returns the index of item in the array, but only in the begin to end range.
     */
    function indexOf(item, arr, begin, end) {
        for (var i = begin; i < end; i++) {
            if (arr[i] === item)
                return i;
        }
        return -1;
    }
    /**
     * Use this with `multi` `providers`.
     */
    function multiProvidersFactoryResolver(_, tData, lData, tNode) {
        return multiResolve(this.multi, []);
    }
    /**
     * Use this with `multi` `viewProviders`.
     *
     * This factory knows how to concatenate itself with the existing `multi` `providers`.
     */
    function multiViewProvidersFactoryResolver(_, tData, lData, tNode) {
        var factories = this.multi;
        var result;
        if (this.providerFactory) {
            var componentCount = this.providerFactory.componentProviders;
            var multiProviders = getNodeInjectable(tData, lData, this.providerFactory.index, tNode);
            // Copy the section of the array which contains `multi` `providers` from the component
            result = multiProviders.slice(0, componentCount);
            // Insert the `viewProvider` instances.
            multiResolve(factories, result);
            // Copy the section of the array which contains `multi` `providers` from other directives
            for (var i = componentCount; i < multiProviders.length; i++) {
                result.push(multiProviders[i]);
            }
        }
        else {
            result = [];
            // Insert the `viewProvider` instances.
            multiResolve(factories, result);
        }
        return result;
    }
    /**
     * Maps an array of factories into an array of values.
     */
    function multiResolve(factories, result) {
        for (var i = 0; i < factories.length; i++) {
            var factory = factories[i];
            result.push(factory());
        }
        return result;
    }
    /**
     * Creates a multi factory.
     */
    function multiFactory(factoryFn, index, isViewProvider, isComponent, f) {
        var factory = new NodeInjectorFactory(factoryFn, isViewProvider, ɵɵdirectiveInject);
        factory.multi = [];
        factory.index = index;
        factory.componentProviders = 0;
        multiFactoryAdd(factory, f, isComponent && !isViewProvider);
        return factory;
    }

    /**
     * This feature resolves the providers of a directive (or component),
     * and publish them into the DI system, making it visible to others for injection.
     *
     * For example:
     * ```ts
     * class ComponentWithProviders {
     *   constructor(private greeter: GreeterDE) {}
     *
     *   static ngComponentDef = defineComponent({
     *     type: ComponentWithProviders,
     *     selectors: [['component-with-providers']],
     *    factory: () => new ComponentWithProviders(directiveInject(GreeterDE as any)),
     *    consts: 1,
     *    vars: 1,
     *    template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
     *      if (fs & RenderFlags.Create) {
     *        ɵɵtext(0);
     *      }
     *      if (fs & RenderFlags.Update) {
     *        ɵɵselect(0);
     *        ɵɵtextBinding(ctx.greeter.greet());
     *      }
     *    },
     *    features: [ProvidersFeature([GreeterDE])]
     *  });
     * }
     * ```
     *
     * @param definition
     *
     * @codeGenApi
     */
    function ɵɵProvidersFeature(providers, viewProviders) {
        if (viewProviders === void 0) { viewProviders = []; }
        return function (definition) {
            definition.providersResolver =
                function (def, processProvidersFn) {
                    return providersResolver(def, //
                    processProvidersFn ? processProvidersFn(providers) : providers, //
                    viewProviders);
                };
        };
    }

    /**
     * @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
     */
    /**
     * Represents a component created by a `ComponentFactory`.
     * Provides access to the component instance and related objects,
     * and provides the means of destroying the instance.
     *
     * @publicApi
     */
    var ComponentRef = /** @class */ (function () {
        function ComponentRef() {
        }
        return ComponentRef;
    }());
    /**
     * Base class for a factory that can create a component dynamically.
     * Instantiate a factory for a given type of component with `resolveComponentFactory()`.
     * Use the resulting `ComponentFactory.create()` method to create a component of that type.
     *
     * @see [Dynamic Components](guide/dynamic-component-loader)
     *
     * @publicApi
     */
    var ComponentFactory = /** @class */ (function () {
        function ComponentFactory() {
        }
        return ComponentFactory;
    }());

    /**
     * @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
     */
    function noComponentFactoryError(component) {
        var error = Error("No component factory found for " + stringify(component) + ". Did you add it to @NgModule.entryComponents?");
        error[ERROR_COMPONENT] = component;
        return error;
    }
    var ERROR_COMPONENT = 'ngComponent';
    function getComponent$1(error) {
        return error[ERROR_COMPONENT];
    }
    var _NullComponentFactoryResolver = /** @class */ (function () {
        function _NullComponentFactoryResolver() {
        }
        _NullComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
            throw noComponentFactoryError(component);
        };
        return _NullComponentFactoryResolver;
    }());
    /**
     * A simple registry that maps `Components` to generated `ComponentFactory` classes
     * that can be used to create instances of components.
     * Use to obtain the factory for a given component type,
     * then use the factory's `create()` method to create a component of that type.
     *
     * @see [Dynamic Components](guide/dynamic-component-loader)
     * @publicApi
     */
    var ComponentFactoryResolver = /** @class */ (function () {
        function ComponentFactoryResolver() {
        }
        ComponentFactoryResolver.NULL = new _NullComponentFactoryResolver();
        return ComponentFactoryResolver;
    }());
    var CodegenComponentFactoryResolver = /** @class */ (function () {
        function CodegenComponentFactoryResolver(factories, _parent, _ngModule) {
            this._parent = _parent;
            this._ngModule = _ngModule;
            this._factories = new Map();
            for (var i = 0; i < factories.length; i++) {
                var factory = factories[i];
                this._factories.set(factory.componentType, factory);
            }
        }
        CodegenComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
            var factory = this._factories.get(component);
            if (!factory && this._parent) {
                factory = this._parent.resolveComponentFactory(component);
            }
            if (!factory) {
                throw noComponentFactoryError(component);
            }
            return new ComponentFactoryBoundToModule(factory, this._ngModule);
        };
        return CodegenComponentFactoryResolver;
    }());
    var ComponentFactoryBoundToModule = /** @class */ (function (_super) {
        __extends(ComponentFactoryBoundToModule, _super);
        function ComponentFactoryBoundToModule(factory, ngModule) {
            var _this = _super.call(this) || this;
            _this.factory = factory;
            _this.ngModule = ngModule;
            _this.selector = factory.selector;
            _this.componentType = factory.componentType;
            _this.ngContentSelectors = factory.ngContentSelectors;
            _this.inputs = factory.inputs;
            _this.outputs = factory.outputs;
            return _this;
        }
        ComponentFactoryBoundToModule.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
            return this.factory.create(injector, projectableNodes, rootSelectorOrNode, ngModule || this.ngModule);
        };
        return ComponentFactoryBoundToModule;
    }(ComponentFactory));

    /**
     * @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
     */
    function noop() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        // Do nothing.
    }

    /**
     * @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
     */
    /**
     * A wrapper around a native element inside of a View.
     *
     * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
     * element.
     *
     * @security Permitting direct access to the DOM can make your application more vulnerable to
     * XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the
     * [Security Guide](http://g.co/ng/security).
     *
     * @publicApi
     */
    // Note: We don't expose things like `Injector`, `ViewContainer`, ... here,
    // i.e. users have to ask for what they need. With that, we can build better analysis tools
    // and could do better codegen in the future.
    var ElementRef = /** @class */ (function () {
        function ElementRef(nativeElement) {
            this.nativeElement = nativeElement;
        }
        /**
         * @internal
         * @nocollapse
         */
        ElementRef.__NG_ELEMENT_ID__ = function () { return SWITCH_ELEMENT_REF_FACTORY(ElementRef); };
        return ElementRef;
    }());
    var SWITCH_ELEMENT_REF_FACTORY__POST_R3__ = injectElementRef;
    var SWITCH_ELEMENT_REF_FACTORY__PRE_R3__ = noop;
    var SWITCH_ELEMENT_REF_FACTORY = SWITCH_ELEMENT_REF_FACTORY__PRE_R3__;

    /**
     * @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
     */
    /**
     * @deprecated Use `RendererType2` (and `Renderer2`) instead.
     * @publicApi
     */
    var RenderComponentType = /** @class */ (function () {
        function RenderComponentType(id, templateUrl, slotCount, encapsulation, styles, animations) {
            this.id = id;
            this.templateUrl = templateUrl;
            this.slotCount = slotCount;
            this.encapsulation = encapsulation;
            this.styles = styles;
            this.animations = animations;
        }
        return RenderComponentType;
    }());
    /**
     * @deprecated Debug info is handled internally in the view engine now.
     */
    var RenderDebugInfo = /** @class */ (function () {
        function RenderDebugInfo() {
        }
        return RenderDebugInfo;
    }());
    /**
     * @deprecated Use the `Renderer2` instead.
     * @publicApi
     */
    var Renderer = /** @class */ (function () {
        function Renderer() {
        }
        return Renderer;
    }());
    var Renderer2Interceptor = new InjectionToken('Renderer2Interceptor');
    /**
     * Injectable service that provides a low-level interface for modifying the UI.
     *
     * Use this service to bypass Angular's templating and make custom UI changes that can't be
     * expressed declaratively. For example if you need to set a property or an attribute whose name is
     * not statically known, use {@link Renderer#setElementProperty setElementProperty} or
     * {@link Renderer#setElementAttribute setElementAttribute} respectively.
     *
     * If you are implementing a custom renderer, you must implement this interface.
     *
     * The default Renderer implementation is `DomRenderer`. Also available is `WebWorkerRenderer`.
     *
     * @deprecated Use `RendererFactory2` instead.
     * @publicApi
     */
    var RootRenderer = /** @class */ (function () {
        function RootRenderer() {
        }
        return RootRenderer;
    }());
    /**
     * Creates and initializes a custom renderer that implements the `Renderer2` base class.
     *
     * @publicApi
     */
    var RendererFactory2 = /** @class */ (function () {
        function RendererFactory2() {
        }
        return RendererFactory2;
    }());
    (function (RendererStyleFlags2) {
        /**
         * Marks a style as important.
         */
        RendererStyleFlags2[RendererStyleFlags2["Important"] = 1] = "Important";
        /**
         * Marks a style as using dash case naming (this-is-dash-case).
         */
        RendererStyleFlags2[RendererStyleFlags2["DashCase"] = 2] = "DashCase";
    })(exports.RendererStyleFlags2 || (exports.RendererStyleFlags2 = {}));
    /**
     * Extend this base class to implement custom rendering. By default, Angular
     * renders a template into DOM. You can use custom rendering to intercept
     * rendering calls, or to render to something other than DOM.
     *
     * Create your custom renderer using `RendererFactory2`.
     *
     * Use a custom renderer to bypass Angular's templating and
     * make custom UI changes that can't be expressed declaratively.
     * For example if you need to set a property or an attribute whose name is
     * not statically known, use the `setProperty()` or
     * `setAttribute()` method.
     *
     * @publicApi
     */
    var Renderer2 = /** @class */ (function () {
        function Renderer2() {
        }
        /**
         * @internal
         * @nocollapse
         */
        Renderer2.__NG_ELEMENT_ID__ = function () { return SWITCH_RENDERER2_FACTORY(); };
        return Renderer2;
    }());
    var SWITCH_RENDERER2_FACTORY__POST_R3__ = injectRenderer2;
    var SWITCH_RENDERER2_FACTORY__PRE_R3__ = noop;
    var SWITCH_RENDERER2_FACTORY = SWITCH_RENDERER2_FACTORY__PRE_R3__;

    /**
     * @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
     */
    /**
     * @description Represents the version of Angular
     *
     * @publicApi
     */
    var Version = /** @class */ (function () {
        function Version(full) {
            this.full = full;
            this.major = full.split('.')[0];
            this.minor = full.split('.')[1];
            this.patch = full.split('.').slice(2).join('.');
        }
        return Version;
    }());
    /**
     * @publicApi
     */
    var VERSION = new Version('8.2.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
     */
    var DefaultIterableDifferFactory = /** @class */ (function () {
        function DefaultIterableDifferFactory() {
        }
        DefaultIterableDifferFactory.prototype.supports = function (obj) { return isListLikeIterable$1(obj); };
        DefaultIterableDifferFactory.prototype.create = function (trackByFn) {
            return new DefaultIterableDiffer(trackByFn);
        };
        return DefaultIterableDifferFactory;
    }());
    var trackByIdentity = function (index, item) { return item; };
    var ɵ0$d = trackByIdentity;
    /**
     * @deprecated v4.0.0 - Should not be part of public API.
     * @publicApi
     */
    var DefaultIterableDiffer = /** @class */ (function () {
        function DefaultIterableDiffer(trackByFn) {
            this.length = 0;
            // Keeps track of the used records at any point in time (during & across `_check()` calls)
            this._linkedRecords = null;
            // Keeps track of the removed records at any point in time during `_check()` calls.
            this._unlinkedRecords = null;
            this._previousItHead = null;
            this._itHead = null;
            this._itTail = null;
            this._additionsHead = null;
            this._additionsTail = null;
            this._movesHead = null;
            this._movesTail = null;
            this._removalsHead = null;
            this._removalsTail = null;
            // Keeps track of records where custom track by is the same, but item identity has changed
            this._identityChangesHead = null;
            this._identityChangesTail = null;
            this._trackByFn = trackByFn || trackByIdentity;
        }
        DefaultIterableDiffer.prototype.forEachItem = function (fn) {
            var record;
            for (record = this._itHead; record !== null; record = record._next) {
                fn(record);
            }
        };
        DefaultIterableDiffer.prototype.forEachOperation = function (fn) {
            var nextIt = this._itHead;
            var nextRemove = this._removalsHead;
            var addRemoveOffset = 0;
            var moveOffsets = null;
            while (nextIt || nextRemove) {
                // Figure out which is the next record to process
                // Order: remove, add, move
                var record = !nextRemove ||
                    nextIt &&
                        nextIt.currentIndex <
                            getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ?
                    nextIt :
                    nextRemove;
                var adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
                var currentIndex = record.currentIndex;
                // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
                if (record === nextRemove) {
                    addRemoveOffset--;
                    nextRemove = nextRemove._nextRemoved;
                }
                else {
                    nextIt = nextIt._next;
                    if (record.previousIndex == null) {
                        addRemoveOffset++;
                    }
                    else {
                        // INVARIANT:  currentIndex < previousIndex
                        if (!moveOffsets)
                            moveOffsets = [];
                        var localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
                        var localCurrentIndex = currentIndex - addRemoveOffset;
                        if (localMovePreviousIndex != localCurrentIndex) {
                            for (var i = 0; i < localMovePreviousIndex; i++) {
                                var offset = i < moveOffsets.length ? moveOffsets[i] : (moveOffsets[i] = 0);
                                var index = offset + i;
                                if (localCurrentIndex <= index && index < localMovePreviousIndex) {
                                    moveOffsets[i] = offset + 1;
                                }
                            }
                            var previousIndex = record.previousIndex;
                            moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
                        }
                    }
                }
                if (adjPreviousIndex !== currentIndex) {
                    fn(record, adjPreviousIndex, currentIndex);
                }
            }
        };
        DefaultIterableDiffer.prototype.forEachPreviousItem = function (fn) {
            var record;
            for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
                fn(record);
            }
        };
        DefaultIterableDiffer.prototype.forEachAddedItem = function (fn) {
            var record;
            for (record = this._additionsHead; record !== null; record = record._nextAdded) {
                fn(record);
            }
        };
        DefaultIterableDiffer.prototype.forEachMovedItem = function (fn) {
            var record;
            for (record = this._movesHead; record !== null; record = record._nextMoved) {
                fn(record);
            }
        };
        DefaultIterableDiffer.prototype.forEachRemovedItem = function (fn) {
            var record;
            for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
                fn(record);
            }
        };
        DefaultIterableDiffer.prototype.forEachIdentityChange = function (fn) {
            var record;
            for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
                fn(record);
            }
        };
        DefaultIterableDiffer.prototype.diff = function (collection) {
            if (collection == null)
                collection = [];
            if (!isListLikeIterable$1(collection)) {
                throw new Error("Error trying to diff '" + stringify(collection) + "'. Only arrays and iterables are allowed");
            }
            if (this.check(collection)) {
                return this;
            }
            else {
                return null;
            }
        };
        DefaultIterableDiffer.prototype.onDestroy = function () { };
        DefaultIterableDiffer.prototype.check = function (collection) {
            var _this = this;
            this._reset();
            var record = this._itHead;
            var mayBeDirty = false;
            var index;
            var item;
            var itemTrackBy;
            if (Array.isArray(collection)) {
                this.length = collection.length;
                for (var index_1 = 0; index_1 < this.length; index_1++) {
                    item = collection[index_1];
                    itemTrackBy = this._trackByFn(index_1, item);
                    if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
                        record = this._mismatch(record, item, itemTrackBy, index_1);
                        mayBeDirty = true;
                    }
                    else {
                        if (mayBeDirty) {
                            // TODO(misko): can we limit this to duplicates only?
                            record = this._verifyReinsertion(record, item, itemTrackBy, index_1);
                        }
                        if (!looseIdentical(record.item, item))
                            this._addIdentityChange(record, item);
                    }
                    record = record._next;
                }
            }
            else {
                index = 0;
                iterateListLike$1(collection, function (item) {
                    itemTrackBy = _this._trackByFn(index, item);
                    if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
                        record = _this._mismatch(record, item, itemTrackBy, index);
                        mayBeDirty = true;
                    }
                    else {
                        if (mayBeDirty) {
                            // TODO(misko): can we limit this to duplicates only?
                            record = _this._verifyReinsertion(record, item, itemTrackBy, index);
                        }
                        if (!looseIdentical(record.item, item))
                            _this._addIdentityChange(record, item);
                    }
                    record = record._next;
                    index++;
                });
                this.length = index;
            }
            this._truncate(record);
            this.collection = collection;
            return this.isDirty;
        };
        Object.defineProperty(DefaultIterableDiffer.prototype, "isDirty", {
            /* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity
             * changes.
             */
            get: function () {
                return this._additionsHead !== null || this._movesHead !== null ||
                    this._removalsHead !== null || this._identityChangesHead !== null;
            },
            enumerable: true,
            configurable: true
        });
        /**
         * Reset the state of the change objects to show no changes. This means set previousKey to
         * currentKey, and clear all of the queues (additions, moves, removals).
         * Set the previousIndexes of moved and added items to their currentIndexes
         * Reset the list of additions, moves and removals
         *
         * @internal
         */
        DefaultIterableDiffer.prototype._reset = function () {
            if (this.isDirty) {
                var record = void 0;
                var nextRecord = void 0;
                for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
                    record._nextPrevious = record._next;
                }
                for (record = this._additionsHead; record !== null; record = record._nextAdded) {
                    record.previousIndex = record.currentIndex;
                }
                this._additionsHead = this._additionsTail = null;
                for (record = this._movesHead; record !== null; record = nextRecord) {
                    record.previousIndex = record.currentIndex;
                    nextRecord = record._nextMoved;
                }
                this._movesHead = this._movesTail = null;
                this._removalsHead = this._removalsTail = null;
                this._identityChangesHead = this._identityChangesTail = null;
                // TODO(vicb): when assert gets supported
                // assert(!this.isDirty);
            }
        };
        /**
         * This is the core function which handles differences between collections.
         *
         * - `record` is the record which we saw at this position last time. If null then it is a new
         *   item.
         * - `item` is the current item in the collection
         * - `index` is the position of the item in the collection
         *
         * @internal
         */
        DefaultIterableDiffer.prototype._mismatch = function (record, item, itemTrackBy, index) {
            // The previous record after which we will append the current one.
            var previousRecord;
            if (record === null) {
                previousRecord = this._itTail;
            }
            else {
                previousRecord = record._prev;
                // Remove the record from the collection since we know it does not match the item.
                this._remove(record);
            }
            // Attempt to see if we have seen the item before.
            record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
            if (record !== null) {
                // We have seen this before, we need to move it forward in the collection.
                // But first we need to check if identity changed, so we can update in view if necessary
                if (!looseIdentical(record.item, item))
                    this._addIdentityChange(record, item);
                this._moveAfter(record, previousRecord, index);
            }
            else {
                // Never seen it, check evicted list.
                record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
                if (record !== null) {
                    // It is an item which we have evicted earlier: reinsert it back into the list.
                    // But first we need to check if identity changed, so we can update in view if necessary
                    if (!looseIdentical(record.item, item))
                        this._addIdentityChange(record, item);
                    this._reinsertAfter(record, previousRecord, index);
                }
                else {
                    // It is a new item: add it.
                    record =
                        this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
                }
            }
            return record;
        };
        /**
         * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
         *
         * Use case: `[a, a]` => `[b, a, a]`
         *
         * If we did not have this check then the insertion of `b` would:
         *   1) evict first `a`
         *   2) insert `b` at `0` index.
         *   3) leave `a` at index `1` as is. <-- this is wrong!
         *   3) reinsert `a` at index 2. <-- this is wrong!
         *
         * The correct behavior is:
         *   1) evict first `a`
         *   2) insert `b` at `0` index.
         *   3) reinsert `a` at index 1.
         *   3) move `a` at from `1` to `2`.
         *
         *
         * Double check that we have not evicted a duplicate item. We need to check if the item type may
         * have already been removed:
         * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
         * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
         * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
         * at the end.
         *
         * @internal
         */
        DefaultIterableDiffer.prototype._verifyReinsertion = function (record, item, itemTrackBy, index) {
            var reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
            if (reinsertRecord !== null) {
                record = this._reinsertAfter(reinsertRecord, record._prev, index);
            }
            else if (record.currentIndex != index) {
                record.currentIndex = index;
                this._addToMoves(record, index);
            }
            return record;
        };
        /**
         * Get rid of any excess {@link IterableChangeRecord_}s from the previous collection
         *
         * - `record` The first excess {@link IterableChangeRecord_}.
         *
         * @internal
         */
        DefaultIterableDiffer.prototype._truncate = function (record) {
            // Anything after that needs to be removed;
            while (record !== null) {
                var nextRecord = record._next;
                this._addToRemovals(this._unlink(record));
                record = nextRecord;
            }
            if (this._unlinkedRecords !== null) {
                this._unlinkedRecords.clear();
            }
            if (this._additionsTail !== null) {
                this._additionsTail._nextAdded = null;
            }
            if (this._movesTail !== null) {
                this._movesTail._nextMoved = null;
            }
            if (this._itTail !== null) {
                this._itTail._next = null;
            }
            if (this._removalsTail !== null) {
                this._removalsTail._nextRemoved = null;
            }
            if (this._identityChangesTail !== null) {
                this._identityChangesTail._nextIdentityChange = null;
            }
        };
        /** @internal */
        DefaultIterableDiffer.prototype._reinsertAfter = function (record, prevRecord, index) {
            if (this._unlinkedRecords !== null) {
                this._unlinkedRecords.remove(record);
            }
            var prev = record._prevRemoved;
            var next = record._nextRemoved;
            if (prev === null) {
                this._removalsHead = next;
            }
            else {
                prev._nextRemoved = next;
            }
            if (next === null) {
                this._removalsTail = prev;
            }
            else {
                next._prevRemoved = prev;
            }
            this._insertAfter(record, prevRecord, index);
            this._addToMoves(record, index);
            return record;
        };
        /** @internal */
        DefaultIterableDiffer.prototype._moveAfter = function (record, prevRecord, index) {
            this._unlink(record);
            this._insertAfter(record, prevRecord, index);
            this._addToMoves(record, index);
            return record;
        };
        /** @internal */
        DefaultIterableDiffer.prototype._addAfter = function (record, prevRecord, index) {
            this._insertAfter(record, prevRecord, index);
            if (this._additionsTail === null) {
                // TODO(vicb):
                // assert(this._additionsHead === null);
                this._additionsTail = this._additionsHead = record;
            }
            else {
                // TODO(vicb):
                // assert(_additionsTail._nextAdded === null);
                // assert(record._nextAdded === null);
                this._additionsTail = this._additionsTail._nextAdded = record;
            }
            return record;
        };
        /** @internal */
        DefaultIterableDiffer.prototype._insertAfter = function (record, prevRecord, index) {
            // TODO(vicb):
            // assert(record != prevRecord);
            // assert(record._next === null);
            // assert(record._prev === null);
            var next = prevRecord === null ? this._itHead : prevRecord._next;
            // TODO(vicb):
            // assert(next != record);
            // assert(prevRecord != record);
            record._next = next;
            record._prev = prevRecord;
            if (next === null) {
                this._itTail = record;
            }
            else {
                next._prev = record;
            }
            if (prevRecord === null) {
                this._itHead = record;
            }
            else {
                prevRecord._next = record;
            }
            if (this._linkedRecords === null) {
                this._linkedRecords = new _DuplicateMap();
            }
            this._linkedRecords.put(record);
            record.currentIndex = index;
            return record;
        };
        /** @internal */
        DefaultIterableDiffer.prototype._remove = function (record) {
            return this._addToRemovals(this._unlink(record));
        };
        /** @internal */
        DefaultIterableDiffer.prototype._unlink = function (record) {
            if (this._linkedRecords !== null) {
                this._linkedRecords.remove(record);
            }
            var prev = record._prev;
            var next = record._next;
            // TODO(vicb):
            // assert((record._prev = null) === null);
            // assert((record._next = null) === null);
            if (prev === null) {
                this._itHead = next;
            }
            else {
                prev._next = next;
            }
            if (next === null) {
                this._itTail = prev;
            }
            else {
                next._prev = prev;
            }
            return record;
        };
        /** @internal */
        DefaultIterableDiffer.prototype._addToMoves = function (record, toIndex) {
            // TODO(vicb):
            // assert(record._nextMoved === null);
            if (record.previousIndex === toIndex) {
                return record;
            }
            if (this._movesTail === null) {
                // TODO(vicb):
                // assert(_movesHead === null);
                this._movesTail = this._movesHead = record;
            }
            else {
                // TODO(vicb):
                // assert(_movesTail._nextMoved === null);
                this._movesTail = this._movesTail._nextMoved = record;
            }
            return record;
        };
        DefaultIterableDiffer.prototype._addToRemovals = function (record) {
            if (this._unlinkedRecords === null) {
                this._unlinkedRecords = new _DuplicateMap();
            }
            this._unlinkedRecords.put(record);
            record.currentIndex = null;
            record._nextRemoved = null;
            if (this._removalsTail === null) {
                // TODO(vicb):
                // assert(_removalsHead === null);
                this._removalsTail = this._removalsHead = record;
                record._prevRemoved = null;
            }
            else {
                // TODO(vicb):
                // assert(_removalsTail._nextRemoved === null);
                // assert(record._nextRemoved === null);
                record._prevRemoved = this._removalsTail;
                this._removalsTail = this._removalsTail._nextRemoved = record;
            }
            return record;
        };
        /** @internal */
        DefaultIterableDiffer.prototype._addIdentityChange = function (record, item) {
            record.item = item;
            if (this._identityChangesTail === null) {
                this._identityChangesTail = this._identityChangesHead = record;
            }
            else {
                this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
            }
            return record;
        };
        return DefaultIterableDiffer;
    }());
    var IterableChangeRecord_ = /** @class */ (function () {
        function IterableChangeRecord_(item, trackById) {
            this.item = item;
            this.trackById = trackById;
            this.currentIndex = null;
            this.previousIndex = null;
            /** @internal */
            this._nextPrevious = null;
            /** @internal */
            this._prev = null;
            /** @internal */
            this._next = null;
            /** @internal */
            this._prevDup = null;
            /** @internal */
            this._nextDup = null;
            /** @internal */
            this._prevRemoved = null;
            /** @internal */
            this._nextRemoved = null;
            /** @internal */
            this._nextAdded = null;
            /** @internal */
            this._nextMoved = null;
            /** @internal */
            this._nextIdentityChange = null;
        }
        return IterableChangeRecord_;
    }());
    // A linked list of CollectionChangeRecords with the same IterableChangeRecord_.item
    var _DuplicateItemRecordList = /** @class */ (function () {
        function _DuplicateItemRecordList() {
            /** @internal */
            this._head = null;
            /** @internal */
            this._tail = null;
        }
        /**
         * Append the record to the list of duplicates.
         *
         * Note: by design all records in the list of duplicates hold the same value in record.item.
         */
        _DuplicateItemRecordList.prototype.add = function (record) {
            if (this._head === null) {
                this._head = this._tail = record;
                record._nextDup = null;
                record._prevDup = null;
            }
            else {
                // TODO(vicb):
                // assert(record.item ==  _head.item ||
                //       record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
                this._tail._nextDup = record;
                record._prevDup = this._tail;
                record._nextDup = null;
                this._tail = record;
            }
        };
        // Returns a IterableChangeRecord_ having IterableChangeRecord_.trackById == trackById and
        // IterableChangeRecord_.currentIndex >= atOrAfterIndex
        _DuplicateItemRecordList.prototype.get = function (trackById, atOrAfterIndex) {
            var record;
            for (record = this._head; record !== null; record = record._nextDup) {
                if ((atOrAfterIndex === null || atOrAfterIndex <= record.currentIndex) &&
                    looseIdentical(record.trackById, trackById)) {
                    return record;
                }
            }
            return null;
        };
        /**
         * Remove one {@link IterableChangeRecord_} from the list of duplicates.
         *
         * Returns whether the list of duplicates is empty.
         */
        _DuplicateItemRecordList.prototype.remove = function (record) {
            // TODO(vicb):
            // assert(() {
            //  // verify that the record being removed is in the list.
            //  for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
            //    if (identical(cursor, record)) return true;
            //  }
            //  return false;
            //});
            var prev = record._prevDup;
            var next = record._nextDup;
            if (prev === null) {
                this._head = next;
            }
            else {
                prev._nextDup = next;
            }
            if (next === null) {
                this._tail = prev;
            }
            else {
                next._prevDup = prev;
            }
            return this._head === null;
        };
        return _DuplicateItemRecordList;
    }());
    var _DuplicateMap = /** @class */ (function () {
        function _DuplicateMap() {
            this.map = new Map();
        }
        _DuplicateMap.prototype.put = function (record) {
            var key = record.trackById;
            var duplicates = this.map.get(key);
            if (!duplicates) {
                duplicates = new _DuplicateItemRecordList();
                this.map.set(key, duplicates);
            }
            duplicates.add(record);
        };
        /**
         * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
         * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
         *
         * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
         * have any more `a`s needs to return the second `a`.
         */
        _DuplicateMap.prototype.get = function (trackById, atOrAfterIndex) {
            var key = trackById;
            var recordList = this.map.get(key);
            return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
        };
        /**
         * Removes a {@link IterableChangeRecord_} from the list of duplicates.
         *
         * The list of duplicates also is removed from the map if it gets empty.
         */
        _DuplicateMap.prototype.remove = function (record) {
            var key = record.trackById;
            var recordList = this.map.get(key);
            // Remove the list of duplicates when it gets empty
            if (recordList.remove(record)) {
                this.map.delete(key);
            }
            return record;
        };
        Object.defineProperty(_DuplicateMap.prototype, "isEmpty", {
            get: function () { return this.map.size === 0; },
            enumerable: true,
            configurable: true
        });
        _DuplicateMap.prototype.clear = function () { this.map.clear(); };
        return _DuplicateMap;
    }());
    function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
        var previousIndex = item.previousIndex;
        if (previousIndex === null)
            return previousIndex;
        var moveOffset = 0;
        if (moveOffsets && previousIndex < moveOffsets.length) {
            moveOffset = moveOffsets[previousIndex];
        }
        return previousIndex + addRemoveOffset + moveOffset;
    }

    /**
     * @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
     */
    var DefaultKeyValueDifferFactory = /** @class */ (function () {
        function DefaultKeyValueDifferFactory() {
        }
        DefaultKeyValueDifferFactory.prototype.supports = function (obj) { return obj instanceof Map || isJsObject$1(obj); };
        DefaultKeyValueDifferFactory.prototype.create = function () { return new DefaultKeyValueDiffer(); };
        return DefaultKeyValueDifferFactory;
    }());
    var DefaultKeyValueDiffer = /** @class */ (function () {
        function DefaultKeyValueDiffer() {
            this._records = new Map();
            this._mapHead = null;
            // _appendAfter is used in the check loop
            this._appendAfter = null;
            this._previousMapHead = null;
            this._changesHead = null;
            this._changesTail = null;
            this._additionsHead = null;
            this._additionsTail = null;
            this._removalsHead = null;
            this._removalsTail = null;
        }
        Object.defineProperty(DefaultKeyValueDiffer.prototype, "isDirty", {
            get: function () {
                return this._additionsHead !== null || this._changesHead !== null ||
                    this._removalsHead !== null;
            },
            enumerable: true,
            configurable: true
        });
        DefaultKeyValueDiffer.prototype.forEachItem = function (fn) {
            var record;
            for (record = this._mapHead; record !== null; record = record._next) {
                fn(record);
            }
        };
        DefaultKeyValueDiffer.prototype.forEachPreviousItem = function (fn) {
            var record;
            for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
                fn(record);
            }
        };
        DefaultKeyValueDiffer.prototype.forEachChangedItem = function (fn) {
            var record;
            for (record = this._changesHead; record !== null; record = record._nextChanged) {
                fn(record);
            }
        };
        DefaultKeyValueDiffer.prototype.forEachAddedItem = function (fn) {
            var record;
            for (record = this._additionsHead; record !== null; record = record._nextAdded) {
                fn(record);
            }
        };
        DefaultKeyValueDiffer.prototype.forEachRemovedItem = function (fn) {
            var record;
            for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
                fn(record);
            }
        };
        DefaultKeyValueDiffer.prototype.diff = function (map) {
            if (!map) {
                map = new Map();
            }
            else if (!(map instanceof Map || isJsObject$1(map))) {
                throw new Error("Error trying to diff '" + stringify(map) + "'. Only maps and objects are allowed");
            }
            return this.check(map) ? this : null;
        };
        DefaultKeyValueDiffer.prototype.onDestroy = function () { };
        /**
         * Check the current state of the map vs the previous.
         * The algorithm is optimised for when the keys do no change.
         */
        DefaultKeyValueDiffer.prototype.check = function (map) {
            var _this = this;
            this._reset();
            var insertBefore = this._mapHead;
            this._appendAfter = null;
            this._forEach(map, function (value, key) {
                if (insertBefore && insertBefore.key === key) {
                    _this._maybeAddToChanges(insertBefore, value);
                    _this._appendAfter = insertBefore;
                    insertBefore = insertBefore._next;
                }
                else {
                    var record = _this._getOrCreateRecordForKey(key, value);
                    insertBefore = _this._insertBeforeOrAppend(insertBefore, record);
                }
            });
            // Items remaining at the end of the list have been deleted
            if (insertBefore) {
                if (insertBefore._prev) {
                    insertBefore._prev._next = null;
                }
                this._removalsHead = insertBefore;
                for (var record = insertBefore; record !== null; record = record._nextRemoved) {
                    if (record === this._mapHead) {
                        this._mapHead = null;
                    }
                    this._records.delete(record.key);
                    record._nextRemoved = record._next;
                    record.previousValue = record.currentValue;
                    record.currentValue = null;
                    record._prev = null;
                    record._next = null;
                }
            }
            // Make sure tails have no next records from previous runs
            if (this._changesTail)
                this._changesTail._nextChanged = null;
            if (this._additionsTail)
                this._additionsTail._nextAdded = null;
            return this.isDirty;
        };
        /**
         * Inserts a record before `before` or append at the end of the list when `before` is null.
         *
         * Notes:
         * - This method appends at `this._appendAfter`,
         * - This method updates `this._appendAfter`,
         * - The return value is the new value for the insertion pointer.
         */
        DefaultKeyValueDiffer.prototype._insertBeforeOrAppend = function (before, record) {
            if (before) {
                var prev = before._prev;
                record._next = before;
                record._prev = prev;
                before._prev = record;
                if (prev) {
                    prev._next = record;
                }
                if (before === this._mapHead) {
                    this._mapHead = record;
                }
                this._appendAfter = before;
                return before;
            }
            if (this._appendAfter) {
                this._appendAfter._next = record;
                record._prev = this._appendAfter;
            }
            else {
                this._mapHead = record;
            }
            this._appendAfter = record;
            return null;
        };
        DefaultKeyValueDiffer.prototype._getOrCreateRecordForKey = function (key, value) {
            if (this._records.has(key)) {
                var record_1 = this._records.get(key);
                this._maybeAddToChanges(record_1, value);
                var prev = record_1._prev;
                var next = record_1._next;
                if (prev) {
                    prev._next = next;
                }
                if (next) {
                    next._prev = prev;
                }
                record_1._next = null;
                record_1._prev = null;
                return record_1;
            }
            var record = new KeyValueChangeRecord_(key);
            this._records.set(key, record);
            record.currentValue = value;
            this._addToAdditions(record);
            return record;
        };
        /** @internal */
        DefaultKeyValueDiffer.prototype._reset = function () {
            if (this.isDirty) {
                var record = void 0;
                // let `_previousMapHead` contain the state of the map before the changes
                this._previousMapHead = this._mapHead;
                for (record = this._previousMapHead; record !== null; record = record._next) {
                    record._nextPrevious = record._next;
                }
                // Update `record.previousValue` with the value of the item before the changes
                // We need to update all changed items (that's those which have been added and changed)
                for (record = this._changesHead; record !== null; record = record._nextChanged) {
                    record.previousValue = record.currentValue;
                }
                for (record = this._additionsHead; record != null; record = record._nextAdded) {
                    record.previousValue = record.currentValue;
                }
                this._changesHead = this._changesTail = null;
                this._additionsHead = this._additionsTail = null;
                this._removalsHead = null;
            }
        };
        // Add the record or a given key to the list of changes only when the value has actually changed
        DefaultKeyValueDiffer.prototype._maybeAddToChanges = function (record, newValue) {
            if (!looseIdentical(newValue, record.currentValue)) {
                record.previousValue = record.currentValue;
                record.currentValue = newValue;
                this._addToChanges(record);
            }
        };
        DefaultKeyValueDiffer.prototype._addToAdditions = function (record) {
            if (this._additionsHead === null) {
                this._additionsHead = this._additionsTail = record;
            }
            else {
                this._additionsTail._nextAdded = record;
                this._additionsTail = record;
            }
        };
        DefaultKeyValueDiffer.prototype._addToChanges = function (record) {
            if (this._changesHead === null) {
                this._changesHead = this._changesTail = record;
            }
            else {
                this._changesTail._nextChanged = record;
                this._changesTail = record;
            }
        };
        /** @internal */
        DefaultKeyValueDiffer.prototype._forEach = function (obj, fn) {
            if (obj instanceof Map) {
                obj.forEach(fn);
            }
            else {
                Object.keys(obj).forEach(function (k) { return fn(obj[k], k); });
            }
        };
        return DefaultKeyValueDiffer;
    }());
    var KeyValueChangeRecord_ = /** @class */ (function () {
        function KeyValueChangeRecord_(key) {
            this.key = key;
            this.previousValue = null;
            this.currentValue = null;
            /** @internal */
            this._nextPrevious = null;
            /** @internal */
            this._next = null;
            /** @internal */
            this._prev = null;
            /** @internal */
            this._nextAdded = null;
            /** @internal */
            this._nextRemoved = null;
            /** @internal */
            this._nextChanged = null;
        }
        return KeyValueChangeRecord_;
    }());

    /**
     * @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
     */
    /**
     * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
     *
     * @publicApi
     */
    var IterableDiffers = /** @class */ (function () {
        function IterableDiffers(factories) {
            this.factories = factories;
        }
        IterableDiffers.create = function (factories, parent) {
            if (parent != null) {
                var copied = parent.factories.slice();
                factories = factories.concat(copied);
            }
            return new IterableDiffers(factories);
        };
        /**
         * Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
         * inherited {@link IterableDiffers} instance with the provided factories and return a new
         * {@link IterableDiffers} instance.
         *
         * @usageNotes
         * ### Example
         *
         * The following example shows how to extend an existing list of factories,
         * which will only be applied to the injector for this component and its children.
         * This step is all that's required to make a new {@link IterableDiffer} available.
         *
         * ```
         * @Component({
         *   viewProviders: [
         *     IterableDiffers.extend([new ImmutableListDiffer()])
         *   ]
         * })
         * ```
         */
        IterableDiffers.extend = function (factories) {
            return {
                provide: IterableDiffers,
                useFactory: function (parent) {
                    if (!parent) {
                        // Typically would occur when calling IterableDiffers.extend inside of dependencies passed
                        // to
                        // bootstrap(), which would override default pipes instead of extending them.
                        throw new Error('Cannot extend IterableDiffers without a parent injector');
                    }
                    return IterableDiffers.create(factories, parent);
                },
                // Dependency technically isn't optional, but we can provide a better error message this way.
                deps: [[IterableDiffers, new SkipSelf(), new Optional()]]
            };
        };
        IterableDiffers.prototype.find = function (iterable) {
            var factory = this.factories.find(function (f) { return f.supports(iterable); });
            if (factory != null) {
                return factory;
            }
            else {
                throw new Error("Cannot find a differ supporting object '" + iterable + "' of type '" + getTypeNameForDebugging(iterable) + "'");
            }
        };
        /** @nocollapse */
        IterableDiffers.ngInjectableDef = ɵɵdefineInjectable({
            token: IterableDiffers,
            providedIn: 'root',
            factory: function () { return new IterableDiffers([new DefaultIterableDifferFactory()]); }
        });
        return IterableDiffers;
    }());
    function getTypeNameForDebugging(type) {
        return type['name'] || typeof type;
    }

    /**
     * @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
     */
    /**
     * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
     *
     * @publicApi
     */
    var KeyValueDiffers = /** @class */ (function () {
        function KeyValueDiffers(factories) {
            this.factories = factories;
        }
        KeyValueDiffers.create = function (factories, parent) {
            if (parent) {
                var copied = parent.factories.slice();
                factories = factories.concat(copied);
            }
            return new KeyValueDiffers(factories);
        };
        /**
         * Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
         * inherited {@link KeyValueDiffers} instance with the provided factories and return a new
         * {@link KeyValueDiffers} instance.
         *
         * @usageNotes
         * ### Example
         *
         * The following example shows how to extend an existing list of factories,
         * which will only be applied to the injector for this component and its children.
         * This step is all that's required to make a new {@link KeyValueDiffer} available.
         *
         * ```
         * @Component({
         *   viewProviders: [
         *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
         *   ]
         * })
         * ```
         */
        KeyValueDiffers.extend = function (factories) {
            return {
                provide: KeyValueDiffers,
                useFactory: function (parent) {
                    if (!parent) {
                        // Typically would occur when calling KeyValueDiffers.extend inside of dependencies passed
                        // to bootstrap(), which would override default pipes instead of extending them.
                        throw new Error('Cannot extend KeyValueDiffers without a parent injector');
                    }
                    return KeyValueDiffers.create(factories, parent);
                },
                // Dependency technically isn't optional, but we can provide a better error message this way.
                deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
            };
        };
        KeyValueDiffers.prototype.find = function (kv) {
            var factory = this.factories.find(function (f) { return f.supports(kv); });
            if (factory) {
                return factory;
            }
            throw new Error("Cannot find a differ supporting object '" + kv + "'");
        };
        /** @nocollapse */
        KeyValueDiffers.ngInjectableDef = ɵɵdefineInjectable({
            token: KeyValueDiffers,
            providedIn: 'root',
            factory: function () { return new KeyValueDiffers([new DefaultKeyValueDifferFactory()]); }
        });
        return KeyValueDiffers;
    }());

    /**
     * @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
     */
    /**
     * Structural diffing for `Object`s and `Map`s.
     */
    var keyValDiff = [new DefaultKeyValueDifferFactory()];
    /**
     * Structural diffing for `Iterable` types such as `Array`s.
     */
    var iterableDiff = [new DefaultIterableDifferFactory()];
    var defaultIterableDiffers = new IterableDiffers(iterableDiff);
    var defaultKeyValueDiffers = new KeyValueDiffers(keyValDiff);

    /**
     * @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
     */
    /**
     * Represents an embedded template that can be used to instantiate embedded views.
     * To instantiate embedded views based on a template, use the `ViewContainerRef`
     * method `createEmbeddedView()`.
     *
     * Access a `TemplateRef` instance by placing a directive on an `<ng-template>`
     * element (or directive prefixed with `*`). The `TemplateRef` for the embedded view
     * is injected into the constructor of the directive,
     * using the `TemplateRef` token.
     *
     * You can also use a `Query` to find a `TemplateRef` associated with
     * a component or a directive.
     *
     * @see `ViewContainerRef`
     * @see [Navigate the Component Tree with DI](guide/dependency-injection-navtree)
     *
     * @publicApi
     */
    var TemplateRef = /** @class */ (function () {
        function TemplateRef() {
        }
        /**
         * @internal
         * @nocollapse
         */
        TemplateRef.__NG_ELEMENT_ID__ = function () { return SWITCH_TEMPLATE_REF_FACTORY(TemplateRef, ElementRef); };
        return TemplateRef;
    }());
    var SWITCH_TEMPLATE_REF_FACTORY__POST_R3__ = injectTemplateRef;
    var SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__ = noop;
    var SWITCH_TEMPLATE_REF_FACTORY = SWITCH_TEMPLATE_REF_FACTORY__PRE_R3__;

    /**
     * @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
     */
    /**
     * Represents a container where one or more views can be attached to a component.
     *
     * Can contain *host views* (created by instantiating a
     * component with the `createComponent()` method), and *embedded views*
     * (created by instantiating a `TemplateRef` with the `createEmbeddedView()` method).
     *
     * A view container instance can contain other view containers,
     * creating a [view hierarchy](guide/glossary#view-tree).
     *
     * @see `ComponentRef`
     * @see `EmbeddedViewRef`
     *
     * @publicApi
     */
    var ViewContainerRef = /** @class */ (function () {
        function ViewContainerRef() {
        }
        /**
         * @internal
         * @nocollapse
         */
        ViewContainerRef.__NG_ELEMENT_ID__ = function () { return SWITCH_VIEW_CONTAINER_REF_FACTORY(ViewContainerRef, ElementRef); };
        return ViewContainerRef;
    }());
    var SWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__ = injectViewContainerRef;
    var SWITCH_VIEW_CONTAINER_REF_FACTORY__PRE_R3__ = noop;
    var SWITCH_VIEW_CONTAINER_REF_FACTORY = SWITCH_VIEW_CONTAINER_REF_FACTORY__PRE_R3__;

    /**
     * @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
     */
    function expressionChangedAfterItHasBeenCheckedError(context, oldValue, currValue, isFirstCheck) {
        var msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
        if (isFirstCheck) {
            msg +=
                " It seems like the view has been created after its parent and its children have been dirty checked." +
                    " Has it been created in a change detection hook ?";
        }
        return viewDebugError(msg, context);
    }
    function viewWrappedDebugError(err, context) {
        if (!(err instanceof Error)) {
            // errors that are not Error instances don't have a stack,
            // so it is ok to wrap them into a new Error object...
            err = new Error(err.toString());
        }
        _addDebugContext(err, context);
        return err;
    }
    function viewDebugError(msg, context) {
        var err = new Error(msg);
        _addDebugContext(err, context);
        return err;
    }
    function _addDebugContext(err, context) {
        err[ERROR_DEBUG_CONTEXT] = context;
        err[ERROR_LOGGER] = context.logError.bind(context);
    }
    function isViewDebugError(err) {
        return !!getDebugContext(err);
    }
    function viewDestroyedError(action) {
        return new Error("ViewDestroyedError: Attempt to use a destroyed view: " + action);
    }

    /**
     * @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
     */
    // Called before each cycle of a view's check to detect whether this is in the
    // initState for which we need to call ngOnInit, ngAfterContentInit or ngAfterViewInit
    // lifecycle methods. Returns true if this check cycle should call lifecycle
    // methods.
    function shiftInitState(view, priorInitState, newInitState) {
        // Only update the InitState if we are currently in the prior state.
        // For example, only move into CallingInit if we are in BeforeInit. Only
        // move into CallingContentInit if we are in CallingInit. Normally this will
        // always be true because of how checkCycle is called in checkAndUpdateView.
        // However, if checkAndUpdateView is called recursively or if an exception is
        // thrown while checkAndUpdateView is running, checkAndUpdateView starts over
        // from the beginning. This ensures the state is monotonically increasing,
        // terminating in the AfterInit state, which ensures the Init methods are called
        // at least once and only once.
        var state = view.state;
        var initState = state & 1792 /* InitState_Mask */;
        if (initState === priorInitState) {
            view.state = (state & ~1792 /* InitState_Mask */) | newInitState;
            view.initIndex = -1;
            return true;
        }
        return initState === newInitState;
    }
    // Returns true if the lifecycle init method should be called for the node with
    // the given init index.
    function shouldCallLifecycleInitHook(view, initState, index) {
        if ((view.state & 1792 /* InitState_Mask */) === initState && view.initIndex <= index) {
            view.initIndex = index + 1;
            return true;
        }
        return false;
    }
    /**
     * Node instance data.
     *
     * We have a separate type per NodeType to save memory
     * (TextData | ElementData | ProviderData | PureExpressionData | QueryList<any>)
     *
     * To keep our code monomorphic,
     * we prohibit using `NodeData` directly but enforce the use of accessors (`asElementData`, ...).
     * This way, no usage site can get a `NodeData` from view.nodes and then use it for different
     * purposes.
     */
    var NodeData = /** @class */ (function () {
        function NodeData() {
        }
        return NodeData;
    }());
    /**
     * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
     */
    function asTextData(view, index) {
        return view.nodes[index];
    }
    /**
     * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
     */
    function asElementData(view, index) {
        return view.nodes[index];
    }
    /**
     * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
     */
    function asProviderData(view, index) {
        return view.nodes[index];
    }
    /**
     * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
     */
    function asPureExpressionData(view, index) {
        return view.nodes[index];
    }
    /**
     * Accessor for view.nodes, enforcing that every usage site stays monomorphic.
     */
    function asQueryList(view, index) {
        return view.nodes[index];
    }
    var DebugContext = /** @class */ (function () {
        function DebugContext() {
        }
        return DebugContext;
    }());
    /**
     * This object is used to prevent cycles in the source files and to have a place where
     * debug mode can hook it. It is lazily filled when `isDevMode` is known.
     */
    var Services = {
        setCurrentNode: undefined,
        createRootView: undefined,
        createEmbeddedView: undefined,
        createComponentView: undefined,
        createNgModuleRef: undefined,
        overrideProvider: undefined,
        overrideComponentView: undefined,
        clearOverrides: undefined,
        checkAndUpdateView: undefined,
        checkNoChangesView: undefined,
        destroyView: undefined,
        resolveDep: undefined,
        createDebugContext: undefined,
        handleEvent: undefined,
        updateDirectives: undefined,
        updateRenderer: undefined,
        dirtyParentQueries: undefined,
    };

    /**
     * @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
     */
    var NOOP = function () { };
    var _tokenKeyCache = new Map();
    function tokenKey(token) {
        var key = _tokenKeyCache.get(token);
        if (!key) {
            key = stringify(token) + '_' + _tokenKeyCache.size;
            _tokenKeyCache.set(token, key);
        }
        return key;
    }
    function unwrapValue(view, nodeIdx, bindingIdx, value) {
        if (WrappedValue.isWrapped(value)) {
            value = WrappedValue.unwrap(value);
            var globalBindingIdx = view.def.nodes[nodeIdx].bindingIndex + bindingIdx;
            var oldValue = WrappedValue.unwrap(view.oldValues[globalBindingIdx]);
            view.oldValues[globalBindingIdx] = new WrappedValue(oldValue);
        }
        return value;
    }
    var UNDEFINED_RENDERER_TYPE_ID = '$$undefined';
    var EMPTY_RENDERER_TYPE_ID = '$$empty';
    // Attention: this function is called as top level function.
    // Putting any logic in here will destroy closure tree shaking!
    function createRendererType2(values) {
        return {
            id: UNDEFINED_RENDERER_TYPE_ID,
            styles: values.styles,
            encapsulation: values.encapsulation,
            data: values.data
        };
    }
    var _renderCompCount$1 = 0;
    function resolveRendererType2(type) {
        if (type && type.id === UNDEFINED_RENDERER_TYPE_ID) {
            // first time we see this RendererType2. Initialize it...
            var isFilled = ((type.encapsulation != null && type.encapsulation !== exports.ViewEncapsulation.None) ||
                type.styles.length || Object.keys(type.data).length);
            if (isFilled) {
                type.id = "c" + _renderCompCount$1++;
            }
            else {
                type.id = EMPTY_RENDERER_TYPE_ID;
            }
        }
        if (type && type.id === EMPTY_RENDERER_TYPE_ID) {
            type = null;
        }
        return type || null;
    }
    function checkBinding(view, def, bindingIdx, value) {
        var oldValues = view.oldValues;
        if ((view.state & 2 /* FirstCheck */) ||
            !looseIdentical(oldValues[def.bindingIndex + bindingIdx], value)) {
            return true;
        }
        return false;
    }
    function checkAndUpdateBinding(view, def, bindingIdx, value) {
        if (checkBinding(view, def, bindingIdx, value)) {
            view.oldValues[def.bindingIndex + bindingIdx] = value;
            return true;
        }
        return false;
    }
    function checkBindingNoChanges(view, def, bindingIdx, value) {
        var oldValue = view.oldValues[def.bindingIndex + bindingIdx];
        if ((view.state & 1 /* BeforeFirstCheck */) || !devModeEqual$1(oldValue, value)) {
            var bindingName = def.bindings[bindingIdx].name;
            throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, def.nodeIndex), bindingName + ": " + oldValue, bindingName + ": " + value, (view.state & 1 /* BeforeFirstCheck */) !== 0);
        }
    }
    function markParentViewsForCheck(view) {
        var currView = view;
        while (currView) {
            if (currView.def.flags & 2 /* OnPush */) {
                currView.state |= 8 /* ChecksEnabled */;
            }
            currView = currView.viewContainerParent || currView.parent;
        }
    }
    function markParentViewsForCheckProjectedViews(view, endView) {
        var currView = view;
        while (currView && currView !== endView) {
            currView.state |= 64 /* CheckProjectedViews */;
            currView = currView.viewContainerParent || currView.parent;
        }
    }
    function dispatchEvent(view, nodeIndex, eventName, event) {
        try {
            var nodeDef = view.def.nodes[nodeIndex];
            var startView = nodeDef.flags & 33554432 /* ComponentView */ ?
                asElementData(view, nodeIndex).componentView :
                view;
            markParentViewsForCheck(startView);
            return Services.handleEvent(view, nodeIndex, eventName, event);
        }
        catch (e) {
            // Attention: Don't rethrow, as it would cancel Observable subscriptions!
            view.root.errorHandler.handleError(e);
        }
    }
    function declaredViewContainer(view) {
        if (view.parent) {
            var parentView = view.parent;
            return asElementData(parentView, view.parentNodeDef.nodeIndex);
        }
        return null;
    }
    /**
     * for component views, this is the host element.
     * for embedded views, this is the index of the parent node
     * that contains the view container.
     */
    function viewParentEl(view) {
        var parentView = view.parent;
        if (parentView) {
            return view.parentNodeDef.parent;
        }
        else {
            return null;
        }
    }
    function renderNode(view, def) {
        switch (def.flags & 201347067 /* Types */) {
            case 1 /* TypeElement */:
                return asElementData(view, def.nodeIndex).renderElement;
            case 2 /* TypeText */:
                return asTextData(view, def.nodeIndex).renderText;
        }
    }
    function elementEventFullName(target, name) {
        return target ? target + ":" + name : name;
    }
    function isComponentView(view) {
        return !!view.parent && !!(view.parentNodeDef.flags & 32768 /* Component */);
    }
    function isEmbeddedView(view) {
        return !!view.parent && !(view.parentNodeDef.flags & 32768 /* Component */);
    }
    function filterQueryId(queryId) {
        return 1 << (queryId % 32);
    }
    function splitMatchedQueriesDsl(matchedQueriesDsl) {
        var matchedQueries = {};
        var matchedQueryIds = 0;
        var references = {};
        if (matchedQueriesDsl) {
            matchedQueriesDsl.forEach(function (_a) {
                var _b = __read(_a, 2), queryId = _b[0], valueType = _b[1];
                if (typeof queryId === 'number') {
                    matchedQueries[queryId] = valueType;
                    matchedQueryIds |= filterQueryId(queryId);
                }
                else {
                    references[queryId] = valueType;
                }
            });
        }
        return { matchedQueries: matchedQueries, references: references, matchedQueryIds: matchedQueryIds };
    }
    function splitDepsDsl(deps, sourceName) {
        return deps.map(function (value) {
            var _a;
            var token;
            var flags;
            if (Array.isArray(value)) {
                _a = __read(value, 2), flags = _a[0], token = _a[1];
            }
            else {
                flags = 0 /* None */;
                token = value;
            }
            if (token && (typeof token === 'function' || typeof token === 'object') && sourceName) {
                Object.defineProperty(token, SOURCE, { value: sourceName, configurable: true });
            }
            return { flags: flags, token: token, tokenKey: tokenKey(token) };
        });
    }
    function getParentRenderElement(view, renderHost, def) {
        var renderParent = def.renderParent;
        if (renderParent) {
            if ((renderParent.flags & 1 /* TypeElement */) === 0 ||
                (renderParent.flags & 33554432 /* ComponentView */) === 0 ||
                (renderParent.element.componentRendererType &&
                    renderParent.element.componentRendererType.encapsulation ===
                        exports.ViewEncapsulation.Native)) {
                // only children of non components, or children of components with native encapsulation should
                // be attached.
                return asElementData(view, def.renderParent.nodeIndex).renderElement;
            }
        }
        else {
            return renderHost;
        }
    }
    var DEFINITION_CACHE = new WeakMap();
    function resolveDefinition(factory) {
        var value = DEFINITION_CACHE.get(factory);
        if (!value) {
            value = factory(function () { return NOOP; });
            value.factory = factory;
            DEFINITION_CACHE.set(factory, value);
        }
        return value;
    }
    function rootRenderNodes(view) {
        var renderNodes = [];
        visitRootRenderNodes(view, 0 /* Collect */, undefined, undefined, renderNodes);
        return renderNodes;
    }
    function visitRootRenderNodes(view, action, parentNode, nextSibling, target) {
        // We need to re-compute the parent node in case the nodes have been moved around manually
        if (action === 3 /* RemoveChild */) {
            parentNode = view.renderer.parentNode(renderNode(view, view.def.lastRenderRootNode));
        }
        visitSiblingRenderNodes(view, action, 0, view.def.nodes.length - 1, parentNode, nextSibling, target);
    }
    function visitSiblingRenderNodes(view, action, startIndex, endIndex, parentNode, nextSibling, target) {
        for (var i = startIndex; i <= endIndex; i++) {
            var nodeDef = view.def.nodes[i];
            if (nodeDef.flags & (1 /* TypeElement */ | 2 /* TypeText */ | 8 /* TypeNgContent */)) {
                visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target);
            }
            // jump to next sibling
            i += nodeDef.childCount;
        }
    }
    function visitProjectedRenderNodes(view, ngContentIndex, action, parentNode, nextSibling, target) {
        var compView = view;
        while (compView && !isComponentView(compView)) {
            compView = compView.parent;
        }
        var hostView = compView.parent;
        var hostElDef = viewParentEl(compView);
        var startIndex = hostElDef.nodeIndex + 1;
        var endIndex = hostElDef.nodeIndex + hostElDef.childCount;
        for (var i = startIndex; i <= endIndex; i++) {
            var nodeDef = hostView.def.nodes[i];
            if (nodeDef.ngContentIndex === ngContentIndex) {
                visitRenderNode(hostView, nodeDef, action, parentNode, nextSibling, target);
            }
            // jump to next sibling
            i += nodeDef.childCount;
        }
        if (!hostView.parent) {
            // a root view
            var projectedNodes = view.root.projectableNodes[ngContentIndex];
            if (projectedNodes) {
                for (var i = 0; i < projectedNodes.length; i++) {
                    execRenderNodeAction(view, projectedNodes[i], action, parentNode, nextSibling, target);
                }
            }
        }
    }
    function visitRenderNode(view, nodeDef, action, parentNode, nextSibling, target) {
        if (nodeDef.flags & 8 /* TypeNgContent */) {
            visitProjectedRenderNodes(view, nodeDef.ngContent.index, action, parentNode, nextSibling, target);
        }
        else {
            var rn = renderNode(view, nodeDef);
            if (action === 3 /* RemoveChild */ && (nodeDef.flags & 33554432 /* ComponentView */) &&
                (nodeDef.bindingFlags & 48 /* CatSyntheticProperty */)) {
                // Note: we might need to do both actions.
                if (nodeDef.bindingFlags & (16 /* SyntheticProperty */)) {
                    execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
                }
                if (nodeDef.bindingFlags & (32 /* SyntheticHostProperty */)) {
                    var compView = asElementData(view, nodeDef.nodeIndex).componentView;
                    execRenderNodeAction(compView, rn, action, parentNode, nextSibling, target);
                }
            }
            else {
                execRenderNodeAction(view, rn, action, parentNode, nextSibling, target);
            }
            if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
                var embeddedViews = asElementData(view, nodeDef.nodeIndex).viewContainer._embeddedViews;
                for (var k = 0; k < embeddedViews.length; k++) {
                    visitRootRenderNodes(embeddedViews[k], action, parentNode, nextSibling, target);
                }
            }
            if (nodeDef.flags & 1 /* TypeElement */ && !nodeDef.element.name) {
                visitSiblingRenderNodes(view, action, nodeDef.nodeIndex + 1, nodeDef.nodeIndex + nodeDef.childCount, parentNode, nextSibling, target);
            }
        }
    }
    function execRenderNodeAction(view, renderNode, action, parentNode, nextSibling, target) {
        var renderer = view.renderer;
        switch (action) {
            case 1 /* AppendChild */:
                renderer.appendChild(parentNode, renderNode);
                break;
            case 2 /* InsertBefore */:
                renderer.insertBefore(parentNode, renderNode, nextSibling);
                break;
            case 3 /* RemoveChild */:
                renderer.removeChild(parentNode, renderNode);
                break;
            case 0 /* Collect */:
                target.push(renderNode);
                break;
        }
    }
    var NS_PREFIX_RE = /^:([^:]+):(.+)$/;
    function splitNamespace(name) {
        if (name[0] === ':') {
            var match = name.match(NS_PREFIX_RE);
            return [match[1], match[2]];
        }
        return ['', name];
    }
    function calcBindingFlags(bindings) {
        var flags = 0;
        for (var i = 0; i < bindings.length; i++) {
            flags |= bindings[i].flags;
        }
        return flags;
    }
    function interpolate(valueCount, constAndInterp) {
        var result = '';
        for (var i = 0; i < valueCount * 2; i = i + 2) {
            result = result + constAndInterp[i] + _toStringWithNull(constAndInterp[i + 1]);
        }
        return result + constAndInterp[valueCount * 2];
    }
    function inlineInterpolate(valueCount, c0, a1, c1, a2, c2, a3, c3, a4, c4, a5, c5, a6, c6, a7, c7, a8, c8, a9, c9) {
        switch (valueCount) {
            case 1:
                return c0 + _toStringWithNull(a1) + c1;
            case 2:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2;
            case 3:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                    c3;
            case 4:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                    c3 + _toStringWithNull(a4) + c4;
            case 5:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                    c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5;
            case 6:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                    c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) + c6;
            case 7:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                    c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
                    c6 + _toStringWithNull(a7) + c7;
            case 8:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                    c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
                    c6 + _toStringWithNull(a7) + c7 + _toStringWithNull(a8) + c8;
            case 9:
                return c0 + _toStringWithNull(a1) + c1 + _toStringWithNull(a2) + c2 + _toStringWithNull(a3) +
                    c3 + _toStringWithNull(a4) + c4 + _toStringWithNull(a5) + c5 + _toStringWithNull(a6) +
                    c6 + _toStringWithNull(a7) + c7 + _toStringWithNull(a8) + c8 + _toStringWithNull(a9) + c9;
            default:
                throw new Error("Does not support more than 9 expressions");
        }
    }
    function _toStringWithNull(v) {
        return v != null ? v.toString() : '';
    }
    var EMPTY_ARRAY$3 = [];
    var EMPTY_MAP = {};

    /**
     * @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
     */
    var UNDEFINED_VALUE = new Object();
    var InjectorRefTokenKey = tokenKey(Injector);
    var INJECTORRefTokenKey = tokenKey(INJECTOR);
    var NgModuleRefTokenKey = tokenKey(NgModuleRef);
    function moduleProvideDef(flags, token, value, deps) {
        // Need to resolve forwardRefs as e.g. for `useValue` we
        // lowered the expression and then stopped evaluating it,
        // i.e. also didn't unwrap it.
        value = resolveForwardRef(value);
        var depDefs = splitDepsDsl(deps, stringify(token));
        return {
            // will bet set by the module definition
            index: -1,
            deps: depDefs, flags: flags, token: token, value: value
        };
    }
    function moduleDef(providers) {
        var providersByKey = {};
        var modules = [];
        var isRoot = false;
        for (var i = 0; i < providers.length; i++) {
            var provider = providers[i];
            if (provider.token === APP_ROOT && provider.value === true) {
                isRoot = true;
            }
            if (provider.flags & 1073741824 /* TypeNgModule */) {
                modules.push(provider.token);
            }
            provider.index = i;
            providersByKey[tokenKey(provider.token)] = provider;
        }
        return {
            // Will be filled later...
            factory: null,
            providersByKey: providersByKey,
            providers: providers,
            modules: modules,
            isRoot: isRoot,
        };
    }
    function initNgModule(data) {
        var def = data._def;
        var providers = data._providers = new Array(def.providers.length);
        for (var i = 0; i < def.providers.length; i++) {
            var provDef = def.providers[i];
            if (!(provDef.flags & 4096 /* LazyProvider */)) {
                // Make sure the provider has not been already initialized outside this loop.
                if (providers[i] === undefined) {
                    providers[i] = _createProviderInstance(data, provDef);
                }
            }
        }
    }
    function resolveNgModuleDep(data, depDef, notFoundValue) {
        if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
        var former = setCurrentInjector(data);
        try {
            if (depDef.flags & 8 /* Value */) {
                return depDef.token;
            }
            if (depDef.flags & 2 /* Optional */) {
                notFoundValue = null;
            }
            if (depDef.flags & 1 /* SkipSelf */) {
                return data._parent.get(depDef.token, notFoundValue);
            }
            var tokenKey_1 = depDef.tokenKey;
            switch (tokenKey_1) {
                case InjectorRefTokenKey:
                case INJECTORRefTokenKey:
                case NgModuleRefTokenKey:
                    return data;
            }
            var providerDef = data._def.providersByKey[tokenKey_1];
            var injectableDef = void 0;
            if (providerDef) {
                var providerInstance = data._providers[providerDef.index];
                if (providerInstance === undefined) {
                    providerInstance = data._providers[providerDef.index] =
                        _createProviderInstance(data, providerDef);
                }
                return providerInstance === UNDEFINED_VALUE ? undefined : providerInstance;
            }
            else if ((injectableDef = getInjectableDef(depDef.token)) && targetsModule(data, injectableDef)) {
                var index = data._providers.length;
                data._def.providers[index] = data._def.providersByKey[depDef.tokenKey] = {
                    flags: 1024 /* TypeFactoryProvider */ | 4096 /* LazyProvider */,
                    value: injectableDef.factory,
                    deps: [], index: index,
                    token: depDef.token,
                };
                data._providers[index] = UNDEFINED_VALUE;
                return (data._providers[index] =
                    _createProviderInstance(data, data._def.providersByKey[depDef.tokenKey]));
            }
            else if (depDef.flags & 4 /* Self */) {
                return notFoundValue;
            }
            return data._parent.get(depDef.token, notFoundValue);
        }
        finally {
            setCurrentInjector(former);
        }
    }
    function moduleTransitivelyPresent(ngModule, scope) {
        return ngModule._def.modules.indexOf(scope) > -1;
    }
    function targetsModule(ngModule, def) {
        return def.providedIn != null && (moduleTransitivelyPresent(ngModule, def.providedIn) ||
            def.providedIn === 'root' && ngModule._def.isRoot);
    }
    function _createProviderInstance(ngModule, providerDef) {
        var injectable;
        switch (providerDef.flags & 201347067 /* Types */) {
            case 512 /* TypeClassProvider */:
                injectable = _createClass(ngModule, providerDef.value, providerDef.deps);
                break;
            case 1024 /* TypeFactoryProvider */:
                injectable = _callFactory(ngModule, providerDef.value, providerDef.deps);
                break;
            case 2048 /* TypeUseExistingProvider */:
                injectable = resolveNgModuleDep(ngModule, providerDef.deps[0]);
                break;
            case 256 /* TypeValueProvider */:
                injectable = providerDef.value;
                break;
        }
        // The read of `ngOnDestroy` here is slightly expensive as it's megamorphic, so it should be
        // avoided if possible. The sequence of checks here determines whether ngOnDestroy needs to be
        // checked. It might not if the `injectable` isn't an object or if NodeFlags.OnDestroy is already
        // set (ngOnDestroy was detected statically).
        if (injectable !== UNDEFINED_VALUE && injectable !== null && typeof injectable === 'object' &&
            !(providerDef.flags & 131072 /* OnDestroy */) && typeof injectable.ngOnDestroy === 'function') {
            providerDef.flags |= 131072 /* OnDestroy */;
        }
        return injectable === undefined ? UNDEFINED_VALUE : injectable;
    }
    function _createClass(ngModule, ctor, deps) {
        var len = deps.length;
        switch (len) {
            case 0:
                return new ctor();
            case 1:
                return new ctor(resolveNgModuleDep(ngModule, deps[0]));
            case 2:
                return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
            case 3:
                return new ctor(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
            default:
                var depValues = new Array(len);
                for (var i = 0; i < len; i++) {
                    depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
                }
                return new (ctor.bind.apply(ctor, __spread([void 0], depValues)))();
        }
    }
    function _callFactory(ngModule, factory, deps) {
        var len = deps.length;
        switch (len) {
            case 0:
                return factory();
            case 1:
                return factory(resolveNgModuleDep(ngModule, deps[0]));
            case 2:
                return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]));
            case 3:
                return factory(resolveNgModuleDep(ngModule, deps[0]), resolveNgModuleDep(ngModule, deps[1]), resolveNgModuleDep(ngModule, deps[2]));
            default:
                var depValues = Array(len);
                for (var i = 0; i < len; i++) {
                    depValues[i] = resolveNgModuleDep(ngModule, deps[i]);
                }
                return factory.apply(void 0, __spread(depValues));
        }
    }
    function callNgModuleLifecycle(ngModule, lifecycles) {
        var def = ngModule._def;
        var destroyed = new Set();
        for (var i = 0; i < def.providers.length; i++) {
            var provDef = def.providers[i];
            if (provDef.flags & 131072 /* OnDestroy */) {
                var instance = ngModule._providers[i];
                if (instance && instance !== UNDEFINED_VALUE) {
                    var onDestroy = instance.ngOnDestroy;
                    if (typeof onDestroy === 'function' && !destroyed.has(instance)) {
                        onDestroy.apply(instance);
                        destroyed.add(instance);
                    }
                }
            }
        }
    }

    /**
     * @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
     */
    function attachEmbeddedView(parentView, elementData, viewIndex, view) {
        var embeddedViews = elementData.viewContainer._embeddedViews;
        if (viewIndex === null || viewIndex === undefined) {
            viewIndex = embeddedViews.length;
        }
        view.viewContainerParent = parentView;
        addToArray(embeddedViews, viewIndex, view);
        attachProjectedView(elementData, view);
        Services.dirtyParentQueries(view);
        var prevView = viewIndex > 0 ? embeddedViews[viewIndex - 1] : null;
        renderAttachEmbeddedView(elementData, prevView, view);
    }
    function attachProjectedView(vcElementData, view) {
        var dvcElementData = declaredViewContainer(view);
        if (!dvcElementData || dvcElementData === vcElementData ||
            view.state & 16 /* IsProjectedView */) {
            return;
        }
        // Note: For performance reasons, we
        // - add a view to template._projectedViews only 1x throughout its lifetime,
        //   and remove it not until the view is destroyed.
        //   (hard, as when a parent view is attached/detached we would need to attach/detach all
        //    nested projected views as well, even across component boundaries).
        // - don't track the insertion order of views in the projected views array
        //   (hard, as when the views of the same template are inserted different view containers)
        view.state |= 16 /* IsProjectedView */;
        var projectedViews = dvcElementData.template._projectedViews;
        if (!projectedViews) {
            projectedViews = dvcElementData.template._projectedViews = [];
        }
        projectedViews.push(view);
        // Note: we are changing the NodeDef here as we cannot calculate
        // the fact whether a template is used for projection during compilation.
        markNodeAsProjectedTemplate(view.parent.def, view.parentNodeDef);
    }
    function markNodeAsProjectedTemplate(viewDef, nodeDef) {
        if (nodeDef.flags & 4 /* ProjectedTemplate */) {
            return;
        }
        viewDef.nodeFlags |= 4 /* ProjectedTemplate */;
        nodeDef.flags |= 4 /* ProjectedTemplate */;
        var parentNodeDef = nodeDef.parent;
        while (parentNodeDef) {
            parentNodeDef.childFlags |= 4 /* ProjectedTemplate */;
            parentNodeDef = parentNodeDef.parent;
        }
    }
    function detachEmbeddedView(elementData, viewIndex) {
        var embeddedViews = elementData.viewContainer._embeddedViews;
        if (viewIndex == null || viewIndex >= embeddedViews.length) {
            viewIndex = embeddedViews.length - 1;
        }
        if (viewIndex < 0) {
            return null;
        }
        var view = embeddedViews[viewIndex];
        view.viewContainerParent = null;
        removeFromArray(embeddedViews, viewIndex);
        // See attachProjectedView for why we don't update projectedViews here.
        Services.dirtyParentQueries(view);
        renderDetachView$1(view);
        return view;
    }
    function detachProjectedView(view) {
        if (!(view.state & 16 /* IsProjectedView */)) {
            return;
        }
        var dvcElementData = declaredViewContainer(view);
        if (dvcElementData) {
            var projectedViews = dvcElementData.template._projectedViews;
            if (projectedViews) {
                removeFromArray(projectedViews, projectedViews.indexOf(view));
                Services.dirtyParentQueries(view);
            }
        }
    }
    function moveEmbeddedView(elementData, oldViewIndex, newViewIndex) {
        var embeddedViews = elementData.viewContainer._embeddedViews;
        var view = embeddedViews[oldViewIndex];
        removeFromArray(embeddedViews, oldViewIndex);
        if (newViewIndex == null) {
            newViewIndex = embeddedViews.length;
        }
        addToArray(embeddedViews, newViewIndex, view);
        // Note: Don't need to change projectedViews as the order in there
        // as always invalid...
        Services.dirtyParentQueries(view);
        renderDetachView$1(view);
        var prevView = newViewIndex > 0 ? embeddedViews[newViewIndex - 1] : null;
        renderAttachEmbeddedView(elementData, prevView, view);
        return view;
    }
    function renderAttachEmbeddedView(elementData, prevView, view) {
        var prevRenderNode = prevView ? renderNode(prevView, prevView.def.lastRenderRootNode) :
            elementData.renderElement;
        var parentNode = view.renderer.parentNode(prevRenderNode);
        var nextSibling = view.renderer.nextSibling(prevRenderNode);
        // Note: We can't check if `nextSibling` is present, as on WebWorkers it will always be!
        // However, browsers automatically do `appendChild` when there is no `nextSibling`.
        visitRootRenderNodes(view, 2 /* InsertBefore */, parentNode, nextSibling, undefined);
    }
    function renderDetachView$1(view) {
        visitRootRenderNodes(view, 3 /* RemoveChild */, null, null, undefined);
    }

    /**
     * @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
     */
    var EMPTY_CONTEXT = new Object();
    // Attention: this function is called as top level function.
    // Putting any logic in here will destroy closure tree shaking!
    function createComponentFactory(selector, componentType, viewDefFactory, inputs, outputs, ngContentSelectors) {
        return new ComponentFactory_(selector, componentType, viewDefFactory, inputs, outputs, ngContentSelectors);
    }
    function getComponentViewDefinitionFactory(componentFactory) {
        return componentFactory.viewDefFactory;
    }
    var ComponentFactory_ = /** @class */ (function (_super) {
        __extends(ComponentFactory_, _super);
        function ComponentFactory_(selector, componentType, viewDefFactory, _inputs, _outputs, ngContentSelectors) {
            var _this = 
            // Attention: this ctor is called as top level function.
            // Putting any logic in here will destroy closure tree shaking!
            _super.call(this) || this;
            _this.selector = selector;
            _this.componentType = componentType;
            _this._inputs = _inputs;
            _this._outputs = _outputs;
            _this.ngContentSelectors = ngContentSelectors;
            _this.viewDefFactory = viewDefFactory;
            return _this;
        }
        Object.defineProperty(ComponentFactory_.prototype, "inputs", {
            get: function () {
                var inputsArr = [];
                var inputs = this._inputs;
                for (var propName in inputs) {
                    var templateName = inputs[propName];
                    inputsArr.push({ propName: propName, templateName: templateName });
                }
                return inputsArr;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ComponentFactory_.prototype, "outputs", {
            get: function () {
                var outputsArr = [];
                for (var propName in this._outputs) {
                    var templateName = this._outputs[propName];
                    outputsArr.push({ propName: propName, templateName: templateName });
                }
                return outputsArr;
            },
            enumerable: true,
            configurable: true
        });
        /**
         * Creates a new component.
         */
        ComponentFactory_.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
            if (!ngModule) {
                throw new Error('ngModule should be provided');
            }
            var viewDef = resolveDefinition(this.viewDefFactory);
            var componentNodeIndex = viewDef.nodes[0].element.componentProvider.nodeIndex;
            var view = Services.createRootView(injector, projectableNodes || [], rootSelectorOrNode, viewDef, ngModule, EMPTY_CONTEXT);
            var component = asProviderData(view, componentNodeIndex).instance;
            if (rootSelectorOrNode) {
                view.renderer.setAttribute(asElementData(view, 0).renderElement, 'ng-version', VERSION.full);
            }
            return new ComponentRef_(view, new ViewRef_(view), component);
        };
        return ComponentFactory_;
    }(ComponentFactory));
    var ComponentRef_ = /** @class */ (function (_super) {
        __extends(ComponentRef_, _super);
        function ComponentRef_(_view, _viewRef, _component) {
            var _this = _super.call(this) || this;
            _this._view = _view;
            _this._viewRef = _viewRef;
            _this._component = _component;
            _this._elDef = _this._view.def.nodes[0];
            _this.hostView = _viewRef;
            _this.changeDetectorRef = _viewRef;
            _this.instance = _component;
            return _this;
        }
        Object.defineProperty(ComponentRef_.prototype, "location", {
            get: function () {
                return new ElementRef(asElementData(this._view, this._elDef.nodeIndex).renderElement);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ComponentRef_.prototype, "injector", {
            get: function () { return new Injector_(this._view, this._elDef); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ComponentRef_.prototype, "componentType", {
            get: function () { return this._component.constructor; },
            enumerable: true,
            configurable: true
        });
        ComponentRef_.prototype.destroy = function () { this._viewRef.destroy(); };
        ComponentRef_.prototype.onDestroy = function (callback) { this._viewRef.onDestroy(callback); };
        return ComponentRef_;
    }(ComponentRef));
    function createViewContainerData(view, elDef, elData) {
        return new ViewContainerRef_(view, elDef, elData);
    }
    var ViewContainerRef_ = /** @class */ (function () {
        function ViewContainerRef_(_view, _elDef, _data) {
            this._view = _view;
            this._elDef = _elDef;
            this._data = _data;
            /**
             * @internal
             */
            this._embeddedViews = [];
        }
        Object.defineProperty(ViewContainerRef_.prototype, "element", {
            get: function () { return new ElementRef(this._data.renderElement); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ViewContainerRef_.prototype, "injector", {
            get: function () { return new Injector_(this._view, this._elDef); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ViewContainerRef_.prototype, "parentInjector", {
            /** @deprecated No replacement */
            get: function () {
                var view = this._view;
                var elDef = this._elDef.parent;
                while (!elDef && view) {
                    elDef = viewParentEl(view);
                    view = view.parent;
                }
                return view ? new Injector_(view, elDef) : new Injector_(this._view, null);
            },
            enumerable: true,
            configurable: true
        });
        ViewContainerRef_.prototype.clear = function () {
            var len = this._embeddedViews.length;
            for (var i = len - 1; i >= 0; i--) {
                var view = detachEmbeddedView(this._data, i);
                Services.destroyView(view);
            }
        };
        ViewContainerRef_.prototype.get = function (index) {
            var view = this._embeddedViews[index];
            if (view) {
                var ref = new ViewRef_(view);
                ref.attachToViewContainerRef(this);
                return ref;
            }
            return null;
        };
        Object.defineProperty(ViewContainerRef_.prototype, "length", {
            get: function () { return this._embeddedViews.length; },
            enumerable: true,
            configurable: true
        });
        ViewContainerRef_.prototype.createEmbeddedView = function (templateRef, context, index) {
            var viewRef = templateRef.createEmbeddedView(context || {});
            this.insert(viewRef, index);
            return viewRef;
        };
        ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes, ngModuleRef) {
            var contextInjector = injector || this.parentInjector;
            if (!ngModuleRef && !(componentFactory instanceof ComponentFactoryBoundToModule)) {
                ngModuleRef = contextInjector.get(NgModuleRef);
            }
            var componentRef = componentFactory.create(contextInjector, projectableNodes, undefined, ngModuleRef);
            this.insert(componentRef.hostView, index);
            return componentRef;
        };
        ViewContainerRef_.prototype.insert = function (viewRef, index) {
            if (viewRef.destroyed) {
                throw new Error('Cannot insert a destroyed View in a ViewContainer!');
            }
            var viewRef_ = viewRef;
            var viewData = viewRef_._view;
            attachEmbeddedView(this._view, this._data, index, viewData);
            viewRef_.attachToViewContainerRef(this);
            return viewRef;
        };
        ViewContainerRef_.prototype.move = function (viewRef, currentIndex) {
            if (viewRef.destroyed) {
                throw new Error('Cannot move a destroyed View in a ViewContainer!');
            }
            var previousIndex = this._embeddedViews.indexOf(viewRef._view);
            moveEmbeddedView(this._data, previousIndex, currentIndex);
            return viewRef;
        };
        ViewContainerRef_.prototype.indexOf = function (viewRef) {
            return this._embeddedViews.indexOf(viewRef._view);
        };
        ViewContainerRef_.prototype.remove = function (index) {
            var viewData = detachEmbeddedView(this._data, index);
            if (viewData) {
                Services.destroyView(viewData);
            }
        };
        ViewContainerRef_.prototype.detach = function (index) {
            var view = detachEmbeddedView(this._data, index);
            return view ? new ViewRef_(view) : null;
        };
        return ViewContainerRef_;
    }());
    function createChangeDetectorRef(view) {
        return new ViewRef_(view);
    }
    var ViewRef_ = /** @class */ (function () {
        function ViewRef_(_view) {
            this._view = _view;
            this._viewContainerRef = null;
            this._appRef = null;
        }
        Object.defineProperty(ViewRef_.prototype, "rootNodes", {
            get: function () { return rootRenderNodes(this._view); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ViewRef_.prototype, "context", {
            get: function () { return this._view.context; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ViewRef_.prototype, "destroyed", {
            get: function () { return (this._view.state & 128 /* Destroyed */) !== 0; },
            enumerable: true,
            configurable: true
        });
        ViewRef_.prototype.markForCheck = function () { markParentViewsForCheck(this._view); };
        ViewRef_.prototype.detach = function () { this._view.state &= ~4 /* Attached */; };
        ViewRef_.prototype.detectChanges = function () {
            var fs = this._view.root.rendererFactory;
            if (fs.begin) {
                fs.begin();
            }
            try {
                Services.checkAndUpdateView(this._view);
            }
            finally {
                if (fs.end) {
                    fs.end();
                }
            }
        };
        ViewRef_.prototype.checkNoChanges = function () { Services.checkNoChangesView(this._view); };
        ViewRef_.prototype.reattach = function () { this._view.state |= 4 /* Attached */; };
        ViewRef_.prototype.onDestroy = function (callback) {
            if (!this._view.disposables) {
                this._view.disposables = [];
            }
            this._view.disposables.push(callback);
        };
        ViewRef_.prototype.destroy = function () {
            if (this._appRef) {
                this._appRef.detachView(this);
            }
            else if (this._viewContainerRef) {
                this._viewContainerRef.detach(this._viewContainerRef.indexOf(this));
            }
            Services.destroyView(this._view);
        };
        ViewRef_.prototype.detachFromAppRef = function () {
            this._appRef = null;
            renderDetachView$1(this._view);
            Services.dirtyParentQueries(this._view);
        };
        ViewRef_.prototype.attachToAppRef = function (appRef) {
            if (this._viewContainerRef) {
                throw new Error('This view is already attached to a ViewContainer!');
            }
            this._appRef = appRef;
        };
        ViewRef_.prototype.attachToViewContainerRef = function (vcRef) {
            if (this._appRef) {
                throw new Error('This view is already attached directly to the ApplicationRef!');
            }
            this._viewContainerRef = vcRef;
        };
        return ViewRef_;
    }());
    function createTemplateData(view, def) {
        return new TemplateRef_(view, def);
    }
    var TemplateRef_ = /** @class */ (function (_super) {
        __extends(TemplateRef_, _super);
        function TemplateRef_(_parentView, _def) {
            var _this = _super.call(this) || this;
            _this._parentView = _parentView;
            _this._def = _def;
            return _this;
        }
        TemplateRef_.prototype.createEmbeddedView = function (context) {
            return new ViewRef_(Services.createEmbeddedView(this._parentView, this._def, this._def.element.template, context));
        };
        Object.defineProperty(TemplateRef_.prototype, "elementRef", {
            get: function () {
                return new ElementRef(asElementData(this._parentView, this._def.nodeIndex).renderElement);
            },
            enumerable: true,
            configurable: true
        });
        return TemplateRef_;
    }(TemplateRef));
    function createInjector$1(view, elDef) {
        return new Injector_(view, elDef);
    }
    var Injector_ = /** @class */ (function () {
        function Injector_(view, elDef) {
            this.view = view;
            this.elDef = elDef;
        }
        Injector_.prototype.get = function (token, notFoundValue) {
            if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
            var allowPrivateServices = this.elDef ? (this.elDef.flags & 33554432 /* ComponentView */) !== 0 : false;
            return Services.resolveDep(this.view, this.elDef, allowPrivateServices, { flags: 0 /* None */, token: token, tokenKey: tokenKey(token) }, notFoundValue);
        };
        return Injector_;
    }());
    function nodeValue(view, index) {
        var def = view.def.nodes[index];
        if (def.flags & 1 /* TypeElement */) {
            var elData = asElementData(view, def.nodeIndex);
            return def.element.template ? elData.template : elData.renderElement;
        }
        else if (def.flags & 2 /* TypeText */) {
            return asTextData(view, def.nodeIndex).renderText;
        }
        else if (def.flags & (20224 /* CatProvider */ | 16 /* TypePipe */)) {
            return asProviderData(view, def.nodeIndex).instance;
        }
        throw new Error("Illegal state: read nodeValue for node index " + index);
    }
    function createRendererV1(view) {
        return new RendererAdapter(view.renderer);
    }
    var RendererAdapter = /** @class */ (function () {
        function RendererAdapter(delegate) {
            this.delegate = delegate;
        }
        RendererAdapter.prototype.selectRootElement = function (selectorOrNode) {
            return this.delegate.selectRootElement(selectorOrNode);
        };
        RendererAdapter.prototype.createElement = function (parent, namespaceAndName) {
            var _a = __read(splitNamespace(namespaceAndName), 2), ns = _a[0], name = _a[1];
            var el = this.delegate.createElement(name, ns);
            if (parent) {
                this.delegate.appendChild(parent, el);
            }
            return el;
        };
        RendererAdapter.prototype.createViewRoot = function (hostElement) { return hostElement; };
        RendererAdapter.prototype.createTemplateAnchor = function (parentElement) {
            var comment = this.delegate.createComment('');
            if (parentElement) {
                this.delegate.appendChild(parentElement, comment);
            }
            return comment;
        };
        RendererAdapter.prototype.createText = function (parentElement, value) {
            var node = this.delegate.createText(value);
            if (parentElement) {
                this.delegate.appendChild(parentElement, node);
            }
            return node;
        };
        RendererAdapter.prototype.projectNodes = function (parentElement, nodes) {
            for (var i = 0; i < nodes.length; i++) {
                this.delegate.appendChild(parentElement, nodes[i]);
            }
        };
        RendererAdapter.prototype.attachViewAfter = function (node, viewRootNodes) {
            var parentElement = this.delegate.parentNode(node);
            var nextSibling = this.delegate.nextSibling(node);
            for (var i = 0; i < viewRootNodes.length; i++) {
                this.delegate.insertBefore(parentElement, viewRootNodes[i], nextSibling);
            }
        };
        RendererAdapter.prototype.detachView = function (viewRootNodes) {
            for (var i = 0; i < viewRootNodes.length; i++) {
                var node = viewRootNodes[i];
                var parentElement = this.delegate.parentNode(node);
                this.delegate.removeChild(parentElement, node);
            }
        };
        RendererAdapter.prototype.destroyView = function (hostElement, viewAllNodes) {
            for (var i = 0; i < viewAllNodes.length; i++) {
                this.delegate.destroyNode(viewAllNodes[i]);
            }
        };
        RendererAdapter.prototype.listen = function (renderElement, name, callback) {
            return this.delegate.listen(renderElement, name, callback);
        };
        RendererAdapter.prototype.listenGlobal = function (target, name, callback) {
            return this.delegate.listen(target, name, callback);
        };
        RendererAdapter.prototype.setElementProperty = function (renderElement, propertyName, propertyValue) {
            this.delegate.setProperty(renderElement, propertyName, propertyValue);
        };
        RendererAdapter.prototype.setElementAttribute = function (renderElement, namespaceAndName, attributeValue) {
            var _a = __read(splitNamespace(namespaceAndName), 2), ns = _a[0], name = _a[1];
            if (attributeValue != null) {
                this.delegate.setAttribute(renderElement, name, attributeValue, ns);
            }
            else {
                this.delegate.removeAttribute(renderElement, name, ns);
            }
        };
        RendererAdapter.prototype.setBindingDebugInfo = function (renderElement, propertyName, propertyValue) { };
        RendererAdapter.prototype.setElementClass = function (renderElement, className, isAdd) {
            if (isAdd) {
                this.delegate.addClass(renderElement, className);
            }
            else {
                this.delegate.removeClass(renderElement, className);
            }
        };
        RendererAdapter.prototype.setElementStyle = function (renderElement, styleName, styleValue) {
            if (styleValue != null) {
                this.delegate.setStyle(renderElement, styleName, styleValue);
            }
            else {
                this.delegate.removeStyle(renderElement, styleName);
            }
        };
        RendererAdapter.prototype.invokeElementMethod = function (renderElement, methodName, args) {
            renderElement[methodName].apply(renderElement, args);
        };
        RendererAdapter.prototype.setText = function (renderNode, text) { this.delegate.setValue(renderNode, text); };
        RendererAdapter.prototype.animate = function () { throw new Error('Renderer.animate is no longer supported!'); };
        return RendererAdapter;
    }());
    function createNgModuleRef(moduleType, parent, bootstrapComponents, def) {
        return new NgModuleRef_(moduleType, parent, bootstrapComponents, def);
    }
    var NgModuleRef_ = /** @class */ (function () {
        function NgModuleRef_(_moduleType, _parent, _bootstrapComponents, _def) {
            this._moduleType = _moduleType;
            this._parent = _parent;
            this._bootstrapComponents = _bootstrapComponents;
            this._def = _def;
            this._destroyListeners = [];
            this._destroyed = false;
            this.injector = this;
            initNgModule(this);
        }
        NgModuleRef_.prototype.get = function (token, notFoundValue, injectFlags) {
            if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
            if (injectFlags === void 0) { injectFlags = exports.InjectFlags.Default; }
            var flags = 0 /* None */;
            if (injectFlags & exports.InjectFlags.SkipSelf) {
                flags |= 1 /* SkipSelf */;
            }
            else if (injectFlags & exports.InjectFlags.Self) {
                flags |= 4 /* Self */;
            }
            return resolveNgModuleDep(this, { token: token, tokenKey: tokenKey(token), flags: flags }, notFoundValue);
        };
        Object.defineProperty(NgModuleRef_.prototype, "instance", {
            get: function () { return this.get(this._moduleType); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(NgModuleRef_.prototype, "componentFactoryResolver", {
            get: function () { return this.get(ComponentFactoryResolver); },
            enumerable: true,
            configurable: true
        });
        NgModuleRef_.prototype.destroy = function () {
            if (this._destroyed) {
                throw new Error("The ng module " + stringify(this.instance.constructor) + " has already been destroyed.");
            }
            this._destroyed = true;
            callNgModuleLifecycle(this, 131072 /* OnDestroy */);
            this._destroyListeners.forEach(function (listener) { return listener(); });
        };
        NgModuleRef_.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
        return NgModuleRef_;
    }());

    /**
     * @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
     */
    var RendererV1TokenKey = tokenKey(Renderer);
    var Renderer2TokenKey = tokenKey(Renderer2);
    var ElementRefTokenKey = tokenKey(ElementRef);
    var ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
    var TemplateRefTokenKey = tokenKey(TemplateRef);
    var ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
    var InjectorRefTokenKey$1 = tokenKey(Injector);
    var INJECTORRefTokenKey$1 = tokenKey(INJECTOR);
    function directiveDef(checkIndex, flags, matchedQueries, childCount, ctor, deps, props, outputs) {
        var bindings = [];
        if (props) {
            for (var prop in props) {
                var _a = __read(props[prop], 2), bindingIndex = _a[0], nonMinifiedName = _a[1];
                bindings[bindingIndex] = {
                    flags: 8 /* TypeProperty */,
                    name: prop, nonMinifiedName: nonMinifiedName,
                    ns: null,
                    securityContext: null,
                    suffix: null
                };
            }
        }
        var outputDefs = [];
        if (outputs) {
            for (var propName in outputs) {
                outputDefs.push({ type: 1 /* DirectiveOutput */, propName: propName, target: null, eventName: outputs[propName] });
            }
        }
        flags |= 16384 /* TypeDirective */;
        return _def(checkIndex, flags, matchedQueries, childCount, ctor, ctor, deps, bindings, outputDefs);
    }
    function pipeDef(flags, ctor, deps) {
        flags |= 16 /* TypePipe */;
        return _def(-1, flags, null, 0, ctor, ctor, deps);
    }
    function providerDef(flags, matchedQueries, token, value, deps) {
        return _def(-1, flags, matchedQueries, 0, token, value, deps);
    }
    function _def(checkIndex, flags, matchedQueriesDsl, childCount, token, value, deps, bindings, outputs) {
        var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
        if (!outputs) {
            outputs = [];
        }
        if (!bindings) {
            bindings = [];
        }
        // Need to resolve forwardRefs as e.g. for `useValue` we
        // lowered the expression and then stopped evaluating it,
        // i.e. also didn't unwrap it.
        value = resolveForwardRef(value);
        var depDefs = splitDepsDsl(deps, stringify(token));
        return {
            // will bet set by the view definition
            nodeIndex: -1,
            parent: null,
            renderParent: null,
            bindingIndex: -1,
            outputIndex: -1,
            // regular values
            checkIndex: checkIndex,
            flags: flags,
            childFlags: 0,
            directChildFlags: 0,
            childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references,
            ngContentIndex: -1, childCount: childCount, bindings: bindings,
            bindingFlags: calcBindingFlags(bindings), outputs: outputs,
            element: null,
            provider: { token: token, value: value, deps: depDefs },
            text: null,
            query: null,
            ngContent: null
        };
    }
    function createProviderInstance(view, def) {
        return _createProviderInstance$1(view, def);
    }
    function createPipeInstance(view, def) {
        // deps are looked up from component.
        var compView = view;
        while (compView.parent && !isComponentView(compView)) {
            compView = compView.parent;
        }
        // pipes can see the private services of the component
        var allowPrivateServices = true;
        // pipes are always eager and classes!
        return createClass(compView.parent, viewParentEl(compView), allowPrivateServices, def.provider.value, def.provider.deps);
    }
    function createDirectiveInstance(view, def) {
        // components can see other private services, other directives can't.
        var allowPrivateServices = (def.flags & 32768 /* Component */) > 0;
        // directives are always eager and classes!
        var instance = createClass(view, def.parent, allowPrivateServices, def.provider.value, def.provider.deps);
        if (def.outputs.length) {
            for (var i = 0; i < def.outputs.length; i++) {
                var output = def.outputs[i];
                var outputObservable = instance[output.propName];
                if (isObservable(outputObservable)) {
                    var subscription = outputObservable.subscribe(eventHandlerClosure(view, def.parent.nodeIndex, output.eventName));
                    view.disposables[def.outputIndex + i] = subscription.unsubscribe.bind(subscription);
                }
                else {
                    throw new Error("@Output " + output.propName + " not initialized in '" + instance.constructor.name + "'.");
                }
            }
        }
        return instance;
    }
    function eventHandlerClosure(view, index, eventName) {
        return function (event) { return dispatchEvent(view, index, eventName, event); };
    }
    function checkAndUpdateDirectiveInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        var providerData = asProviderData(view, def.nodeIndex);
        var directive = providerData.instance;
        var changed = false;
        var changes = undefined;
        var bindLen = def.bindings.length;
        if (bindLen > 0 && checkBinding(view, def, 0, v0)) {
            changed = true;
            changes = updateProp(view, providerData, def, 0, v0, changes);
        }
        if (bindLen > 1 && checkBinding(view, def, 1, v1)) {
            changed = true;
            changes = updateProp(view, providerData, def, 1, v1, changes);
        }
        if (bindLen > 2 && checkBinding(view, def, 2, v2)) {
            changed = true;
            changes = updateProp(view, providerData, def, 2, v2, changes);
        }
        if (bindLen > 3 && checkBinding(view, def, 3, v3)) {
            changed = true;
            changes = updateProp(view, providerData, def, 3, v3, changes);
        }
        if (bindLen > 4 && checkBinding(view, def, 4, v4)) {
            changed = true;
            changes = updateProp(view, providerData, def, 4, v4, changes);
        }
        if (bindLen > 5 && checkBinding(view, def, 5, v5)) {
            changed = true;
            changes = updateProp(view, providerData, def, 5, v5, changes);
        }
        if (bindLen > 6 && checkBinding(view, def, 6, v6)) {
            changed = true;
            changes = updateProp(view, providerData, def, 6, v6, changes);
        }
        if (bindLen > 7 && checkBinding(view, def, 7, v7)) {
            changed = true;
            changes = updateProp(view, providerData, def, 7, v7, changes);
        }
        if (bindLen > 8 && checkBinding(view, def, 8, v8)) {
            changed = true;
            changes = updateProp(view, providerData, def, 8, v8, changes);
        }
        if (bindLen > 9 && checkBinding(view, def, 9, v9)) {
            changed = true;
            changes = updateProp(view, providerData, def, 9, v9, changes);
        }
        if (changes) {
            directive.ngOnChanges(changes);
        }
        if ((def.flags & 65536 /* OnInit */) &&
            shouldCallLifecycleInitHook(view, 256 /* InitState_CallingOnInit */, def.nodeIndex)) {
            directive.ngOnInit();
        }
        if (def.flags & 262144 /* DoCheck */) {
            directive.ngDoCheck();
        }
        return changed;
    }
    function checkAndUpdateDirectiveDynamic(view, def, values) {
        var providerData = asProviderData(view, def.nodeIndex);
        var directive = providerData.instance;
        var changed = false;
        var changes = undefined;
        for (var i = 0; i < values.length; i++) {
            if (checkBinding(view, def, i, values[i])) {
                changed = true;
                changes = updateProp(view, providerData, def, i, values[i], changes);
            }
        }
        if (changes) {
            directive.ngOnChanges(changes);
        }
        if ((def.flags & 65536 /* OnInit */) &&
            shouldCallLifecycleInitHook(view, 256 /* InitState_CallingOnInit */, def.nodeIndex)) {
            directive.ngOnInit();
        }
        if (def.flags & 262144 /* DoCheck */) {
            directive.ngDoCheck();
        }
        return changed;
    }
    function _createProviderInstance$1(view, def) {
        // private services can see other private services
        var allowPrivateServices = (def.flags & 8192 /* PrivateProvider */) > 0;
        var providerDef = def.provider;
        switch (def.flags & 201347067 /* Types */) {
            case 512 /* TypeClassProvider */:
                return createClass(view, def.parent, allowPrivateServices, providerDef.value, providerDef.deps);
            case 1024 /* TypeFactoryProvider */:
                return callFactory(view, def.parent, allowPrivateServices, providerDef.value, providerDef.deps);
            case 2048 /* TypeUseExistingProvider */:
                return resolveDep(view, def.parent, allowPrivateServices, providerDef.deps[0]);
            case 256 /* TypeValueProvider */:
                return providerDef.value;
        }
    }
    function createClass(view, elDef, allowPrivateServices, ctor, deps) {
        var len = deps.length;
        switch (len) {
            case 0:
                return new ctor();
            case 1:
                return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]));
            case 2:
                return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
            case 3:
                return new ctor(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
            default:
                var depValues = new Array(len);
                for (var i = 0; i < len; i++) {
                    depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
                }
                return new (ctor.bind.apply(ctor, __spread([void 0], depValues)))();
        }
    }
    function callFactory(view, elDef, allowPrivateServices, factory, deps) {
        var len = deps.length;
        switch (len) {
            case 0:
                return factory();
            case 1:
                return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]));
            case 2:
                return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]));
            case 3:
                return factory(resolveDep(view, elDef, allowPrivateServices, deps[0]), resolveDep(view, elDef, allowPrivateServices, deps[1]), resolveDep(view, elDef, allowPrivateServices, deps[2]));
            default:
                var depValues = Array(len);
                for (var i = 0; i < len; i++) {
                    depValues[i] = resolveDep(view, elDef, allowPrivateServices, deps[i]);
                }
                return factory.apply(void 0, __spread(depValues));
        }
    }
    // This default value is when checking the hierarchy for a token.
    //
    // It means both:
    // - the token is not provided by the current injector,
    // - only the element injectors should be checked (ie do not check module injectors
    //
    //          mod1
    //         /
    //       el1   mod2
    //         \  /
    //         el2
    //
    // When requesting el2.injector.get(token), we should check in the following order and return the
    // first found value:
    // - el2.injector.get(token, default)
    // - el1.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) -> do not check the module
    // - mod2.injector.get(token, default)
    var NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};
    function resolveDep(view, elDef, allowPrivateServices, depDef, notFoundValue) {
        if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
        if (depDef.flags & 8 /* Value */) {
            return depDef.token;
        }
        var startView = view;
        if (depDef.flags & 2 /* Optional */) {
            notFoundValue = null;
        }
        var tokenKey = depDef.tokenKey;
        if (tokenKey === ChangeDetectorRefTokenKey) {
            // directives on the same element as a component should be able to control the change detector
            // of that component as well.
            allowPrivateServices = !!(elDef && elDef.element.componentView);
        }
        if (elDef && (depDef.flags & 1 /* SkipSelf */)) {
            allowPrivateServices = false;
            elDef = elDef.parent;
        }
        var searchView = view;
        while (searchView) {
            if (elDef) {
                switch (tokenKey) {
                    case RendererV1TokenKey: {
                        var compView = findCompView(searchView, elDef, allowPrivateServices);
                        return createRendererV1(compView);
                    }
                    case Renderer2TokenKey: {
                        var compView = findCompView(searchView, elDef, allowPrivateServices);
                        return compView.renderer;
                    }
                    case ElementRefTokenKey:
                        return new ElementRef(asElementData(searchView, elDef.nodeIndex).renderElement);
                    case ViewContainerRefTokenKey:
                        return asElementData(searchView, elDef.nodeIndex).viewContainer;
                    case TemplateRefTokenKey: {
                        if (elDef.element.template) {
                            return asElementData(searchView, elDef.nodeIndex).template;
                        }
                        break;
                    }
                    case ChangeDetectorRefTokenKey: {
                        var cdView = findCompView(searchView, elDef, allowPrivateServices);
                        return createChangeDetectorRef(cdView);
                    }
                    case InjectorRefTokenKey$1:
                    case INJECTORRefTokenKey$1:
                        return createInjector$1(searchView, elDef);
                    default:
                        var providerDef_1 = (allowPrivateServices ? elDef.element.allProviders :
                            elDef.element.publicProviders)[tokenKey];
                        if (providerDef_1) {
                            var providerData = asProviderData(searchView, providerDef_1.nodeIndex);
                            if (!providerData) {
                                providerData = { instance: _createProviderInstance$1(searchView, providerDef_1) };
                                searchView.nodes[providerDef_1.nodeIndex] = providerData;
                            }
                            return providerData.instance;
                        }
                }
            }
            allowPrivateServices = isComponentView(searchView);
            elDef = viewParentEl(searchView);
            searchView = searchView.parent;
            if (depDef.flags & 4 /* Self */) {
                searchView = null;
            }
        }
        var value = startView.root.injector.get(depDef.token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR);
        if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
            notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
            // Return the value from the root element injector when
            // - it provides it
            //   (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
            // - the module injector should not be checked
            //   (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
            return value;
        }
        return startView.root.ngModule.injector.get(depDef.token, notFoundValue);
    }
    function findCompView(view, elDef, allowPrivateServices) {
        var compView;
        if (allowPrivateServices) {
            compView = asElementData(view, elDef.nodeIndex).componentView;
        }
        else {
            compView = view;
            while (compView.parent && !isComponentView(compView)) {
                compView = compView.parent;
            }
        }
        return compView;
    }
    function updateProp(view, providerData, def, bindingIdx, value, changes) {
        if (def.flags & 32768 /* Component */) {
            var compView = asElementData(view, def.parent.nodeIndex).componentView;
            if (compView.def.flags & 2 /* OnPush */) {
                compView.state |= 8 /* ChecksEnabled */;
            }
        }
        var binding = def.bindings[bindingIdx];
        var propName = binding.name;
        // Note: This is still safe with Closure Compiler as
        // the user passed in the property name as an object has to `providerDef`,
        // so Closure Compiler will have renamed the property correctly already.
        providerData.instance[propName] = value;
        if (def.flags & 524288 /* OnChanges */) {
            changes = changes || {};
            var oldValue = WrappedValue.unwrap(view.oldValues[def.bindingIndex + bindingIdx]);
            var binding_1 = def.bindings[bindingIdx];
            changes[binding_1.nonMinifiedName] =
                new SimpleChange(oldValue, value, (view.state & 2 /* FirstCheck */) !== 0);
        }
        view.oldValues[def.bindingIndex + bindingIdx] = value;
        return changes;
    }
    // This function calls the ngAfterContentCheck, ngAfterContentInit,
    // ngAfterViewCheck, and ngAfterViewInit lifecycle hooks (depending on the node
    // flags in lifecycle). Unlike ngDoCheck, ngOnChanges and ngOnInit, which are
    // called during a pre-order traversal of the view tree (that is calling the
    // parent hooks before the child hooks) these events are sent in using a
    // post-order traversal of the tree (children before parents). This changes the
    // meaning of initIndex in the view state. For ngOnInit, initIndex tracks the
    // expected nodeIndex which a ngOnInit should be called. When sending
    // ngAfterContentInit and ngAfterViewInit it is the expected count of
    // ngAfterContentInit or ngAfterViewInit methods that have been called. This
    // ensure that despite being called recursively or after picking up after an
    // exception, the ngAfterContentInit or ngAfterViewInit will be called on the
    // correct nodes. Consider for example, the following (where E is an element
    // and D is a directive)
    //  Tree:       pre-order index  post-order index
    //    E1        0                6
    //      E2      1                1
    //       D3     2                0
    //      E4      3                5
    //       E5     4                4
    //        E6    5                2
    //        E7    6                3
    // As can be seen, the post-order index has an unclear relationship to the
    // pre-order index (postOrderIndex === preOrderIndex - parentCount +
    // childCount). Since number of calls to ngAfterContentInit and ngAfterViewInit
    // are stable (will be the same for the same view regardless of exceptions or
    // recursion) we just need to count them which will roughly correspond to the
    // post-order index (it skips elements and directives that do not have
    // lifecycle hooks).
    //
    // For example, if an exception is raised in the E6.onAfterViewInit() the
    // initIndex is left at 3 (by shouldCallLifecycleInitHook() which set it to
    // initIndex + 1). When checkAndUpdateView() is called again D3, E2 and E6 will
    // not have their ngAfterViewInit() called but, starting with E7, the rest of
    // the view will begin getting ngAfterViewInit() called until a check and
    // pass is complete.
    //
    // This algorthim also handles recursion. Consider if E4's ngAfterViewInit()
    // indirectly calls E1's ChangeDetectorRef.detectChanges(). The expected
    // initIndex is set to 6, the recusive checkAndUpdateView() starts walk again.
    // D3, E2, E6, E7, E5 and E4 are skipped, ngAfterViewInit() is called on E1.
    // When the recursion returns the initIndex will be 7 so E1 is skipped as it
    // has already been called in the recursively called checkAnUpdateView().
    function callLifecycleHooksChildrenFirst(view, lifecycles) {
        if (!(view.def.nodeFlags & lifecycles)) {
            return;
        }
        var nodes = view.def.nodes;
        var initIndex = 0;
        for (var i = 0; i < nodes.length; i++) {
            var nodeDef = nodes[i];
            var parent_1 = nodeDef.parent;
            if (!parent_1 && nodeDef.flags & lifecycles) {
                // matching root node (e.g. a pipe)
                callProviderLifecycles(view, i, nodeDef.flags & lifecycles, initIndex++);
            }
            if ((nodeDef.childFlags & lifecycles) === 0) {
                // no child matches one of the lifecycles
                i += nodeDef.childCount;
            }
            while (parent_1 && (parent_1.flags & 1 /* TypeElement */) &&
                i === parent_1.nodeIndex + parent_1.childCount) {
                // last child of an element
                if (parent_1.directChildFlags & lifecycles) {
                    initIndex = callElementProvidersLifecycles(view, parent_1, lifecycles, initIndex);
                }
                parent_1 = parent_1.parent;
            }
        }
    }
    function callElementProvidersLifecycles(view, elDef, lifecycles, initIndex) {
        for (var i = elDef.nodeIndex + 1; i <= elDef.nodeIndex + elDef.childCount; i++) {
            var nodeDef = view.def.nodes[i];
            if (nodeDef.flags & lifecycles) {
                callProviderLifecycles(view, i, nodeDef.flags & lifecycles, initIndex++);
            }
            // only visit direct children
            i += nodeDef.childCount;
        }
        return initIndex;
    }
    function callProviderLifecycles(view, index, lifecycles, initIndex) {
        var providerData = asProviderData(view, index);
        if (!providerData) {
            return;
        }
        var provider = providerData.instance;
        if (!provider) {
            return;
        }
        Services.setCurrentNode(view, index);
        if (lifecycles & 1048576 /* AfterContentInit */ &&
            shouldCallLifecycleInitHook(view, 512 /* InitState_CallingAfterContentInit */, initIndex)) {
            provider.ngAfterContentInit();
        }
        if (lifecycles & 2097152 /* AfterContentChecked */) {
            provider.ngAfterContentChecked();
        }
        if (lifecycles & 4194304 /* AfterViewInit */ &&
            shouldCallLifecycleInitHook(view, 768 /* InitState_CallingAfterViewInit */, initIndex)) {
            provider.ngAfterViewInit();
        }
        if (lifecycles & 8388608 /* AfterViewChecked */) {
            provider.ngAfterViewChecked();
        }
        if (lifecycles & 131072 /* OnDestroy */) {
            provider.ngOnDestroy();
        }
    }

    /**
     * @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
     */
    var ComponentFactoryResolver$1 = /** @class */ (function (_super) {
        __extends(ComponentFactoryResolver, _super);
        /**
         * @param ngModule The NgModuleRef to which all resolved factories are bound.
         */
        function ComponentFactoryResolver(ngModule) {
            var _this = _super.call(this) || this;
            _this.ngModule = ngModule;
            return _this;
        }
        ComponentFactoryResolver.prototype.resolveComponentFactory = function (component) {
            ngDevMode && assertComponentType(component);
            var componentDef = getComponentDef(component);
            return new ComponentFactory$1(componentDef, this.ngModule);
        };
        return ComponentFactoryResolver;
    }(ComponentFactoryResolver));
    function toRefArray(map) {
        var array = [];
        for (var nonMinified in map) {
            if (map.hasOwnProperty(nonMinified)) {
                var minified = map[nonMinified];
                array.push({ propName: minified, templateName: nonMinified });
            }
        }
        return array;
    }
    /**
     * A change detection scheduler token for {@link RootContext}. This token is the default value used
     * for the default `RootContext` found in the {@link ROOT_CONTEXT} token.
     */
    var SCHEDULER = new InjectionToken('SCHEDULER_TOKEN', {
        providedIn: 'root',
        factory: function () { return defaultScheduler; },
    });
    function createChainedInjector(rootViewInjector, moduleInjector) {
        return {
            get: function (token, notFoundValue, flags) {
                var value = rootViewInjector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, flags);
                if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR ||
                    notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
                    // Return the value from the root element injector when
                    // - it provides it
                    //   (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
                    // - the module injector should not be checked
                    //   (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
                    return value;
                }
                return moduleInjector.get(token, notFoundValue, flags);
            }
        };
    }
    /**
     * Render3 implementation of {@link viewEngine_ComponentFactory}.
     */
    var ComponentFactory$1 = /** @class */ (function (_super) {
        __extends(ComponentFactory, _super);
        /**
         * @param componentDef The component definition.
         * @param ngModule The NgModuleRef to which the factory is bound.
         */
        function ComponentFactory(componentDef, ngModule) {
            var _this = _super.call(this) || this;
            _this.componentDef = componentDef;
            _this.ngModule = ngModule;
            _this.componentType = componentDef.type;
            // default to 'div' in case this component has an attribute selector
            _this.selector = componentDef.selectors[0][0] || 'div';
            _this.ngContentSelectors =
                componentDef.ngContentSelectors ? componentDef.ngContentSelectors : [];
            _this.isBoundToModule = !!ngModule;
            return _this;
        }
        Object.defineProperty(ComponentFactory.prototype, "inputs", {
            get: function () {
                return toRefArray(this.componentDef.inputs);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(ComponentFactory.prototype, "outputs", {
            get: function () {
                return toRefArray(this.componentDef.outputs);
            },
            enumerable: true,
            configurable: true
        });
        ComponentFactory.prototype.create = function (injector, projectableNodes, rootSelectorOrNode, ngModule) {
            ngModule = ngModule || this.ngModule;
            var rootViewInjector = ngModule ? createChainedInjector(injector, ngModule.injector) : injector;
            var rendererFactory = rootViewInjector.get(RendererFactory2, domRendererFactory3);
            var sanitizer = rootViewInjector.get(Sanitizer, null);
            // Ensure that the namespace for the root node is correct,
            // otherwise the browser might not render out the element properly.
            namespaceHTMLInternal();
            var hostRNode = rootSelectorOrNode ?
                locateHostElement(rendererFactory, rootSelectorOrNode) :
                elementCreate(this.selector, rendererFactory.createRenderer(null, this.componentDef));
            var rootFlags = this.componentDef.onPush ? 64 /* Dirty */ | 512 /* IsRoot */ :
                16 /* CheckAlways */ | 512 /* IsRoot */;
            // Check whether this Component needs to be isolated from other components, i.e. whether it
            // should be placed into its own (empty) root context or existing root context should be used.
            // Note: this is internal-only convention and might change in the future, so it should not be
            // relied upon externally.
            var isIsolated = typeof rootSelectorOrNode === 'string' &&
                /^#root-ng-internal-isolated-\d+/.test(rootSelectorOrNode);
            var rootContext = createRootContext();
            var renderer = rendererFactory.createRenderer(hostRNode, this.componentDef);
            if (rootSelectorOrNode && hostRNode) {
                ngDevMode && ngDevMode.rendererSetAttribute++;
                isProceduralRenderer(renderer) ?
                    renderer.setAttribute(hostRNode, 'ng-version', VERSION.full) :
                    hostRNode.setAttribute('ng-version', VERSION.full);
            }
            // Create the root view. Uses empty TView and ContentTemplate.
            var rootLView = createLView(null, createTView(-1, null, 1, 0, null, null, null, null), rootContext, rootFlags, null, null, rendererFactory, renderer, sanitizer, rootViewInjector);
            // rootView is the parent when bootstrapping
            var oldLView = enterView(rootLView, null);
            var component;
            var tElementNode;
            // Will become true if the `try` block executes with no errors.
            var safeToRunHooks = false;
            try {
                var componentView = createRootComponentView(hostRNode, this.componentDef, rootLView, rendererFactory, renderer);
                tElementNode = getTNode(0, rootLView);
                if (projectableNodes) {
                    // projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
                    // case). Here we do normalize passed data structure to be an array of arrays to avoid
                    // complex checks down the line.
                    tElementNode.projection =
                        projectableNodes.map(function (nodesforSlot) { return Array.from(nodesforSlot); });
                }
                // TODO: should LifecycleHooksFeature and other host features be generated by the compiler and
                // executed here?
                // Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
                component = createRootComponent(componentView, this.componentDef, rootLView, rootContext, [LifecycleHooksFeature]);
                addToViewTree(rootLView, componentView);
                refreshDescendantViews(rootLView);
                safeToRunHooks = true;
            }
            finally {
                leaveView(oldLView, safeToRunHooks);
            }
            var componentRef = new ComponentRef$1(this.componentType, component, createElementRef(ElementRef, tElementNode, rootLView), rootLView, tElementNode);
            if (!rootSelectorOrNode || isIsolated) {
                // The host element of the internal or isolated root view is attached to the component's host
                // view node.
                componentRef.hostView._tViewNode.child = tElementNode;
            }
            return componentRef;
        };
        return ComponentFactory;
    }(ComponentFactory));
    var componentFactoryResolver = new ComponentFactoryResolver$1();
    /**
     * Creates a ComponentFactoryResolver and stores it on the injector. Or, if the
     * ComponentFactoryResolver
     * already exists, retrieves the existing ComponentFactoryResolver.
     *
     * @returns The ComponentFactoryResolver instance to use
     */
    function injectComponentFactoryResolver() {
        return componentFactoryResolver;
    }
    /**
     * Represents an instance of a Component created via a {@link ComponentFactory}.
     *
     * `ComponentRef` provides access to the Component Instance as well other objects related to this
     * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
     * method.
     *
     */
    var ComponentRef$1 = /** @class */ (function (_super) {
        __extends(ComponentRef, _super);
        function ComponentRef(componentType, instance, location, _rootLView, _tNode) {
            var _this = _super.call(this) || this;
            _this.location = location;
            _this._rootLView = _rootLView;
            _this._tNode = _tNode;
            _this.destroyCbs = [];
            _this.instance = instance;
            _this.hostView = _this.changeDetectorRef = new RootViewRef(_rootLView);
            _this.hostView._tViewNode = assignTViewNodeToLView(_rootLView[TVIEW], null, -1, _rootLView);
            _this.componentType = componentType;
            return _this;
        }
        Object.defineProperty(ComponentRef.prototype, "injector", {
            get: function () { return new NodeInjector(this._tNode, this._rootLView); },
            enumerable: true,
            configurable: true
        });
        ComponentRef.prototype.destroy = function () {
            if (this.destroyCbs) {
                this.destroyCbs.forEach(function (fn) { return fn(); });
                this.destroyCbs = null;
                !this.hostView.destroyed && this.hostView.destroy();
            }
        };
        ComponentRef.prototype.onDestroy = function (callback) {
            if (this.destroyCbs) {
                this.destroyCbs.push(callback);
            }
        };
        return ComponentRef;
    }(ComponentRef));

    /**
     * @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
     */
    /**
     * NOTE: changes to the `ngI18nClosureMode` name must be synced with `compiler-cli/src/tooling.ts`.
     */
    if (typeof ngI18nClosureMode === 'undefined') {
        // These property accesses can be ignored because ngI18nClosureMode will be set to false
        // when optimizing code and the whole if statement will be dropped.
        // Make sure to refer to ngI18nClosureMode as ['ngI18nClosureMode'] for closure.
        // NOTE: we need to have it in IIFE so that the tree-shaker is happy.
        (function () {
            // tslint:disable-next-line:no-toplevel-property-access
            _global['ngI18nClosureMode'] =
                // TODO(FW-1250): validate that this actually, you know, works.
                // tslint:disable-next-line:no-toplevel-property-access
                typeof goog !== 'undefined' && typeof goog.getMsg === 'function';
        })();
    }

    /**
     * @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 const is used to store the locale data registered with `registerLocaleData`
     */
    var LOCALE_DATA = {};
    (function (LocaleDataIndex) {
        LocaleDataIndex[LocaleDataIndex["LocaleId"] = 0] = "LocaleId";
        LocaleDataIndex[LocaleDataIndex["DayPeriodsFormat"] = 1] = "DayPeriodsFormat";
        LocaleDataIndex[LocaleDataIndex["DayPeriodsStandalone"] = 2] = "DayPeriodsStandalone";
        LocaleDataIndex[LocaleDataIndex["DaysFormat"] = 3] = "DaysFormat";
        LocaleDataIndex[LocaleDataIndex["DaysStandalone"] = 4] = "DaysStandalone";
        LocaleDataIndex[LocaleDataIndex["MonthsFormat"] = 5] = "MonthsFormat";
        LocaleDataIndex[LocaleDataIndex["MonthsStandalone"] = 6] = "MonthsStandalone";
        LocaleDataIndex[LocaleDataIndex["Eras"] = 7] = "Eras";
        LocaleDataIndex[LocaleDataIndex["FirstDayOfWeek"] = 8] = "FirstDayOfWeek";
        LocaleDataIndex[LocaleDataIndex["WeekendRange"] = 9] = "WeekendRange";
        LocaleDataIndex[LocaleDataIndex["DateFormat"] = 10] = "DateFormat";
        LocaleDataIndex[LocaleDataIndex["TimeFormat"] = 11] = "TimeFormat";
        LocaleDataIndex[LocaleDataIndex["DateTimeFormat"] = 12] = "DateTimeFormat";
        LocaleDataIndex[LocaleDataIndex["NumberSymbols"] = 13] = "NumberSymbols";
        LocaleDataIndex[LocaleDataIndex["NumberFormats"] = 14] = "NumberFormats";
        LocaleDataIndex[LocaleDataIndex["CurrencySymbol"] = 15] = "CurrencySymbol";
        LocaleDataIndex[LocaleDataIndex["CurrencyName"] = 16] = "CurrencyName";
        LocaleDataIndex[LocaleDataIndex["Currencies"] = 17] = "Currencies";
        LocaleDataIndex[LocaleDataIndex["PluralCase"] = 18] = "PluralCase";
        LocaleDataIndex[LocaleDataIndex["ExtraData"] = 19] = "ExtraData";
    })(exports.ɵLocaleDataIndex || (exports.ɵLocaleDataIndex = {}));

    /**
     * @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 CODE IS GENERATED - DO NOT MODIFY
    // See angular/tools/gulp-tasks/cldr/extract.js
    var u = undefined;
    function plural(n) {
        var i = Math.floor(Math.abs(n)), v = n.toString().replace(/^[^.]*\.?/, '').length;
        if (i === 1 && v === 0)
            return 1;
        return 5;
    }
    var localeEn = [
        'en', [['a', 'p'], ['AM', 'PM'], u], [['AM', 'PM'], u, u],
        [
            ['S', 'M', 'T', 'W', 'T', 'F', 'S'], ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
            ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
            ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
        ],
        u,
        [
            ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
            ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
            [
                'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September',
                'October', 'November', 'December'
            ]
        ],
        u, [['B', 'A'], ['BC', 'AD'], ['Before Christ', 'Anno Domini']], 0, [6, 0],
        ['M/d/yy', 'MMM d, y', 'MMMM d, y', 'EEEE, MMMM d, y'],
        ['h:mm a', 'h:mm:ss a', 'h:mm:ss a z', 'h:mm:ss a zzzz'], ['{1}, {0}', u, '{1} \'at\' {0}', u],
        ['.', ',', ';', '%', '+', '-', 'E', '×', '‰', '∞', 'NaN', ':'],
        ['#,##0.###', '#,##0%', '¤#,##0.00', '#E0'], '$', 'US Dollar', {}, plural
    ];

    /**
     * @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
     */
    /**
     * Retrieves the plural function used by ICU expressions to determine the plural case to use
     * for a given locale.
     * @param locale A locale code for the locale format rules to use.
     * @returns The plural function for the locale.
     * @see `NgPlural`
     * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n)
     */
    function getLocalePluralCase(locale) {
        var data = findLocaleData(locale);
        return data[exports.ɵLocaleDataIndex.PluralCase];
    }
    /**
     * Finds the locale data for a given locale.
     *
     * @param locale The locale code.
     * @returns The locale data.
     * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n)
     */
    function findLocaleData(locale) {
        var normalizedLocale = locale.toLowerCase().replace(/_/g, '-');
        var match = LOCALE_DATA[normalizedLocale];
        if (match) {
            return match;
        }
        // let's try to find a parent locale
        var parentLocale = normalizedLocale.split('-')[0];
        match = LOCALE_DATA[parentLocale];
        if (match) {
            return match;
        }
        if (parentLocale === 'en') {
            return localeEn;
        }
        throw new Error("Missing locale data for the locale \"" + locale + "\".");
    }

    /**
     * @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
     */
    /**
     * Returns the plural case based on the locale
     */
    function getPluralCase(value, locale) {
        var plural = getLocalePluralCase(locale)(value);
        switch (plural) {
            case 0:
                return 'zero';
            case 1:
                return 'one';
            case 2:
                return 'two';
            case 3:
                return 'few';
            case 4:
                return 'many';
            default:
                return 'other';
        }
    }
    /**
     * The locale id that the application is using by default (for translations and ICU expressions).
     */
    var DEFAULT_LOCALE_ID = 'en-US';

    /**
     * @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
     */
    var MARKER = "\uFFFD";
    var ICU_BLOCK_REGEXP = /^\s*(�\d+:?\d*�)\s*,\s*(select|plural)\s*,/;
    var SUBTEMPLATE_REGEXP = /�\/?\*(\d+:\d+)�/gi;
    var PH_REGEXP = /�(\/?[#*!]\d+):?\d*�/gi;
    var BINDING_REGEXP = /�(\d+):?\d*�/gi;
    var ICU_REGEXP = /({\s*�\d+:?\d*�\s*,\s*\S{6}\s*,[\s\S]*})/gi;
    // i18nPostprocess consts
    var ROOT_TEMPLATE_ID = 0;
    var PP_MULTI_VALUE_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]/;
    var PP_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]|(�\/?\*\d+:\d+�)/g;
    var PP_ICU_VARS_REGEXP = /({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g;
    var PP_ICU_PLACEHOLDERS_REGEXP = /{([A-Z0-9_]+)}/g;
    var PP_ICUS_REGEXP = /�I18N_EXP_(ICU(_\d+)?)�/g;
    var PP_CLOSE_TEMPLATE_REGEXP = /\/\*/;
    var PP_TEMPLATE_ID_REGEXP = /\d+\:(\d+)/;
    /**
     * Breaks pattern into strings and top level {...} blocks.
     * Can be used to break a message into text and ICU expressions, or to break an ICU expression into
     * keys and cases.
     * Original code from closure library, modified for Angular.
     *
     * @param pattern (sub)Pattern to be broken.
     *
     */
    function extractParts(pattern) {
        if (!pattern) {
            return [];
        }
        var prevPos = 0;
        var braceStack = [];
        var results = [];
        var braces = /[{}]/g;
        // lastIndex doesn't get set to 0 so we have to.
        braces.lastIndex = 0;
        var match;
        while (match = braces.exec(pattern)) {
            var pos = match.index;
            if (match[0] == '}') {
                braceStack.pop();
                if (braceStack.length == 0) {
                    // End of the block.
                    var block = pattern.substring(prevPos, pos);
                    if (ICU_BLOCK_REGEXP.test(block)) {
                        results.push(parseICUBlock(block));
                    }
                    else {
                        results.push(block);
                    }
                    prevPos = pos + 1;
                }
            }
            else {
                if (braceStack.length == 0) {
                    var substring_1 = pattern.substring(prevPos, pos);
                    results.push(substring_1);
                    prevPos = pos + 1;
                }
                braceStack.push('{');
            }
        }
        var substring = pattern.substring(prevPos);
        results.push(substring);
        return results;
    }
    /**
     * Parses text containing an ICU expression and produces a JSON object for it.
     * Original code from closure library, modified for Angular.
     *
     * @param pattern Text containing an ICU expression that needs to be parsed.
     *
     */
    function parseICUBlock(pattern) {
        var cases = [];
        var values = [];
        var icuType = 1 /* plural */;
        var mainBinding = 0;
        pattern = pattern.replace(ICU_BLOCK_REGEXP, function (str, binding, type) {
            if (type === 'select') {
                icuType = 0 /* select */;
            }
            else {
                icuType = 1 /* plural */;
            }
            mainBinding = parseInt(binding.substr(1), 10);
            return '';
        });
        var parts = extractParts(pattern);
        // Looking for (key block)+ sequence. One of the keys has to be "other".
        for (var pos = 0; pos < parts.length;) {
            var key = parts[pos++].trim();
            if (icuType === 1 /* plural */) {
                // Key can be "=x", we just want "x"
                key = key.replace(/\s*(?:=)?(\w+)\s*/, '$1');
            }
            if (key.length) {
                cases.push(key);
            }
            var blocks = extractParts(parts[pos++]);
            if (cases.length > values.length) {
                values.push(blocks);
            }
        }
        assertGreaterThan(cases.indexOf('other'), -1, 'Missing key "other" in ICU statement.');
        // TODO(ocombe): support ICU expressions in attributes, see #21615
        return { type: icuType, mainBinding: mainBinding, cases: cases, values: values };
    }
    /**
     * Removes everything inside the sub-templates of a message.
     */
    function removeInnerTemplateTranslation(message) {
        var match;
        var res = '';
        var index = 0;
        var inTemplate = false;
        var tagMatched;
        while ((match = SUBTEMPLATE_REGEXP.exec(message)) !== null) {
            if (!inTemplate) {
                res += message.substring(index, match.index + match[0].length);
                tagMatched = match[1];
                inTemplate = true;
            }
            else {
                if (match[0] === MARKER + "/*" + tagMatched + MARKER) {
                    index = match.index;
                    inTemplate = false;
                }
            }
        }
        ngDevMode &&
            assertEqual(inTemplate, false, "Tag mismatch: unable to find the end of the sub-template in the translation \"" + message + "\"");
        res += message.substr(index);
        return res;
    }
    /**
     * Extracts a part of a message and removes the rest.
     *
     * This method is used for extracting a part of the message associated with a template. A translated
     * message can span multiple templates.
     *
     * Example:
     * ```
     * <div i18n>Translate <span *ngIf>me</span>!</div>
     * ```
     *
     * @param message The message to crop
     * @param subTemplateIndex Index of the sub-template to extract. If undefined it returns the
     * external template and removes all sub-templates.
     */
    function getTranslationForTemplate(message, subTemplateIndex) {
        if (typeof subTemplateIndex !== 'number') {
            // We want the root template message, ignore all sub-templates
            return removeInnerTemplateTranslation(message);
        }
        else {
            // We want a specific sub-template
            var start = message.indexOf(":" + subTemplateIndex + MARKER) + 2 + subTemplateIndex.toString().length;
            var end = message.search(new RegExp(MARKER + "\\/\\*\\d+:" + subTemplateIndex + MARKER));
            return removeInnerTemplateTranslation(message.substring(start, end));
        }
    }
    /**
     * Generate the OpCodes to update the bindings of a string.
     *
     * @param str The string containing the bindings.
     * @param destinationNode Index of the destination node which will receive the binding.
     * @param attrName Name of the attribute, if the string belongs to an attribute.
     * @param sanitizeFn Sanitization function used to sanitize the string after update, if necessary.
     */
    function generateBindingUpdateOpCodes(str, destinationNode, attrName, sanitizeFn) {
        if (sanitizeFn === void 0) { sanitizeFn = null; }
        var updateOpCodes = [null, null]; // Alloc space for mask and size
        var textParts = str.split(BINDING_REGEXP);
        var mask = 0;
        for (var j = 0; j < textParts.length; j++) {
            var textValue = textParts[j];
            if (j & 1) {
                // Odd indexes are bindings
                var bindingIndex = parseInt(textValue, 10);
                updateOpCodes.push(-1 - bindingIndex);
                mask = mask | toMaskBit(bindingIndex);
            }
            else if (textValue !== '') {
                // Even indexes are text
                updateOpCodes.push(textValue);
            }
        }
        updateOpCodes.push(destinationNode << 2 /* SHIFT_REF */ |
            (attrName ? 1 /* Attr */ : 0 /* Text */));
        if (attrName) {
            updateOpCodes.push(attrName, sanitizeFn);
        }
        updateOpCodes[0] = mask;
        updateOpCodes[1] = updateOpCodes.length - 2;
        return updateOpCodes;
    }
    function getBindingMask(icuExpression, mask) {
        if (mask === void 0) { mask = 0; }
        mask = mask | toMaskBit(icuExpression.mainBinding);
        var match;
        for (var i = 0; i < icuExpression.values.length; i++) {
            var valueArr = icuExpression.values[i];
            for (var j = 0; j < valueArr.length; j++) {
                var value = valueArr[j];
                if (typeof value === 'string') {
                    while (match = BINDING_REGEXP.exec(value)) {
                        mask = mask | toMaskBit(parseInt(match[1], 10));
                    }
                }
                else {
                    mask = getBindingMask(value, mask);
                }
            }
        }
        return mask;
    }
    var i18nIndexStack = [];
    var i18nIndexStackPointer = -1;
    /**
     * Convert binding index to mask bit.
     *
     * Each index represents a single bit on the bit-mask. Because bit-mask only has 32 bits, we make
     * the 32nd bit share all masks for all bindings higher than 32. Since it is extremely rare to have
     * more than 32 bindings this will be hit very rarely. The downside of hitting this corner case is
     * that we will execute binding code more often than necessary. (penalty of performance)
     */
    function toMaskBit(bindingIndex) {
        return 1 << Math.min(bindingIndex, 31);
    }
    var parentIndexStack = [];
    /**
     * Marks a block of text as translatable.
     *
     * The instructions `i18nStart` and `i18nEnd` mark the translation block in the template.
     * The translation `message` is the value which is locale specific. The translation string may
     * contain placeholders which associate inner elements and sub-templates within the translation.
     *
     * The translation `message` placeholders are:
     * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
     *   interpolated into. The placeholder `index` points to the expression binding index. An optional
     *   `block` that matches the sub-template in which it was declared.
     * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*:  Marks the beginning
     *   and end of DOM element that were embedded in the original translation block. The placeholder
     *   `index` points to the element index in the template instructions set. An optional `block` that
     *   matches the sub-template in which it was declared.
     * - `�!{index}(:{block})�`/`�/!{index}(:{block})�`: *Projection Placeholder*:  Marks the
     *   beginning and end of <ng-content> that was embedded in the original translation block.
     *   The placeholder `index` points to the element index in the template instructions set.
     *   An optional `block` that matches the sub-template in which it was declared.
     * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
     *   split up and translated separately in each angular template function. The `index` points to the
     *   `template` instruction index. A `block` that matches the sub-template in which it was declared.
     *
     * @param index A unique index of the translation in the static block.
     * @param message The translation message.
     * @param subTemplateIndex Optional sub-template index in the `message`.
     *
     * @codeGenApi
     */
    function ɵɵi18nStart(index, message, subTemplateIndex) {
        var tView = getLView()[TVIEW];
        ngDevMode && assertDefined(tView, "tView should be defined");
        i18nIndexStack[++i18nIndexStackPointer] = index;
        // We need to delay projections until `i18nEnd`
        setDelayProjection(true);
        if (tView.firstTemplatePass && tView.data[index + HEADER_OFFSET] === null) {
            i18nStartFirstPass(tView, index, message, subTemplateIndex);
        }
    }
    // Count for the number of vars that will be allocated for each i18n block.
    // It is global because this is used in multiple functions that include loops and recursive calls.
    // This is reset to 0 when `i18nStartFirstPass` is called.
    var i18nVarsCount;
    /**
     * See `i18nStart` above.
     */
    function i18nStartFirstPass(tView, index, message, subTemplateIndex) {
        var viewData = getLView();
        var startIndex = tView.blueprint.length - HEADER_OFFSET;
        i18nVarsCount = 0;
        var previousOrParentTNode = getPreviousOrParentTNode();
        var parentTNode = getIsParent() ? getPreviousOrParentTNode() :
            previousOrParentTNode && previousOrParentTNode.parent;
        var parentIndex = parentTNode && parentTNode !== viewData[T_HOST] ? parentTNode.index - HEADER_OFFSET : index;
        var parentIndexPointer = 0;
        parentIndexStack[parentIndexPointer] = parentIndex;
        var createOpCodes = [];
        // If the previous node wasn't the direct parent then we have a translation without top level
        // element and we need to keep a reference of the previous element if there is one
        if (index > 0 && previousOrParentTNode !== parentTNode) {
            // Create an OpCode to select the previous TNode
            createOpCodes.push(previousOrParentTNode.index << 3 /* SHIFT_REF */ | 0 /* Select */);
        }
        var updateOpCodes = [];
        var icuExpressions = [];
        var templateTranslation = getTranslationForTemplate(message, subTemplateIndex);
        var msgParts = replaceNgsp(templateTranslation).split(PH_REGEXP);
        for (var i = 0; i < msgParts.length; i++) {
            var value = msgParts[i];
            if (i & 1) {
                // Odd indexes are placeholders (elements and sub-templates)
                if (value.charAt(0) === '/') {
                    // It is a closing tag
                    if (value.charAt(1) === "#" /* ELEMENT */) {
                        var phIndex = parseInt(value.substr(2), 10);
                        parentIndex = parentIndexStack[--parentIndexPointer];
                        createOpCodes.push(phIndex << 3 /* SHIFT_REF */ | 5 /* ElementEnd */);
                    }
                }
                else {
                    var phIndex = parseInt(value.substr(1), 10);
                    // The value represents a placeholder that we move to the designated index
                    createOpCodes.push(phIndex << 3 /* SHIFT_REF */ | 0 /* Select */, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
                    if (value.charAt(0) === "#" /* ELEMENT */) {
                        parentIndexStack[++parentIndexPointer] = parentIndex = phIndex;
                    }
                }
            }
            else {
                // Even indexes are text (including bindings & ICU expressions)
                var parts = extractParts(value);
                for (var j = 0; j < parts.length; j++) {
                    if (j & 1) {
                        // Odd indexes are ICU expressions
                        // Create the comment node that will anchor the ICU expression
                        var icuNodeIndex = startIndex + i18nVarsCount++;
                        createOpCodes.push(COMMENT_MARKER, ngDevMode ? "ICU " + icuNodeIndex : '', icuNodeIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
                        // Update codes for the ICU expression
                        var icuExpression = parts[j];
                        var mask = getBindingMask(icuExpression);
                        icuStart(icuExpressions, icuExpression, icuNodeIndex, icuNodeIndex);
                        // Since this is recursive, the last TIcu that was pushed is the one we want
                        var tIcuIndex = icuExpressions.length - 1;
                        updateOpCodes.push(toMaskBit(icuExpression.mainBinding), // mask of the main binding
                        3, // skip 3 opCodes if not changed
                        -1 - icuExpression.mainBinding, icuNodeIndex << 2 /* SHIFT_REF */ | 2 /* IcuSwitch */, tIcuIndex, mask, // mask of all the bindings of this ICU expression
                        2, // skip 2 opCodes if not changed
                        icuNodeIndex << 2 /* SHIFT_REF */ | 3 /* IcuUpdate */, tIcuIndex);
                    }
                    else if (parts[j] !== '') {
                        var text = parts[j];
                        // Even indexes are text (including bindings)
                        var hasBinding = text.match(BINDING_REGEXP);
                        // Create text nodes
                        var textNodeIndex = startIndex + i18nVarsCount++;
                        createOpCodes.push(
                        // If there is a binding, the value will be set during update
                        hasBinding ? '' : text, textNodeIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
                        if (hasBinding) {
                            addAllToArray(generateBindingUpdateOpCodes(text, textNodeIndex), updateOpCodes);
                        }
                    }
                }
            }
        }
        if (i18nVarsCount > 0) {
            allocExpando(viewData, i18nVarsCount);
        }
        ngDevMode &&
            attachI18nOpCodesDebug(createOpCodes, updateOpCodes, icuExpressions.length ? icuExpressions : null, viewData);
        // NOTE: local var needed to properly assert the type of `TI18n`.
        var tI18n = {
            vars: i18nVarsCount,
            create: createOpCodes,
            update: updateOpCodes,
            icus: icuExpressions.length ? icuExpressions : null,
        };
        tView.data[index + HEADER_OFFSET] = tI18n;
    }
    function appendI18nNode(tNode, parentTNode, previousTNode, viewData) {
        ngDevMode && ngDevMode.rendererMoveNode++;
        var nextNode = tNode.next;
        if (!previousTNode) {
            previousTNode = parentTNode;
        }
        // Re-organize node tree to put this node in the correct position.
        if (previousTNode === parentTNode && tNode !== parentTNode.child) {
            tNode.next = parentTNode.child;
            parentTNode.child = tNode;
        }
        else if (previousTNode !== parentTNode && tNode !== previousTNode.next) {
            tNode.next = previousTNode.next;
            previousTNode.next = tNode;
        }
        else {
            tNode.next = null;
        }
        if (parentTNode !== viewData[T_HOST]) {
            tNode.parent = parentTNode;
        }
        // If tNode was moved around, we might need to fix a broken link.
        var cursor = tNode.next;
        while (cursor) {
            if (cursor.next === tNode) {
                cursor.next = nextNode;
            }
            cursor = cursor.next;
        }
        // If the placeholder to append is a projection, we need to move the projected nodes instead
        if (tNode.type === 1 /* Projection */) {
            var tProjectionNode = tNode;
            appendProjectedNodes(viewData, tProjectionNode, tProjectionNode.projection, findComponentView(viewData));
            return tNode;
        }
        appendChild(getNativeByTNode(tNode, viewData), tNode, viewData);
        var slotValue = viewData[tNode.index];
        if (tNode.type !== 0 /* Container */ && isLContainer(slotValue)) {
            // Nodes that inject ViewContainerRef also have a comment node that should be moved
            appendChild(slotValue[NATIVE], tNode, viewData);
        }
        return tNode;
    }
    /**
     * Handles message string post-processing for internationalization.
     *
     * Handles message string post-processing by transforming it from intermediate
     * format (that might contain some markers that we need to replace) to the final
     * form, consumable by i18nStart instruction. Post processing steps include:
     *
     * 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
     * 2. Replace all ICU vars (like "VAR_PLURAL")
     * 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
     * 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
     *    in case multiple ICUs have the same placeholder name
     *
     * @param message Raw translation string for post processing
     * @param replacements Set of replacements that should be applied
     *
     * @returns Transformed string that can be consumed by i18nStart instruction
     *
     * @codeGenApi
     */
    function ɵɵi18nPostprocess(message, replacements) {
        if (replacements === void 0) { replacements = {}; }
        /**
         * Step 1: resolve all multi-value placeholders like [�#5�|�*1:1��#2:1�|�#4:1�]
         *
         * Note: due to the way we process nested templates (BFS), multi-value placeholders are typically
         * grouped by templates, for example: [�#5�|�#6�|�#1:1�|�#3:2�] where �#5� and �#6� belong to root
         * template, �#1:1� belong to nested template with index 1 and �#1:2� - nested template with index
         * 3. However in real templates the order might be different: i.e. �#1:1� and/or �#3:2� may go in
         * front of �#6�. The post processing step restores the right order by keeping track of the
         * template id stack and looks for placeholders that belong to the currently active template.
         */
        var result = message;
        if (PP_MULTI_VALUE_PLACEHOLDERS_REGEXP.test(message)) {
            var matches_1 = {};
            var templateIdsStack_1 = [ROOT_TEMPLATE_ID];
            result = result.replace(PP_PLACEHOLDERS_REGEXP, function (m, phs, tmpl) {
                var content = phs || tmpl;
                var placeholders = matches_1[content] || [];
                if (!placeholders.length) {
                    content.split('|').forEach(function (placeholder) {
                        var match = placeholder.match(PP_TEMPLATE_ID_REGEXP);
                        var templateId = match ? parseInt(match[1], 10) : ROOT_TEMPLATE_ID;
                        var isCloseTemplateTag = PP_CLOSE_TEMPLATE_REGEXP.test(placeholder);
                        placeholders.push([templateId, isCloseTemplateTag, placeholder]);
                    });
                    matches_1[content] = placeholders;
                }
                if (!placeholders.length) {
                    throw new Error("i18n postprocess: unmatched placeholder - " + content);
                }
                var currentTemplateId = templateIdsStack_1[templateIdsStack_1.length - 1];
                var idx = 0;
                // find placeholder index that matches current template id
                for (var i = 0; i < placeholders.length; i++) {
                    if (placeholders[i][0] === currentTemplateId) {
                        idx = i;
                        break;
                    }
                }
                // update template id stack based on the current tag extracted
                var _a = __read(placeholders[idx], 3), templateId = _a[0], isCloseTemplateTag = _a[1], placeholder = _a[2];
                if (isCloseTemplateTag) {
                    templateIdsStack_1.pop();
                }
                else if (currentTemplateId !== templateId) {
                    templateIdsStack_1.push(templateId);
                }
                // remove processed tag from the list
                placeholders.splice(idx, 1);
                return placeholder;
            });
        }
        // return current result if no replacements specified
        if (!Object.keys(replacements).length) {
            return result;
        }
        /**
         * Step 2: replace all ICU vars (like "VAR_PLURAL")
         */
        result = result.replace(PP_ICU_VARS_REGEXP, function (match, start, key, _type, _idx, end) {
            return replacements.hasOwnProperty(key) ? "" + start + replacements[key] + end : match;
        });
        /**
         * Step 3: replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
         */
        result = result.replace(PP_ICU_PLACEHOLDERS_REGEXP, function (match, key) {
            return replacements.hasOwnProperty(key) ? replacements[key] : match;
        });
        /**
         * Step 4: replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�) in case
         * multiple ICUs have the same placeholder name
         */
        result = result.replace(PP_ICUS_REGEXP, function (match, key) {
            if (replacements.hasOwnProperty(key)) {
                var list = replacements[key];
                if (!list.length) {
                    throw new Error("i18n postprocess: unmatched ICU - " + match + " with key: " + key);
                }
                return list.shift();
            }
            return match;
        });
        return result;
    }
    /**
     * Translates a translation block marked by `i18nStart` and `i18nEnd`. It inserts the text/ICU nodes
     * into the render tree, moves the placeholder nodes and removes the deleted nodes.
     *
     * @codeGenApi
     */
    function ɵɵi18nEnd() {
        var tView = getLView()[TVIEW];
        ngDevMode && assertDefined(tView, "tView should be defined");
        i18nEndFirstPass(tView);
        // Stop delaying projections
        setDelayProjection(false);
    }
    /**
     * See `i18nEnd` above.
     */
    function i18nEndFirstPass(tView) {
        var viewData = getLView();
        ngDevMode && assertEqual(viewData[BINDING_INDEX], viewData[TVIEW].bindingStartIndex, 'i18nEnd should be called before any binding');
        var rootIndex = i18nIndexStack[i18nIndexStackPointer--];
        var tI18n = tView.data[rootIndex + HEADER_OFFSET];
        ngDevMode && assertDefined(tI18n, "You should call i18nStart before i18nEnd");
        // Find the last node that was added before `i18nEnd`
        var lastCreatedNode = getPreviousOrParentTNode();
        // Read the instructions to insert/move/remove DOM elements
        var visitedNodes = readCreateOpCodes(rootIndex, tI18n.create, tI18n.icus, viewData);
        // Remove deleted nodes
        for (var i = rootIndex + 1; i <= lastCreatedNode.index - HEADER_OFFSET; i++) {
            if (visitedNodes.indexOf(i) === -1) {
                removeNode(i, viewData);
            }
        }
    }
    /**
     * Creates and stores the dynamic TNode, and unhooks it from the tree for now.
     */
    function createDynamicNodeAtIndex(lView, index, type, native, name) {
        var previousOrParentTNode = getPreviousOrParentTNode();
        ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
        lView[index + HEADER_OFFSET] = native;
        var tNode = getOrCreateTNode(lView[TVIEW], lView[T_HOST], index, type, name, null);
        // We are creating a dynamic node, the previous tNode might not be pointing at this node.
        // We will link ourselves into the tree later with `appendI18nNode`.
        if (previousOrParentTNode.next === tNode) {
            previousOrParentTNode.next = null;
        }
        return tNode;
    }
    function readCreateOpCodes(index, createOpCodes, icus, viewData) {
        var renderer = getLView()[RENDERER];
        var currentTNode = null;
        var previousTNode = null;
        var visitedNodes = [];
        for (var i = 0; i < createOpCodes.length; i++) {
            var opCode = createOpCodes[i];
            if (typeof opCode == 'string') {
                var textRNode = createTextNode(opCode, renderer);
                var textNodeIndex = createOpCodes[++i];
                ngDevMode && ngDevMode.rendererCreateTextNode++;
                previousTNode = currentTNode;
                currentTNode =
                    createDynamicNodeAtIndex(viewData, textNodeIndex, 3 /* Element */, textRNode, null);
                visitedNodes.push(textNodeIndex);
                setIsNotParent();
            }
            else if (typeof opCode == 'number') {
                switch (opCode & 7 /* MASK_OPCODE */) {
                    case 1 /* AppendChild */:
                        var destinationNodeIndex = opCode >>> 17 /* SHIFT_PARENT */;
                        var destinationTNode = void 0;
                        if (destinationNodeIndex === index) {
                            // If the destination node is `i18nStart`, we don't have a
                            // top-level node and we should use the host node instead
                            destinationTNode = viewData[T_HOST];
                        }
                        else {
                            destinationTNode = getTNode(destinationNodeIndex, viewData);
                        }
                        ngDevMode &&
                            assertDefined(currentTNode, "You need to create or select a node before you can insert it into the DOM");
                        previousTNode = appendI18nNode(currentTNode, destinationTNode, previousTNode, viewData);
                        break;
                    case 0 /* Select */:
                        var nodeIndex = opCode >>> 3 /* SHIFT_REF */;
                        visitedNodes.push(nodeIndex);
                        previousTNode = currentTNode;
                        currentTNode = getTNode(nodeIndex, viewData);
                        if (currentTNode) {
                            setPreviousOrParentTNode(currentTNode, currentTNode.type === 3 /* Element */);
                        }
                        break;
                    case 5 /* ElementEnd */:
                        var elementIndex = opCode >>> 3 /* SHIFT_REF */;
                        previousTNode = currentTNode = getTNode(elementIndex, viewData);
                        setPreviousOrParentTNode(currentTNode, false);
                        break;
                    case 4 /* Attr */:
                        var elementNodeIndex = opCode >>> 3 /* SHIFT_REF */;
                        var attrName = createOpCodes[++i];
                        var attrValue = createOpCodes[++i];
                        // This code is used for ICU expressions only, since we don't support
                        // directives/components in ICUs, we don't need to worry about inputs here
                        elementAttributeInternal(elementNodeIndex, attrName, attrValue, viewData);
                        break;
                    default:
                        throw new Error("Unable to determine the type of mutate operation for \"" + opCode + "\"");
                }
            }
            else {
                switch (opCode) {
                    case COMMENT_MARKER:
                        var commentValue = createOpCodes[++i];
                        var commentNodeIndex = createOpCodes[++i];
                        ngDevMode && assertEqual(typeof commentValue, 'string', "Expected \"" + commentValue + "\" to be a comment node value");
                        var commentRNode = renderer.createComment(commentValue);
                        ngDevMode && ngDevMode.rendererCreateComment++;
                        previousTNode = currentTNode;
                        currentTNode = createDynamicNodeAtIndex(viewData, commentNodeIndex, 5 /* IcuContainer */, commentRNode, null);
                        visitedNodes.push(commentNodeIndex);
                        attachPatchData(commentRNode, viewData);
                        currentTNode.activeCaseIndex = null;
                        // We will add the case nodes later, during the update phase
                        setIsNotParent();
                        break;
                    case ELEMENT_MARKER:
                        var tagNameValue = createOpCodes[++i];
                        var elementNodeIndex = createOpCodes[++i];
                        ngDevMode && assertEqual(typeof tagNameValue, 'string', "Expected \"" + tagNameValue + "\" to be an element node tag name");
                        var elementRNode = renderer.createElement(tagNameValue);
                        ngDevMode && ngDevMode.rendererCreateElement++;
                        previousTNode = currentTNode;
                        currentTNode = createDynamicNodeAtIndex(viewData, elementNodeIndex, 3 /* Element */, elementRNode, tagNameValue);
                        visitedNodes.push(elementNodeIndex);
                        break;
                    default:
                        throw new Error("Unable to determine the type of mutate operation for \"" + opCode + "\"");
                }
            }
        }
        setIsNotParent();
        return visitedNodes;
    }
    function readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, viewData, bypassCheckBit) {
        if (bypassCheckBit === void 0) { bypassCheckBit = false; }
        var caseCreated = false;
        for (var i = 0; i < updateOpCodes.length; i++) {
            // bit code to check if we should apply the next update
            var checkBit = updateOpCodes[i];
            // Number of opCodes to skip until next set of update codes
            var skipCodes = updateOpCodes[++i];
            if (bypassCheckBit || (checkBit & changeMask)) {
                // The value has been updated since last checked
                var value = '';
                for (var j = i + 1; j <= (i + skipCodes); j++) {
                    var opCode = updateOpCodes[j];
                    if (typeof opCode == 'string') {
                        value += opCode;
                    }
                    else if (typeof opCode == 'number') {
                        if (opCode < 0) {
                            // It's a binding index whose value is negative
                            value += renderStringify(viewData[bindingsStartIndex - opCode]);
                        }
                        else {
                            var nodeIndex = opCode >>> 2 /* SHIFT_REF */;
                            var tIcuIndex = void 0;
                            var tIcu = void 0;
                            var icuTNode = void 0;
                            switch (opCode & 3 /* MASK_OPCODE */) {
                                case 1 /* Attr */:
                                    var propName = updateOpCodes[++j];
                                    var sanitizeFn = updateOpCodes[++j];
                                    elementPropertyInternal(nodeIndex, propName, value, sanitizeFn);
                                    break;
                                case 0 /* Text */:
                                    textBindingInternal(viewData, nodeIndex, value);
                                    break;
                                case 2 /* IcuSwitch */:
                                    tIcuIndex = updateOpCodes[++j];
                                    tIcu = icus[tIcuIndex];
                                    icuTNode = getTNode(nodeIndex, viewData);
                                    // If there is an active case, delete the old nodes
                                    if (icuTNode.activeCaseIndex !== null) {
                                        var removeCodes = tIcu.remove[icuTNode.activeCaseIndex];
                                        for (var k = 0; k < removeCodes.length; k++) {
                                            var removeOpCode = removeCodes[k];
                                            switch (removeOpCode & 7 /* MASK_OPCODE */) {
                                                case 3 /* Remove */:
                                                    var nodeIndex_1 = removeOpCode >>> 3 /* SHIFT_REF */;
                                                    removeNode(nodeIndex_1, viewData);
                                                    break;
                                                case 6 /* RemoveNestedIcu */:
                                                    var nestedIcuNodeIndex = removeCodes[k + 1] >>> 3 /* SHIFT_REF */;
                                                    var nestedIcuTNode = getTNode(nestedIcuNodeIndex, viewData);
                                                    var activeIndex = nestedIcuTNode.activeCaseIndex;
                                                    if (activeIndex !== null) {
                                                        var nestedIcuTIndex = removeOpCode >>> 3 /* SHIFT_REF */;
                                                        var nestedTIcu = icus[nestedIcuTIndex];
                                                        addAllToArray(nestedTIcu.remove[activeIndex], removeCodes);
                                                    }
                                                    break;
                                            }
                                        }
                                    }
                                    // Update the active caseIndex
                                    var caseIndex = getCaseIndex(tIcu, value);
                                    icuTNode.activeCaseIndex = caseIndex !== -1 ? caseIndex : null;
                                    // Add the nodes for the new case
                                    readCreateOpCodes(-1, tIcu.create[caseIndex], icus, viewData);
                                    caseCreated = true;
                                    break;
                                case 3 /* IcuUpdate */:
                                    tIcuIndex = updateOpCodes[++j];
                                    tIcu = icus[tIcuIndex];
                                    icuTNode = getTNode(nodeIndex, viewData);
                                    readUpdateOpCodes(tIcu.update[icuTNode.activeCaseIndex], icus, bindingsStartIndex, changeMask, viewData, caseCreated);
                                    break;
                            }
                        }
                    }
                }
            }
            i += skipCodes;
        }
    }
    function removeNode(index, viewData) {
        var removedPhTNode = getTNode(index, viewData);
        var removedPhRNode = getNativeByIndex(index, viewData);
        if (removedPhRNode) {
            nativeRemoveNode(viewData[RENDERER], removedPhRNode);
        }
        var slotValue = ɵɵload(index);
        if (isLContainer(slotValue)) {
            var lContainer = slotValue;
            if (removedPhTNode.type !== 0 /* Container */) {
                nativeRemoveNode(viewData[RENDERER], lContainer[NATIVE]);
            }
        }
        // Define this node as detached so that we don't risk projecting it
        removedPhTNode.flags |= 32 /* isDetached */;
        ngDevMode && ngDevMode.rendererRemoveNode++;
    }
    /**
     *
     * Use this instruction to create a translation block that doesn't contain any placeholder.
     * It calls both {@link i18nStart} and {@link i18nEnd} in one instruction.
     *
     * The translation `message` is the value which is locale specific. The translation string may
     * contain placeholders which associate inner elements and sub-templates within the translation.
     *
     * The translation `message` placeholders are:
     * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
     *   interpolated into. The placeholder `index` points to the expression binding index. An optional
     *   `block` that matches the sub-template in which it was declared.
     * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*:  Marks the beginning
     *   and end of DOM element that were embedded in the original translation block. The placeholder
     *   `index` points to the element index in the template instructions set. An optional `block` that
     *   matches the sub-template in which it was declared.
     * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
     *   split up and translated separately in each angular template function. The `index` points to the
     *   `template` instruction index. A `block` that matches the sub-template in which it was declared.
     *
     * @param index A unique index of the translation in the static block.
     * @param message The translation message.
     * @param subTemplateIndex Optional sub-template index in the `message`.
     *
     * @codeGenApi
     */
    function ɵɵi18n(index, message, subTemplateIndex) {
        ɵɵi18nStart(index, message, subTemplateIndex);
        ɵɵi18nEnd();
    }
    /**
     * Marks a list of attributes as translatable.
     *
     * @param index A unique index in the static block
     * @param values
     *
     * @codeGenApi
     */
    function ɵɵi18nAttributes(index, values) {
        var tView = getLView()[TVIEW];
        ngDevMode && assertDefined(tView, "tView should be defined");
        i18nAttributesFirstPass(tView, index, values);
    }
    /**
     * See `i18nAttributes` above.
     */
    function i18nAttributesFirstPass(tView, index, values) {
        var previousElement = getPreviousOrParentTNode();
        var previousElementIndex = previousElement.index - HEADER_OFFSET;
        var updateOpCodes = [];
        for (var i = 0; i < values.length; i += 2) {
            var attrName = values[i];
            var message = values[i + 1];
            var parts = message.split(ICU_REGEXP);
            for (var j = 0; j < parts.length; j++) {
                var value = parts[j];
                if (j & 1) {
                    // Odd indexes are ICU expressions
                    // TODO(ocombe): support ICU expressions in attributes
                    throw new Error('ICU expressions are not yet supported in attributes');
                }
                else if (value !== '') {
                    // Even indexes are text (including bindings)
                    var hasBinding = !!value.match(BINDING_REGEXP);
                    if (hasBinding) {
                        if (tView.firstTemplatePass && tView.data[index + HEADER_OFFSET] === null) {
                            addAllToArray(generateBindingUpdateOpCodes(value, previousElementIndex, attrName), updateOpCodes);
                        }
                    }
                    else {
                        var lView = getLView();
                        elementAttributeInternal(previousElementIndex, attrName, value, lView);
                        // Check if that attribute is a directive input
                        var tNode = getTNode(previousElementIndex, lView);
                        var dataValue = tNode.inputs && tNode.inputs[attrName];
                        if (dataValue) {
                            setInputsForProperty(lView, dataValue, value);
                        }
                    }
                }
            }
        }
        if (tView.firstTemplatePass && tView.data[index + HEADER_OFFSET] === null) {
            tView.data[index + HEADER_OFFSET] = updateOpCodes;
        }
    }
    var changeMask = 0;
    var shiftsCounter = 0;
    /**
     * Stores the values of the bindings during each update cycle in order to determine if we need to
     * update the translated nodes.
     *
     * @param value The binding's value
     * @returns This function returns itself so that it may be chained
     * (e.g. `i18nExp(ctx.name)(ctx.title)`)
     *
     * @codeGenApi
     */
    function ɵɵi18nExp(value) {
        var lView = getLView();
        var expression = bind(lView, value);
        if (expression !== NO_CHANGE) {
            changeMask = changeMask | (1 << shiftsCounter);
        }
        shiftsCounter++;
        return ɵɵi18nExp;
    }
    /**
     * Updates a translation block or an i18n attribute when the bindings have changed.
     *
     * @param index Index of either {@link i18nStart} (translation block) or {@link i18nAttributes}
     * (i18n attribute) on which it should update the content.
     *
     * @codeGenApi
     */
    function ɵɵi18nApply(index) {
        if (shiftsCounter) {
            var lView = getLView();
            var tView = lView[TVIEW];
            ngDevMode && assertDefined(tView, "tView should be defined");
            var tI18n = tView.data[index + HEADER_OFFSET];
            var updateOpCodes = void 0;
            var icus = null;
            if (Array.isArray(tI18n)) {
                updateOpCodes = tI18n;
            }
            else {
                updateOpCodes = tI18n.update;
                icus = tI18n.icus;
            }
            var bindingsStartIndex = lView[BINDING_INDEX] - shiftsCounter - 1;
            readUpdateOpCodes(updateOpCodes, icus, bindingsStartIndex, changeMask, lView);
            // Reset changeMask & maskBit to default for the next update cycle
            changeMask = 0;
            shiftsCounter = 0;
        }
    }
    /**
     * Returns the index of the current case of an ICU expression depending on the main binding value
     *
     * @param icuExpression
     * @param bindingValue The value of the main binding used by this ICU expression
     */
    function getCaseIndex(icuExpression, bindingValue) {
        var index = icuExpression.cases.indexOf(bindingValue);
        if (index === -1) {
            switch (icuExpression.type) {
                case 1 /* plural */: {
                    var resolvedCase = getPluralCase(bindingValue, getLocaleId());
                    index = icuExpression.cases.indexOf(resolvedCase);
                    if (index === -1 && resolvedCase !== 'other') {
                        index = icuExpression.cases.indexOf('other');
                    }
                    break;
                }
                case 0 /* select */: {
                    index = icuExpression.cases.indexOf('other');
                    break;
                }
            }
        }
        return index;
    }
    /**
     * Generate the OpCodes for ICU expressions.
     *
     * @param tIcus
     * @param icuExpression
     * @param startIndex
     * @param expandoStartIndex
     */
    function icuStart(tIcus, icuExpression, startIndex, expandoStartIndex) {
        var createCodes = [];
        var removeCodes = [];
        var updateCodes = [];
        var vars = [];
        var childIcus = [];
        for (var i = 0; i < icuExpression.values.length; i++) {
            // Each value is an array of strings & other ICU expressions
            var valueArr = icuExpression.values[i];
            var nestedIcus = [];
            for (var j = 0; j < valueArr.length; j++) {
                var value = valueArr[j];
                if (typeof value !== 'string') {
                    // It is an nested ICU expression
                    var icuIndex = nestedIcus.push(value) - 1;
                    // Replace nested ICU expression by a comment node
                    valueArr[j] = "<!--\uFFFD" + icuIndex + "\uFFFD-->";
                }
            }
            var icuCase = parseIcuCase(valueArr.join(''), startIndex, nestedIcus, tIcus, expandoStartIndex);
            createCodes.push(icuCase.create);
            removeCodes.push(icuCase.remove);
            updateCodes.push(icuCase.update);
            vars.push(icuCase.vars);
            childIcus.push(icuCase.childIcus);
        }
        var tIcu = {
            type: icuExpression.type,
            vars: vars,
            childIcus: childIcus,
            cases: icuExpression.cases,
            create: createCodes,
            remove: removeCodes,
            update: updateCodes
        };
        tIcus.push(tIcu);
        // Adding the maximum possible of vars needed (based on the cases with the most vars)
        i18nVarsCount += Math.max.apply(Math, __spread(vars));
    }
    /**
     * Transforms a string template into an HTML template and a list of instructions used to update
     * attributes or nodes that contain bindings.
     *
     * @param unsafeHtml The string to parse
     * @param parentIndex
     * @param nestedIcus
     * @param tIcus
     * @param expandoStartIndex
     */
    function parseIcuCase(unsafeHtml, parentIndex, nestedIcus, tIcus, expandoStartIndex) {
        var inertBodyHelper = new InertBodyHelper(document);
        var inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
        if (!inertBodyElement) {
            throw new Error('Unable to generate inert body element');
        }
        var wrapper = getTemplateContent(inertBodyElement) || inertBodyElement;
        var opCodes = { vars: 0, childIcus: [], create: [], remove: [], update: [] };
        parseNodes(wrapper.firstChild, opCodes, parentIndex, nestedIcus, tIcus, expandoStartIndex);
        return opCodes;
    }
    var NESTED_ICU = /�(\d+)�/;
    /**
     * Parses a node, its children and its siblings, and generates the mutate & update OpCodes.
     *
     * @param currentNode The first node to parse
     * @param icuCase The data for the ICU expression case that contains those nodes
     * @param parentIndex Index of the current node's parent
     * @param nestedIcus Data for the nested ICU expressions that this case contains
     * @param tIcus Data for all ICU expressions of the current message
     * @param expandoStartIndex Expando start index for the current ICU expression
     */
    function parseNodes(currentNode, icuCase, parentIndex, nestedIcus, tIcus, expandoStartIndex) {
        if (currentNode) {
            var nestedIcusToCreate = [];
            while (currentNode) {
                var nextNode = currentNode.nextSibling;
                var newIndex = expandoStartIndex + ++icuCase.vars;
                switch (currentNode.nodeType) {
                    case Node.ELEMENT_NODE:
                        var element = currentNode;
                        var tagName = element.tagName.toLowerCase();
                        if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
                            // This isn't a valid element, we won't create an element for it
                            icuCase.vars--;
                        }
                        else {
                            icuCase.create.push(ELEMENT_MARKER, tagName, newIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
                            var elAttrs = element.attributes;
                            for (var i = 0; i < elAttrs.length; i++) {
                                var attr = elAttrs.item(i);
                                var lowerAttrName = attr.name.toLowerCase();
                                var hasBinding_1 = !!attr.value.match(BINDING_REGEXP);
                                // we assume the input string is safe, unless it's using a binding
                                if (hasBinding_1) {
                                    if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
                                        if (URI_ATTRS[lowerAttrName]) {
                                            addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name, _sanitizeUrl), icuCase.update);
                                        }
                                        else if (SRCSET_ATTRS[lowerAttrName]) {
                                            addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name, sanitizeSrcset), icuCase.update);
                                        }
                                        else {
                                            addAllToArray(generateBindingUpdateOpCodes(attr.value, newIndex, attr.name), icuCase.update);
                                        }
                                    }
                                    else {
                                        ngDevMode &&
                                            console.warn("WARNING: ignoring unsafe attribute value " + lowerAttrName + " on element " + tagName + " (see http://g.co/ng/security#xss)");
                                    }
                                }
                                else {
                                    icuCase.create.push(newIndex << 3 /* SHIFT_REF */ | 4 /* Attr */, attr.name, attr.value);
                                }
                            }
                            // Parse the children of this node (if any)
                            parseNodes(currentNode.firstChild, icuCase, newIndex, nestedIcus, tIcus, expandoStartIndex);
                            // Remove the parent node after the children
                            icuCase.remove.push(newIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
                        }
                        break;
                    case Node.TEXT_NODE:
                        var value = currentNode.textContent || '';
                        var hasBinding = value.match(BINDING_REGEXP);
                        icuCase.create.push(hasBinding ? '' : value, newIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
                        icuCase.remove.push(newIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
                        if (hasBinding) {
                            addAllToArray(generateBindingUpdateOpCodes(value, newIndex), icuCase.update);
                        }
                        break;
                    case Node.COMMENT_NODE:
                        // Check if the comment node is a placeholder for a nested ICU
                        var match = NESTED_ICU.exec(currentNode.textContent || '');
                        if (match) {
                            var nestedIcuIndex = parseInt(match[1], 10);
                            var newLocal = ngDevMode ? "nested ICU " + nestedIcuIndex : '';
                            // Create the comment node that will anchor the ICU expression
                            icuCase.create.push(COMMENT_MARKER, newLocal, newIndex, parentIndex << 17 /* SHIFT_PARENT */ | 1 /* AppendChild */);
                            var nestedIcu = nestedIcus[nestedIcuIndex];
                            nestedIcusToCreate.push([nestedIcu, newIndex]);
                        }
                        else {
                            // We do not handle any other type of comment
                            icuCase.vars--;
                        }
                        break;
                    default:
                        // We do not handle any other type of element
                        icuCase.vars--;
                }
                currentNode = nextNode;
            }
            for (var i = 0; i < nestedIcusToCreate.length; i++) {
                var nestedIcu = nestedIcusToCreate[i][0];
                var nestedIcuNodeIndex = nestedIcusToCreate[i][1];
                icuStart(tIcus, nestedIcu, nestedIcuNodeIndex, expandoStartIndex + icuCase.vars);
                // Since this is recursive, the last TIcu that was pushed is the one we want
                var nestTIcuIndex = tIcus.length - 1;
                icuCase.vars += Math.max.apply(Math, __spread(tIcus[nestTIcuIndex].vars));
                icuCase.childIcus.push(nestTIcuIndex);
                var mask = getBindingMask(nestedIcu);
                icuCase.update.push(toMaskBit(nestedIcu.mainBinding), // mask of the main binding
                3, // skip 3 opCodes if not changed
                -1 - nestedIcu.mainBinding, nestedIcuNodeIndex << 2 /* SHIFT_REF */ | 2 /* IcuSwitch */, nestTIcuIndex, mask, // mask of all the bindings of this ICU expression
                2, // skip 2 opCodes if not changed
                nestedIcuNodeIndex << 2 /* SHIFT_REF */ | 3 /* IcuUpdate */, nestTIcuIndex);
                icuCase.remove.push(nestTIcuIndex << 3 /* SHIFT_REF */ | 6 /* RemoveNestedIcu */, nestedIcuNodeIndex << 3 /* SHIFT_REF */ | 3 /* Remove */);
            }
        }
    }
    /**
     * Angular Dart introduced &ngsp; as a placeholder for non-removable space, see:
     * https://github.com/dart-lang/angular/blob/0bb611387d29d65b5af7f9d2515ab571fd3fbee4/_tests/test/compiler/preserve_whitespace_test.dart#L25-L32
     * In Angular Dart &ngsp; is converted to the 0xE500 PUA (Private Use Areas) unicode character
     * and later on replaced by a space. We are re-implementing the same idea here, since translations
     * might contain this special character.
     */
    var NGSP_UNICODE_REGEXP = /\uE500/g;
    function replaceNgsp(value) {
        return value.replace(NGSP_UNICODE_REGEXP, ' ');
    }
    var TRANSLATIONS = {};
    /**
     * Set the configuration for `i18nLocalize`.
     *
     * @deprecated this method is temporary & should not be used as it will be removed soon
     */
    function i18nConfigureLocalize(options) {
        if (options === void 0) { options = {
            translations: {}
        }; }
        TRANSLATIONS = options.translations;
    }
    var LOCALIZE_PH_REGEXP = /\{\$(.*?)\}/g;
    /**
     * A goog.getMsg-like function for users that do not use Closure.
     *
     * This method is required as a *temporary* measure to prevent i18n tests from being blocked while
     * running outside of Closure Compiler. This method will not be needed once runtime translation
     * service support is introduced.
     *
     * @codeGenApi
     * @deprecated this method is temporary & should not be used as it will be removed soon
     */
    function ɵɵi18nLocalize(input, placeholders) {
        if (typeof TRANSLATIONS[input] !== 'undefined') { // to account for empty string
            input = TRANSLATIONS[input];
        }
        if (placeholders !== undefined && Object.keys(placeholders).length) {
            return input.replace(LOCALIZE_PH_REGEXP, function (_, key) { return placeholders[key] || ''; });
        }
        return input;
    }
    /**
     * The locale id that the application is currently using (for translations and ICU expressions).
     * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
     * but is now defined as a global value.
     */
    var LOCALE_ID = DEFAULT_LOCALE_ID;
    /**
     * Sets the locale id that will be used for translations and ICU expressions.
     * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
     * but is now defined as a global value.
     *
     * @param localeId
     */
    function setLocaleId(localeId) {
        assertDefined(localeId, "Expected localeId to be defined");
        if (typeof localeId === 'string') {
            LOCALE_ID = localeId.toLowerCase().replace(/_/g, '-');
        }
    }
    /**
     * Gets the locale id that will be used for translations and ICU expressions.
     * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
     * but is now defined as a global value.
     */
    function getLocaleId() {
        return LOCALE_ID;
    }

    /**
     * @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
     */
    /**
     * Map of module-id to the corresponding NgModule.
     * - In pre Ivy we track NgModuleFactory,
     * - In post Ivy we track the NgModuleType
     */
    var modules = new Map();
    /**
     * Registers a loaded module. Should only be called from generated NgModuleFactory code.
     * @publicApi
     */
    function registerModuleFactory(id, factory) {
        var existing = modules.get(id);
        assertSameOrNotExisting(id, existing && existing.moduleType, factory.moduleType);
        modules.set(id, factory);
    }
    function assertSameOrNotExisting(id, type, incoming) {
        if (type && type !== incoming) {
            throw new Error("Duplicate module registered for " + id + " - " + stringify(type) + " vs " + stringify(type.name));
        }
    }
    function registerNgModuleType(ngModuleType) {
        if (ngModuleType.ngModuleDef.id !== null) {
            var id = ngModuleType.ngModuleDef.id;
            var existing = modules.get(id);
            assertSameOrNotExisting(id, existing, ngModuleType);
            modules.set(id, ngModuleType);
        }
        var imports = ngModuleType.ngModuleDef.imports;
        if (imports instanceof Function) {
            imports = imports();
        }
        if (imports) {
            imports.forEach(function (i) { return registerNgModuleType(i); });
        }
    }
    function clearModulesForTest() {
        modules.clear();
    }
    function getRegisteredNgModuleType(id) {
        return modules.get(id);
    }

    /**
     * @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
     */
    var COMPONENT_FACTORY_RESOLVER = {
        provide: ComponentFactoryResolver,
        useClass: ComponentFactoryResolver$1,
        deps: [NgModuleRef],
    };
    var NgModuleRef$1 = /** @class */ (function (_super) {
        __extends(NgModuleRef$1, _super);
        function NgModuleRef$1(ngModuleType, _parent) {
            var _this = _super.call(this) || this;
            _this._parent = _parent;
            // tslint:disable-next-line:require-internal-with-underscore
            _this._bootstrapComponents = [];
            _this.injector = _this;
            _this.destroyCbs = [];
            var ngModuleDef = getNgModuleDef(ngModuleType);
            ngDevMode && assertDefined(ngModuleDef, "NgModule '" + stringify(ngModuleType) + "' is not a subtype of 'NgModuleType'.");
            var ngLocaleIdDef = getNgLocaleIdDef(ngModuleType);
            if (ngLocaleIdDef) {
                setLocaleId(ngLocaleIdDef);
            }
            _this._bootstrapComponents = maybeUnwrapFn(ngModuleDef.bootstrap);
            var additionalProviders = [
                {
                    provide: NgModuleRef,
                    useValue: _this,
                },
                COMPONENT_FACTORY_RESOLVER
            ];
            _this._r3Injector = createInjector(ngModuleType, _parent, additionalProviders, stringify(ngModuleType));
            _this.instance = _this.get(ngModuleType);
            return _this;
        }
        NgModuleRef$1.prototype.get = function (token, notFoundValue, injectFlags) {
            if (notFoundValue === void 0) { notFoundValue = Injector.THROW_IF_NOT_FOUND; }
            if (injectFlags === void 0) { injectFlags = exports.InjectFlags.Default; }
            if (token === Injector || token === NgModuleRef || token === INJECTOR) {
                return this;
            }
            return this._r3Injector.get(token, notFoundValue, injectFlags);
        };
        Object.defineProperty(NgModuleRef$1.prototype, "componentFactoryResolver", {
            get: function () {
                return this.get(ComponentFactoryResolver);
            },
            enumerable: true,
            configurable: true
        });
        NgModuleRef$1.prototype.destroy = function () {
            ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
            var injector = this._r3Injector;
            !injector.destroyed && injector.destroy();
            this.destroyCbs.forEach(function (fn) { return fn(); });
            this.destroyCbs = null;
        };
        NgModuleRef$1.prototype.onDestroy = function (callback) {
            ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
            this.destroyCbs.push(callback);
        };
        return NgModuleRef$1;
    }(NgModuleRef));
    var NgModuleFactory$1 = /** @class */ (function (_super) {
        __extends(NgModuleFactory, _super);
        function NgModuleFactory(moduleType) {
            var _this = _super.call(this) || this;
            _this.moduleType = moduleType;
            var ngModuleDef = getNgModuleDef(moduleType);
            if (ngModuleDef !== null) {
                // Register the NgModule with Angular's module registry. The location (and hence timing) of
                // this call is critical to ensure this works correctly (modules get registered when expected)
                // without bloating bundles (modules are registered when otherwise not referenced).
                //
                // In View Engine, registration occurs in the .ngfactory.js file as a side effect. This has
                // several practical consequences:
                //
                // - If an .ngfactory file is not imported from, the module won't be registered (and can be
                //   tree shaken).
                // - If an .ngfactory file is imported from, the module will be registered even if an instance
                //   is not actually created (via `create` below).
                // - Since an .ngfactory file in View Engine references the .ngfactory files of the NgModule's
                //   imports,
                //
                // In Ivy, things are a bit different. .ngfactory files still exist for compatibility, but are
                // not a required API to use - there are other ways to obtain an NgModuleFactory for a given
                // NgModule. Thus, relying on a side effect in the .ngfactory file is not sufficient. Instead,
                // the side effect of registration is added here, in the constructor of NgModuleFactory,
                // ensuring no matter how a factory is created, the module is registered correctly.
                //
                // An alternative would be to include the registration side effect inline following the actual
                // NgModule definition. This also has the correct timing, but breaks tree-shaking - modules
                // will be registered and retained even if they're otherwise never referenced.
                registerNgModuleType(moduleType);
            }
            return _this;
        }
        NgModuleFactory.prototype.create = function (parentInjector) {
            return new NgModuleRef$1(this.moduleType, parentInjector);
        };
        return NgModuleFactory;
    }(NgModuleFactory));

    /**
     * @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
     */
    /**
     * Adds decorator, constructor, and property metadata to a given type via static metadata fields
     * on the type.
     *
     * These metadata fields can later be read with Angular's `ReflectionCapabilities` API.
     *
     * Calls to `setClassMetadata` can be marked as pure, resulting in the metadata assignments being
     * tree-shaken away during production builds.
     */
    function setClassMetadata(type, decorators, ctorParameters, propDecorators) {
        return noSideEffects(function () {
            var _a;
            var clazz = type;
            // We determine whether a class has its own metadata by taking the metadata from the parent
            // constructor and checking whether it's the same as the subclass metadata below. We can't use
            // `hasOwnProperty` here because it doesn't work correctly in IE10 for static fields that are
            // defined by TS. See https://github.com/angular/angular/pull/28439#issuecomment-459349218.
            var parentPrototype = clazz.prototype ? Object.getPrototypeOf(clazz.prototype) : null;
            var parentConstructor = parentPrototype && parentPrototype.constructor;
            if (decorators !== null) {
                if (clazz.decorators !== undefined &&
                    (!parentConstructor || parentConstructor.decorators !== clazz.decorators)) {
                    (_a = clazz.decorators).push.apply(_a, __spread(decorators));
                }
                else {
                    clazz.decorators = decorators;
                }
            }
            if (ctorParameters !== null) {
                // Rather than merging, clobber the existing parameters. If other projects exist which use
                // tsickle-style annotations and reflect over them in the same way, this could cause issues,
                // but that is vanishingly unlikely.
                clazz.ctorParameters = ctorParameters;
            }
            if (propDecorators !== null) {
                // The property decorator objects are merged as it is possible different fields have different
                // decorator types. Decorators on individual fields are not merged, as it's also incredibly
                // unlikely that a field will be decorated both with an Angular decorator and a non-Angular
                // decorator that's also been downleveled.
                if (clazz.propDecorators !== undefined &&
                    (!parentConstructor || parentConstructor.propDecorators !== clazz.propDecorators)) {
                    clazz.propDecorators = __assign({}, clazz.propDecorators, propDecorators);
                }
                else {
                    clazz.propDecorators = propDecorators;
                }
            }
        });
    }

    /**
     * @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
     */
    /**
     * Bindings for pure functions are stored after regular bindings.
     *
     * |------consts------|---------vars---------|                 |----- hostVars (dir1) ------|
     * ------------------------------------------------------------------------------------------
     * | nodes/refs/pipes | bindings | fn slots  | injector | dir1 | host bindings | host slots |
     * ------------------------------------------------------------------------------------------
     *                    ^                      ^
     *      TView.bindingStartIndex      TView.expandoStartIndex
     *
     * Pure function instructions are given an offset from the binding root. Adding the offset to the
     * binding root gives the first index where the bindings are stored. In component views, the binding
     * root is the bindingStartIndex. In host bindings, the binding root is the expandoStartIndex +
     * any directive instances + any hostVars in directives evaluated before it.
     *
     * See VIEW_DATA.md for more information about host binding resolution.
     */
    /**
     * If the value hasn't been saved, calls the pure function to store and return the
     * value. If it has been saved, returns the saved value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn Function that returns a value
     * @param thisArg Optional calling context of pureFn
     * @returns value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction0(slotOffset, pureFn, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        return isCreationMode() ?
            updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) :
            getBinding(lView, bindingIndex);
    }
    /**
     * If the value of the provided exp has changed, calls the pure function to return
     * an updated value. Or if the value has not changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn Function that returns an updated value
     * @param exp Updated expression value
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction1(slotOffset, pureFn, exp, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var lView = getLView();
        var bindingIndex = getBindingRoot() + slotOffset;
        return bindingUpdated(lView, bindingIndex, exp) ?
            updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) :
            getBinding(lView, bindingIndex + 1);
    }
    /**
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn
     * @param exp1
     * @param exp2
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction2(slotOffset, pureFn, exp1, exp2, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        return bindingUpdated2(lView, bindingIndex, exp1, exp2) ?
            updateBinding(lView, bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) :
            getBinding(lView, bindingIndex + 2);
    }
    /**
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn
     * @param exp1
     * @param exp2
     * @param exp3
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction3(slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ?
            updateBinding(lView, bindingIndex + 3, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) :
            getBinding(lView, bindingIndex + 3);
    }
    /**
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn
     * @param exp1
     * @param exp2
     * @param exp3
     * @param exp4
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction4(slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ?
            updateBinding(lView, bindingIndex + 4, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) :
            getBinding(lView, bindingIndex + 4);
    }
    /**
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn
     * @param exp1
     * @param exp2
     * @param exp3
     * @param exp4
     * @param exp5
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction5(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
        return bindingUpdated(lView, bindingIndex + 4, exp5) || different ?
            updateBinding(lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) :
                pureFn(exp1, exp2, exp3, exp4, exp5)) :
            getBinding(lView, bindingIndex + 5);
    }
    /**
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn
     * @param exp1
     * @param exp2
     * @param exp3
     * @param exp4
     * @param exp5
     * @param exp6
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction6(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
        return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ?
            updateBinding(lView, bindingIndex + 6, thisArg ?
                pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) :
                pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) :
            getBinding(lView, bindingIndex + 6);
    }
    /**
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn
     * @param exp1
     * @param exp2
     * @param exp3
     * @param exp4
     * @param exp5
     * @param exp6
     * @param exp7
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction7(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
        return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ?
            updateBinding(lView, bindingIndex + 7, thisArg ?
                pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) :
                pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) :
            getBinding(lView, bindingIndex + 7);
    }
    /**
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn
     * @param exp1
     * @param exp2
     * @param exp3
     * @param exp4
     * @param exp5
     * @param exp6
     * @param exp7
     * @param exp8
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunction8(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var lView = getLView();
        var different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
        return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ?
            updateBinding(lView, bindingIndex + 8, thisArg ?
                pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) :
                pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) :
            getBinding(lView, bindingIndex + 8);
    }
    /**
     * pureFunction instruction that can support any number of bindings.
     *
     * If the value of any provided exp has changed, calls the pure function to return
     * an updated value. Or if no values have changed, returns cached value.
     *
     * @param slotOffset the offset from binding root to the reserved slot
     * @param pureFn A pure function that takes binding values and builds an object or array
     * containing those values.
     * @param exps An array of binding values
     * @param thisArg Optional calling context of pureFn
     * @returns Updated or cached value
     *
     * @codeGenApi
     */
    function ɵɵpureFunctionV(slotOffset, pureFn, exps, thisArg) {
        // TODO(kara): use bindingRoot instead of bindingStartIndex when implementing host bindings
        var bindingIndex = getBindingRoot() + slotOffset;
        var different = false;
        var lView = getLView();
        for (var i = 0; i < exps.length; i++) {
            bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
        }
        return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) :
            getBinding(lView, bindingIndex);
    }

    /**
     * @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
     */
    /**
     * Create a pipe.
     *
     * @param index Pipe index where the pipe will be stored.
     * @param pipeName The name of the pipe
     * @returns T the instance of the pipe.
     *
     * @codeGenApi
     */
    function ɵɵpipe(index, pipeName) {
        var tView = getLView()[TVIEW];
        var pipeDef;
        var adjustedIndex = index + HEADER_OFFSET;
        if (tView.firstTemplatePass) {
            pipeDef = getPipeDef$1(pipeName, tView.pipeRegistry);
            tView.data[adjustedIndex] = pipeDef;
            if (pipeDef.onDestroy) {
                (tView.destroyHooks || (tView.destroyHooks = [])).push(adjustedIndex, pipeDef.onDestroy);
            }
        }
        else {
            pipeDef = tView.data[adjustedIndex];
        }
        var pipeInstance = pipeDef.factory();
        store(index, pipeInstance);
        return pipeInstance;
    }
    /**
     * Searches the pipe registry for a pipe with the given name. If one is found,
     * returns the pipe. Otherwise, an error is thrown because the pipe cannot be resolved.
     *
     * @param name Name of pipe to resolve
     * @param registry Full list of available pipes
     * @returns Matching PipeDef
     *
     * @publicApi
     */
    function getPipeDef$1(name, registry) {
        if (registry) {
            for (var i = registry.length - 1; i >= 0; i--) {
                var pipeDef = registry[i];
                if (name === pipeDef.name) {
                    return pipeDef;
                }
            }
        }
        throw new Error("The pipe '" + name + "' could not be found!");
    }
    /**
     * Invokes a pipe with 1 arguments.
     *
     * This instruction acts as a guard to {@link PipeTransform#transform} invoking
     * the pipe only when an input to the pipe changes.
     *
     * @param index Pipe index where the pipe was stored on creation.
     * @param slotOffset the offset in the reserved slot space
     * @param v1 1st argument to {@link PipeTransform#transform}.
     *
     * @codeGenApi
     */
    function ɵɵpipeBind1(index, slotOffset, v1) {
        var pipeInstance = ɵɵload(index);
        return unwrapValue$1(isPure(index) ? ɵɵpureFunction1(slotOffset, pipeInstance.transform, v1, pipeInstance) :
            pipeInstance.transform(v1));
    }
    /**
     * Invokes a pipe with 2 arguments.
     *
     * This instruction acts as a guard to {@link PipeTransform#transform} invoking
     * the pipe only when an input to the pipe changes.
     *
     * @param index Pipe index where the pipe was stored on creation.
     * @param slotOffset the offset in the reserved slot space
     * @param v1 1st argument to {@link PipeTransform#transform}.
     * @param v2 2nd argument to {@link PipeTransform#transform}.
     *
     * @codeGenApi
     */
    function ɵɵpipeBind2(index, slotOffset, v1, v2) {
        var pipeInstance = ɵɵload(index);
        return unwrapValue$1(isPure(index) ? ɵɵpureFunction2(slotOffset, pipeInstance.transform, v1, v2, pipeInstance) :
            pipeInstance.transform(v1, v2));
    }
    /**
     * Invokes a pipe with 3 arguments.
     *
     * This instruction acts as a guard to {@link PipeTransform#transform} invoking
     * the pipe only when an input to the pipe changes.
     *
     * @param index Pipe index where the pipe was stored on creation.
     * @param slotOffset the offset in the reserved slot space
     * @param v1 1st argument to {@link PipeTransform#transform}.
     * @param v2 2nd argument to {@link PipeTransform#transform}.
     * @param v3 4rd argument to {@link PipeTransform#transform}.
     *
     * @codeGenApi
     */
    function ɵɵpipeBind3(index, slotOffset, v1, v2, v3) {
        var pipeInstance = ɵɵload(index);
        return unwrapValue$1(isPure(index) ?
            ɵɵpureFunction3(slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) :
            pipeInstance.transform(v1, v2, v3));
    }
    /**
     * Invokes a pipe with 4 arguments.
     *
     * This instruction acts as a guard to {@link PipeTransform#transform} invoking
     * the pipe only when an input to the pipe changes.
     *
     * @param index Pipe index where the pipe was stored on creation.
     * @param slotOffset the offset in the reserved slot space
     * @param v1 1st argument to {@link PipeTransform#transform}.
     * @param v2 2nd argument to {@link PipeTransform#transform}.
     * @param v3 3rd argument to {@link PipeTransform#transform}.
     * @param v4 4th argument to {@link PipeTransform#transform}.
     *
     * @codeGenApi
     */
    function ɵɵpipeBind4(index, slotOffset, v1, v2, v3, v4) {
        var pipeInstance = ɵɵload(index);
        return unwrapValue$1(isPure(index) ?
            ɵɵpureFunction4(slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) :
            pipeInstance.transform(v1, v2, v3, v4));
    }
    /**
     * Invokes a pipe with variable number of arguments.
     *
     * This instruction acts as a guard to {@link PipeTransform#transform} invoking
     * the pipe only when an input to the pipe changes.
     *
     * @param index Pipe index where the pipe was stored on creation.
     * @param slotOffset the offset in the reserved slot space
     * @param values Array of arguments to pass to {@link PipeTransform#transform} method.
     *
     * @codeGenApi
     */
    function ɵɵpipeBindV(index, slotOffset, values) {
        var pipeInstance = ɵɵload(index);
        return unwrapValue$1(isPure(index) ? ɵɵpureFunctionV(slotOffset, pipeInstance.transform, values, pipeInstance) :
            pipeInstance.transform.apply(pipeInstance, values));
    }
    function isPure(index) {
        return getLView()[TVIEW].data[index + HEADER_OFFSET].pure;
    }
    /**
     * Unwrap the output of a pipe transformation.
     * In order to trick change detection into considering that the new value is always different from
     * the old one, the old value is overwritten by NO_CHANGE.
     *
     * @param newValue the pipe transformation output.
     */
    function unwrapValue$1(newValue) {
        if (WrappedValue.isWrapped(newValue)) {
            newValue = WrappedValue.unwrap(newValue);
            var lView = getLView();
            // The NO_CHANGE value needs to be written at the index where the impacted binding value is
            // stored
            var bindingToInvalidateIdx = lView[BINDING_INDEX];
            lView[bindingToInvalidateIdx] = NO_CHANGE;
        }
        return newValue;
    }

    /**
     * @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
     */
    /**
     * Use in components with the `@Output` directive to emit custom events
     * synchronously or asynchronously, and register handlers for those events
     * by subscribing to an instance.
     *
     * @usageNotes
     *
     * Extends
     * [RxJS `Subject`](https://rxjs.dev/api/index/class/Subject)
     * for Angular by adding the `emit()` method.
     *
     * In the following example, a component defines two output properties
     * that create event emitters. When the title is clicked, the emitter
     * emits an open or close event to toggle the current visibility state.
     *
     * ```html
     * @Component({
     *   selector: 'zippy',
     *   template: `
     *   <div class="zippy">
     *     <div (click)="toggle()">Toggle</div>
     *     <div [hidden]="!visible">
     *       <ng-content></ng-content>
     *     </div>
     *  </div>`})
     * export class Zippy {
     *   visible: boolean = true;
     *   @Output() open: EventEmitter<any> = new EventEmitter();
     *   @Output() close: EventEmitter<any> = new EventEmitter();
     *
     *   toggle() {
     *     this.visible = !this.visible;
     *     if (this.visible) {
     *       this.open.emit(null);
     *     } else {
     *       this.close.emit(null);
     *     }
     *   }
     * }
     * ```
     *
     * Access the event object with the `$event` argument passed to the output event
     * handler:
     *
     * ```html
     * <zippy (open)="onOpen($event)" (close)="onClose($event)"></zippy>
     * ```
     *
     * @see [Observables in Angular](guide/observables-in-angular)
     * @publicApi
     */
    var EventEmitter = /** @class */ (function (_super) {
        __extends(EventEmitter, _super);
        /**
         * Creates an instance of this class that can
         * deliver events synchronously or asynchronously.
         *
         * @param isAsync When true, deliver events asynchronously.
         *
         */
        function EventEmitter(isAsync) {
            if (isAsync === void 0) { isAsync = false; }
            var _this = _super.call(this) || this;
            _this.__isAsync = isAsync;
            return _this;
        }
        /**
         * Emits an event containing a given value.
         * @param value The value to emit.
         */
        EventEmitter.prototype.emit = function (value) { _super.prototype.next.call(this, value); };
        /**
         * Registers handlers for events emitted by this instance.
         * @param generatorOrNext When supplied, a custom handler for emitted events.
         * @param error When supplied, a custom handler for an error notification
         * from this emitter.
         * @param complete When supplied, a custom handler for a completion
         * notification from this emitter.
         */
        EventEmitter.prototype.subscribe = function (generatorOrNext, error, complete) {
            var schedulerFn;
            var errorFn = function (err) { return null; };
            var completeFn = function () { return null; };
            if (generatorOrNext && typeof generatorOrNext === 'object') {
                schedulerFn = this.__isAsync ? function (value) {
                    setTimeout(function () { return generatorOrNext.next(value); });
                } : function (value) { generatorOrNext.next(value); };
                if (generatorOrNext.error) {
                    errorFn = this.__isAsync ? function (err) { setTimeout(function () { return generatorOrNext.error(err); }); } :
                        function (err) { generatorOrNext.error(err); };
                }
                if (generatorOrNext.complete) {
                    completeFn = this.__isAsync ? function () { setTimeout(function () { return generatorOrNext.complete(); }); } :
                        function () { generatorOrNext.complete(); };
                }
            }
            else {
                schedulerFn = this.__isAsync ? function (value) { setTimeout(function () { return generatorOrNext(value); }); } :
                    function (value) { generatorOrNext(value); };
                if (error) {
                    errorFn =
                        this.__isAsync ? function (err) { setTimeout(function () { return error(err); }); } : function (err) { error(err); };
                }
                if (complete) {
                    completeFn =
                        this.__isAsync ? function () { setTimeout(function () { return complete(); }); } : function () { complete(); };
                }
            }
            var sink = _super.prototype.subscribe.call(this, schedulerFn, errorFn, completeFn);
            if (generatorOrNext instanceof rxjs.Subscription) {
                generatorOrNext.add(sink);
            }
            return sink;
        };
        return EventEmitter;
    }(rxjs.Subject));

    /**
     * @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
     */
    function symbolIterator() {
        return this._results[getSymbolIterator()]();
    }
    /**
     * An unmodifiable list of items that Angular keeps up to date when the state
     * of the application changes.
     *
     * The type of object that {@link ViewChildren}, {@link ContentChildren}, and {@link QueryList}
     * provide.
     *
     * Implements an iterable interface, therefore it can be used in both ES6
     * javascript `for (var i of items)` loops as well as in Angular templates with
     * `*ngFor="let i of myList"`.
     *
     * Changes can be observed by subscribing to the changes `Observable`.
     *
     * NOTE: In the future this class will implement an `Observable` interface.
     *
     * @usageNotes
     * ### Example
     * ```typescript
     * @Component({...})
     * class Container {
     *   @ViewChildren(Item) items:QueryList<Item>;
     * }
     * ```
     *
     * @publicApi
     */
    var QueryList = /** @class */ (function () {
        function QueryList() {
            this.dirty = true;
            this._results = [];
            this.changes = new EventEmitter();
            this.length = 0;
            // This function should be declared on the prototype, but doing so there will cause the class
            // declaration to have side-effects and become not tree-shakable. For this reason we do it in
            // the constructor.
            // [getSymbolIterator()](): Iterator<T> { ... }
            var symbol = getSymbolIterator();
            var proto = QueryList.prototype;
            if (!proto[symbol])
                proto[symbol] = symbolIterator;
        }
        /**
         * See
         * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
         */
        QueryList.prototype.map = function (fn) { return this._results.map(fn); };
        /**
         * See
         * [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
         */
        QueryList.prototype.filter = function (fn) {
            return this._results.filter(fn);
        };
        /**
         * See
         * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
         */
        QueryList.prototype.find = function (fn) {
            return this._results.find(fn);
        };
        /**
         * See
         * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
         */
        QueryList.prototype.reduce = function (fn, init) {
            return this._results.reduce(fn, init);
        };
        /**
         * See
         * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
         */
        QueryList.prototype.forEach = function (fn) { this._results.forEach(fn); };
        /**
         * See
         * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
         */
        QueryList.prototype.some = function (fn) {
            return this._results.some(fn);
        };
        /**
         * Returns a copy of the internal results list as an Array.
         */
        QueryList.prototype.toArray = function () { return this._results.slice(); };
        QueryList.prototype.toString = function () { return this._results.toString(); };
        /**
         * Updates the stored data of the query list, and resets the `dirty` flag to `false`, so that
         * on change detection, it will not notify of changes to the queries, unless a new change
         * occurs.
         *
         * @param resultsTree The query results to store
         */
        QueryList.prototype.reset = function (resultsTree) {
            this._results = flatten(resultsTree);
            this.dirty = false;
            this.length = this._results.length;
            this.last = this._results[this.length - 1];
            this.first = this._results[0];
        };
        /**
         * Triggers a change event by emitting on the `changes` {@link EventEmitter}.
         */
        QueryList.prototype.notifyOnChanges = function () { this.changes.emit(this); };
        /** internal */
        QueryList.prototype.setDirty = function () { this.dirty = true; };
        /** internal */
        QueryList.prototype.destroy = function () {
            this.changes.complete();
            this.changes.unsubscribe();
        };
        return QueryList;
    }());

    /**
     * @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
     */
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$7 = 1;

    /**
     * @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
     */
    // Note: This hack is necessary so we don't erroneously get a circular dependency
    // failure based on types.
    var unusedValueExportToPlacateAjd$8 = 1;

    /**
     * @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
     */
    var unusedValueToPlacateAjd$2 = unusedValueExportToPlacateAjd$7 + unusedValueExportToPlacateAjd$2 + unusedValueExportToPlacateAjd$4 + unusedValueExportToPlacateAjd$8;
    var LQuery_ = /** @class */ (function () {
        function LQuery_(queryList) {
            this.queryList = queryList;
            this.matches = null;
        }
        LQuery_.prototype.clone = function () { return new LQuery_(this.queryList); };
        LQuery_.prototype.setDirty = function () { this.queryList.setDirty(); };
        return LQuery_;
    }());
    var LQueries_ = /** @class */ (function () {
        function LQueries_(queries) {
            if (queries === void 0) { queries = []; }
            this.queries = queries;
        }
        LQueries_.prototype.createEmbeddedView = function (tView) {
            var tQueries = tView.queries;
            if (tQueries !== null) {
                var noOfInheritedQueries = tView.contentQueries !== null ? tView.contentQueries[0] : tQueries.length;
                var viewLQueries = new Array(noOfInheritedQueries);
                // An embedded view has queries propagated from a declaration view at the beginning of the
                // TQueries collection and up until a first content query declared in the embedded view. Only
                // propagated LQueries are created at this point (LQuery corresponding to declared content
                // queries will be instantiated from the content query instructions for each directive).
                for (var i = 0; i < noOfInheritedQueries; i++) {
                    var tQuery = tQueries.getByIndex(i);
                    var parentLQuery = this.queries[tQuery.indexInDeclarationView];
                    viewLQueries[i] = parentLQuery.clone();
                }
                return new LQueries_(viewLQueries);
            }
            return null;
        };
        LQueries_.prototype.insertView = function (tView) { this.dirtyQueriesWithMatches(tView); };
        LQueries_.prototype.detachView = function (tView) { this.dirtyQueriesWithMatches(tView); };
        LQueries_.prototype.dirtyQueriesWithMatches = function (tView) {
            for (var i = 0; i < this.queries.length; i++) {
                if (getTQuery(tView, i).matches !== null) {
                    this.queries[i].setDirty();
                }
            }
        };
        return LQueries_;
    }());
    var TQueryMetadata_ = /** @class */ (function () {
        function TQueryMetadata_(predicate, descendants, isStatic, read) {
            if (read === void 0) { read = null; }
            this.predicate = predicate;
            this.descendants = descendants;
            this.isStatic = isStatic;
            this.read = read;
        }
        return TQueryMetadata_;
    }());
    var TQueries_ = /** @class */ (function () {
        function TQueries_(queries) {
            if (queries === void 0) { queries = []; }
            this.queries = queries;
        }
        TQueries_.prototype.elementStart = function (tView, tNode) {
            var e_1, _a;
            ngDevMode && assertFirstTemplatePass(tView, 'Queries should collect results on the first template pass only');
            try {
                for (var _b = __values(this.queries), _c = _b.next(); !_c.done; _c = _b.next()) {
                    var query = _c.value;
                    query.elementStart(tView, tNode);
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                }
                finally { if (e_1) throw e_1.error; }
            }
        };
        TQueries_.prototype.elementEnd = function (tNode) {
            var e_2, _a;
            try {
                for (var _b = __values(this.queries), _c = _b.next(); !_c.done; _c = _b.next()) {
                    var query = _c.value;
                    query.elementEnd(tNode);
                }
            }
            catch (e_2_1) { e_2 = { error: e_2_1 }; }
            finally {
                try {
                    if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                }
                finally { if (e_2) throw e_2.error; }
            }
        };
        TQueries_.prototype.embeddedTView = function (tNode) {
            var queriesForTemplateRef = null;
            for (var i = 0; i < this.length; i++) {
                var childQueryIndex = queriesForTemplateRef !== null ? queriesForTemplateRef.length : 0;
                var tqueryClone = this.getByIndex(i).embeddedTView(tNode, childQueryIndex);
                if (tqueryClone) {
                    tqueryClone.indexInDeclarationView = i;
                    if (queriesForTemplateRef !== null) {
                        queriesForTemplateRef.push(tqueryClone);
                    }
                    else {
                        queriesForTemplateRef = [tqueryClone];
                    }
                }
            }
            return queriesForTemplateRef !== null ? new TQueries_(queriesForTemplateRef) : null;
        };
        TQueries_.prototype.template = function (tView, tNode) {
            var e_3, _a;
            ngDevMode && assertFirstTemplatePass(tView, 'Queries should collect results on the first template pass only');
            try {
                for (var _b = __values(this.queries), _c = _b.next(); !_c.done; _c = _b.next()) {
                    var query = _c.value;
                    query.template(tView, tNode);
                }
            }
            catch (e_3_1) { e_3 = { error: e_3_1 }; }
            finally {
                try {
                    if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                }
                finally { if (e_3) throw e_3.error; }
            }
        };
        TQueries_.prototype.getByIndex = function (index) {
            ngDevMode && assertDataInRange(this.queries, index);
            return this.queries[index];
        };
        Object.defineProperty(TQueries_.prototype, "length", {
            get: function () { return this.queries.length; },
            enumerable: true,
            configurable: true
        });
        TQueries_.prototype.track = function (tquery) { this.queries.push(tquery); };
        return TQueries_;
    }());
    var TQuery_ = /** @class */ (function () {
        function TQuery_(metadata, nodeIndex) {
            if (nodeIndex === void 0) { nodeIndex = -1; }
            this.metadata = metadata;
            this.matches = null;
            this.indexInDeclarationView = -1;
            this.crossesNgTemplate = false;
            /**
             * A flag indicating if a given query still applies to nodes it is crossing. We use this flag
             * (alongside with _declarationNodeIndex) to know when to stop applying content queries to
             * elements in a template.
             */
            this._appliesToNextNode = true;
            this._declarationNodeIndex = nodeIndex;
        }
        TQuery_.prototype.elementStart = function (tView, tNode) {
            if (this.isApplyingToNode(tNode)) {
                this.matchTNode(tView, tNode);
            }
        };
        TQuery_.prototype.elementEnd = function (tNode) {
            if (this._declarationNodeIndex === tNode.index) {
                this._appliesToNextNode = false;
            }
        };
        TQuery_.prototype.template = function (tView, tNode) { this.elementStart(tView, tNode); };
        TQuery_.prototype.embeddedTView = function (tNode, childQueryIndex) {
            if (this.isApplyingToNode(tNode)) {
                this.crossesNgTemplate = true;
                // A marker indicating a `<ng-template>` element (a placeholder for query results from
                // embedded views created based on this `<ng-template>`).
                this.addMatch(-tNode.index, childQueryIndex);
                return new TQuery_(this.metadata);
            }
            return null;
        };
        TQuery_.prototype.isApplyingToNode = function (tNode) {
            if (this._appliesToNextNode && this.metadata.descendants === false) {
                return this._declarationNodeIndex === (tNode.parent ? tNode.parent.index : -1);
            }
            return this._appliesToNextNode;
        };
        TQuery_.prototype.matchTNode = function (tView, tNode) {
            if (Array.isArray(this.metadata.predicate)) {
                var localNames = this.metadata.predicate;
                for (var i = 0; i < localNames.length; i++) {
                    this.matchTNodeWithReadOption(tView, tNode, getIdxOfMatchingSelector(tNode, localNames[i]));
                }
            }
            else {
                var typePredicate = this.metadata.predicate;
                if (typePredicate === TemplateRef) {
                    if (tNode.type === 0 /* Container */) {
                        this.matchTNodeWithReadOption(tView, tNode, -1);
                    }
                }
                else {
                    this.matchTNodeWithReadOption(tView, tNode, locateDirectiveOrProvider(tNode, tView, typePredicate, false, false));
                }
            }
        };
        TQuery_.prototype.matchTNodeWithReadOption = function (tView, tNode, nodeMatchIdx) {
            if (nodeMatchIdx !== null) {
                var read = this.metadata.read;
                if (read !== null) {
                    if (read === ElementRef || read === ViewContainerRef ||
                        read === TemplateRef && tNode.type === 0 /* Container */) {
                        this.addMatch(tNode.index, -2);
                    }
                    else {
                        var directiveOrProviderIdx = locateDirectiveOrProvider(tNode, tView, read, false, false);
                        if (directiveOrProviderIdx !== null) {
                            this.addMatch(tNode.index, directiveOrProviderIdx);
                        }
                    }
                }
                else {
                    this.addMatch(tNode.index, nodeMatchIdx);
                }
            }
        };
        TQuery_.prototype.addMatch = function (tNodeIdx, matchIdx) {
            if (this.matches === null) {
                this.matches = [tNodeIdx, matchIdx];
            }
            else {
                this.matches.push(tNodeIdx, matchIdx);
            }
        };
        return TQuery_;
    }());
    /**
     * Iterates over local names for a given node and returns directive index
     * (or -1 if a local name points to an element).
     *
     * @param tNode static data of a node to check
     * @param selector selector to match
     * @returns directive index, -1 or null if a selector didn't match any of the local names
     */
    function getIdxOfMatchingSelector(tNode, selector) {
        var localNames = tNode.localNames;
        if (localNames !== null) {
            for (var i = 0; i < localNames.length; i += 2) {
                if (localNames[i] === selector) {
                    return localNames[i + 1];
                }
            }
        }
        return null;
    }
    function createResultByTNodeType(tNode, currentView) {
        if (tNode.type === 3 /* Element */ || tNode.type === 4 /* ElementContainer */) {
            return createElementRef(ElementRef, tNode, currentView);
        }
        else if (tNode.type === 0 /* Container */) {
            return createTemplateRef(TemplateRef, ElementRef, tNode, currentView);
        }
        return null;
    }
    function createResultForNode(lView, tNode, matchingIdx, read) {
        if (matchingIdx === -1) {
            // if read token and / or strategy is not specified, detect it using appropriate tNode type
            return createResultByTNodeType(tNode, lView);
        }
        else if (matchingIdx === -2) {
            // read a special token from a node injector
            return createSpecialToken(lView, tNode, read);
        }
        else {
            // read a token
            return getNodeInjectable(lView[TVIEW].data, lView, matchingIdx, tNode);
        }
    }
    function createSpecialToken(lView, tNode, read) {
        if (read === ElementRef) {
            return createElementRef(ElementRef, tNode, lView);
        }
        else if (read === TemplateRef) {
            return createTemplateRef(TemplateRef, ElementRef, tNode, lView);
        }
        else if (read === ViewContainerRef) {
            ngDevMode && assertNodeOfPossibleTypes(tNode, 3 /* Element */, 0 /* Container */, 4 /* ElementContainer */);
            return createContainerRef(ViewContainerRef, ElementRef, tNode, lView);
        }
        else {
            ngDevMode &&
                throwError("Special token to read should be one of ElementRef, TemplateRef or ViewContainerRef but got " + stringify(read) + ".");
        }
    }
    /**
     * A helper function that creates query results for a given view. This function is meant to do the
     * processing once and only once for a given view instance (a set of results for a given view
     * doesn't change).
     */
    function materializeViewResults(lView, tQuery, queryIndex) {
        var lQuery = lView[QUERIES].queries[queryIndex];
        if (lQuery.matches === null) {
            var tViewData = lView[TVIEW].data;
            var tQueryMatches = tQuery.matches;
            var result = new Array(tQueryMatches.length / 2);
            for (var i = 0; i < tQueryMatches.length; i += 2) {
                var matchedNodeIdx = tQueryMatches[i];
                if (matchedNodeIdx < 0) {
                    // we at the <ng-template> marker which might have results in views created based on this
                    // <ng-template> - those results will be in separate views though, so here we just leave
                    // null as a placeholder
                    result[i / 2] = null;
                }
                else {
                    ngDevMode && assertDataInRange(tViewData, matchedNodeIdx);
                    var tNode = tViewData[matchedNodeIdx];
                    result[i / 2] =
                        createResultForNode(lView, tNode, tQueryMatches[i + 1], tQuery.metadata.read);
                }
            }
            lQuery.matches = result;
        }
        return lQuery.matches;
    }
    /**
     * A helper function that collects (already materialized) query results from a tree of views,
     * starting with a provided LView.
     */
    function collectQueryResults(lView, queryIndex, result) {
        var e_4, _a;
        var tQuery = lView[TVIEW].queries.getByIndex(queryIndex);
        var tQueryMatches = tQuery.matches;
        if (tQueryMatches !== null) {
            var lViewResults = materializeViewResults(lView, tQuery, queryIndex);
            for (var i = 0; i < tQueryMatches.length; i += 2) {
                var tNodeIdx = tQueryMatches[i];
                if (tNodeIdx > 0) {
                    var viewResult = lViewResults[i / 2];
                    ngDevMode && assertDefined(viewResult, 'materialized query result should be defined');
                    result.push(viewResult);
                }
                else {
                    var childQueryIndex = tQueryMatches[i + 1];
                    var declarationLContainer = lView[-tNodeIdx];
                    ngDevMode && assertLContainer(declarationLContainer);
                    // collect matches for views inserted in this container
                    for (var i_1 = CONTAINER_HEADER_OFFSET; i_1 < declarationLContainer.length; i_1++) {
                        var embeddedLView = declarationLContainer[i_1];
                        if (embeddedLView[DECLARATION_LCONTAINER] === embeddedLView[PARENT]) {
                            collectQueryResults(embeddedLView, childQueryIndex, result);
                        }
                    }
                    // collect matches for views created from this declaration container and inserted into
                    // different containers
                    if (declarationLContainer[MOVED_VIEWS] !== null) {
                        try {
                            for (var _b = (e_4 = void 0, __values(declarationLContainer[MOVED_VIEWS])), _c = _b.next(); !_c.done; _c = _b.next()) {
                                var embeddedLView = _c.value;
                                collectQueryResults(embeddedLView, childQueryIndex, result);
                            }
                        }
                        catch (e_4_1) { e_4 = { error: e_4_1 }; }
                        finally {
                            try {
                                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                            }
                            finally { if (e_4) throw e_4.error; }
                        }
                    }
                }
            }
        }
        return result;
    }
    /**
     * Refreshes a query by combining matches from all active views and removing matches from deleted
     * views.
     *
     * @returns `true` if a query got dirty during change detection or if this is a static query
     * resolving in creation mode, `false` otherwise.
     *
     * @codeGenApi
     */
    function ɵɵqueryRefresh(queryList) {
        var lView = getLView();
        var queryIndex = getCurrentQueryIndex();
        setCurrentQueryIndex(queryIndex + 1);
        var tQuery = getTQuery(lView[TVIEW], queryIndex);
        if (queryList.dirty && (isCreationMode() === tQuery.metadata.isStatic)) {
            if (tQuery.matches === null) {
                queryList.reset([]);
            }
            else {
                var result = tQuery.crossesNgTemplate ? collectQueryResults(lView, queryIndex, []) :
                    materializeViewResults(lView, tQuery, queryIndex);
                queryList.reset(result);
                queryList.notifyOnChanges();
            }
            return true;
        }
        return false;
    }
    /**
     * Creates new QueryList for a static view query.
     *
     * @param predicate The type for which the query will search
     * @param descend Whether or not to descend into children
     * @param read What to save in the query
     *
     * @codeGenApi
     */
    function ɵɵstaticViewQuery(predicate, descend, read) {
        viewQueryInternal(getLView(), predicate, descend, read, true);
    }
    /**
     * Creates new QueryList, stores the reference in LView and returns QueryList.
     *
     * @param predicate The type for which the query will search
     * @param descend Whether or not to descend into children
     * @param read What to save in the query
     *
     * @codeGenApi
     */
    function ɵɵviewQuery(predicate, descend, read) {
        viewQueryInternal(getLView(), predicate, descend, read, false);
    }
    function viewQueryInternal(lView, predicate, descend, read, isStatic) {
        var tView = lView[TVIEW];
        if (tView.firstTemplatePass) {
            createTQuery(tView, new TQueryMetadata_(predicate, descend, isStatic, read), -1);
            if (isStatic) {
                tView.staticViewQueries = true;
            }
        }
        createLQuery(lView);
    }
    /**
     * Loads a QueryList corresponding to the current view query.
     *
     * @codeGenApi
     */
    function ɵɵloadViewQuery() {
        return loadQueryInternal(getLView(), getCurrentQueryIndex());
    }
    /**
     * Registers a QueryList, associated with a content query, for later refresh (part of a view
     * refresh).
     *
     * @param directiveIndex Current directive index
     * @param predicate The type for which the query will search
     * @param descend Whether or not to descend into children
     * @param read What to save in the query
     * @returns QueryList<T>
     *
     * @codeGenApi
     */
    function ɵɵcontentQuery(directiveIndex, predicate, descend, read) {
        contentQueryInternal(getLView(), predicate, descend, read, false, getPreviousOrParentTNode(), directiveIndex);
    }
    /**
     * Registers a QueryList, associated with a static content query, for later refresh
     * (part of a view refresh).
     *
     * @param directiveIndex Current directive index
     * @param predicate The type for which the query will search
     * @param descend Whether or not to descend into children
     * @param read What to save in the query
     * @returns QueryList<T>
     *
     * @codeGenApi
     */
    function ɵɵstaticContentQuery(directiveIndex, predicate, descend, read) {
        contentQueryInternal(getLView(), predicate, descend, read, true, getPreviousOrParentTNode(), directiveIndex);
    }
    function contentQueryInternal(lView, predicate, descend, read, isStatic, tNode, directiveIndex) {
        var tView = lView[TVIEW];
        if (tView.firstTemplatePass) {
            createTQuery(tView, new TQueryMetadata_(predicate, descend, isStatic, read), tNode.index);
            saveContentQueryAndDirectiveIndex(tView, directiveIndex);
            if (isStatic) {
                tView.staticContentQueries = true;
            }
        }
        createLQuery(lView);
    }
    /**
     * Loads a QueryList corresponding to the current content query.
     *
     * @codeGenApi
     */
    function ɵɵloadContentQuery() {
        return loadQueryInternal(getLView(), getCurrentQueryIndex());
    }
    function loadQueryInternal(lView, queryIndex) {
        ngDevMode &&
            assertDefined(lView[QUERIES], 'LQueries should be defined when trying to load a query');
        ngDevMode && assertDataInRange(lView[QUERIES].queries, queryIndex);
        return lView[QUERIES].queries[queryIndex].queryList;
    }
    function createLQuery(lView) {
        var queryList = new QueryList();
        storeCleanupWithContext(lView, queryList, queryList.destroy);
        if (lView[QUERIES] === null)
            lView[QUERIES] = new LQueries_();
        lView[QUERIES].queries.push(new LQuery_(queryList));
    }
    function createTQuery(tView, metadata, nodeIndex) {
        if (tView.queries === null)
            tView.queries = new TQueries_();
        tView.queries.track(new TQuery_(metadata, nodeIndex));
    }
    function saveContentQueryAndDirectiveIndex(tView, directiveIndex) {
        var tViewContentQueries = tView.contentQueries || (tView.contentQueries = []);
        var lastSavedDirectiveIndex = tView.contentQueries.length ? tViewContentQueries[tViewContentQueries.length - 1] : -1;
        if (directiveIndex !== lastSavedDirectiveIndex) {
            tViewContentQueries.push(tView.queries.length - 1, directiveIndex);
        }
    }
    function getTQuery(tView, index) {
        ngDevMode && assertDefined(tView.queries, 'TQueries must be defined to retrieve a TQuery');
        return tView.queries.getByIndex(index);
    }

    /**
     * @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
     */
    /**
     * Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
     * `<ng-template>` element.
     *
     * @codeGenApi
     */
    function ɵɵtemplateRefExtractor(tNode, currentView) {
        return createTemplateRef(TemplateRef, ElementRef, tNode, currentView);
    }
    /**
     * Returns the appropriate `ChangeDetectorRef` for a pipe.
     *
     * @codeGenApi
     */
    function ɵɵinjectPipeChangeDetectorRef(flags) {
        if (flags === void 0) { flags = exports.InjectFlags.Default; }
        var value = injectChangeDetectorRef(true);
        if (value == null && !(flags & exports.InjectFlags.Optional)) {
            throw new Error("No provider for ChangeDetectorRef!");
        }
        else {
            return value;
        }
    }

    /**
     * @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
     */

    /**
     * @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
     */
    var ɵ0$e = function () { return ({
        'ɵɵattribute': ɵɵattribute,
        'ɵɵattributeInterpolate1': ɵɵattributeInterpolate1,
        'ɵɵattributeInterpolate2': ɵɵattributeInterpolate2,
        'ɵɵattributeInterpolate3': ɵɵattributeInterpolate3,
        'ɵɵattributeInterpolate4': ɵɵattributeInterpolate4,
        'ɵɵattributeInterpolate5': ɵɵattributeInterpolate5,
        'ɵɵattributeInterpolate6': ɵɵattributeInterpolate6,
        'ɵɵattributeInterpolate7': ɵɵattributeInterpolate7,
        'ɵɵattributeInterpolate8': ɵɵattributeInterpolate8,
        'ɵɵattributeInterpolateV': ɵɵattributeInterpolateV,
        'ɵɵdefineBase': ɵɵdefineBase,
        'ɵɵdefineComponent': ɵɵdefineComponent,
        'ɵɵdefineDirective': ɵɵdefineDirective,
        'ɵɵdefineInjectable': ɵɵdefineInjectable,
        'ɵɵdefineInjector': ɵɵdefineInjector,
        'ɵɵdefineNgModule': ɵɵdefineNgModule,
        'ɵɵdefinePipe': ɵɵdefinePipe,
        'ɵɵdirectiveInject': ɵɵdirectiveInject,
        'ɵɵgetFactoryOf': ɵɵgetFactoryOf,
        'ɵɵgetInheritedFactory': ɵɵgetInheritedFactory,
        'ɵɵinject': ɵɵinject,
        'ɵɵinjectAttribute': ɵɵinjectAttribute,
        'ɵɵinjectPipeChangeDetectorRef': ɵɵinjectPipeChangeDetectorRef,
        'ɵɵtemplateRefExtractor': ɵɵtemplateRefExtractor,
        'ɵɵNgOnChangesFeature': ɵɵNgOnChangesFeature,
        'ɵɵProvidersFeature': ɵɵProvidersFeature,
        'ɵɵInheritDefinitionFeature': ɵɵInheritDefinitionFeature,
        'ɵɵcontainer': ɵɵcontainer,
        'ɵɵnextContext': ɵɵnextContext,
        'ɵɵcontainerRefreshStart': ɵɵcontainerRefreshStart,
        'ɵɵcontainerRefreshEnd': ɵɵcontainerRefreshEnd,
        'ɵɵnamespaceHTML': ɵɵnamespaceHTML,
        'ɵɵnamespaceMathML': ɵɵnamespaceMathML,
        'ɵɵnamespaceSVG': ɵɵnamespaceSVG,
        'ɵɵenableBindings': ɵɵenableBindings,
        'ɵɵdisableBindings': ɵɵdisableBindings,
        'ɵɵallocHostVars': ɵɵallocHostVars,
        'ɵɵelementStart': ɵɵelementStart,
        'ɵɵelementEnd': ɵɵelementEnd,
        'ɵɵelement': ɵɵelement,
        'ɵɵelementContainerStart': ɵɵelementContainerStart,
        'ɵɵelementContainerEnd': ɵɵelementContainerEnd,
        'ɵɵelementContainer': ɵɵelementContainer,
        'ɵɵpureFunction0': ɵɵpureFunction0,
        'ɵɵpureFunction1': ɵɵpureFunction1,
        'ɵɵpureFunction2': ɵɵpureFunction2,
        'ɵɵpureFunction3': ɵɵpureFunction3,
        'ɵɵpureFunction4': ɵɵpureFunction4,
        'ɵɵpureFunction5': ɵɵpureFunction5,
        'ɵɵpureFunction6': ɵɵpureFunction6,
        'ɵɵpureFunction7': ɵɵpureFunction7,
        'ɵɵpureFunction8': ɵɵpureFunction8,
        'ɵɵpureFunctionV': ɵɵpureFunctionV,
        'ɵɵgetCurrentView': ɵɵgetCurrentView,
        'ɵɵrestoreView': ɵɵrestoreView,
        'ɵɵlistener': ɵɵlistener,
        'ɵɵload': ɵɵload,
        'ɵɵprojection': ɵɵprojection,
        'ɵɵupdateSyntheticHostBinding': ɵɵupdateSyntheticHostBinding,
        'ɵɵcomponentHostSyntheticListener': ɵɵcomponentHostSyntheticListener,
        'ɵɵpipeBind1': ɵɵpipeBind1,
        'ɵɵpipeBind2': ɵɵpipeBind2,
        'ɵɵpipeBind3': ɵɵpipeBind3,
        'ɵɵpipeBind4': ɵɵpipeBind4,
        'ɵɵpipeBindV': ɵɵpipeBindV,
        'ɵɵprojectionDef': ɵɵprojectionDef,
        'ɵɵhostProperty': ɵɵhostProperty,
        'ɵɵproperty': ɵɵproperty,
        'ɵɵpropertyInterpolate': ɵɵpropertyInterpolate,
        'ɵɵpropertyInterpolate1': ɵɵpropertyInterpolate1,
        'ɵɵpropertyInterpolate2': ɵɵpropertyInterpolate2,
        'ɵɵpropertyInterpolate3': ɵɵpropertyInterpolate3,
        'ɵɵpropertyInterpolate4': ɵɵpropertyInterpolate4,
        'ɵɵpropertyInterpolate5': ɵɵpropertyInterpolate5,
        'ɵɵpropertyInterpolate6': ɵɵpropertyInterpolate6,
        'ɵɵpropertyInterpolate7': ɵɵpropertyInterpolate7,
        'ɵɵpropertyInterpolate8': ɵɵpropertyInterpolate8,
        'ɵɵpropertyInterpolateV': ɵɵpropertyInterpolateV,
        'ɵɵpipe': ɵɵpipe,
        'ɵɵqueryRefresh': ɵɵqueryRefresh,
        'ɵɵviewQuery': ɵɵviewQuery,
        'ɵɵstaticViewQuery': ɵɵstaticViewQuery,
        'ɵɵstaticContentQuery': ɵɵstaticContentQuery,
        'ɵɵloadViewQuery': ɵɵloadViewQuery,
        'ɵɵcontentQuery': ɵɵcontentQuery,
        'ɵɵloadContentQuery': ɵɵloadContentQuery,
        'ɵɵreference': ɵɵreference,
        'ɵɵelementHostAttrs': ɵɵelementHostAttrs,
        'ɵɵclassMap': ɵɵclassMap,
        'ɵɵclassMapInterpolate1': ɵɵclassMapInterpolate1,
        'ɵɵclassMapInterpolate2': ɵɵclassMapInterpolate2,
        'ɵɵclassMapInterpolate3': ɵɵclassMapInterpolate3,
        'ɵɵclassMapInterpolate4': ɵɵclassMapInterpolate4,
        'ɵɵclassMapInterpolate5': ɵɵclassMapInterpolate5,
        'ɵɵclassMapInterpolate6': ɵɵclassMapInterpolate6,
        'ɵɵclassMapInterpolate7': ɵɵclassMapInterpolate7,
        'ɵɵclassMapInterpolate8': ɵɵclassMapInterpolate8,
        'ɵɵclassMapInterpolateV': ɵɵclassMapInterpolateV,
        'ɵɵstyling': ɵɵstyling,
        'ɵɵstyleMap': ɵɵstyleMap,
        'ɵɵstyleProp': ɵɵstyleProp,
        'ɵɵstylePropInterpolate1': ɵɵstylePropInterpolate1,
        'ɵɵstylePropInterpolate2': ɵɵstylePropInterpolate2,
        'ɵɵstylePropInterpolate3': ɵɵstylePropInterpolate3,
        'ɵɵstylePropInterpolate4': ɵɵstylePropInterpolate4,
        'ɵɵstylePropInterpolate5': ɵɵstylePropInterpolate5,
        'ɵɵstylePropInterpolate6': ɵɵstylePropInterpolate6,
        'ɵɵstylePropInterpolate7': ɵɵstylePropInterpolate7,
        'ɵɵstylePropInterpolate8': ɵɵstylePropInterpolate8,
        'ɵɵstylePropInterpolateV': ɵɵstylePropInterpolateV,
        'ɵɵstyleSanitizer': ɵɵstyleSanitizer,
        'ɵɵstylingApply': ɵɵstylingApply,
        'ɵɵclassProp': ɵɵclassProp,
        'ɵɵselect': ɵɵselect,
        'ɵɵtemplate': ɵɵtemplate,
        'ɵɵtext': ɵɵtext,
        'ɵɵtextBinding': ɵɵtextBinding,
        'ɵɵtextInterpolate': ɵɵtextInterpolate,
        'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
        'ɵɵtextInterpolate2': ɵɵtextInterpolate2,
        'ɵɵtextInterpolate3': ɵɵtextInterpolate3,
        'ɵɵtextInterpolate4': ɵɵtextInterpolate4,
        'ɵɵtextInterpolate5': ɵɵtextInterpolate5,
        'ɵɵtextInterpolate6': ɵɵtextInterpolate6,
        'ɵɵtextInterpolate7': ɵɵtextInterpolate7,
        'ɵɵtextInterpolate8': ɵɵtextInterpolate8,
        'ɵɵtextInterpolateV': ɵɵtextInterpolateV,
        'ɵɵembeddedViewStart': ɵɵembeddedViewStart,
        'ɵɵembeddedViewEnd': ɵɵembeddedViewEnd,
        'ɵɵi18n': ɵɵi18n,
        'ɵɵi18nAttributes': ɵɵi18nAttributes,
        'ɵɵi18nExp': ɵɵi18nExp,
        'ɵɵi18nStart': ɵɵi18nStart,
        'ɵɵi18nEnd': ɵɵi18nEnd,
        'ɵɵi18nApply': ɵɵi18nApply,
        'ɵɵi18nPostprocess': ɵɵi18nPostprocess,
        'ɵɵi18nLocalize': ɵɵi18nLocalize,
        'ɵɵresolveWindow': ɵɵresolveWindow,
        'ɵɵresolveDocument': ɵɵresolveDocument,
        'ɵɵresolveBody': ɵɵresolveBody,
        'ɵɵsetComponentScope': ɵɵsetComponentScope,
        'ɵɵsetNgModuleScope': ɵɵsetNgModuleScope,
        'ɵɵsanitizeHtml': ɵɵsanitizeHtml,
        'ɵɵsanitizeStyle': ɵɵsanitizeStyle,
        'ɵɵdefaultStyleSanitizer': ɵɵdefaultStyleSanitizer,
        'ɵɵsanitizeResourceUrl': ɵɵsanitizeResourceUrl,
        'ɵɵsanitizeScript': ɵɵsanitizeScript,
        'ɵɵsanitizeUrl': ɵɵsanitizeUrl,
        'ɵɵsanitizeUrlOrResourceUrl': ɵɵsanitizeUrlOrResourceUrl,
    }); };
    /**
     * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
     *
     * This should be kept up to date with the public exports of @angular/core.
     */
    var angularCoreEnv = (ɵ0$e)();

    /**
     * @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
     */
    var EMPTY_ARRAY$4 = [];
    var moduleQueue = [];
    /**
     * Enqueues moduleDef to be checked later to see if scope can be set on its
     * component declarations.
     */
    function enqueueModuleForDelayedScoping(moduleType, ngModule) {
        moduleQueue.push({ moduleType: moduleType, ngModule: ngModule });
    }
    var flushingModuleQueue = false;
    /**
     * Loops over queued module definitions, if a given module definition has all of its
     * declarations resolved, it dequeues that module definition and sets the scope on
     * its declarations.
     */
    function flushModuleScopingQueueAsMuchAsPossible() {
        if (!flushingModuleQueue) {
            flushingModuleQueue = true;
            try {
                for (var i = moduleQueue.length - 1; i >= 0; i--) {
                    var _a = moduleQueue[i], moduleType = _a.moduleType, ngModule = _a.ngModule;
                    if (ngModule.declarations && ngModule.declarations.every(isResolvedDeclaration)) {
                        // dequeue
                        moduleQueue.splice(i, 1);
                        setScopeOnDeclaredComponents(moduleType, ngModule);
                    }
                }
            }
            finally {
                flushingModuleQueue = false;
            }
        }
    }
    /**
     * Returns truthy if a declaration has resolved. If the declaration happens to be
     * an array of declarations, it will recurse to check each declaration in that array
     * (which may also be arrays).
     */
    function isResolvedDeclaration(declaration) {
        if (Array.isArray(declaration)) {
            return declaration.every(isResolvedDeclaration);
        }
        return !!resolveForwardRef(declaration);
    }
    /**
     * Compiles a module in JIT mode.
     *
     * This function automatically gets called when a class has a `@NgModule` decorator.
     */
    function compileNgModule(moduleType, ngModule) {
        if (ngModule === void 0) { ngModule = {}; }
        compileNgModuleDefs(moduleType, ngModule);
        // Because we don't know if all declarations have resolved yet at the moment the
        // NgModule decorator is executing, we're enqueueing the setting of module scope
        // on its declarations to be run at a later time when all declarations for the module,
        // including forward refs, have resolved.
        enqueueModuleForDelayedScoping(moduleType, ngModule);
    }
    /**
     * Compiles and adds the `ngModuleDef` and `ngInjectorDef` properties to the module class.
     *
     * It's possible to compile a module via this API which will allow duplicate declarations in its
     * root.
     */
    function compileNgModuleDefs(moduleType, ngModule, allowDuplicateDeclarationsInRoot) {
        if (allowDuplicateDeclarationsInRoot === void 0) { allowDuplicateDeclarationsInRoot = false; }
        ngDevMode && assertDefined(moduleType, 'Required value moduleType');
        ngDevMode && assertDefined(ngModule, 'Required value ngModule');
        var declarations = flatten(ngModule.declarations || EMPTY_ARRAY$4);
        var ngModuleDef = null;
        Object.defineProperty(moduleType, NG_MODULE_DEF, {
            configurable: true,
            get: function () {
                if (ngModuleDef === null) {
                    if (ngDevMode && ngModule.imports && ngModule.imports.indexOf(moduleType) > -1) {
                        // We need to assert this immediately, because allowing it to continue will cause it to
                        // go into an infinite loop before we've reached the point where we throw all the errors.
                        throw new Error("'" + stringifyForError(moduleType) + "' module can't import itself");
                    }
                    ngModuleDef = getCompilerFacade().compileNgModule(angularCoreEnv, "ng:///" + moduleType.name + "/ngModuleDef.js", {
                        type: moduleType,
                        bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY$4).map(resolveForwardRef),
                        declarations: declarations.map(resolveForwardRef),
                        imports: flatten(ngModule.imports || EMPTY_ARRAY$4)
                            .map(resolveForwardRef)
                            .map(expandModuleWithProviders),
                        exports: flatten(ngModule.exports || EMPTY_ARRAY$4)
                            .map(resolveForwardRef)
                            .map(expandModuleWithProviders),
                        emitInline: true,
                        schemas: ngModule.schemas ? flatten(ngModule.schemas) : null,
                        id: ngModule.id || null,
                    });
                }
                return ngModuleDef;
            }
        });
        var ngInjectorDef = null;
        Object.defineProperty(moduleType, NG_INJECTOR_DEF, {
            get: function () {
                if (ngInjectorDef === null) {
                    ngDevMode && verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot);
                    var meta = {
                        name: moduleType.name,
                        type: moduleType,
                        deps: reflectDependencies(moduleType),
                        providers: ngModule.providers || EMPTY_ARRAY$4,
                        imports: [
                            (ngModule.imports || EMPTY_ARRAY$4).map(resolveForwardRef),
                            (ngModule.exports || EMPTY_ARRAY$4).map(resolveForwardRef),
                        ],
                    };
                    ngInjectorDef = getCompilerFacade().compileInjector(angularCoreEnv, "ng:///" + moduleType.name + "/ngInjectorDef.js", meta);
                }
                return ngInjectorDef;
            },
            // Make the property configurable in dev mode to allow overriding in tests
            configurable: !!ngDevMode,
        });
    }
    function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot, importingModule) {
        if (verifiedNgModule.get(moduleType))
            return;
        verifiedNgModule.set(moduleType, true);
        moduleType = resolveForwardRef(moduleType);
        var ngModuleDef;
        if (importingModule) {
            ngModuleDef = getNgModuleDef(moduleType);
            if (!ngModuleDef) {
                throw new Error("Unexpected value '" + moduleType.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation.");
            }
        }
        else {
            ngModuleDef = getNgModuleDef(moduleType, true);
        }
        var errors = [];
        var declarations = maybeUnwrapFn(ngModuleDef.declarations);
        var imports = maybeUnwrapFn(ngModuleDef.imports);
        flatten(imports).map(unwrapModuleWithProvidersImports).forEach(function (mod) {
            verifySemanticsOfNgModuleImport(mod, moduleType);
            verifySemanticsOfNgModuleDef(mod, false, moduleType);
        });
        var exports = maybeUnwrapFn(ngModuleDef.exports);
        declarations.forEach(verifyDeclarationsHaveDefinitions);
        var combinedDeclarations = __spread(declarations.map(resolveForwardRef), flatten(imports.map(computeCombinedExports)).map(resolveForwardRef));
        exports.forEach(verifyExportsAreDeclaredOrReExported);
        declarations.forEach(function (decl) { return verifyDeclarationIsUnique(decl, allowDuplicateDeclarationsInRoot); });
        declarations.forEach(verifyComponentEntryComponentsIsPartOfNgModule);
        var ngModule = getAnnotation(moduleType, 'NgModule');
        if (ngModule) {
            ngModule.imports &&
                flatten(ngModule.imports).map(unwrapModuleWithProvidersImports).forEach(function (mod) {
                    verifySemanticsOfNgModuleImport(mod, moduleType);
                    verifySemanticsOfNgModuleDef(mod, false, moduleType);
                });
            ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyCorrectBootstrapType);
            ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyComponentIsPartOfNgModule);
            ngModule.entryComponents &&
                deepForEach(ngModule.entryComponents, verifyComponentIsPartOfNgModule);
        }
        // Throw Error if any errors were detected.
        if (errors.length) {
            throw new Error(errors.join('\n'));
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////
        function verifyDeclarationsHaveDefinitions(type) {
            type = resolveForwardRef(type);
            var def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef(type);
            if (!def) {
                errors.push("Unexpected value '" + stringifyForError(type) + "' declared by the module '" + stringifyForError(moduleType) + "'. Please add a @Pipe/@Directive/@Component annotation.");
            }
        }
        function verifyExportsAreDeclaredOrReExported(type) {
            type = resolveForwardRef(type);
            var kind = getComponentDef(type) && 'component' || getDirectiveDef(type) && 'directive' ||
                getPipeDef(type) && 'pipe';
            if (kind) {
                // only checked if we are declared as Component, Directive, or Pipe
                // Modules don't need to be declared or imported.
                if (combinedDeclarations.lastIndexOf(type) === -1) {
                    // We are exporting something which we don't explicitly declare or import.
                    errors.push("Can't export " + kind + " " + stringifyForError(type) + " from " + stringifyForError(moduleType) + " as it was neither declared nor imported!");
                }
            }
        }
        function verifyDeclarationIsUnique(type, suppressErrors) {
            type = resolveForwardRef(type);
            var existingModule = ownerNgModule.get(type);
            if (existingModule && existingModule !== moduleType) {
                if (!suppressErrors) {
                    var modules = [existingModule, moduleType].map(stringifyForError).sort();
                    errors.push("Type " + stringifyForError(type) + " is part of the declarations of 2 modules: " + modules[0] + " and " + modules[1] + "! " +
                        ("Please consider moving " + stringifyForError(type) + " to a higher module that imports " + modules[0] + " and " + modules[1] + ". ") +
                        ("You can also create a new NgModule that exports and includes " + stringifyForError(type) + " then import that NgModule in " + modules[0] + " and " + modules[1] + "."));
                }
            }
            else {
                // Mark type as having owner.
                ownerNgModule.set(type, moduleType);
            }
        }
        function verifyComponentIsPartOfNgModule(type) {
            type = resolveForwardRef(type);
            var existingModule = ownerNgModule.get(type);
            if (!existingModule) {
                errors.push("Component " + stringifyForError(type) + " is not part of any NgModule or the module has not been imported into your module.");
            }
        }
        function verifyCorrectBootstrapType(type) {
            type = resolveForwardRef(type);
            if (!getComponentDef(type)) {
                errors.push(stringifyForError(type) + " cannot be used as an entry component.");
            }
        }
        function verifyComponentEntryComponentsIsPartOfNgModule(type) {
            type = resolveForwardRef(type);
            if (getComponentDef(type)) {
                // We know we are component
                var component = getAnnotation(type, 'Component');
                if (component && component.entryComponents) {
                    deepForEach(component.entryComponents, verifyComponentIsPartOfNgModule);
                }
            }
        }
        function verifySemanticsOfNgModuleImport(type, importingModule) {
            type = resolveForwardRef(type);
            if (getComponentDef(type) || getDirectiveDef(type)) {
                throw new Error("Unexpected directive '" + type.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation.");
            }
            if (getPipeDef(type)) {
                throw new Error("Unexpected pipe '" + type.name + "' imported by the module '" + importingModule.name + "'. Please add an @NgModule annotation.");
            }
        }
    }
    function unwrapModuleWithProvidersImports(typeOrWithProviders) {
        typeOrWithProviders = resolveForwardRef(typeOrWithProviders);
        return typeOrWithProviders.ngModule || typeOrWithProviders;
    }
    function getAnnotation(type, name) {
        var annotation = null;
        collect(type.__annotations__);
        collect(type.decorators);
        return annotation;
        function collect(annotations) {
            if (annotations) {
                annotations.forEach(readAnnotation);
            }
        }
        function readAnnotation(decorator) {
            if (!annotation) {
                var proto = Object.getPrototypeOf(decorator);
                if (proto.ngMetadataName == name) {
                    annotation = decorator;
                }
                else if (decorator.type) {
                    var proto_1 = Object.getPrototypeOf(decorator.type);
                    if (proto_1.ngMetadataName == name) {
                        annotation = decorator.args[0];
                    }
                }
            }
        }
    }
    /**
     * Keep track of compiled components. This is needed because in tests we often want to compile the
     * same component with more than one NgModule. This would cause an error unless we reset which
     * NgModule the component belongs to. We keep the list of compiled components here so that the
     * TestBed can reset it later.
     */
    var ownerNgModule = new Map();
    var verifiedNgModule = new Map();
    function resetCompiledComponents() {
        ownerNgModule = new Map();
        verifiedNgModule = new Map();
        moduleQueue.length = 0;
    }
    /**
     * Computes the combined declarations of explicit declarations, as well as declarations inherited by
     * traversing the exports of imported modules.
     * @param type
     */
    function computeCombinedExports(type) {
        type = resolveForwardRef(type);
        var ngModuleDef = getNgModuleDef(type, true);
        return __spread(flatten(maybeUnwrapFn(ngModuleDef.exports).map(function (type) {
            var ngModuleDef = getNgModuleDef(type);
            if (ngModuleDef) {
                verifySemanticsOfNgModuleDef(type, false);
                return computeCombinedExports(type);
            }
            else {
                return type;
            }
        })));
    }
    /**
     * Some declared components may be compiled asynchronously, and thus may not have their
     * ngComponentDef set yet. If this is the case, then a reference to the module is written into
     * the `ngSelectorScope` property of the declared type.
     */
    function setScopeOnDeclaredComponents(moduleType, ngModule) {
        var declarations = flatten(ngModule.declarations || EMPTY_ARRAY$4);
        var transitiveScopes = transitiveScopesFor(moduleType);
        declarations.forEach(function (declaration) {
            if (declaration.hasOwnProperty(NG_COMPONENT_DEF)) {
                // An `ngComponentDef` field exists - go ahead and patch the component directly.
                var component = declaration;
                var componentDef = getComponentDef(component);
                patchComponentDefWithScope(componentDef, transitiveScopes);
            }
            else if (!declaration.hasOwnProperty(NG_DIRECTIVE_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
                // Set `ngSelectorScope` for future reference when the component compilation finishes.
                declaration.ngSelectorScope = moduleType;
            }
        });
    }
    /**
     * Patch the definition of a component with directives and pipes from the compilation scope of
     * a given module.
     */
    function patchComponentDefWithScope(componentDef, transitiveScopes) {
        componentDef.directiveDefs = function () {
            return Array.from(transitiveScopes.compilation.directives)
                .map(function (dir) { return dir.hasOwnProperty(NG_COMPONENT_DEF) ? getComponentDef(dir) :
                getDirectiveDef(dir); })
                .filter(function (def) { return !!def; });
        };
        componentDef.pipeDefs = function () {
            return Array.from(transitiveScopes.compilation.pipes).map(function (pipe) { return getPipeDef(pipe); });
        };
        componentDef.schemas = transitiveScopes.schemas;
        // Since we avoid Components/Directives/Pipes recompiling in case there are no overrides, we
        // may face a problem where previously compiled defs available to a given Component/Directive
        // are cached in TView and may become stale (in case any of these defs gets recompiled). In
        // order to avoid this problem, we force fresh TView to be created.
        componentDef.tView = null;
    }
    /**
     * Compute the pair of transitive scopes (compilation scope and exported scope) for a given module.
     *
     * This operation is memoized and the result is cached on the module's definition. It can be called
     * on modules with components that have not fully compiled yet, but the result should not be used
     * until they have.
     */
    function transitiveScopesFor(moduleType, processNgModuleFn) {
        if (!isNgModule(moduleType)) {
            throw new Error(moduleType.name + " does not have an ngModuleDef");
        }
        var def = getNgModuleDef(moduleType);
        if (def.transitiveCompileScopes !== null) {
            return def.transitiveCompileScopes;
        }
        var scopes = {
            schemas: def.schemas || null,
            compilation: {
                directives: new Set(),
                pipes: new Set(),
            },
            exported: {
                directives: new Set(),
                pipes: new Set(),
            },
        };
        maybeUnwrapFn(def.declarations).forEach(function (declared) {
            var declaredWithDefs = declared;
            if (getPipeDef(declaredWithDefs)) {
                scopes.compilation.pipes.add(declared);
            }
            else {
                // Either declared has an ngComponentDef or ngDirectiveDef, or it's a component which hasn't
                // had its template compiled yet. In either case, it gets added to the compilation's
                // directives.
                scopes.compilation.directives.add(declared);
            }
        });
        maybeUnwrapFn(def.imports).forEach(function (imported) {
            var importedType = imported;
            if (!isNgModule(importedType)) {
                throw new Error("Importing " + importedType.name + " which does not have an ngModuleDef");
            }
            if (processNgModuleFn) {
                processNgModuleFn(importedType);
            }
            // When this module imports another, the imported module's exported directives and pipes are
            // added to the compilation scope of this module.
            var importedScope = transitiveScopesFor(importedType, processNgModuleFn);
            importedScope.exported.directives.forEach(function (entry) { return scopes.compilation.directives.add(entry); });
            importedScope.exported.pipes.forEach(function (entry) { return scopes.compilation.pipes.add(entry); });
        });
        maybeUnwrapFn(def.exports).forEach(function (exported) {
            var exportedType = exported;
            // Either the type is a module, a pipe, or a component/directive (which may not have an
            // ngComponentDef as it might be compiled asynchronously).
            if (isNgModule(exportedType)) {
                // When this module exports another, the exported module's exported directives and pipes are
                // added to both the compilation and exported scopes of this module.
                var exportedScope = transitiveScopesFor(exportedType, processNgModuleFn);
                exportedScope.exported.directives.forEach(function (entry) {
                    scopes.compilation.directives.add(entry);
                    scopes.exported.directives.add(entry);
                });
                exportedScope.exported.pipes.forEach(function (entry) {
                    scopes.compilation.pipes.add(entry);
                    scopes.exported.pipes.add(entry);
                });
            }
            else if (getPipeDef(exportedType)) {
                scopes.exported.pipes.add(exportedType);
            }
            else {
                scopes.exported.directives.add(exportedType);
            }
        });
        def.transitiveCompileScopes = scopes;
        return scopes;
    }
    function expandModuleWithProviders(value) {
        if (isModuleWithProviders(value)) {
            return value.ngModule;
        }
        return value;
    }
    function isModuleWithProviders(value) {
        return value.ngModule !== undefined;
    }
    function isNgModule(value) {
        return !!getNgModuleDef(value);
    }

    /**
     * @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
     */
    /**
     * Compile an Angular component according to its decorator metadata, and patch the resulting
     * ngComponentDef onto the component type.
     *
     * Compilation may be asynchronous (due to the need to resolve URLs for the component template or
     * other resources, for example). In the event that compilation is not immediate, `compileComponent`
     * will enqueue resource resolution into a global queue and will fail to return the `ngComponentDef`
     * until the global queue has been resolved with a call to `resolveComponentResources`.
     */
    function compileComponent(type, metadata) {
        var ngComponentDef = null;
        // Metadata may have resources which need to be resolved.
        maybeQueueResolutionOfComponentResources(type, metadata);
        Object.defineProperty(type, NG_COMPONENT_DEF, {
            get: function () {
                var compiler = getCompilerFacade();
                if (ngComponentDef === null) {
                    if (componentNeedsResolution(metadata)) {
                        var error = ["Component '" + type.name + "' is not resolved:"];
                        if (metadata.templateUrl) {
                            error.push(" - templateUrl: " + metadata.templateUrl);
                        }
                        if (metadata.styleUrls && metadata.styleUrls.length) {
                            error.push(" - styleUrls: " + JSON.stringify(metadata.styleUrls));
                        }
                        error.push("Did you run and wait for 'resolveComponentResources()'?");
                        throw new Error(error.join('\n'));
                    }
                    var templateUrl = metadata.templateUrl || "ng:///" + type.name + "/template.html";
                    var meta = __assign({}, directiveMetadata(type, metadata), { typeSourceSpan: compiler.createParseSourceSpan('Component', type.name, templateUrl), template: metadata.template || '', preserveWhitespaces: metadata.preserveWhitespaces || false, styles: metadata.styles || EMPTY_ARRAY, animations: metadata.animations, directives: [], changeDetection: metadata.changeDetection, pipes: new Map(), encapsulation: metadata.encapsulation || exports.ViewEncapsulation.Emulated, interpolation: metadata.interpolation, viewProviders: metadata.viewProviders || null });
                    if (meta.usesInheritance) {
                        addBaseDefToUndecoratedParents(type);
                    }
                    ngComponentDef = compiler.compileComponent(angularCoreEnv, templateUrl, meta);
                    // When NgModule decorator executed, we enqueued the module definition such that
                    // it would only dequeue and add itself as module scope to all of its declarations,
                    // but only if  if all of its declarations had resolved. This call runs the check
                    // to see if any modules that are in the queue can be dequeued and add scope to
                    // their declarations.
                    flushModuleScopingQueueAsMuchAsPossible();
                    // If component compilation is async, then the @NgModule annotation which declares the
                    // component may execute and set an ngSelectorScope property on the component type. This
                    // allows the component to patch itself with directiveDefs from the module after it
                    // finishes compiling.
                    if (hasSelectorScope(type)) {
                        var scopes = transitiveScopesFor(type.ngSelectorScope);
                        patchComponentDefWithScope(ngComponentDef, scopes);
                    }
                }
                return ngComponentDef;
            },
            // Make the property configurable in dev mode to allow overriding in tests
            configurable: !!ngDevMode,
        });
        // Add ngInjectableDef so components are reachable through the module injector by default
        // This is mostly to support injecting components in tests. In real application code,
        // components should be retrieved through the node injector, so this isn't a problem.
        compileInjectable(type);
    }
    function hasSelectorScope(component) {
        return component.ngSelectorScope !== undefined;
    }
    /**
     * Compile an Angular directive according to its decorator metadata, and patch the resulting
     * ngDirectiveDef onto the component type.
     *
     * In the event that compilation is not immediate, `compileDirective` will return a `Promise` which
     * will resolve when compilation completes and the directive becomes usable.
     */
    function compileDirective(type, directive) {
        var ngDirectiveDef = null;
        Object.defineProperty(type, NG_DIRECTIVE_DEF, {
            get: function () {
                if (ngDirectiveDef === null) {
                    var name_1 = type && type.name;
                    var sourceMapUrl = "ng:///" + name_1 + "/ngDirectiveDef.js";
                    var compiler = getCompilerFacade();
                    var facade = directiveMetadata(type, directive);
                    facade.typeSourceSpan = compiler.createParseSourceSpan('Directive', name_1, sourceMapUrl);
                    if (facade.usesInheritance) {
                        addBaseDefToUndecoratedParents(type);
                    }
                    ngDirectiveDef = compiler.compileDirective(angularCoreEnv, sourceMapUrl, facade);
                }
                return ngDirectiveDef;
            },
            // Make the property configurable in dev mode to allow overriding in tests
            configurable: !!ngDevMode,
        });
        // Add ngInjectableDef so directives are reachable through the module injector by default
        // This is mostly to support injecting directives in tests. In real application code,
        // directives should be retrieved through the node injector, so this isn't a problem.
        compileInjectable(type);
    }
    function extendsDirectlyFromObject(type) {
        return Object.getPrototypeOf(type.prototype) === Object.prototype;
    }
    /**
     * Extract the `R3DirectiveMetadata` for a particular directive (either a `Directive` or a
     * `Component`).
     */
    function directiveMetadata(type, metadata) {
        // Reflect inputs and outputs.
        var propMetadata = getReflect().ownPropMetadata(type);
        return {
            name: type.name,
            type: type,
            typeArgumentCount: 0,
            selector: metadata.selector,
            deps: reflectDependencies(type),
            host: metadata.host || EMPTY_OBJ,
            propMetadata: propMetadata,
            inputs: metadata.inputs || EMPTY_ARRAY,
            outputs: metadata.outputs || EMPTY_ARRAY,
            queries: extractQueriesMetadata(type, propMetadata, isContentQuery),
            lifecycle: { usesOnChanges: type.prototype.hasOwnProperty('ngOnChanges') },
            typeSourceSpan: null,
            usesInheritance: !extendsDirectlyFromObject(type),
            exportAs: extractExportAs(metadata.exportAs),
            providers: metadata.providers || null,
            viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery),
        };
    }
    /**
     * Adds an `ngBaseDef` to all parent classes of a type that don't have an Angular decorator.
     */
    function addBaseDefToUndecoratedParents(type) {
        var objPrototype = Object.prototype;
        var parent = Object.getPrototypeOf(type);
        // Go up the prototype until we hit `Object`.
        while (parent && parent !== objPrototype) {
            // Since inheritance works if the class was annotated already, we only need to add
            // the base def if there are no annotations and the base def hasn't been created already.
            if (!getDirectiveDef(parent) && !getComponentDef(parent) && !getBaseDef(parent)) {
                var facade = extractBaseDefMetadata(parent);
                facade && compileBase(parent, facade);
            }
            parent = Object.getPrototypeOf(parent);
        }
    }
    /** Compiles the base metadata into a base definition. */
    function compileBase(type, facade) {
        var ngBaseDef = null;
        Object.defineProperty(type, NG_BASE_DEF, {
            get: function () {
                if (ngBaseDef === null) {
                    var name_2 = type && type.name;
                    var sourceMapUrl = "ng://" + name_2 + "/ngBaseDef.js";
                    var compiler = getCompilerFacade();
                    ngBaseDef = compiler.compileBase(angularCoreEnv, sourceMapUrl, facade);
                }
                return ngBaseDef;
            },
            // Make the property configurable in dev mode to allow overriding in tests
            configurable: !!ngDevMode,
        });
    }
    /** Extracts the metadata necessary to construct an `ngBaseDef` from a class. */
    function extractBaseDefMetadata(type) {
        var propMetadata = getReflect().ownPropMetadata(type);
        var viewQueries = extractQueriesMetadata(type, propMetadata, isViewQuery);
        var queries = extractQueriesMetadata(type, propMetadata, isContentQuery);
        var inputs;
        var outputs;
        // We only need to know whether there are any HostListener or HostBinding
        // decorators present, the parsing logic is in the compiler already.
        var hasHostDecorators = false;
        var _loop_1 = function (field) {
            propMetadata[field].forEach(function (ann) {
                var metadataName = ann.ngMetadataName;
                if (metadataName === 'Input') {
                    inputs = inputs || {};
                    inputs[field] = ann.bindingPropertyName ? [ann.bindingPropertyName, field] : field;
                }
                else if (metadataName === 'Output') {
                    outputs = outputs || {};
                    outputs[field] = ann.bindingPropertyName || field;
                }
                else if (metadataName === 'HostBinding' || metadataName === 'HostListener') {
                    hasHostDecorators = true;
                }
            });
        };
        for (var field in propMetadata) {
            _loop_1(field);
        }
        // Only generate the base def if there's any info inside it.
        if (inputs || outputs || viewQueries.length || queries.length || hasHostDecorators) {
            return { name: type.name, type: type, inputs: inputs, outputs: outputs, viewQueries: viewQueries, queries: queries, propMetadata: propMetadata };
        }
        return null;
    }
    function convertToR3QueryPredicate(selector) {
        return typeof selector === 'string' ? splitByComma(selector) : resolveForwardRef(selector);
    }
    function convertToR3QueryMetadata(propertyName, ann) {
        return {
            propertyName: propertyName,
            predicate: convertToR3QueryPredicate(ann.selector),
            descendants: ann.descendants,
            first: ann.first,
            read: ann.read ? ann.read : null,
            static: !!ann.static
        };
    }
    function extractQueriesMetadata(type, propMetadata, isQueryAnn) {
        var queriesMeta = [];
        var _loop_2 = function (field) {
            if (propMetadata.hasOwnProperty(field)) {
                var annotations_1 = propMetadata[field];
                annotations_1.forEach(function (ann) {
                    if (isQueryAnn(ann)) {
                        if (!ann.selector) {
                            throw new Error("Can't construct a query for the property \"" + field + "\" of " +
                                ("\"" + stringifyForError(type) + "\" since the query selector wasn't defined."));
                        }
                        if (annotations_1.some(isInputAnn)) {
                            throw new Error("Cannot combine @Input decorators with query decorators");
                        }
                        queriesMeta.push(convertToR3QueryMetadata(field, ann));
                    }
                });
            }
        };
        for (var field in propMetadata) {
            _loop_2(field);
        }
        return queriesMeta;
    }
    function extractExportAs(exportAs) {
        if (exportAs === undefined) {
            return null;
        }
        return exportAs.split(',').map(function (part) { return part.trim(); });
    }
    function isContentQuery(value) {
        var name = value.ngMetadataName;
        return name === 'ContentChild' || name === 'ContentChildren';
    }
    function isViewQuery(value) {
        var name = value.ngMetadataName;
        return name === 'ViewChild' || name === 'ViewChildren';
    }
    function isInputAnn(value) {
        return value.ngMetadataName === 'Input';
    }
    function splitByComma(value) {
        return value.split(',').map(function (piece) { return piece.trim(); });
    }

    /**
     * @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
     */
    function compilePipe(type, meta) {
        var ngPipeDef = null;
        Object.defineProperty(type, NG_PIPE_DEF, {
            get: function () {
                if (ngPipeDef === null) {
                    var typeName = type.name;
                    ngPipeDef =
                        getCompilerFacade().compilePipe(angularCoreEnv, "ng:///" + typeName + "/ngPipeDef.js", {
                            type: type,
                            typeArgumentCount: 0,
                            name: typeName,
                            deps: reflectDependencies(type),
                            pipeName: meta.name,
                            pure: meta.pure !== undefined ? meta.pure : true
                        });
                }
                return ngPipeDef;
            },
            // Make the property configurable in dev mode to allow overriding in tests
            configurable: !!ngDevMode,
        });
    }

    /**
     * @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
     */
    var ɵ0$f = function (dir) {
        if (dir === void 0) { dir = {}; }
        return dir;
    }, ɵ1$4 = function (type, meta) { return SWITCH_COMPILE_DIRECTIVE(type, meta); };
    /**
     * Type of the Directive metadata.
     *
     * @publicApi
     */
    var Directive = makeDecorator('Directive', ɵ0$f, undefined, undefined, ɵ1$4);
    var ɵ2$1 = function (c) {
        if (c === void 0) { c = {}; }
        return (__assign({ changeDetection: exports.ChangeDetectionStrategy.Default }, c));
    }, ɵ3$1 = function (type, meta) { return SWITCH_COMPILE_COMPONENT(type, meta); };
    /**
     * Component decorator and metadata.
     *
     * @Annotation
     * @publicApi
     */
    var Component = makeDecorator('Component', ɵ2$1, Directive, undefined, ɵ3$1);
    var ɵ4 = function (p) { return (__assign({ pure: true }, p)); }, ɵ5 = function (type, meta) { return SWITCH_COMPILE_PIPE(type, meta); };
    /**
     * @Annotation
     * @publicApi
     */
    var Pipe = makeDecorator('Pipe', ɵ4, undefined, undefined, ɵ5);
    var ɵ6 = function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); };
    /**
     * @Annotation
     * @publicApi
     */
    var Input = makePropDecorator('Input', ɵ6);
    var ɵ7 = function (bindingPropertyName) { return ({ bindingPropertyName: bindingPropertyName }); };
    /**
     * @Annotation
     * @publicApi
     */
    var Output = makePropDecorator('Output', ɵ7);
    var ɵ8 = function (hostPropertyName) { return ({ hostPropertyName: hostPropertyName }); };
    /**
     * @Annotation
     * @publicApi
     */
    var HostBinding = makePropDecorator('HostBinding', ɵ8);
    var ɵ9 = function (eventName, args) { return ({ eventName: eventName, args: args }); };
    /**
     * Decorator that binds a DOM event to a host listener and supplies configuration metadata.
     * Angular invokes the supplied handler method when the host element emits the specified event,
     * and updates the bound element with the result.
     *
     * If the handler method returns false, applies `preventDefault` on the bound element.
     *
     * @usageNotes
     *
     * The following example declares a directive
     * that attaches a click listener to a button and counts clicks.
     *
     * ```ts
     * @Directive({selector: 'button[counting]'})
     * class CountClicks {
     *   numberOfClicks = 0;
     *
     *   @HostListener('click', ['$event.target'])
     *   onClick(btn) {
     *     console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
     *  }
     * }
     *
     * @Component({
     *   selector: 'app',
     *   template: '<button counting>Increment</button>',
     * })
     * class App {}
     * ```
     *
     * @Annotation
     * @publicApi
     */
    var HostListener = makePropDecorator('HostListener', ɵ9);
    var SWITCH_COMPILE_COMPONENT__POST_R3__ = compileComponent;
    var SWITCH_COMPILE_DIRECTIVE__POST_R3__ = compileDirective;
    var SWITCH_COMPILE_PIPE__POST_R3__ = compilePipe;
    var SWITCH_COMPILE_COMPONENT__PRE_R3__ = noop;
    var SWITCH_COMPILE_DIRECTIVE__PRE_R3__ = noop;
    var SWITCH_COMPILE_PIPE__PRE_R3__ = noop;
    var SWITCH_COMPILE_COMPONENT = SWITCH_COMPILE_COMPONENT__PRE_R3__;
    var SWITCH_COMPILE_DIRECTIVE = SWITCH_COMPILE_DIRECTIVE__PRE_R3__;
    var SWITCH_COMPILE_PIPE = SWITCH_COMPILE_PIPE__PRE_R3__;

    /**
     * @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
     */
    var ɵ0$g = function (ngModule) { return ngModule; }, ɵ1$5 = 
    /**
     * Decorator that marks the following class as an NgModule, and supplies
     * configuration metadata for it.
     *
     * * The `declarations` and `entryComponents` options configure the compiler
     * with information about what belongs to the NgModule.
     * * The `providers` options configures the NgModule's injector to provide
     * dependencies the NgModule members.
     * * The `imports` and `exports` options bring in members from other modules, and make
     * this module's members available to others.
     */
    function (type, meta) { return SWITCH_COMPILE_NGMODULE(type, meta); };
    /**
     * @Annotation
     * @publicApi
     */
    var NgModule = makeDecorator('NgModule', ɵ0$g, undefined, undefined, ɵ1$5);
    function preR3NgModuleCompile(moduleType, metadata) {
        var imports = (metadata && metadata.imports) || [];
        if (metadata && metadata.exports) {
            imports = __spread(imports, [metadata.exports]);
        }
        moduleType.ngInjectorDef = ɵɵdefineInjector({
            factory: convertInjectableProviderToFactory(moduleType, { useClass: moduleType }),
            providers: metadata && metadata.providers,
            imports: imports,
        });
    }
    var SWITCH_COMPILE_NGMODULE__POST_R3__ = compileNgModule;
    var SWITCH_COMPILE_NGMODULE__PRE_R3__ = preR3NgModuleCompile;
    var SWITCH_COMPILE_NGMODULE = SWITCH_COMPILE_NGMODULE__PRE_R3__;

    /**
     * @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
     */

    /**
     * @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
     */
    /**
     * A function that will be executed when an application is initialized.
     *
     * @publicApi
     */
    var APP_INITIALIZER = new InjectionToken('Application Initializer');
    /**
     * A class that reflects the state of running {@link APP_INITIALIZER}s.
     *
     * @publicApi
     */
    var ApplicationInitStatus = /** @class */ (function () {
        function ApplicationInitStatus(appInits) {
            var _this = this;
            this.appInits = appInits;
            this.initialized = false;
            this.done = false;
            this.donePromise = new Promise(function (res, rej) {
                _this.resolve = res;
                _this.reject = rej;
            });
        }
        /** @internal */
        ApplicationInitStatus.prototype.runInitializers = function () {
            var _this = this;
            if (this.initialized) {
                return;
            }
            var asyncInitPromises = [];
            var complete = function () {
                _this.done = true;
                _this.resolve();
            };
            if (this.appInits) {
                for (var i = 0; i < this.appInits.length; i++) {
                    var initResult = this.appInits[i]();
                    if (isPromise(initResult)) {
                        asyncInitPromises.push(initResult);
                    }
                }
            }
            Promise.all(asyncInitPromises).then(function () { complete(); }).catch(function (e) { _this.reject(e); });
            if (asyncInitPromises.length === 0) {
                complete();
            }
            this.initialized = true;
        };
        ApplicationInitStatus = __decorate([
            Injectable(),
            __param(0, Inject(APP_INITIALIZER)), __param(0, Optional()),
            __metadata("design:paramtypes", [Array])
        ], ApplicationInitStatus);
        return ApplicationInitStatus;
    }());

    /**
     * @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
     */
    /**
     * A DI Token representing a unique string id assigned to the application by Angular and used
     * primarily for prefixing application attributes and CSS styles when
     * {@link ViewEncapsulation#Emulated ViewEncapsulation.Emulated} is being used.
     *
     * If you need to avoid randomly generated value to be used as an application id, you can provide
     * a custom value via a DI provider <!-- TODO: provider --> configuring the root {@link Injector}
     * using this token.
     * @publicApi
     */
    var APP_ID = new InjectionToken('AppId');
    function _appIdRandomProviderFactory() {
        return "" + _randomChar() + _randomChar() + _randomChar();
    }
    /**
     * Providers that will generate a random APP_ID_TOKEN.
     * @publicApi
     */
    var APP_ID_RANDOM_PROVIDER = {
        provide: APP_ID,
        useFactory: _appIdRandomProviderFactory,
        deps: [],
    };
    function _randomChar() {
        return String.fromCharCode(97 + Math.floor(Math.random() * 25));
    }
    /**
     * A function that will be executed when a platform is initialized.
     * @publicApi
     */
    var PLATFORM_INITIALIZER = new InjectionToken('Platform Initializer');
    /**
     * A token that indicates an opaque platform id.
     * @publicApi
     */
    var PLATFORM_ID = new InjectionToken('Platform ID');
    /**
     * All callbacks provided via this token will be called for every component that is bootstrapped.
     * Signature of the callback:
     *
     * `(componentRef: ComponentRef) => void`.
     *
     * @publicApi
     */
    var APP_BOOTSTRAP_LISTENER = new InjectionToken('appBootstrapListener');
    /**
     * A token which indicates the root directory of the application
     * @publicApi
     */
    var PACKAGE_ROOT_URL = new InjectionToken('Application Packages Root URL');

    /**
     * @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
     */
    var Console = /** @class */ (function () {
        function Console() {
        }
        Console.prototype.log = function (message) {
            // tslint:disable-next-line:no-console
            console.log(message);
        };
        // Note: for reporting errors use `DOM.logError()` as it is platform specific
        Console.prototype.warn = function (message) {
            // tslint:disable-next-line:no-console
            console.warn(message);
        };
        Console = __decorate([
            Injectable()
        ], Console);
        return Console;
    }());

    /**
     * @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
     */
    /**
     * Provide this token to set the locale of your application.
     * It is used for i18n extraction, by i18n pipes (DatePipe, I18nPluralPipe, CurrencyPipe,
     * DecimalPipe and PercentPipe) and by ICU expressions.
     *
     * See the [i18n guide](guide/i18n#setting-up-locale) for more information.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * import { LOCALE_ID } from '@angular/core';
     * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
     * import { AppModule } from './app/app.module';
     *
     * platformBrowserDynamic().bootstrapModule(AppModule, {
     *   providers: [{provide: LOCALE_ID, useValue: 'en-US' }]
     * });
     * ```
     *
     * @publicApi
     */
    var LOCALE_ID$1 = new InjectionToken('LocaleId');
    /**
     * Use this token at bootstrap to provide the content of your translation file (`xtb`,
     * `xlf` or `xlf2`) when you want to translate your application in another language.
     *
     * See the [i18n guide](guide/i18n#merge) for more information.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * import { TRANSLATIONS } from '@angular/core';
     * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
     * import { AppModule } from './app/app.module';
     *
     * // content of your translation file
     * const translations = '....';
     *
     * platformBrowserDynamic().bootstrapModule(AppModule, {
     *   providers: [{provide: TRANSLATIONS, useValue: translations }]
     * });
     * ```
     *
     * @publicApi
     */
    var TRANSLATIONS$1 = new InjectionToken('Translations');
    /**
     * Provide this token at bootstrap to set the format of your {@link TRANSLATIONS}: `xtb`,
     * `xlf` or `xlf2`.
     *
     * See the [i18n guide](guide/i18n#merge) for more information.
     *
     * @usageNotes
     * ### Example
     *
     * ```typescript
     * import { TRANSLATIONS_FORMAT } from '@angular/core';
     * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
     * import { AppModule } from './app/app.module';
     *
     * platformBrowserDynamic().bootstrapModule(AppModule, {
     *   providers: [{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
     * });
     * ```
     *
     * @publicApi
     */
    var TRANSLATIONS_FORMAT = new InjectionToken('TranslationsFormat');
    (function (MissingTranslationStrategy) {
        MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error";
        MissingTranslationStrategy[MissingTranslationStrategy["Warning"] = 1] = "Warning";
        MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore";
    })(exports.MissingTranslationStrategy || (exports.MissingTranslationStrategy = {}));

    /**
     * @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
     */
    var SWITCH_IVY_ENABLED__POST_R3__ = true;
    var SWITCH_IVY_ENABLED__PRE_R3__ = false;
    var ivyEnabled = SWITCH_IVY_ENABLED__PRE_R3__;

    /**
     * @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
     */
    /**
     * Combination of NgModuleFactory and ComponentFactorys.
     *
     * @publicApi
     */
    var ModuleWithComponentFactories = /** @class */ (function () {
        function ModuleWithComponentFactories(ngModuleFactory, componentFactories) {
            this.ngModuleFactory = ngModuleFactory;
            this.componentFactories = componentFactories;
        }
        return ModuleWithComponentFactories;
    }());
    function _throwError() {
        throw new Error("Runtime compiler is not loaded");
    }
    var Compiler_compileModuleSync__PRE_R3__ = _throwError;
    var Compiler_compileModuleSync__POST_R3__ = function (moduleType) {
        return new NgModuleFactory$1(moduleType);
    };
    var Compiler_compileModuleSync = Compiler_compileModuleSync__PRE_R3__;
    var Compiler_compileModuleAsync__PRE_R3__ = _throwError;
    var Compiler_compileModuleAsync__POST_R3__ = function (moduleType) {
        return Promise.resolve(Compiler_compileModuleSync__POST_R3__(moduleType));
    };
    var Compiler_compileModuleAsync = Compiler_compileModuleAsync__PRE_R3__;
    var Compiler_compileModuleAndAllComponentsSync__PRE_R3__ = _throwError;
    var Compiler_compileModuleAndAllComponentsSync__POST_R3__ = function (moduleType) {
        var ngModuleFactory = Compiler_compileModuleSync__POST_R3__(moduleType);
        var moduleDef = getNgModuleDef(moduleType);
        var componentFactories = maybeUnwrapFn(moduleDef.declarations)
            .reduce(function (factories, declaration) {
            var componentDef = getComponentDef(declaration);
            componentDef && factories.push(new ComponentFactory$1(componentDef));
            return factories;
        }, []);
        return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
    };
    var Compiler_compileModuleAndAllComponentsSync = Compiler_compileModuleAndAllComponentsSync__PRE_R3__;
    var Compiler_compileModuleAndAllComponentsAsync__PRE_R3__ = _throwError;
    var Compiler_compileModuleAndAllComponentsAsync__POST_R3__ = function (moduleType) {
        return Promise.resolve(Compiler_compileModuleAndAllComponentsSync__POST_R3__(moduleType));
    };
    var Compiler_compileModuleAndAllComponentsAsync = Compiler_compileModuleAndAllComponentsAsync__PRE_R3__;
    /**
     * Low-level service for running the angular compiler during runtime
     * to create {@link ComponentFactory}s, which
     * can later be used to create and render a Component instance.
     *
     * Each `@NgModule` provides an own `Compiler` to its injector,
     * that will use the directives/pipes of the ng module for compilation
     * of components.
     *
     * @publicApi
     */
    var Compiler = /** @class */ (function () {
        function Compiler() {
            /**
             * Compiles the given NgModule and all of its components. All templates of the components listed
             * in `entryComponents` have to be inlined.
             */
            this.compileModuleSync = Compiler_compileModuleSync;
            /**
             * Compiles the given NgModule and all of its components
             */
            this.compileModuleAsync = Compiler_compileModuleAsync;
            /**
             * Same as {@link #compileModuleSync} but also creates ComponentFactories for all components.
             */
            this.compileModuleAndAllComponentsSync = Compiler_compileModuleAndAllComponentsSync;
            /**
             * Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components.
             */
            this.compileModuleAndAllComponentsAsync = Compiler_compileModuleAndAllComponentsAsync;
        }
        /**
         * Clears all caches.
         */
        Compiler.prototype.clearCache = function () { };
        /**
         * Clears the cache for the given component/ngModule.
         */
        Compiler.prototype.clearCacheFor = function (type) { };
        /**
         * Returns the id for a given NgModule, if one is defined and known to the compiler.
         */
        Compiler.prototype.getModuleId = function (moduleType) { return undefined; };
        Compiler = __decorate([
            Injectable()
        ], Compiler);
        return Compiler;
    }());
    /**
     * Token to provide CompilerOptions in the platform injector.
     *
     * @publicApi
     */
    var COMPILER_OPTIONS = new InjectionToken('compilerOptions');
    /**
     * A factory for creating a Compiler
     *
     * @publicApi
     */
    var CompilerFactory = /** @class */ (function () {
        function CompilerFactory() {
        }
        return CompilerFactory;
    }());

    /**
     * @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
     */
    var trace;
    var events;
    function detectWTF() {
        var wtf = _global /** TODO #9100 */['wtf'];
        if (wtf) {
            trace = wtf['trace'];
            if (trace) {
                events = trace['events'];
                return true;
            }
        }
        return false;
    }
    function createScope(signature, flags) {
        if (flags === void 0) { flags = null; }
        return events.createScope(signature, flags);
    }
    function leave(scope, returnValue) {
        trace.leaveScope(scope, returnValue);
        return returnValue;
    }
    function startTimeRange(rangeType, action) {
        return trace.beginTimeRange(rangeType, action);
    }
    function endTimeRange(range) {
        trace.endTimeRange(range);
    }

    /**
     * @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
     */
    /**
     * True if WTF is enabled.
     */
    var wtfEnabled = detectWTF();
    function noopScope(arg0, arg1) {
        return null;
    }
    /**
     * Create trace scope.
     *
     * Scopes must be strictly nested and are analogous to stack frames, but
     * do not have to follow the stack frames. Instead it is recommended that they follow logical
     * nesting. You may want to use
     * [Event
     * Signatures](http://google.github.io/tracing-framework/instrumenting-code.html#custom-events)
     * as they are defined in WTF.
     *
     * Used to mark scope entry. The return value is used to leave the scope.
     *
     *     var myScope = wtfCreateScope('MyClass#myMethod(ascii someVal)');
     *
     *     someMethod() {
     *        var s = myScope('Foo'); // 'Foo' gets stored in tracing UI
     *        // DO SOME WORK HERE
     *        return wtfLeave(s, 123); // Return value 123
     *     }
     *
     * Note, adding try-finally block around the work to ensure that `wtfLeave` gets called can
     * negatively impact the performance of your application. For this reason we recommend that
     * you don't add them to ensure that `wtfLeave` gets called. In production `wtfLeave` is a noop and
     * so try-finally block has no value. When debugging perf issues, skipping `wtfLeave`, do to
     * exception, will produce incorrect trace, but presence of exception signifies logic error which
     * needs to be fixed before the app should be profiled. Add try-finally only when you expect that
     * an exception is expected during normal execution while profiling.
     *
     * @publicApi
     * @deprecated the Web Tracing Framework is no longer supported in Angular
     */
    var wtfCreateScope = wtfEnabled ? createScope : function (signature, flags) { return noopScope; };
    /**
     * Used to mark end of Scope.
     *
     * - `scope` to end.
     * - `returnValue` (optional) to be passed to the WTF.
     *
     * Returns the `returnValue for easy chaining.
     * @publicApi
     * @deprecated the Web Tracing Framework is no longer supported in Angular
     */
    var wtfLeave = wtfEnabled ? leave : function (s, r) { return r; };
    /**
     * Used to mark Async start. Async are similar to scope but they don't have to be strictly nested.
     * The return value is used in the call to [endAsync]. Async ranges only work if WTF has been
     * enabled.
     *
     *     someMethod() {
     *        var s = wtfStartTimeRange('HTTP:GET', 'some.url');
     *        var future = new Future.delay(5).then((_) {
     *          wtfEndTimeRange(s);
     *        });
     *     }
     * @publicApi
     * @deprecated the Web Tracing Framework is no longer supported in Angular
     */
    var wtfStartTimeRange = wtfEnabled ? startTimeRange : function (rangeType, action) { return null; };
    /**
     * Ends a async time range operation.
     * [range] is the return value from [wtfStartTimeRange] Async ranges only work if WTF has been
     * enabled.
     * @publicApi
     * @deprecated the Web Tracing Framework is no longer supported in Angular
     */
    var wtfEndTimeRange = wtfEnabled ? endTimeRange : function (r) { return null; };

    /**
     * @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
     */
    var promise = (function () { return Promise.resolve(0); })();
    function scheduleMicroTask(fn) {
        if (typeof Zone === 'undefined') {
            // use promise to schedule microTask instead of use Zone
            promise.then(function () { fn && fn.apply(null, null); });
        }
        else {
            Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
        }
    }

    /**
     * @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
     */
    /**
     * An injectable service for executing work inside or outside of the Angular zone.
     *
     * The most common use of this service is to optimize performance when starting a work consisting of
     * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
     * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
     * can reenter the Angular zone via {@link #run}.
     *
     * <!-- TODO: add/fix links to:
     *   - docs explaining zones and the use of zones in Angular and change-detection
     *   - link to runOutsideAngular/run (throughout this file!)
     *   -->
     *
     * @usageNotes
     * ### Example
     *
     * ```
     * import {Component, NgZone} from '@angular/core';
     * import {NgIf} from '@angular/common';
     *
     * @Component({
     *   selector: 'ng-zone-demo',
     *   template: `
     *     <h2>Demo: NgZone</h2>
     *
     *     <p>Progress: {{progress}}%</p>
     *     <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
     *
     *     <button (click)="processWithinAngularZone()">Process within Angular zone</button>
     *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
     *   `,
     * })
     * export class NgZoneDemo {
     *   progress: number = 0;
     *   label: string;
     *
     *   constructor(private _ngZone: NgZone) {}
     *
     *   // Loop inside the Angular zone
     *   // so the UI DOES refresh after each setTimeout cycle
     *   processWithinAngularZone() {
     *     this.label = 'inside';
     *     this.progress = 0;
     *     this._increaseProgress(() => console.log('Inside Done!'));
     *   }
     *
     *   // Loop outside of the Angular zone
     *   // so the UI DOES NOT refresh after each setTimeout cycle
     *   processOutsideOfAngularZone() {
     *     this.label = 'outside';
     *     this.progress = 0;
     *     this._ngZone.runOutsideAngular(() => {
     *       this._increaseProgress(() => {
     *         // reenter the Angular zone and display done
     *         this._ngZone.run(() => { console.log('Outside Done!'); });
     *       });
     *     });
     *   }
     *
     *   _increaseProgress(doneCallback: () => void) {
     *     this.progress += 1;
     *     console.log(`Current progress: ${this.progress}%`);
     *
     *     if (this.progress < 100) {
     *       window.setTimeout(() => this._increaseProgress(doneCallback), 10);
     *     } else {
     *       doneCallback();
     *     }
     *   }
     * }
     * ```
     *
     * @publicApi
     */
    var NgZone = /** @class */ (function () {
        function NgZone(_a) {
            var _b = _a.enableLongStackTrace, enableLongStackTrace = _b === void 0 ? false : _b;
            this.hasPendingMicrotasks = false;
            this.hasPendingMacrotasks = false;
            /**
             * Whether there are no outstanding microtasks or macrotasks.
             */
            this.isStable = true;
            /**
             * Notifies when code enters Angular Zone. This gets fired first on VM Turn.
             */
            this.onUnstable = new EventEmitter(false);
            /**
             * Notifies when there is no more microtasks enqueued in the current VM Turn.
             * This is a hint for Angular to do change detection, which may enqueue more microtasks.
             * For this reason this event can fire multiple times per VM Turn.
             */
            this.onMicrotaskEmpty = new EventEmitter(false);
            /**
             * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
             * implies we are about to relinquish VM turn.
             * This event gets called just once.
             */
            this.onStable = new EventEmitter(false);
            /**
             * Notifies that an error has been delivered.
             */
            this.onError = new EventEmitter(false);
            if (typeof Zone == 'undefined') {
                throw new Error("In this configuration Angular requires Zone.js");
            }
            Zone.assertZonePatched();
            var self = this;
            self._nesting = 0;
            self._outer = self._inner = Zone.current;
            if (Zone['wtfZoneSpec']) {
                self._inner = self._inner.fork(Zone['wtfZoneSpec']);
            }
            if (Zone['TaskTrackingZoneSpec']) {
                self._inner = self._inner.fork(new Zone['TaskTrackingZoneSpec']);
            }
            if (enableLongStackTrace && Zone['longStackTraceZoneSpec']) {
                self._inner = self._inner.fork(Zone['longStackTraceZoneSpec']);
            }
            forkInnerZoneWithAngularBehavior(self);
        }
        NgZone.isInAngularZone = function () { return Zone.current.get('isAngularZone') === true; };
        NgZone.assertInAngularZone = function () {
            if (!NgZone.isInAngularZone()) {
                throw new Error('Expected to be in Angular Zone, but it is not!');
            }
        };
        NgZone.assertNotInAngularZone = function () {
            if (NgZone.isInAngularZone()) {
                throw new Error('Expected to not be in Angular Zone, but it is!');
            }
        };
        /**
         * Executes the `fn` function synchronously within the Angular zone and returns value returned by
         * the function.
         *
         * Running functions via `run` allows you to reenter Angular zone from a task that was executed
         * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
         *
         * Any future tasks or microtasks scheduled from within this function will continue executing from
         * within the Angular zone.
         *
         * If a synchronous error happens it will be rethrown and not reported via `onError`.
         */
        NgZone.prototype.run = function (fn, applyThis, applyArgs) {
            return this._inner.run(fn, applyThis, applyArgs);
        };
        /**
         * Executes the `fn` function synchronously within the Angular zone as a task and returns value
         * returned by the function.
         *
         * Running functions via `run` allows you to reenter Angular zone from a task that was executed
         * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
         *
         * Any future tasks or microtasks scheduled from within this function will continue executing from
         * within the Angular zone.
         *
         * If a synchronous error happens it will be rethrown and not reported via `onError`.
         */
        NgZone.prototype.runTask = function (fn, applyThis, applyArgs, name) {
            var zone = this._inner;
            var task = zone.scheduleEventTask('NgZoneEvent: ' + name, fn, EMPTY_PAYLOAD, noop$1, noop$1);
            try {
                return zone.runTask(task, applyThis, applyArgs);
            }
            finally {
                zone.cancelTask(task);
            }
        };
        /**
         * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
         * rethrown.
         */
        NgZone.prototype.runGuarded = function (fn, applyThis, applyArgs) {
            return this._inner.runGuarded(fn, applyThis, applyArgs);
        };
        /**
         * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
         * the function.
         *
         * Running functions via {@link #runOutsideAngular} allows you to escape Angular's zone and do
         * work that
         * doesn't trigger Angular change-detection or is subject to Angular's error handling.
         *
         * Any future tasks or microtasks scheduled from within this function will continue executing from
         * outside of the Angular zone.
         *
         * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
         */
        NgZone.prototype.runOutsideAngular = function (fn) {
            return this._outer.run(fn);
        };
        return NgZone;
    }());
    function noop$1() { }
    var EMPTY_PAYLOAD = {};
    function checkStable(zone) {
        if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
            try {
                zone._nesting++;
                zone.onMicrotaskEmpty.emit(null);
            }
            finally {
                zone._nesting--;
                if (!zone.hasPendingMicrotasks) {
                    try {
                        zone.runOutsideAngular(function () { return zone.onStable.emit(null); });
                    }
                    finally {
                        zone.isStable = true;
                    }
                }
            }
        }
    }
    function forkInnerZoneWithAngularBehavior(zone) {
        zone._inner = zone._inner.fork({
            name: 'angular',
            properties: { 'isAngularZone': true },
            onInvokeTask: function (delegate, current, target, task, applyThis, applyArgs) {
                try {
                    onEnter(zone);
                    return delegate.invokeTask(target, task, applyThis, applyArgs);
                }
                finally {
                    onLeave(zone);
                }
            },
            onInvoke: function (delegate, current, target, callback, applyThis, applyArgs, source) {
                try {
                    onEnter(zone);
                    return delegate.invoke(target, callback, applyThis, applyArgs, source);
                }
                finally {
                    onLeave(zone);
                }
            },
            onHasTask: function (delegate, current, target, hasTaskState) {
                delegate.hasTask(target, hasTaskState);
                if (current === target) {
                    // We are only interested in hasTask events which originate from our zone
                    // (A child hasTask event is not interesting to us)
                    if (hasTaskState.change == 'microTask') {
                        zone.hasPendingMicrotasks = hasTaskState.microTask;
                        checkStable(zone);
                    }
                    else if (hasTaskState.change == 'macroTask') {
                        zone.hasPendingMacrotasks = hasTaskState.macroTask;
                    }
                }
            },
            onHandleError: function (delegate, current, target, error) {
                delegate.handleError(target, error);
                zone.runOutsideAngular(function () { return zone.onError.emit(error); });
                return false;
            }
        });
    }
    function onEnter(zone) {
        zone._nesting++;
        if (zone.isStable) {
            zone.isStable = false;
            zone.onUnstable.emit(null);
        }
    }
    function onLeave(zone) {
        zone._nesting--;
        checkStable(zone);
    }
    /**
     * Provides a noop implementation of `NgZone` which does nothing. This zone requires explicit calls
     * to framework to perform rendering.
     */
    var NoopNgZone = /** @class */ (function () {
        function NoopNgZone() {
            this.hasPendingMicrotasks = false;
            this.hasPendingMacrotasks = false;
            this.isStable = true;
            this.onUnstable = new EventEmitter();
            this.onMicrotaskEmpty = new EventEmitter();
            this.onStable = new EventEmitter();
            this.onError = new EventEmitter();
        }
        NoopNgZone.prototype.run = function (fn) { return fn(); };
        NoopNgZone.prototype.runGuarded = function (fn) { return fn(); };
        NoopNgZone.prototype.runOutsideAngular = function (fn) { return fn(); };
        NoopNgZone.prototype.runTask = function (fn) { return fn(); };
        return NoopNgZone;
    }());

    /**
     * @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
     */
    /**
     * The Testability service provides testing hooks that can be accessed from
     * the browser and by services such as Protractor. Each bootstrapped Angular
     * application on the page will have an instance of Testability.
     * @publicApi
     */
    var Testability = /** @class */ (function () {
        function Testability(_ngZone) {
            var _this = this;
            this._ngZone = _ngZone;
            this._pendingCount = 0;
            this._isZoneStable = true;
            /**
             * Whether any work was done since the last 'whenStable' callback. This is
             * useful to detect if this could have potentially destabilized another
             * component while it is stabilizing.
             * @internal
             */
            this._didWork = false;
            this._callbacks = [];
            this.taskTrackingZone = null;
            this._watchAngularEvents();
            _ngZone.run(function () {
                _this.taskTrackingZone =
                    typeof Zone == 'undefined' ? null : Zone.current.get('TaskTrackingZone');
            });
        }
        Testability.prototype._watchAngularEvents = function () {
            var _this = this;
            this._ngZone.onUnstable.subscribe({
                next: function () {
                    _this._didWork = true;
                    _this._isZoneStable = false;
                }
            });
            this._ngZone.runOutsideAngular(function () {
                _this._ngZone.onStable.subscribe({
                    next: function () {
                        NgZone.assertNotInAngularZone();
                        scheduleMicroTask(function () {
                            _this._isZoneStable = true;
                            _this._runCallbacksIfReady();
                        });
                    }
                });
            });
        };
        /**
         * Increases the number of pending request
         * @deprecated pending requests are now tracked with zones.
         */
        Testability.prototype.increasePendingRequestCount = function () {
            this._pendingCount += 1;
            this._didWork = true;
            return this._pendingCount;
        };
        /**
         * Decreases the number of pending request
         * @deprecated pending requests are now tracked with zones
         */
        Testability.prototype.decreasePendingRequestCount = function () {
            this._pendingCount -= 1;
            if (this._pendingCount < 0) {
                throw new Error('pending async requests below zero');
            }
            this._runCallbacksIfReady();
            return this._pendingCount;
        };
        /**
         * Whether an associated application is stable
         */
        Testability.prototype.isStable = function () {
            return this._isZoneStable && this._pendingCount === 0 && !this._ngZone.hasPendingMacrotasks;
        };
        Testability.prototype._runCallbacksIfReady = function () {
            var _this = this;
            if (this.isStable()) {
                // Schedules the call backs in a new frame so that it is always async.
                scheduleMicroTask(function () {
                    while (_this._callbacks.length !== 0) {
                        var cb = _this._callbacks.pop();
                        clearTimeout(cb.timeoutId);
                        cb.doneCb(_this._didWork);
                    }
                    _this._didWork = false;
                });
            }
            else {
                // Still not stable, send updates.
                var pending_1 = this.getPendingTasks();
                this._callbacks = this._callbacks.filter(function (cb) {
                    if (cb.updateCb && cb.updateCb(pending_1)) {
                        clearTimeout(cb.timeoutId);
                        return false;
                    }
                    return true;
                });
                this._didWork = true;
            }
        };
        Testability.prototype.getPendingTasks = function () {
            if (!this.taskTrackingZone) {
                return [];
            }
            // Copy the tasks data so that we don't leak tasks.
            return this.taskTrackingZone.macroTasks.map(function (t) {
                return {
                    source: t.source,
                    // From TaskTrackingZone:
                    // https://github.com/angular/zone.js/blob/master/lib/zone-spec/task-tracking.ts#L40
                    creationLocation: t.creationLocation,
                    data: t.data
                };
            });
        };
        Testability.prototype.addCallback = function (cb, timeout, updateCb) {
            var _this = this;
            var timeoutId = -1;
            if (timeout && timeout > 0) {
                timeoutId = setTimeout(function () {
                    _this._callbacks = _this._callbacks.filter(function (cb) { return cb.timeoutId !== timeoutId; });
                    cb(_this._didWork, _this.getPendingTasks());
                }, timeout);
            }
            this._callbacks.push({ doneCb: cb, timeoutId: timeoutId, updateCb: updateCb });
        };
        /**
         * Wait for the application to be stable with a timeout. If the timeout is reached before that
         * happens, the callback receives a list of the macro tasks that were pending, otherwise null.
         *
         * @param doneCb The callback to invoke when Angular is stable or the timeout expires
         *    whichever comes first.
         * @param timeout Optional. The maximum time to wait for Angular to become stable. If not
         *    specified, whenStable() will wait forever.
         * @param updateCb Optional. If specified, this callback will be invoked whenever the set of
         *    pending macrotasks changes. If this callback returns true doneCb will not be invoked
         *    and no further updates will be issued.
         */
        Testability.prototype.whenStable = function (doneCb, timeout, updateCb) {
            if (updateCb && !this.taskTrackingZone) {
                throw new Error('Task tracking zone is required when passing an update callback to ' +
                    'whenStable(). Is "zone.js/dist/task-tracking.js" loaded?');
            }
            // These arguments are 'Function' above to keep the public API simple.
            this.addCallback(doneCb, timeout, updateCb);
            this._runCallbacksIfReady();
        };
        /**
         * Get the number of pending requests
         * @deprecated pending requests are now tracked with zones
         */
        Testability.prototype.getPendingRequestCount = function () { return this._pendingCount; };
        /**
         * Find providers by name
         * @param using The root element to search from
         * @param provider The name of binding variable
         * @param exactMatch Whether using exactMatch
         */
        Testability.prototype.findProviders = function (using, provider, exactMatch) {
            // TODO(juliemr): implement.
            return [];
        };
        Testability = __decorate([
            Injectable(),
            __metadata("design:paramtypes", [NgZone])
        ], Testability);
        return Testability;
    }());
    /**
     * A global registry of {@link Testability} instances for specific elements.
     * @publicApi
     */
    var TestabilityRegistry = /** @class */ (function () {
        function TestabilityRegistry() {
            /** @internal */
            this._applications = new Map();
            _testabilityGetter.addToWindow(this);
        }
        /**
         * Registers an application with a testability hook so that it can be tracked
         * @param token token of application, root element
         * @param testability Testability hook
         */
        TestabilityRegistry.prototype.registerApplication = function (token, testability) {
            this._applications.set(token, testability);
        };
        /**
         * Unregisters an application.
         * @param token token of application, root element
         */
        TestabilityRegistry.prototype.unregisterApplication = function (token) { this._applications.delete(token); };
        /**
         * Unregisters all applications
         */
        TestabilityRegistry.prototype.unregisterAllApplications = function () { this._applications.clear(); };
        /**
         * Get a testability hook associated with the application
         * @param elem root element
         */
        TestabilityRegistry.prototype.getTestability = function (elem) { return this._applications.get(elem) || null; };
        /**
         * Get all registered testabilities
         */
        TestabilityRegistry.prototype.getAllTestabilities = function () { return Array.from(this._applications.values()); };
        /**
         * Get all registered applications(root elements)
         */
        TestabilityRegistry.prototype.getAllRootElements = function () { return Array.from(this._applications.keys()); };
        /**
         * Find testability of a node in the Tree
         * @param elem node
         * @param findInAncestors whether finding testability in ancestors if testability was not found in
         * current node
         */
        TestabilityRegistry.prototype.findTestabilityInTree = function (elem, findInAncestors) {
            if (findInAncestors === void 0) { findInAncestors = true; }
            return _testabilityGetter.findTestabilityInTree(this, elem, findInAncestors);
        };
        TestabilityRegistry = __decorate([
            Injectable(),
            __metadata("design:paramtypes", [])
        ], TestabilityRegistry);
        return TestabilityRegistry;
    }());
    var _NoopGetTestability = /** @class */ (function () {
        function _NoopGetTestability() {
        }
        _NoopGetTestability.prototype.addToWindow = function (registry) { };
        _NoopGetTestability.prototype.findTestabilityInTree = function (registry, elem, findInAncestors) {
            return null;
        };
        return _NoopGetTestability;
    }());
    /**
     * Set the {@link GetTestability} implementation used by the Angular testing framework.
     * @publicApi
     */
    function setTestabilityGetter(getter) {
        _testabilityGetter = getter;
    }
    var _testabilityGetter = new _NoopGetTestability();

    /**
     * @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
     */
    var _platform;
    var compileNgModuleFactory = compileNgModuleFactory__PRE_R3__;
    function compileNgModuleFactory__PRE_R3__(injector, options, moduleType) {
        var compilerFactory = injector.get(CompilerFactory);
        var compiler = compilerFactory.createCompiler([options]);
        return compiler.compileModuleAsync(moduleType);
    }
    function compileNgModuleFactory__POST_R3__(injector, options, moduleType) {
        ngDevMode && assertNgModuleType(moduleType);
        var moduleFactory = new NgModuleFactory$1(moduleType);
        if (isComponentResourceResolutionQueueEmpty()) {
            return Promise.resolve(moduleFactory);
        }
        var compilerOptions = injector.get(COMPILER_OPTIONS, []).concat(options);
        var compilerProviders = _mergeArrays(compilerOptions.map(function (o) { return o.providers; }));
        // In case there are no compiler providers, we just return the module factory as
        // there won't be any resource loader. This can happen with Ivy, because AOT compiled
        // modules can be still passed through "bootstrapModule". In that case we shouldn't
        // unnecessarily require the JIT compiler.
        if (compilerProviders.length === 0) {
            return Promise.resolve(moduleFactory);
        }
        var compiler = getCompilerFacade();
        var compilerInjector = Injector.create({ providers: compilerProviders });
        var resourceLoader = compilerInjector.get(compiler.ResourceLoader);
        // The resource loader can also return a string while the "resolveComponentResources"
        // always expects a promise. Therefore we need to wrap the returned value in a promise.
        return resolveComponentResources(function (url) { return Promise.resolve(resourceLoader.get(url)); })
            .then(function () { return moduleFactory; });
    }
    var isBoundToModule = isBoundToModule__PRE_R3__;
    function isBoundToModule__PRE_R3__(cf) {
        return cf instanceof ComponentFactoryBoundToModule;
    }
    function isBoundToModule__POST_R3__(cf) {
        return cf.isBoundToModule;
    }
    var ALLOW_MULTIPLE_PLATFORMS = new InjectionToken('AllowMultipleToken');
    /**
     * A token for third-party components that can register themselves with NgProbe.
     *
     * @publicApi
     */
    var NgProbeToken = /** @class */ (function () {
        function NgProbeToken(name, token) {
            this.name = name;
            this.token = token;
        }
        return NgProbeToken;
    }());
    /**
     * Creates a platform.
     * Platforms have to be eagerly created via this function.
     *
     * @publicApi
     */
    function createPlatform(injector) {
        if (_platform && !_platform.destroyed &&
            !_platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
            throw new Error('There can be only one platform. Destroy the previous one to create a new one.');
        }
        _platform = injector.get(PlatformRef);
        var inits = injector.get(PLATFORM_INITIALIZER, null);
        if (inits)
            inits.forEach(function (init) { return init(); });
        return _platform;
    }
    /**
     * Creates a factory for a platform
     *
     * @publicApi
     */
    function createPlatformFactory(parentPlatformFactory, name, providers) {
        if (providers === void 0) { providers = []; }
        var desc = "Platform: " + name;
        var marker = new InjectionToken(desc);
        return function (extraProviders) {
            if (extraProviders === void 0) { extraProviders = []; }
            var platform = getPlatform();
            if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
                if (parentPlatformFactory) {
                    parentPlatformFactory(providers.concat(extraProviders).concat({ provide: marker, useValue: true }));
                }
                else {
                    var injectedProviders = providers.concat(extraProviders).concat({ provide: marker, useValue: true });
                    createPlatform(Injector.create({ providers: injectedProviders, name: desc }));
                }
            }
            return assertPlatform(marker);
        };
    }
    /**
     * Checks that there currently is a platform which contains the given token as a provider.
     *
     * @publicApi
     */
    function assertPlatform(requiredToken) {
        var platform = getPlatform();
        if (!platform) {
            throw new Error('No platform exists!');
        }
        if (!platform.injector.get(requiredToken, null)) {
            throw new Error('A platform with a different configuration has been created. Please destroy it first.');
        }
        return platform;
    }
    /**
     * Destroy the existing platform.
     *
     * @publicApi
     */
    function destroyPlatform() {
        if (_platform && !_platform.destroyed) {
            _platform.destroy();
        }
    }
    /**
     * Returns the current platform.
     *
     * @publicApi
     */
    function getPlatform() {
        return _platform && !_platform.destroyed ? _platform : null;
    }
    /**
     * The Angular platform is the entry point for Angular on a web page. Each page
     * has exactly one platform, and services (such as reflection) which are common
     * to every Angular application running on the page are bound in its scope.
     *
     * A page's platform is initialized implicitly when a platform is created via a platform factory
     * (e.g. {@link platformBrowser}), or explicitly by calling the {@link createPlatform} function.
     *
     * @publicApi
     */
    var PlatformRef = /** @class */ (function () {
        /** @internal */
        function PlatformRef(_injector) {
            this._injector = _injector;
            this._modules = [];
            this._destroyListeners = [];
            this._destroyed = false;
        }
        /**
         * Creates an instance of an `@NgModule` for the given platform
         * for offline compilation.
         *
         * @usageNotes
         * ### Simple Example
         *
         * ```typescript
         * my_module.ts:
         *
         * @NgModule({
         *   imports: [BrowserModule]
         * })
         * class MyModule {}
         *
         * main.ts:
         * import {MyModuleNgFactory} from './my_module.ngfactory';
         * import {platformBrowser} from '@angular/platform-browser';
         *
         * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
         * ```
         */
        PlatformRef.prototype.bootstrapModuleFactory = function (moduleFactory, options) {
            var _this = this;
            // Note: We need to create the NgZone _before_ we instantiate the module,
            // as instantiating the module creates some providers eagerly.
            // So we create a mini parent injector that just contains the new NgZone and
            // pass that as parent to the NgModuleFactory.
            var ngZoneOption = options ? options.ngZone : undefined;
            var ngZone = getNgZone(ngZoneOption);
            var providers = [{ provide: NgZone, useValue: ngZone }];
            // Attention: Don't use ApplicationRef.run here,
            // as we want to be sure that all possible constructor calls are inside `ngZone.run`!
            return ngZone.run(function () {
                var ngZoneInjector = Injector.create({ providers: providers, parent: _this.injector, name: moduleFactory.moduleType.name });
                var moduleRef = moduleFactory.create(ngZoneInjector);
                var exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
                if (!exceptionHandler) {
                    throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
                }
                // If the `LOCALE_ID` provider is defined at bootstrap we set the value for runtime i18n (ivy)
                if (ivyEnabled) {
                    var localeId = moduleRef.injector.get(LOCALE_ID$1, DEFAULT_LOCALE_ID);
                    setLocaleId(localeId || DEFAULT_LOCALE_ID);
                }
                moduleRef.onDestroy(function () { return remove(_this._modules, moduleRef); });
                ngZone.runOutsideAngular(function () { return ngZone.onError.subscribe({ next: function (error) { exceptionHandler.handleError(error); } }); });
                return _callAndReportToErrorHandler(exceptionHandler, ngZone, function () {
                    var initStatus = moduleRef.injector.get(ApplicationInitStatus);
                    initStatus.runInitializers();
                    return initStatus.donePromise.then(function () {
                        _this._moduleDoBootstrap(moduleRef);
                        return moduleRef;
                    });
                });
            });
        };
        /**
         * Creates an instance of an `@NgModule` for a given platform using the given runtime compiler.
         *
         * @usageNotes
         * ### Simple Example
         *
         * ```typescript
         * @NgModule({
         *   imports: [BrowserModule]
         * })
         * class MyModule {}
         *
         * let moduleRef = platformBrowser().bootstrapModule(MyModule);
         * ```
         *
         */
        PlatformRef.prototype.bootstrapModule = function (moduleType, compilerOptions) {
            var _this = this;
            if (compilerOptions === void 0) { compilerOptions = []; }
            var options = optionsReducer({}, compilerOptions);
            return compileNgModuleFactory(this.injector, options, moduleType)
                .then(function (moduleFactory) { return _this.bootstrapModuleFactory(moduleFactory, options); });
        };
        PlatformRef.prototype._moduleDoBootstrap = function (moduleRef) {
            var appRef = moduleRef.injector.get(ApplicationRef);
            if (moduleRef._bootstrapComponents.length > 0) {
                moduleRef._bootstrapComponents.forEach(function (f) { return appRef.bootstrap(f); });
            }
            else if (moduleRef.instance.ngDoBootstrap) {
                moduleRef.instance.ngDoBootstrap(appRef);
            }
            else {
                throw new Error("The module " + stringify(moduleRef.instance.constructor) + " was bootstrapped, but it does not declare \"@NgModule.bootstrap\" components nor a \"ngDoBootstrap\" method. " +
                    "Please define one of these.");
            }
            this._modules.push(moduleRef);
        };
        /**
         * Register a listener to be called when the platform is disposed.
         */
        PlatformRef.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
        Object.defineProperty(PlatformRef.prototype, "injector", {
            /**
             * Retrieve the platform {@link Injector}, which is the parent injector for
             * every Angular application on the page and provides singleton providers.
             */
            get: function () { return this._injector; },
            enumerable: true,
            configurable: true
        });
        /**
         * Destroy the Angular platform and all Angular applications on the page.
         */
        PlatformRef.prototype.destroy = function () {
            if (this._destroyed) {
                throw new Error('The platform has already been destroyed!');
            }
            this._modules.slice().forEach(function (module) { return module.destroy(); });
            this._destroyListeners.forEach(function (listener) { return listener(); });
            this._destroyed = true;
        };
        Object.defineProperty(PlatformRef.prototype, "destroyed", {
            get: function () { return this._destroyed; },
            enumerable: true,
            configurable: true
        });
        PlatformRef = __decorate([
            Injectable(),
            __metadata("design:paramtypes", [Injector])
        ], PlatformRef);
        return PlatformRef;
    }());
    function getNgZone(ngZoneOption) {
        var ngZone;
        if (ngZoneOption === 'noop') {
            ngZone = new NoopNgZone();
        }
        else {
            ngZone = (ngZoneOption === 'zone.js' ? undefined : ngZoneOption) ||
                new NgZone({ enableLongStackTrace: isDevMode() });
        }
        return ngZone;
    }
    function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
        try {
            var result = callback();
            if (isPromise(result)) {
                return result.catch(function (e) {
                    ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
                    // rethrow as the exception handler might not do it
                    throw e;
                });
            }
            return result;
        }
        catch (e) {
            ngZone.runOutsideAngular(function () { return errorHandler.handleError(e); });
            // rethrow as the exception handler might not do it
            throw e;
        }
    }
    function optionsReducer(dst, objs) {
        if (Array.isArray(objs)) {
            dst = objs.reduce(optionsReducer, dst);
        }
        else {
            dst = __assign({}, dst, objs);
        }
        return dst;
    }
    /**
     * A reference to an Angular application running on a page.
     *
     * @usageNotes
     *
     * {@a is-stable-examples}
     * ### isStable examples and caveats
     *
     * Note two important points about `isStable`, demonstrated in the examples below:
     * - the application will never be stable if you start any kind
     * of recurrent asynchronous task when the application starts
     * (for example for a polling process, started with a `setInterval`, a `setTimeout`
     * or using RxJS operators like `interval`);
     * - the `isStable` Observable runs outside of the Angular zone.
     *
     * Let's imagine that you start a recurrent task
     * (here incrementing a counter, using RxJS `interval`),
     * and at the same time subscribe to `isStable`.
     *
     * ```
     * constructor(appRef: ApplicationRef) {
     *   appRef.isStable.pipe(
     *      filter(stable => stable)
     *   ).subscribe(() => console.log('App is stable now');
     *   interval(1000).subscribe(counter => console.log(counter));
     * }
     * ```
     * In this example, `isStable` will never emit `true`,
     * and the trace "App is stable now" will never get logged.
     *
     * If you want to execute something when the app is stable,
     * you have to wait for the application to be stable
     * before starting your polling process.
     *
     * ```
     * constructor(appRef: ApplicationRef) {
     *   appRef.isStable.pipe(
     *     first(stable => stable),
     *     tap(stable => console.log('App is stable now')),
     *     switchMap(() => interval(1000))
     *   ).subscribe(counter => console.log(counter));
     * }
     * ```
     * In this example, the trace "App is stable now" will be logged
     * and then the counter starts incrementing every second.
     *
     * Note also that this Observable runs outside of the Angular zone,
     * which means that the code in the subscription
     * to this Observable will not trigger the change detection.
     *
     * Let's imagine that instead of logging the counter value,
     * you update a field of your component
     * and display it in its template.
     *
     * ```
     * constructor(appRef: ApplicationRef) {
     *   appRef.isStable.pipe(
     *     first(stable => stable),
     *     switchMap(() => interval(1000))
     *   ).subscribe(counter => this.value = counter);
     * }
     * ```
     * As the `isStable` Observable runs outside the zone,
     * the `value` field will be updated properly,
     * but the template will not be refreshed!
     *
     * You'll have to manually trigger the change detection to update the template.
     *
     * ```
     * constructor(appRef: ApplicationRef, cd: ChangeDetectorRef) {
     *   appRef.isStable.pipe(
     *     first(stable => stable),
     *     switchMap(() => interval(1000))
     *   ).subscribe(counter => {
     *     this.value = counter;
     *     cd.detectChanges();
     *   });
     * }
     * ```
     *
     * Or make the subscription callback run inside the zone.
     *
     * ```
     * constructor(appRef: ApplicationRef, zone: NgZone) {
     *   appRef.isStable.pipe(
     *     first(stable => stable),
     *     switchMap(() => interval(1000))
     *   ).subscribe(counter => zone.run(() => this.value = counter));
     * }
     * ```
     *
     * @publicApi
     */
    var ApplicationRef = /** @class */ (function () {
        /** @internal */
        function ApplicationRef(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus) {
            var _this = this;
            this._zone = _zone;
            this._console = _console;
            this._injector = _injector;
            this._exceptionHandler = _exceptionHandler;
            this._componentFactoryResolver = _componentFactoryResolver;
            this._initStatus = _initStatus;
            this._bootstrapListeners = [];
            this._views = [];
            this._runningTick = false;
            this._enforceNoNewChanges = false;
            this._stable = true;
            /**
             * Get a list of component types registered to this application.
             * This list is populated even before the component is created.
             */
            this.componentTypes = [];
            /**
             * Get a list of components registered to this application.
             */
            this.components = [];
            this._enforceNoNewChanges = isDevMode();
            this._zone.onMicrotaskEmpty.subscribe({ next: function () { _this._zone.run(function () { _this.tick(); }); } });
            var isCurrentlyStable = new rxjs.Observable(function (observer) {
                _this._stable = _this._zone.isStable && !_this._zone.hasPendingMacrotasks &&
                    !_this._zone.hasPendingMicrotasks;
                _this._zone.runOutsideAngular(function () {
                    observer.next(_this._stable);
                    observer.complete();
                });
            });
            var isStable = new rxjs.Observable(function (observer) {
                // Create the subscription to onStable outside the Angular Zone so that
                // the callback is run outside the Angular Zone.
                var stableSub;
                _this._zone.runOutsideAngular(function () {
                    stableSub = _this._zone.onStable.subscribe(function () {
                        NgZone.assertNotInAngularZone();
                        // Check whether there are no pending macro/micro tasks in the next tick
                        // to allow for NgZone to update the state.
                        scheduleMicroTask(function () {
                            if (!_this._stable && !_this._zone.hasPendingMacrotasks &&
                                !_this._zone.hasPendingMicrotasks) {
                                _this._stable = true;
                                observer.next(true);
                            }
                        });
                    });
                });
                var unstableSub = _this._zone.onUnstable.subscribe(function () {
                    NgZone.assertInAngularZone();
                    if (_this._stable) {
                        _this._stable = false;
                        _this._zone.runOutsideAngular(function () { observer.next(false); });
                    }
                });
                return function () {
                    stableSub.unsubscribe();
                    unstableSub.unsubscribe();
                };
            });
            this.isStable =
                rxjs.merge(isCurrentlyStable, isStable.pipe(operators.share()));
        }
        ApplicationRef_1 = ApplicationRef;
        /**
         * Bootstrap a new component at the root level of the application.
         *
         * @usageNotes
         * ### Bootstrap process
         *
         * When bootstrapping a new root component into an application, Angular mounts the
         * specified application component onto DOM elements identified by the componentType's
         * selector and kicks off automatic change detection to finish initializing the component.
         *
         * Optionally, a component can be mounted onto a DOM element that does not match the
         * componentType's selector.
         *
         * ### Example
         * {@example core/ts/platform/platform.ts region='longform'}
         */
        ApplicationRef.prototype.bootstrap = function (componentOrFactory, rootSelectorOrNode) {
            var _this = this;
            if (!this._initStatus.done) {
                throw new Error('Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
            }
            var componentFactory;
            if (componentOrFactory instanceof ComponentFactory) {
                componentFactory = componentOrFactory;
            }
            else {
                componentFactory =
                    this._componentFactoryResolver.resolveComponentFactory(componentOrFactory);
            }
            this.componentTypes.push(componentFactory.componentType);
            // Create a factory associated with the current module if it's not bound to some other
            var ngModule = isBoundToModule(componentFactory) ? null : this._injector.get(NgModuleRef);
            var selectorOrNode = rootSelectorOrNode || componentFactory.selector;
            var compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
            compRef.onDestroy(function () { _this._unloadComponent(compRef); });
            var testability = compRef.injector.get(Testability, null);
            if (testability) {
                compRef.injector.get(TestabilityRegistry)
                    .registerApplication(compRef.location.nativeElement, testability);
            }
            this._loadComponent(compRef);
            if (isDevMode()) {
                this._console.log("Angular is running in the development mode. Call enableProdMode() to enable the production mode.");
            }
            return compRef;
        };
        /**
         * Invoke this method to explicitly process change detection and its side-effects.
         *
         * In development mode, `tick()` also performs a second change detection cycle to ensure that no
         * further changes are detected. If additional changes are picked up during this second cycle,
         * bindings in the app have side-effects that cannot be resolved in a single change detection
         * pass.
         * In this case, Angular throws an error, since an Angular application can only have one change
         * detection pass during which all change detection must complete.
         */
        ApplicationRef.prototype.tick = function () {
            var e_1, _a, e_2, _b;
            var _this = this;
            if (this._runningTick) {
                throw new Error('ApplicationRef.tick is called recursively');
            }
            var scope = ApplicationRef_1._tickScope();
            try {
                this._runningTick = true;
                try {
                    for (var _c = __values(this._views), _d = _c.next(); !_d.done; _d = _c.next()) {
                        var view = _d.value;
                        view.detectChanges();
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
                    }
                    finally { if (e_1) throw e_1.error; }
                }
                if (this._enforceNoNewChanges) {
                    try {
                        for (var _e = __values(this._views), _f = _e.next(); !_f.done; _f = _e.next()) {
                            var view = _f.value;
                            view.checkNoChanges();
                        }
                    }
                    catch (e_2_1) { e_2 = { error: e_2_1 }; }
                    finally {
                        try {
                            if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
                        }
                        finally { if (e_2) throw e_2.error; }
                    }
                }
            }
            catch (e) {
                // Attention: Don't rethrow as it could cancel subscriptions to Observables!
                this._zone.runOutsideAngular(function () { return _this._exceptionHandler.handleError(e); });
            }
            finally {
                this._runningTick = false;
                wtfLeave(scope);
            }
        };
        /**
         * Attaches a view so that it will be dirty checked.
         * The view will be automatically detached when it is destroyed.
         * This will throw if the view is already attached to a ViewContainer.
         */
        ApplicationRef.prototype.attachView = function (viewRef) {
            var view = viewRef;
            this._views.push(view);
            view.attachToAppRef(this);
        };
        /**
         * Detaches a view from dirty checking again.
         */
        ApplicationRef.prototype.detachView = function (viewRef) {
            var view = viewRef;
            remove(this._views, view);
            view.detachFromAppRef();
        };
        ApplicationRef.prototype._loadComponent = function (componentRef) {
            this.attachView(componentRef.hostView);
            this.tick();
            this.components.push(componentRef);
            // Get the listeners lazily to prevent DI cycles.
            var listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []).concat(this._bootstrapListeners);
            listeners.forEach(function (listener) { return listener(componentRef); });
        };
        ApplicationRef.prototype._unloadComponent = function (componentRef) {
            this.detachView(componentRef.hostView);
            remove(this.components, componentRef);
        };
        /** @internal */
        ApplicationRef.prototype.ngOnDestroy = function () {
            // TODO(alxhub): Dispose of the NgZone.
            this._views.slice().forEach(function (view) { return view.destroy(); });
        };
        Object.defineProperty(ApplicationRef.prototype, "viewCount", {
            /**
             * Returns the number of attached views.
             */
            get: function () { return this._views.length; },
            enumerable: true,
            configurable: true
        });
        var ApplicationRef_1;
        /** @internal */
        ApplicationRef._tickScope = wtfCreateScope('ApplicationRef#tick()');
        ApplicationRef = ApplicationRef_1 = __decorate([
            Injectable(),
            __metadata("design:paramtypes", [NgZone, Console, Injector,
                ErrorHandler,
                ComponentFactoryResolver,
                ApplicationInitStatus])
        ], ApplicationRef);
        return ApplicationRef;
    }());
    function remove(list, el) {
        var index = list.indexOf(el);
        if (index > -1) {
            list.splice(index, 1);
        }
    }
    function _mergeArrays(parts) {
        var result = [];
        parts.forEach(function (part) { return part && result.push.apply(result, __spread(part)); });
        return result;
    }

    /**
     * @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
     */

    /**
     * @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
     */

    /**
     * @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
     */
    /**
     * Used to load ng module factories.
     *
     * @publicApi
     * @deprecated the `string` form of `loadChildren` is deprecated, and `NgModuleFactoryLoader` is
     * part of its implementation. See `LoadChildren` for more details.
     */
    var NgModuleFactoryLoader = /** @class */ (function () {
        function NgModuleFactoryLoader() {
        }
        return NgModuleFactoryLoader;
    }());
    function getModuleFactory__PRE_R3__(id) {
        var factory = getRegisteredNgModuleType(id);
        if (!factory)
            throw noModuleError(id);
        return factory;
    }
    function getModuleFactory__POST_R3__(id) {
        var type = getRegisteredNgModuleType(id);
        if (!type)
            throw noModuleError(id);
        return new NgModuleFactory$1(type);
    }
    /**
     * Returns the NgModuleFactory with the given id, if it exists and has been loaded.
     * Factories for modules that do not specify an `id` cannot be retrieved. Throws if the module
     * cannot be found.
     * @publicApi
     */
    var getModuleFactory = getModuleFactory__PRE_R3__;
    function noModuleError(id) {
        return new Error("No module with ID " + id + " loaded");
    }

    /**
     * @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
     */
    var _SEPARATOR = '#';
    var FACTORY_CLASS_SUFFIX = 'NgFactory';
    /**
     * Configuration for SystemJsNgModuleLoader.
     * token.
     *
     * @publicApi
     * @deprecated the `string` form of `loadChildren` is deprecated, and `SystemJsNgModuleLoaderConfig`
     * is part of its implementation. See `LoadChildren` for more details.
     */
    var SystemJsNgModuleLoaderConfig = /** @class */ (function () {
        function SystemJsNgModuleLoaderConfig() {
        }
        return SystemJsNgModuleLoaderConfig;
    }());
    var DEFAULT_CONFIG = {
        factoryPathPrefix: '',
        factoryPathSuffix: '.ngfactory',
    };
    /**
     * NgModuleFactoryLoader that uses SystemJS to load NgModuleFactory
     * @publicApi
     * @deprecated the `string` form of `loadChildren` is deprecated, and `SystemJsNgModuleLoader` is
     * part of its implementation. See `LoadChildren` for more details.
     */
    var SystemJsNgModuleLoader = /** @class */ (function () {
        function SystemJsNgModuleLoader(_compiler, config) {
            this._compiler = _compiler;
            this._config = config || DEFAULT_CONFIG;
        }
        SystemJsNgModuleLoader.prototype.load = function (path) {
            var legacyOfflineMode = !ivyEnabled && this._compiler instanceof Compiler;
            return legacyOfflineMode ? this.loadFactory(path) : this.loadAndCompile(path);
        };
        SystemJsNgModuleLoader.prototype.loadAndCompile = function (path) {
            var _this = this;
            var _a = __read(path.split(_SEPARATOR), 2), module = _a[0], exportName = _a[1];
            if (exportName === undefined) {
                exportName = 'default';
            }
            return System.import(module)
                .then(function (module) { return module[exportName]; })
                .then(function (type) { return checkNotEmpty(type, module, exportName); })
                .then(function (type) { return _this._compiler.compileModuleAsync(type); });
        };
        SystemJsNgModuleLoader.prototype.loadFactory = function (path) {
            var _a = __read(path.split(_SEPARATOR), 2), module = _a[0], exportName = _a[1];
            var factoryClassSuffix = FACTORY_CLASS_SUFFIX;
            if (exportName === undefined) {
                exportName = 'default';
                factoryClassSuffix = '';
            }
            return System.import(this._config.factoryPathPrefix + module + this._config.factoryPathSuffix)
                .then(function (module) { return module[exportName + factoryClassSuffix]; })
                .then(function (factory) { return checkNotEmpty(factory, module, exportName); });
        };
        SystemJsNgModuleLoader = __decorate([
            Injectable(),
            __param(1, Optional()),
            __metadata("design:paramtypes", [Compiler, SystemJsNgModuleLoaderConfig])
        ], SystemJsNgModuleLoader);
        return SystemJsNgModuleLoader;
    }());
    function checkNotEmpty(value, modulePath, exportName) {
        if (!value) {
            throw new Error("Cannot find '" + exportName + "' in '" + modulePath + "'");
        }
        return value;
    }

    /**
     * @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
     */
    /**
     * Represents an Angular [view](guide/glossary#view),
     * specifically the [host view](guide/glossary#view-tree) that is defined by a component.
     * Also serves as the base class
     * that adds destroy methods for [embedded views](guide/glossary#view-tree).
     *
     * @see `EmbeddedViewRef`
     *
     * @publicApi
     */
    var ViewRef$1 = /** @class */ (function (_super) {
        __extends(ViewRef, _super);
        function ViewRef() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return ViewRef;
    }(ChangeDetectorRef));
    /**
     * Represents an Angular [view](guide/glossary#view) in a view container.
     * An [embedded view](guide/glossary#view-tree) can be referenced from a component
     * other than the hosting component whose template defines it, or it can be defined
     * independently by a `TemplateRef`.
     *
     * Properties of elements in a view can change, but the structure (number and order) of elements in
     * a view cannot. Change the structure of elements by inserting, moving, or
     * removing nested views in a view container.
     *
     * @see `ViewContainerRef`
     *
     * @usageNotes
     *
     * The following template breaks down into two separate `TemplateRef` instances,
     * an outer one and an inner one.
     *
     * ```
     * Count: {{items.length}}
     * <ul>
     *   <li *ngFor="let  item of items">{{item}}</li>
     * </ul>
     * ```
     *
     * This is the outer `TemplateRef`:
     *
     * ```
     * Count: {{items.length}}
     * <ul>
     *   <ng-template ngFor let-item [ngForOf]="items"></ng-template>
     * </ul>
     * ```
     *
     * This is the inner `TemplateRef`:
     *
     * ```
     *   <li>{{item}}</li>
     * ```
     *
     * The outer and inner `TemplateRef` instances are assembled into views as follows:
     *
     * ```
     * <!-- ViewRef: outer-0 -->
     * Count: 2
     * <ul>
     *   <ng-template view-container-ref></ng-template>
     *   <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
     *   <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
     * </ul>
     * <!-- /ViewRef: outer-0 -->
     * ```
     * @publicApi
     */
    var EmbeddedViewRef = /** @class */ (function (_super) {
        __extends(EmbeddedViewRef, _super);
        function EmbeddedViewRef() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return EmbeddedViewRef;
    }(ViewRef$1));

    /**
     * @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
     */

    /**
     * @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
     */
    /**
     * @publicApi
     */
    var DebugEventListener = /** @class */ (function () {
        function DebugEventListener(name, callback) {
            this.name = name;
            this.callback = callback;
        }
        return DebugEventListener;
    }());
    var DebugNode__PRE_R3__ = /** @class */ (function () {
        function DebugNode__PRE_R3__(nativeNode, parent, _debugContext) {
            this.listeners = [];
            this.parent = null;
            this._debugContext = _debugContext;
            this.nativeNode = nativeNode;
            if (parent && parent instanceof DebugElement__PRE_R3__) {
                parent.addChild(this);
            }
        }
        Object.defineProperty(DebugNode__PRE_R3__.prototype, "injector", {
            get: function () { return this._debugContext.injector; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__PRE_R3__.prototype, "componentInstance", {
            get: function () { return this._debugContext.component; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__PRE_R3__.prototype, "context", {
            get: function () { return this._debugContext.context; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__PRE_R3__.prototype, "references", {
            get: function () { return this._debugContext.references; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__PRE_R3__.prototype, "providerTokens", {
            get: function () { return this._debugContext.providerTokens; },
            enumerable: true,
            configurable: true
        });
        return DebugNode__PRE_R3__;
    }());
    var DebugElement__PRE_R3__ = /** @class */ (function (_super) {
        __extends(DebugElement__PRE_R3__, _super);
        function DebugElement__PRE_R3__(nativeNode, parent, _debugContext) {
            var _this = _super.call(this, nativeNode, parent, _debugContext) || this;
            _this.properties = {};
            _this.attributes = {};
            _this.classes = {};
            _this.styles = {};
            _this.childNodes = [];
            _this.nativeElement = nativeNode;
            return _this;
        }
        DebugElement__PRE_R3__.prototype.addChild = function (child) {
            if (child) {
                this.childNodes.push(child);
                child.parent = this;
            }
        };
        DebugElement__PRE_R3__.prototype.removeChild = function (child) {
            var childIndex = this.childNodes.indexOf(child);
            if (childIndex !== -1) {
                child.parent = null;
                this.childNodes.splice(childIndex, 1);
            }
        };
        DebugElement__PRE_R3__.prototype.insertChildrenAfter = function (child, newChildren) {
            var _a;
            var _this = this;
            var siblingIndex = this.childNodes.indexOf(child);
            if (siblingIndex !== -1) {
                (_a = this.childNodes).splice.apply(_a, __spread([siblingIndex + 1, 0], newChildren));
                newChildren.forEach(function (c) {
                    if (c.parent) {
                        c.parent.removeChild(c);
                    }
                    child.parent = _this;
                });
            }
        };
        DebugElement__PRE_R3__.prototype.insertBefore = function (refChild, newChild) {
            var refIndex = this.childNodes.indexOf(refChild);
            if (refIndex === -1) {
                this.addChild(newChild);
            }
            else {
                if (newChild.parent) {
                    newChild.parent.removeChild(newChild);
                }
                newChild.parent = this;
                this.childNodes.splice(refIndex, 0, newChild);
            }
        };
        DebugElement__PRE_R3__.prototype.query = function (predicate) {
            var results = this.queryAll(predicate);
            return results[0] || null;
        };
        DebugElement__PRE_R3__.prototype.queryAll = function (predicate) {
            var matches = [];
            _queryElementChildren(this, predicate, matches);
            return matches;
        };
        DebugElement__PRE_R3__.prototype.queryAllNodes = function (predicate) {
            var matches = [];
            _queryNodeChildren(this, predicate, matches);
            return matches;
        };
        Object.defineProperty(DebugElement__PRE_R3__.prototype, "children", {
            get: function () {
                return this
                    .childNodes //
                    .filter(function (node) { return node instanceof DebugElement__PRE_R3__; });
            },
            enumerable: true,
            configurable: true
        });
        DebugElement__PRE_R3__.prototype.triggerEventHandler = function (eventName, eventObj) {
            this.listeners.forEach(function (listener) {
                if (listener.name == eventName) {
                    listener.callback(eventObj);
                }
            });
        };
        return DebugElement__PRE_R3__;
    }(DebugNode__PRE_R3__));
    /**
     * @publicApi
     */
    function asNativeElements(debugEls) {
        return debugEls.map(function (el) { return el.nativeElement; });
    }
    function _queryElementChildren(element, predicate, matches) {
        element.childNodes.forEach(function (node) {
            if (node instanceof DebugElement__PRE_R3__) {
                if (predicate(node)) {
                    matches.push(node);
                }
                _queryElementChildren(node, predicate, matches);
            }
        });
    }
    function _queryNodeChildren(parentNode, predicate, matches) {
        if (parentNode instanceof DebugElement__PRE_R3__) {
            parentNode.childNodes.forEach(function (node) {
                if (predicate(node)) {
                    matches.push(node);
                }
                if (node instanceof DebugElement__PRE_R3__) {
                    _queryNodeChildren(node, predicate, matches);
                }
            });
        }
    }
    var DebugNode__POST_R3__ = /** @class */ (function () {
        function DebugNode__POST_R3__(nativeNode) {
            this.nativeNode = nativeNode;
        }
        Object.defineProperty(DebugNode__POST_R3__.prototype, "parent", {
            get: function () {
                var parent = this.nativeNode.parentNode;
                return parent ? new DebugElement__POST_R3__(parent) : null;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__POST_R3__.prototype, "injector", {
            get: function () { return getInjector(this.nativeNode); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__POST_R3__.prototype, "componentInstance", {
            get: function () {
                var nativeElement = this.nativeNode;
                return nativeElement &&
                    (getComponent(nativeElement) || getViewComponent(nativeElement));
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__POST_R3__.prototype, "context", {
            get: function () {
                return getComponent(this.nativeNode) || getContext$1(this.nativeNode);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__POST_R3__.prototype, "listeners", {
            get: function () {
                return getListeners(this.nativeNode).filter(isBrowserEvents);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__POST_R3__.prototype, "references", {
            get: function () { return getLocalRefs(this.nativeNode); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugNode__POST_R3__.prototype, "providerTokens", {
            get: function () { return getInjectionTokens(this.nativeNode); },
            enumerable: true,
            configurable: true
        });
        return DebugNode__POST_R3__;
    }());
    var DebugElement__POST_R3__ = /** @class */ (function (_super) {
        __extends(DebugElement__POST_R3__, _super);
        function DebugElement__POST_R3__(nativeNode) {
            var _this = this;
            ngDevMode && assertDomNode(nativeNode);
            _this = _super.call(this, nativeNode) || this;
            return _this;
        }
        Object.defineProperty(DebugElement__POST_R3__.prototype, "nativeElement", {
            get: function () {
                return this.nativeNode.nodeType == Node.ELEMENT_NODE ? this.nativeNode : null;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugElement__POST_R3__.prototype, "name", {
            get: function () { return this.nativeElement.nodeName; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugElement__POST_R3__.prototype, "properties", {
            /**
             *  Gets a map of property names to property values for an element.
             *
             *  This map includes:
             *  - Regular property bindings (e.g. `[id]="id"`)
             *  - Host property bindings (e.g. `host: { '[id]': "id" }`)
             *  - Interpolated property bindings (e.g. `id="{{ value }}")
             *
             *  It does not include:
             *  - input property bindings (e.g. `[myCustomInput]="value"`)
             *  - attribute bindings (e.g. `[attr.role]="menu"`)
             */
            get: function () {
                var context = loadLContext(this.nativeNode);
                var lView = context.lView;
                var tData = lView[TVIEW].data;
                var tNode = tData[context.nodeIndex];
                var properties = collectPropertyBindings(tNode, lView, tData);
                var hostProperties = collectHostPropertyBindings(tNode, lView, tData);
                var className = collectClassNames(this);
                var output = __assign({}, properties, hostProperties);
                if (className) {
                    output['className'] = output['className'] ? output['className'] + (" " + className) : className;
                }
                return output;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugElement__POST_R3__.prototype, "attributes", {
            get: function () {
                var attributes = {};
                var element = this.nativeElement;
                if (!element) {
                    return attributes;
                }
                var context = loadLContext(element);
                var lView = context.lView;
                var tNodeAttrs = lView[TVIEW].data[context.nodeIndex].attrs;
                var lowercaseTNodeAttrs = [];
                // For debug nodes we take the element's attribute directly from the DOM since it allows us
                // to account for ones that weren't set via bindings (e.g. ViewEngine keeps track of the ones
                // that are set through `Renderer2`). The problem is that the browser will lowercase all names,
                // however since we have the attributes already on the TNode, we can preserve the case by going
                // through them once, adding them to the `attributes` map and putting their lower-cased name
                // into an array. Afterwards when we're going through the native DOM attributes, we can check
                // whether we haven't run into an attribute already through the TNode.
                if (tNodeAttrs) {
                    var i = 0;
                    while (i < tNodeAttrs.length) {
                        var attrName = tNodeAttrs[i];
                        // Stop as soon as we hit a marker. We only care about the regular attributes. Everything
                        // else will be handled below when we read the final attributes off the DOM.
                        if (typeof attrName !== 'string')
                            break;
                        var attrValue = tNodeAttrs[i + 1];
                        attributes[attrName] = attrValue;
                        lowercaseTNodeAttrs.push(attrName.toLowerCase());
                        i += 2;
                    }
                }
                var eAttrs = element.attributes;
                for (var i = 0; i < eAttrs.length; i++) {
                    var attr = eAttrs[i];
                    // Make sure that we don't assign the same attribute both in its
                    // case-sensitive form and the lower-cased one from the browser.
                    if (lowercaseTNodeAttrs.indexOf(attr.name) === -1) {
                        attributes[attr.name] = attr.value;
                    }
                }
                return attributes;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugElement__POST_R3__.prototype, "styles", {
            get: function () {
                return _getStylingDebugInfo(this.nativeElement, false);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugElement__POST_R3__.prototype, "classes", {
            get: function () {
                return _getStylingDebugInfo(this.nativeElement, true);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugElement__POST_R3__.prototype, "childNodes", {
            get: function () {
                var childNodes = this.nativeNode.childNodes;
                var children = [];
                for (var i = 0; i < childNodes.length; i++) {
                    var element = childNodes[i];
                    children.push(getDebugNode__POST_R3__(element));
                }
                return children;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugElement__POST_R3__.prototype, "children", {
            get: function () {
                var nativeElement = this.nativeElement;
                if (!nativeElement)
                    return [];
                var childNodes = nativeElement.children;
                var children = [];
                for (var i = 0; i < childNodes.length; i++) {
                    var element = childNodes[i];
                    children.push(getDebugNode__POST_R3__(element));
                }
                return children;
            },
            enumerable: true,
            configurable: true
        });
        DebugElement__POST_R3__.prototype.query = function (predicate) {
            var results = this.queryAll(predicate);
            return results[0] || null;
        };
        DebugElement__POST_R3__.prototype.queryAll = function (predicate) {
            var matches = [];
            _queryAllR3(this, predicate, matches, true);
            return matches;
        };
        DebugElement__POST_R3__.prototype.queryAllNodes = function (predicate) {
            var matches = [];
            _queryAllR3(this, predicate, matches, false);
            return matches;
        };
        DebugElement__POST_R3__.prototype.triggerEventHandler = function (eventName, eventObj) {
            this.listeners.forEach(function (listener) {
                if (listener.name === eventName) {
                    listener.callback(eventObj);
                }
            });
        };
        return DebugElement__POST_R3__;
    }(DebugNode__POST_R3__));
    function _getStylingDebugInfo(element, isClassBased) {
        if (element) {
            var context = loadLContextFromNode(element);
            var lView = context.lView;
            var tData = lView[TVIEW].data;
            var tNode = tData[context.nodeIndex];
            if (isClassBased) {
                return isStylingContext(tNode.classes) ?
                    new NodeStylingDebug(tNode.classes, lView, true).values :
                    stylingMapToStringMap(tNode.classes);
            }
            else {
                return isStylingContext(tNode.styles) ?
                    new NodeStylingDebug(tNode.styles, lView, false).values :
                    stylingMapToStringMap(tNode.styles);
            }
        }
        return {};
    }
    function _queryAllR3(parentElement, predicate, matches, elementsOnly) {
        var context = loadLContext(parentElement.nativeNode);
        var parentTNode = context.lView[TVIEW].data[context.nodeIndex];
        _queryNodeChildrenR3(parentTNode, context.lView, predicate, matches, elementsOnly, parentElement.nativeNode);
    }
    /**
     * Recursively match the current TNode against the predicate, and goes on with the next ones.
     *
     * @param tNode the current TNode
     * @param lView the LView of this TNode
     * @param predicate the predicate to match
     * @param matches the list of positive matches
     * @param elementsOnly whether only elements should be searched
     * @param rootNativeNode the root native node on which predicate should not be matched
     */
    function _queryNodeChildrenR3(tNode, lView, predicate, matches, elementsOnly, rootNativeNode) {
        var e_1, _a;
        var nativeNode = getNativeByTNodeOrNull(tNode, lView);
        // For each type of TNode, specific logic is executed.
        if (tNode.type === 3 /* Element */ || tNode.type === 4 /* ElementContainer */) {
            // Case 1: the TNode is an element
            // The native node has to be checked.
            _addQueryMatchR3(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
            if (isComponent(tNode)) {
                // If the element is the host of a component, then all nodes in its view have to be processed.
                // Note: the component's content (tNode.child) will be processed from the insertion points.
                var componentView = getComponentViewByIndex(tNode.index, lView);
                if (componentView && componentView[TVIEW].firstChild) {
                    _queryNodeChildrenR3(componentView[TVIEW].firstChild, componentView, predicate, matches, elementsOnly, rootNativeNode);
                }
            }
            else {
                if (tNode.child) {
                    // Otherwise, its children have to be processed.
                    _queryNodeChildrenR3(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
                }
                // We also have to query the DOM directly in order to catch elements inserted through
                // Renderer2. Note that this is __not__ optimal, because we're walking similar trees multiple
                // times. ViewEngine could do it more efficiently, because all the insertions go through
                // Renderer2, however that's not the case in Ivy. This approach is being used because:
                // 1. Matching the ViewEngine behavior would mean potentially introducing a depedency
                //    from `Renderer2` to Ivy which could bring Ivy code into ViewEngine.
                // 2. We would have to make `Renderer3` "know" about debug nodes.
                // 3. It allows us to capture nodes that were inserted directly via the DOM.
                nativeNode && _queryNativeNodeDescendants(nativeNode, predicate, matches, elementsOnly);
            }
            // In all cases, if a dynamic container exists for this node, each view inside it has to be
            // processed.
            var nodeOrContainer = lView[tNode.index];
            if (isLContainer(nodeOrContainer)) {
                _queryNodeChildrenInContainerR3(nodeOrContainer, predicate, matches, elementsOnly, rootNativeNode);
            }
        }
        else if (tNode.type === 0 /* Container */) {
            // Case 2: the TNode is a container
            // The native node has to be checked.
            var lContainer = lView[tNode.index];
            _addQueryMatchR3(lContainer[NATIVE], predicate, matches, elementsOnly, rootNativeNode);
            // Each view inside the container has to be processed.
            _queryNodeChildrenInContainerR3(lContainer, predicate, matches, elementsOnly, rootNativeNode);
        }
        else if (tNode.type === 1 /* Projection */) {
            // Case 3: the TNode is a projection insertion point (i.e. a <ng-content>).
            // The nodes projected at this location all need to be processed.
            var componentView = findComponentView(lView);
            var componentHost = componentView[T_HOST];
            var head = componentHost.projection[tNode.projection];
            if (Array.isArray(head)) {
                try {
                    for (var head_1 = __values(head), head_1_1 = head_1.next(); !head_1_1.done; head_1_1 = head_1.next()) {
                        var nativeNode_1 = head_1_1.value;
                        _addQueryMatchR3(nativeNode_1, predicate, matches, elementsOnly, rootNativeNode);
                    }
                }
                catch (e_1_1) { e_1 = { error: e_1_1 }; }
                finally {
                    try {
                        if (head_1_1 && !head_1_1.done && (_a = head_1.return)) _a.call(head_1);
                    }
                    finally { if (e_1) throw e_1.error; }
                }
            }
            else if (head) {
                var nextLView = componentView[PARENT];
                var nextTNode = nextLView[TVIEW].data[head.index];
                _queryNodeChildrenR3(nextTNode, nextLView, predicate, matches, elementsOnly, rootNativeNode);
            }
        }
        else if (tNode.child) {
            // Case 4: the TNode is a view.
            _queryNodeChildrenR3(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
        }
        // We don't want to go to the next sibling of the root node.
        if (rootNativeNode !== nativeNode) {
            // To determine the next node to be processed, we need to use the next or the projectionNext
            // link, depending on whether the current node has been projected.
            var nextTNode = (tNode.flags & 2 /* isProjected */) ? tNode.projectionNext : tNode.next;
            if (nextTNode) {
                _queryNodeChildrenR3(nextTNode, lView, predicate, matches, elementsOnly, rootNativeNode);
            }
        }
    }
    /**
     * Process all TNodes in a given container.
     *
     * @param lContainer the container to be processed
     * @param predicate the predicate to match
     * @param matches the list of positive matches
     * @param elementsOnly whether only elements should be searched
     * @param rootNativeNode the root native node on which predicate should not be matched
     */
    function _queryNodeChildrenInContainerR3(lContainer, predicate, matches, elementsOnly, rootNativeNode) {
        for (var i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
            var childView = lContainer[i];
            _queryNodeChildrenR3(childView[TVIEW].node, childView, predicate, matches, elementsOnly, rootNativeNode);
        }
    }
    /**
     * Match the current native node against the predicate.
     *
     * @param nativeNode the current native node
     * @param predicate the predicate to match
     * @param matches the list of positive matches
     * @param elementsOnly whether only elements should be searched
     * @param rootNativeNode the root native node on which predicate should not be matched
     */
    function _addQueryMatchR3(nativeNode, predicate, matches, elementsOnly, rootNativeNode) {
        if (rootNativeNode !== nativeNode) {
            var debugNode = getDebugNode(nativeNode);
            if (!debugNode) {
                return;
            }
            // Type of the "predicate and "matches" array are set based on the value of
            // the "elementsOnly" parameter. TypeScript is not able to properly infer these
            // types with generics, so we manually cast the parameters accordingly.
            if (elementsOnly && debugNode instanceof DebugElement__POST_R3__ && predicate(debugNode) &&
                matches.indexOf(debugNode) === -1) {
                matches.push(debugNode);
            }
            else if (!elementsOnly && predicate(debugNode) &&
                matches.indexOf(debugNode) === -1) {
                matches.push(debugNode);
            }
        }
    }
    /**
     * Match all the descendants of a DOM node against a predicate.
     *
     * @param nativeNode the current native node
     * @param predicate the predicate to match
     * @param matches the list of positive matches
     * @param elementsOnly whether only elements should be searched
     */
    function _queryNativeNodeDescendants(parentNode, predicate, matches, elementsOnly) {
        var nodes = parentNode.childNodes;
        var length = nodes.length;
        for (var i = 0; i < length; i++) {
            var node = nodes[i];
            var debugNode = getDebugNode(node);
            if (debugNode) {
                if (elementsOnly && debugNode instanceof DebugElement__POST_R3__ && predicate(debugNode) &&
                    matches.indexOf(debugNode) === -1) {
                    matches.push(debugNode);
                }
                else if (!elementsOnly && predicate(debugNode) &&
                    matches.indexOf(debugNode) === -1) {
                    matches.push(debugNode);
                }
                _queryNativeNodeDescendants(node, predicate, matches, elementsOnly);
            }
        }
    }
    /**
     * Iterates through the property bindings for a given node and generates
     * a map of property names to values. This map only contains property bindings
     * defined in templates, not in host bindings.
     */
    function collectPropertyBindings(tNode, lView, tData) {
        var properties = {};
        var bindingIndex = getFirstBindingIndex(tNode.propertyMetadataStartIndex, tData);
        while (bindingIndex < tNode.propertyMetadataEndIndex) {
            var value = void 0;
            var propMetadata = tData[bindingIndex];
            while (!isPropMetadataString(propMetadata)) {
                // This is the first value for an interpolation. We need to build up
                // the full interpolation by combining runtime values in LView with
                // the static interstitial values stored in TData.
                value = (value || '') + renderStringify(lView[bindingIndex]) + tData[bindingIndex];
                propMetadata = tData[++bindingIndex];
            }
            value = value === undefined ? lView[bindingIndex] : value += lView[bindingIndex];
            // Property metadata string has 3 parts: property name, prefix, and suffix
            var metadataParts = propMetadata.split(INTERPOLATION_DELIMITER);
            var propertyName = metadataParts[0];
            // Attr bindings don't have property names and should be skipped
            if (propertyName) {
                // Wrap value with prefix and suffix (will be '' for normal bindings), if they're defined.
                // Avoid wrapping for normal bindings so that the value doesn't get cast to a string.
                properties[propertyName] = (metadataParts[1] && metadataParts[2]) ?
                    metadataParts[1] + value + metadataParts[2] :
                    value;
            }
            bindingIndex++;
        }
        return properties;
    }
    /**
     * Retrieves the first binding index that holds values for this property
     * binding.
     *
     * For normal bindings (e.g. `[id]="id"`), the binding index is the
     * same as the metadata index. For interpolations (e.g. `id="{{id}}-{{name}}"`),
     * there can be multiple binding values, so we might have to loop backwards
     * from the metadata index until we find the first one.
     *
     * @param metadataIndex The index of the first property metadata string for
     * this node.
     * @param tData The data array for the current TView
     * @returns The first binding index for this binding
     */
    function getFirstBindingIndex(metadataIndex, tData) {
        var currentBindingIndex = metadataIndex - 1;
        // If the slot before the metadata holds a string, we know that this
        // metadata applies to an interpolation with at least 2 bindings, and
        // we need to search further to access the first binding value.
        var currentValue = tData[currentBindingIndex];
        // We need to iterate until we hit either a:
        // - TNode (it is an element slot marking the end of `consts` section), OR a
        // - metadata string (slot is attribute metadata or a previous node's property metadata)
        while (typeof currentValue === 'string' && !isPropMetadataString(currentValue)) {
            currentValue = tData[--currentBindingIndex];
        }
        return currentBindingIndex + 1;
    }
    function collectHostPropertyBindings(tNode, lView, tData) {
        var properties = {};
        // Host binding values for a node are stored after directives on that node
        var hostPropIndex = tNode.directiveEnd;
        var propMetadata = tData[hostPropIndex];
        // When we reach a value in TView.data that is not a string, we know we've
        // hit the next node's providers and directives and should stop copying data.
        while (typeof propMetadata === 'string') {
            var propertyName = propMetadata.split(INTERPOLATION_DELIMITER)[0];
            properties[propertyName] = lView[hostPropIndex];
            propMetadata = tData[++hostPropIndex];
        }
        return properties;
    }
    function collectClassNames(debugElement) {
        var e_2, _a;
        var classes = debugElement.classes;
        var output = '';
        try {
            for (var _b = __values(Object.keys(classes)), _c = _b.next(); !_c.done; _c = _b.next()) {
                var className = _c.value;
                if (classes[className]) {
                    output = output ? output + (" " + className) : className;
                }
            }
        }
        catch (e_2_1) { e_2 = { error: e_2_1 }; }
        finally {
            try {
                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
            }
            finally { if (e_2) throw e_2.error; }
        }
        return output;
    }
    // Need to keep the nodes in a global Map so that multiple angular apps are supported.
    var _nativeNodeToDebugNode = new Map();
    function getDebugNode__PRE_R3__(nativeNode) {
        return _nativeNodeToDebugNode.get(nativeNode) || null;
    }
    var NG_DEBUG_PROPERTY = '__ng_debug__';
    function getDebugNode__POST_R3__(nativeNode) {
        if (nativeNode instanceof Node) {
            if (!(nativeNode.hasOwnProperty(NG_DEBUG_PROPERTY))) {
                nativeNode[NG_DEBUG_PROPERTY] = nativeNode.nodeType == Node.ELEMENT_NODE ?
                    new DebugElement__POST_R3__(nativeNode) :
                    new DebugNode__POST_R3__(nativeNode);
            }
            return nativeNode[NG_DEBUG_PROPERTY];
        }
        return null;
    }
    /**
     * @publicApi
     */
    var getDebugNode = getDebugNode__PRE_R3__;
    function getAllDebugNodes() {
        return Array.from(_nativeNodeToDebugNode.values());
    }
    function indexDebugNode(node) {
        _nativeNodeToDebugNode.set(node.nativeNode, node);
    }
    function removeDebugNodeFromIndex(node) {
        _nativeNodeToDebugNode.delete(node.nativeNode);
    }
    /**
     * @publicApi
     */
    var DebugNode = DebugNode__PRE_R3__;
    /**
     * @publicApi
     */
    var DebugElement = DebugElement__PRE_R3__;

    /**
     * @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
     */

    /**
     * @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
     */
    var _CORE_PLATFORM_PROVIDERS = [
        // Set a default platform name for platforms that don't set it explicitly.
        { provide: PLATFORM_ID, useValue: 'unknown' },
        { provide: PlatformRef, deps: [Injector] },
        { provide: TestabilityRegistry, deps: [] },
        { provide: Console, deps: [] },
    ];
    /**
     * This platform has to be included in any other platform
     *
     * @publicApi
     */
    var platformCore = createPlatformFactory(null, 'core', _CORE_PLATFORM_PROVIDERS);

    /**
     * @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
     */
    function _iterableDiffersFactory() {
        return defaultIterableDiffers;
    }
    function _keyValueDiffersFactory() {
        return defaultKeyValueDiffers;
    }
    function _localeFactory(locale) {
        if (locale) {
            if (ivyEnabled) {
                setLocaleId(locale);
            }
            return locale;
        }
        // Use `goog.LOCALE` as default value for `LOCALE_ID` token for Closure Compiler.
        // Note: default `goog.LOCALE` value is `en`, when Angular used `en-US`. In order to preserve
        // backwards compatibility, we use Angular default value over Closure Compiler's one.
        if (ngI18nClosureMode && typeof goog !== 'undefined' && goog.LOCALE !== 'en') {
            if (ivyEnabled) {
                setLocaleId(goog.LOCALE);
            }
            return goog.LOCALE;
        }
        return DEFAULT_LOCALE_ID;
    }
    /**
     * A built-in [dependency injection token](guide/glossary#di-token)
     * that is used to configure the root injector for bootstrapping.
     */
    var APPLICATION_MODULE_PROVIDERS = [
        {
            provide: ApplicationRef,
            useClass: ApplicationRef,
            deps: [NgZone, Console, Injector, ErrorHandler, ComponentFactoryResolver, ApplicationInitStatus]
        },
        { provide: SCHEDULER, deps: [NgZone], useFactory: zoneSchedulerFactory },
        {
            provide: ApplicationInitStatus,
            useClass: ApplicationInitStatus,
            deps: [[new Optional(), APP_INITIALIZER]]
        },
        { provide: Compiler, useClass: Compiler, deps: [] },
        APP_ID_RANDOM_PROVIDER,
        { provide: IterableDiffers, useFactory: _iterableDiffersFactory, deps: [] },
        { provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory, deps: [] },
        {
            provide: LOCALE_ID$1,
            useFactory: _localeFactory,
            deps: [[new Inject(LOCALE_ID$1), new Optional(), new SkipSelf()]]
        },
    ];
    /**
     * Schedule work at next available slot.
     *
     * In Ivy this is just `requestAnimationFrame`. For compatibility reasons when bootstrapped
     * using `platformRef.bootstrap` we need to use `NgZone.onStable` as the scheduling mechanism.
     * This overrides the scheduling mechanism in Ivy to `NgZone.onStable`.
     *
     * @param ngZone NgZone to use for scheduling.
     */
    function zoneSchedulerFactory(ngZone) {
        var queue = [];
        ngZone.onStable.subscribe(function () {
            while (queue.length) {
                queue.pop()();
            }
        });
        return function (fn) { queue.push(fn); };
    }
    /**
     * Configures the root injector for an app with
     * providers of `@angular/core` dependencies that `ApplicationRef` needs
     * to bootstrap components.
     *
     * Re-exported by `BrowserModule`, which is included automatically in the root
     * `AppModule` when you create a new app with the CLI `new` command.
     *
     * @publicApi
     */
    var ApplicationModule = /** @class */ (function () {
        // Inject ApplicationRef to make it eager...
        function ApplicationModule(appRef) {
        }
        ApplicationModule = __decorate([
            NgModule({ providers: APPLICATION_MODULE_PROVIDERS }),
            __metadata("design:paramtypes", [ApplicationRef])
        ], ApplicationModule);
        return ApplicationModule;
    }());

    /**
     * @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
     */
    function anchorDef(flags, matchedQueriesDsl, ngContentIndex, childCount, handleEvent, templateFactory) {
        flags |= 1 /* TypeElement */;
        var _a = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _a.matchedQueries, references = _a.references, matchedQueryIds = _a.matchedQueryIds;
        var template = templateFactory ? resolveDefinition(templateFactory) : null;
        return {
            // will bet set by the view definition
            nodeIndex: -1,
            parent: null,
            renderParent: null,
            bindingIndex: -1,
            outputIndex: -1,
            // regular values
            flags: flags,
            checkIndex: -1,
            childFlags: 0,
            directChildFlags: 0,
            childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references, ngContentIndex: ngContentIndex, childCount: childCount,
            bindings: [],
            bindingFlags: 0,
            outputs: [],
            element: {
                ns: null,
                name: null,
                attrs: null, template: template,
                componentProvider: null,
                componentView: null,
                componentRendererType: null,
                publicProviders: null,
                allProviders: null,
                handleEvent: handleEvent || NOOP
            },
            provider: null,
            text: null,
            query: null,
            ngContent: null
        };
    }
    function elementDef(checkIndex, flags, matchedQueriesDsl, ngContentIndex, childCount, namespaceAndName, fixedAttrs, bindings, outputs, handleEvent, componentView, componentRendererType) {
        var _a;
        if (fixedAttrs === void 0) { fixedAttrs = []; }
        if (!handleEvent) {
            handleEvent = NOOP;
        }
        var _b = splitMatchedQueriesDsl(matchedQueriesDsl), matchedQueries = _b.matchedQueries, references = _b.references, matchedQueryIds = _b.matchedQueryIds;
        var ns = null;
        var name = null;
        if (namespaceAndName) {
            _a = __read(splitNamespace(namespaceAndName), 2), ns = _a[0], name = _a[1];
        }
        bindings = bindings || [];
        var bindingDefs = new Array(bindings.length);
        for (var i = 0; i < bindings.length; i++) {
            var _c = __read(bindings[i], 3), bindingFlags = _c[0], namespaceAndName_1 = _c[1], suffixOrSecurityContext = _c[2];
            var _d = __read(splitNamespace(namespaceAndName_1), 2), ns_1 = _d[0], name_1 = _d[1];
            var securityContext = undefined;
            var suffix = undefined;
            switch (bindingFlags & 15 /* Types */) {
                case 4 /* TypeElementStyle */:
                    suffix = suffixOrSecurityContext;
                    break;
                case 1 /* TypeElementAttribute */:
                case 8 /* TypeProperty */:
                    securityContext = suffixOrSecurityContext;
                    break;
            }
            bindingDefs[i] =
                { flags: bindingFlags, ns: ns_1, name: name_1, nonMinifiedName: name_1, securityContext: securityContext, suffix: suffix };
        }
        outputs = outputs || [];
        var outputDefs = new Array(outputs.length);
        for (var i = 0; i < outputs.length; i++) {
            var _e = __read(outputs[i], 2), target = _e[0], eventName = _e[1];
            outputDefs[i] = {
                type: 0 /* ElementOutput */,
                target: target, eventName: eventName,
                propName: null
            };
        }
        fixedAttrs = fixedAttrs || [];
        var attrs = fixedAttrs.map(function (_a) {
            var _b = __read(_a, 2), namespaceAndName = _b[0], value = _b[1];
            var _c = __read(splitNamespace(namespaceAndName), 2), ns = _c[0], name = _c[1];
            return [ns, name, value];
        });
        componentRendererType = resolveRendererType2(componentRendererType);
        if (componentView) {
            flags |= 33554432 /* ComponentView */;
        }
        flags |= 1 /* TypeElement */;
        return {
            // will bet set by the view definition
            nodeIndex: -1,
            parent: null,
            renderParent: null,
            bindingIndex: -1,
            outputIndex: -1,
            // regular values
            checkIndex: checkIndex,
            flags: flags,
            childFlags: 0,
            directChildFlags: 0,
            childMatchedQueries: 0, matchedQueries: matchedQueries, matchedQueryIds: matchedQueryIds, references: references, ngContentIndex: ngContentIndex, childCount: childCount,
            bindings: bindingDefs,
            bindingFlags: calcBindingFlags(bindingDefs),
            outputs: outputDefs,
            element: {
                ns: ns,
                name: name,
                attrs: attrs,
                template: null,
                // will bet set by the view definition
                componentProvider: null,
                componentView: componentView || null,
                componentRendererType: componentRendererType,
                publicProviders: null,
                allProviders: null,
                handleEvent: handleEvent || NOOP,
            },
            provider: null,
            text: null,
            query: null,
            ngContent: null
        };
    }
    function createElement(view, renderHost, def) {
        var elDef = def.element;
        var rootSelectorOrNode = view.root.selectorOrNode;
        var renderer = view.renderer;
        var el;
        if (view.parent || !rootSelectorOrNode) {
            if (elDef.name) {
                el = renderer.createElement(elDef.name, elDef.ns);
            }
            else {
                el = renderer.createComment('');
            }
            var parentEl = getParentRenderElement(view, renderHost, def);
            if (parentEl) {
                renderer.appendChild(parentEl, el);
            }
        }
        else {
            // when using native Shadow DOM, do not clear the root element contents to allow slot projection
            var preserveContent = (!!elDef.componentRendererType &&
                elDef.componentRendererType.encapsulation === exports.ViewEncapsulation.ShadowDom);
            el = renderer.selectRootElement(rootSelectorOrNode, preserveContent);
        }
        if (elDef.attrs) {
            for (var i = 0; i < elDef.attrs.length; i++) {
                var _a = __read(elDef.attrs[i], 3), ns = _a[0], name_2 = _a[1], value = _a[2];
                renderer.setAttribute(el, name_2, value, ns);
            }
        }
        return el;
    }
    function listenToElementOutputs(view, compView, def, el) {
        for (var i = 0; i < def.outputs.length; i++) {
            var output = def.outputs[i];
            var handleEventClosure = renderEventHandlerClosure(view, def.nodeIndex, elementEventFullName(output.target, output.eventName));
            var listenTarget = output.target;
            var listenerView = view;
            if (output.target === 'component') {
                listenTarget = null;
                listenerView = compView;
            }
            var disposable = listenerView.renderer.listen(listenTarget || el, output.eventName, handleEventClosure);
            view.disposables[def.outputIndex + i] = disposable;
        }
    }
    function renderEventHandlerClosure(view, index, eventName) {
        return function (event) { return dispatchEvent(view, index, eventName, event); };
    }
    function checkAndUpdateElementInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        var bindLen = def.bindings.length;
        var changed = false;
        if (bindLen > 0 && checkAndUpdateElementValue(view, def, 0, v0))
            changed = true;
        if (bindLen > 1 && checkAndUpdateElementValue(view, def, 1, v1))
            changed = true;
        if (bindLen > 2 && checkAndUpdateElementValue(view, def, 2, v2))
            changed = true;
        if (bindLen > 3 && checkAndUpdateElementValue(view, def, 3, v3))
            changed = true;
        if (bindLen > 4 && checkAndUpdateElementValue(view, def, 4, v4))
            changed = true;
        if (bindLen > 5 && checkAndUpdateElementValue(view, def, 5, v5))
            changed = true;
        if (bindLen > 6 && checkAndUpdateElementValue(view, def, 6, v6))
            changed = true;
        if (bindLen > 7 && checkAndUpdateElementValue(view, def, 7, v7))
            changed = true;
        if (bindLen > 8 && checkAndUpdateElementValue(view, def, 8, v8))
            changed = true;
        if (bindLen > 9 && checkAndUpdateElementValue(view, def, 9, v9))
            changed = true;
        return changed;
    }
    function checkAndUpdateElementDynamic(view, def, values) {
        var changed = false;
        for (var i = 0; i < values.length; i++) {
            if (checkAndUpdateElementValue(view, def, i, values[i]))
                changed = true;
        }
        return changed;
    }
    function checkAndUpdateElementValue(view, def, bindingIdx, value) {
        if (!checkAndUpdateBinding(view, def, bindingIdx, value)) {
            return false;
        }
        var binding = def.bindings[bindingIdx];
        var elData = asElementData(view, def.nodeIndex);
        var renderNode = elData.renderElement;
        var name = binding.name;
        switch (binding.flags & 15 /* Types */) {
            case 1 /* TypeElementAttribute */:
                setElementAttribute(view, binding, renderNode, binding.ns, name, value);
                break;
            case 2 /* TypeElementClass */:
                setElementClass(view, renderNode, name, value);
                break;
            case 4 /* TypeElementStyle */:
                setElementStyle(view, binding, renderNode, name, value);
                break;
            case 8 /* TypeProperty */:
                var bindView = (def.flags & 33554432 /* ComponentView */ &&
                    binding.flags & 32 /* SyntheticHostProperty */) ?
                    elData.componentView :
                    view;
                setElementProperty(bindView, binding, renderNode, name, value);
                break;
        }
        return true;
    }
    function setElementAttribute(view, binding, renderNode, ns, name, value) {
        var securityContext = binding.securityContext;
        var renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
        renderValue = renderValue != null ? renderValue.toString() : null;
        var renderer = view.renderer;
        if (value != null) {
            renderer.setAttribute(renderNode, name, renderValue, ns);
        }
        else {
            renderer.removeAttribute(renderNode, name, ns);
        }
    }
    function setElementClass(view, renderNode, name, value) {
        var renderer = view.renderer;
        if (value) {
            renderer.addClass(renderNode, name);
        }
        else {
            renderer.removeClass(renderNode, name);
        }
    }
    function setElementStyle(view, binding, renderNode, name, value) {
        var renderValue = view.root.sanitizer.sanitize(exports.SecurityContext.STYLE, value);
        if (renderValue != null) {
            renderValue = renderValue.toString();
            var unit = binding.suffix;
            if (unit != null) {
                renderValue = renderValue + unit;
            }
        }
        else {
            renderValue = null;
        }
        var renderer = view.renderer;
        if (renderValue != null) {
            renderer.setStyle(renderNode, name, renderValue);
        }
        else {
            renderer.removeStyle(renderNode, name);
        }
    }
    function setElementProperty(view, binding, renderNode, name, value) {
        var securityContext = binding.securityContext;
        var renderValue = securityContext ? view.root.sanitizer.sanitize(securityContext, value) : value;
        view.renderer.setProperty(renderNode, name, renderValue);
    }

    /**
     * @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
     */
    function queryDef(flags, id, bindings) {
        var bindingDefs = [];
        for (var propName in bindings) {
            var bindingType = bindings[propName];
            bindingDefs.push({ propName: propName, bindingType: bindingType });
        }
        return {
            // will bet set by the view definition
            nodeIndex: -1,
            parent: null,
            renderParent: null,
            bindingIndex: -1,
            outputIndex: -1,
            // regular values
            // TODO(vicb): check
            checkIndex: -1, flags: flags,
            childFlags: 0,
            directChildFlags: 0,
            childMatchedQueries: 0,
            ngContentIndex: -1,
            matchedQueries: {},
            matchedQueryIds: 0,
            references: {},
            childCount: 0,
            bindings: [],
            bindingFlags: 0,
            outputs: [],
            element: null,
            provider: null,
            text: null,
            query: { id: id, filterId: filterQueryId(id), bindings: bindingDefs },
            ngContent: null
        };
    }
    function createQuery() {
        return new QueryList();
    }
    function dirtyParentQueries(view) {
        var queryIds = view.def.nodeMatchedQueries;
        while (view.parent && isEmbeddedView(view)) {
            var tplDef = view.parentNodeDef;
            view = view.parent;
            // content queries
            var end = tplDef.nodeIndex + tplDef.childCount;
            for (var i = 0; i <= end; i++) {
                var nodeDef = view.def.nodes[i];
                if ((nodeDef.flags & 67108864 /* TypeContentQuery */) &&
                    (nodeDef.flags & 536870912 /* DynamicQuery */) &&
                    (nodeDef.query.filterId & queryIds) === nodeDef.query.filterId) {
                    asQueryList(view, i).setDirty();
                }
                if ((nodeDef.flags & 1 /* TypeElement */ && i + nodeDef.childCount < tplDef.nodeIndex) ||
                    !(nodeDef.childFlags & 67108864 /* TypeContentQuery */) ||
                    !(nodeDef.childFlags & 536870912 /* DynamicQuery */)) {
                    // skip elements that don't contain the template element or no query.
                    i += nodeDef.childCount;
                }
            }
        }
        // view queries
        if (view.def.nodeFlags & 134217728 /* TypeViewQuery */) {
            for (var i = 0; i < view.def.nodes.length; i++) {
                var nodeDef = view.def.nodes[i];
                if ((nodeDef.flags & 134217728 /* TypeViewQuery */) && (nodeDef.flags & 536870912 /* DynamicQuery */)) {
                    asQueryList(view, i).setDirty();
                }
                // only visit the root nodes
                i += nodeDef.childCount;
            }
        }
    }
    function checkAndUpdateQuery(view, nodeDef) {
        var queryList = asQueryList(view, nodeDef.nodeIndex);
        if (!queryList.dirty) {
            return;
        }
        var directiveInstance;
        var newValues = undefined;
        if (nodeDef.flags & 67108864 /* TypeContentQuery */) {
            var elementDef = nodeDef.parent.parent;
            newValues = calcQueryValues(view, elementDef.nodeIndex, elementDef.nodeIndex + elementDef.childCount, nodeDef.query, []);
            directiveInstance = asProviderData(view, nodeDef.parent.nodeIndex).instance;
        }
        else if (nodeDef.flags & 134217728 /* TypeViewQuery */) {
            newValues = calcQueryValues(view, 0, view.def.nodes.length - 1, nodeDef.query, []);
            directiveInstance = view.component;
        }
        queryList.reset(newValues);
        var bindings = nodeDef.query.bindings;
        var notify = false;
        for (var i = 0; i < bindings.length; i++) {
            var binding = bindings[i];
            var boundValue = void 0;
            switch (binding.bindingType) {
                case 0 /* First */:
                    boundValue = queryList.first;
                    break;
                case 1 /* All */:
                    boundValue = queryList;
                    notify = true;
                    break;
            }
            directiveInstance[binding.propName] = boundValue;
        }
        if (notify) {
            queryList.notifyOnChanges();
        }
    }
    function calcQueryValues(view, startIndex, endIndex, queryDef, values) {
        for (var i = startIndex; i <= endIndex; i++) {
            var nodeDef = view.def.nodes[i];
            var valueType = nodeDef.matchedQueries[queryDef.id];
            if (valueType != null) {
                values.push(getQueryValue(view, nodeDef, valueType));
            }
            if (nodeDef.flags & 1 /* TypeElement */ && nodeDef.element.template &&
                (nodeDef.element.template.nodeMatchedQueries & queryDef.filterId) ===
                    queryDef.filterId) {
                var elementData = asElementData(view, i);
                // check embedded views that were attached at the place of their template,
                // but process child nodes first if some match the query (see issue #16568)
                if ((nodeDef.childMatchedQueries & queryDef.filterId) === queryDef.filterId) {
                    calcQueryValues(view, i + 1, i + nodeDef.childCount, queryDef, values);
                    i += nodeDef.childCount;
                }
                if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
                    var embeddedViews = elementData.viewContainer._embeddedViews;
                    for (var k = 0; k < embeddedViews.length; k++) {
                        var embeddedView = embeddedViews[k];
                        var dvc = declaredViewContainer(embeddedView);
                        if (dvc && dvc === elementData) {
                            calcQueryValues(embeddedView, 0, embeddedView.def.nodes.length - 1, queryDef, values);
                        }
                    }
                }
                var projectedViews = elementData.template._projectedViews;
                if (projectedViews) {
                    for (var k = 0; k < projectedViews.length; k++) {
                        var projectedView = projectedViews[k];
                        calcQueryValues(projectedView, 0, projectedView.def.nodes.length - 1, queryDef, values);
                    }
                }
            }
            if ((nodeDef.childMatchedQueries & queryDef.filterId) !== queryDef.filterId) {
                // if no child matches the query, skip the children.
                i += nodeDef.childCount;
            }
        }
        return values;
    }
    function getQueryValue(view, nodeDef, queryValueType) {
        if (queryValueType != null) {
            // a match
            switch (queryValueType) {
                case 1 /* RenderElement */:
                    return asElementData(view, nodeDef.nodeIndex).renderElement;
                case 0 /* ElementRef */:
                    return new ElementRef(asElementData(view, nodeDef.nodeIndex).renderElement);
                case 2 /* TemplateRef */:
                    return asElementData(view, nodeDef.nodeIndex).template;
                case 3 /* ViewContainerRef */:
                    return asElementData(view, nodeDef.nodeIndex).viewContainer;
                case 4 /* Provider */:
                    return asProviderData(view, nodeDef.nodeIndex).instance;
            }
        }
    }

    /**
     * @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
     */
    function ngContentDef(ngContentIndex, index) {
        return {
            // will bet set by the view definition
            nodeIndex: -1,
            parent: null,
            renderParent: null,
            bindingIndex: -1,
            outputIndex: -1,
            // regular values
            checkIndex: -1,
            flags: 8 /* TypeNgContent */,
            childFlags: 0,
            directChildFlags: 0,
            childMatchedQueries: 0,
            matchedQueries: {},
            matchedQueryIds: 0,
            references: {}, ngContentIndex: ngContentIndex,
            childCount: 0,
            bindings: [],
            bindingFlags: 0,
            outputs: [],
            element: null,
            provider: null,
            text: null,
            query: null,
            ngContent: { index: index }
        };
    }
    function appendNgContent(view, renderHost, def) {
        var parentEl = getParentRenderElement(view, renderHost, def);
        if (!parentEl) {
            // Nothing to do if there is no parent element.
            return;
        }
        var ngContentIndex = def.ngContent.index;
        visitProjectedRenderNodes(view, ngContentIndex, 1 /* AppendChild */, parentEl, null, undefined);
    }

    /**
     * @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
     */
    function purePipeDef(checkIndex, argCount) {
        // argCount + 1 to include the pipe as first arg
        return _pureExpressionDef(128 /* TypePurePipe */, checkIndex, new Array(argCount + 1));
    }
    function pureArrayDef(checkIndex, argCount) {
        return _pureExpressionDef(32 /* TypePureArray */, checkIndex, new Array(argCount));
    }
    function pureObjectDef(checkIndex, propToIndex) {
        var keys = Object.keys(propToIndex);
        var nbKeys = keys.length;
        var propertyNames = new Array(nbKeys);
        for (var i = 0; i < nbKeys; i++) {
            var key = keys[i];
            var index = propToIndex[key];
            propertyNames[index] = key;
        }
        return _pureExpressionDef(64 /* TypePureObject */, checkIndex, propertyNames);
    }
    function _pureExpressionDef(flags, checkIndex, propertyNames) {
        var bindings = new Array(propertyNames.length);
        for (var i = 0; i < propertyNames.length; i++) {
            var prop = propertyNames[i];
            bindings[i] = {
                flags: 8 /* TypeProperty */,
                name: prop,
                ns: null,
                nonMinifiedName: prop,
                securityContext: null,
                suffix: null
            };
        }
        return {
            // will bet set by the view definition
            nodeIndex: -1,
            parent: null,
            renderParent: null,
            bindingIndex: -1,
            outputIndex: -1,
            // regular values
            checkIndex: checkIndex,
            flags: flags,
            childFlags: 0,
            directChildFlags: 0,
            childMatchedQueries: 0,
            matchedQueries: {},
            matchedQueryIds: 0,
            references: {},
            ngContentIndex: -1,
            childCount: 0, bindings: bindings,
            bindingFlags: calcBindingFlags(bindings),
            outputs: [],
            element: null,
            provider: null,
            text: null,
            query: null,
            ngContent: null
        };
    }
    function createPureExpression(view, def) {
        return { value: undefined };
    }
    function checkAndUpdatePureExpressionInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        var bindings = def.bindings;
        var changed = false;
        var bindLen = bindings.length;
        if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
            changed = true;
        if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
            changed = true;
        if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
            changed = true;
        if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
            changed = true;
        if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
            changed = true;
        if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
            changed = true;
        if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
            changed = true;
        if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
            changed = true;
        if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
            changed = true;
        if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
            changed = true;
        if (changed) {
            var data = asPureExpressionData(view, def.nodeIndex);
            var value = void 0;
            switch (def.flags & 201347067 /* Types */) {
                case 32 /* TypePureArray */:
                    value = new Array(bindings.length);
                    if (bindLen > 0)
                        value[0] = v0;
                    if (bindLen > 1)
                        value[1] = v1;
                    if (bindLen > 2)
                        value[2] = v2;
                    if (bindLen > 3)
                        value[3] = v3;
                    if (bindLen > 4)
                        value[4] = v4;
                    if (bindLen > 5)
                        value[5] = v5;
                    if (bindLen > 6)
                        value[6] = v6;
                    if (bindLen > 7)
                        value[7] = v7;
                    if (bindLen > 8)
                        value[8] = v8;
                    if (bindLen > 9)
                        value[9] = v9;
                    break;
                case 64 /* TypePureObject */:
                    value = {};
                    if (bindLen > 0)
                        value[bindings[0].name] = v0;
                    if (bindLen > 1)
                        value[bindings[1].name] = v1;
                    if (bindLen > 2)
                        value[bindings[2].name] = v2;
                    if (bindLen > 3)
                        value[bindings[3].name] = v3;
                    if (bindLen > 4)
                        value[bindings[4].name] = v4;
                    if (bindLen > 5)
                        value[bindings[5].name] = v5;
                    if (bindLen > 6)
                        value[bindings[6].name] = v6;
                    if (bindLen > 7)
                        value[bindings[7].name] = v7;
                    if (bindLen > 8)
                        value[bindings[8].name] = v8;
                    if (bindLen > 9)
                        value[bindings[9].name] = v9;
                    break;
                case 128 /* TypePurePipe */:
                    var pipe = v0;
                    switch (bindLen) {
                        case 1:
                            value = pipe.transform(v0);
                            break;
                        case 2:
                            value = pipe.transform(v1);
                            break;
                        case 3:
                            value = pipe.transform(v1, v2);
                            break;
                        case 4:
                            value = pipe.transform(v1, v2, v3);
                            break;
                        case 5:
                            value = pipe.transform(v1, v2, v3, v4);
                            break;
                        case 6:
                            value = pipe.transform(v1, v2, v3, v4, v5);
                            break;
                        case 7:
                            value = pipe.transform(v1, v2, v3, v4, v5, v6);
                            break;
                        case 8:
                            value = pipe.transform(v1, v2, v3, v4, v5, v6, v7);
                            break;
                        case 9:
                            value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8);
                            break;
                        case 10:
                            value = pipe.transform(v1, v2, v3, v4, v5, v6, v7, v8, v9);
                            break;
                    }
                    break;
            }
            data.value = value;
        }
        return changed;
    }
    function checkAndUpdatePureExpressionDynamic(view, def, values) {
        var bindings = def.bindings;
        var changed = false;
        for (var i = 0; i < values.length; i++) {
            // Note: We need to loop over all values, so that
            // the old values are updates as well!
            if (checkAndUpdateBinding(view, def, i, values[i])) {
                changed = true;
            }
        }
        if (changed) {
            var data = asPureExpressionData(view, def.nodeIndex);
            var value = void 0;
            switch (def.flags & 201347067 /* Types */) {
                case 32 /* TypePureArray */:
                    value = values;
                    break;
                case 64 /* TypePureObject */:
                    value = {};
                    for (var i = 0; i < values.length; i++) {
                        value[bindings[i].name] = values[i];
                    }
                    break;
                case 128 /* TypePurePipe */:
                    var pipe = values[0];
                    var params = values.slice(1);
                    value = pipe.transform.apply(pipe, __spread(params));
                    break;
            }
            data.value = value;
        }
        return changed;
    }

    /**
     * @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
     */
    function textDef(checkIndex, ngContentIndex, staticText) {
        var bindings = new Array(staticText.length - 1);
        for (var i = 1; i < staticText.length; i++) {
            bindings[i - 1] = {
                flags: 8 /* TypeProperty */,
                name: null,
                ns: null,
                nonMinifiedName: null,
                securityContext: null,
                suffix: staticText[i],
            };
        }
        return {
            // will bet set by the view definition
            nodeIndex: -1,
            parent: null,
            renderParent: null,
            bindingIndex: -1,
            outputIndex: -1,
            // regular values
            checkIndex: checkIndex,
            flags: 2 /* TypeText */,
            childFlags: 0,
            directChildFlags: 0,
            childMatchedQueries: 0,
            matchedQueries: {},
            matchedQueryIds: 0,
            references: {}, ngContentIndex: ngContentIndex,
            childCount: 0, bindings: bindings,
            bindingFlags: 8 /* TypeProperty */,
            outputs: [],
            element: null,
            provider: null,
            text: { prefix: staticText[0] },
            query: null,
            ngContent: null,
        };
    }
    function createText(view, renderHost, def) {
        var renderNode;
        var renderer = view.renderer;
        renderNode = renderer.createText(def.text.prefix);
        var parentEl = getParentRenderElement(view, renderHost, def);
        if (parentEl) {
            renderer.appendChild(parentEl, renderNode);
        }
        return { renderText: renderNode };
    }
    function checkAndUpdateTextInline(view, def, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        var changed = false;
        var bindings = def.bindings;
        var bindLen = bindings.length;
        if (bindLen > 0 && checkAndUpdateBinding(view, def, 0, v0))
            changed = true;
        if (bindLen > 1 && checkAndUpdateBinding(view, def, 1, v1))
            changed = true;
        if (bindLen > 2 && checkAndUpdateBinding(view, def, 2, v2))
            changed = true;
        if (bindLen > 3 && checkAndUpdateBinding(view, def, 3, v3))
            changed = true;
        if (bindLen > 4 && checkAndUpdateBinding(view, def, 4, v4))
            changed = true;
        if (bindLen > 5 && checkAndUpdateBinding(view, def, 5, v5))
            changed = true;
        if (bindLen > 6 && checkAndUpdateBinding(view, def, 6, v6))
            changed = true;
        if (bindLen > 7 && checkAndUpdateBinding(view, def, 7, v7))
            changed = true;
        if (bindLen > 8 && checkAndUpdateBinding(view, def, 8, v8))
            changed = true;
        if (bindLen > 9 && checkAndUpdateBinding(view, def, 9, v9))
            changed = true;
        if (changed) {
            var value = def.text.prefix;
            if (bindLen > 0)
                value += _addInterpolationPart(v0, bindings[0]);
            if (bindLen > 1)
                value += _addInterpolationPart(v1, bindings[1]);
            if (bindLen > 2)
                value += _addInterpolationPart(v2, bindings[2]);
            if (bindLen > 3)
                value += _addInterpolationPart(v3, bindings[3]);
            if (bindLen > 4)
                value += _addInterpolationPart(v4, bindings[4]);
            if (bindLen > 5)
                value += _addInterpolationPart(v5, bindings[5]);
            if (bindLen > 6)
                value += _addInterpolationPart(v6, bindings[6]);
            if (bindLen > 7)
                value += _addInterpolationPart(v7, bindings[7]);
            if (bindLen > 8)
                value += _addInterpolationPart(v8, bindings[8]);
            if (bindLen > 9)
                value += _addInterpolationPart(v9, bindings[9]);
            var renderNode = asTextData(view, def.nodeIndex).renderText;
            view.renderer.setValue(renderNode, value);
        }
        return changed;
    }
    function checkAndUpdateTextDynamic(view, def, values) {
        var bindings = def.bindings;
        var changed = false;
        for (var i = 0; i < values.length; i++) {
            // Note: We need to loop over all values, so that
            // the old values are updates as well!
            if (checkAndUpdateBinding(view, def, i, values[i])) {
                changed = true;
            }
        }
        if (changed) {
            var value = '';
            for (var i = 0; i < values.length; i++) {
                value = value + _addInterpolationPart(values[i], bindings[i]);
            }
            value = def.text.prefix + value;
            var renderNode = asTextData(view, def.nodeIndex).renderText;
            view.renderer.setValue(renderNode, value);
        }
        return changed;
    }
    function _addInterpolationPart(value, binding) {
        var valueStr = value != null ? value.toString() : '';
        return valueStr + binding.suffix;
    }

    /**
     * @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
     */
    function viewDef(flags, nodes, updateDirectives, updateRenderer) {
        // clone nodes and set auto calculated values
        var viewBindingCount = 0;
        var viewDisposableCount = 0;
        var viewNodeFlags = 0;
        var viewRootNodeFlags = 0;
        var viewMatchedQueries = 0;
        var currentParent = null;
        var currentRenderParent = null;
        var currentElementHasPublicProviders = false;
        var currentElementHasPrivateProviders = false;
        var lastRenderRootNode = null;
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            node.nodeIndex = i;
            node.parent = currentParent;
            node.bindingIndex = viewBindingCount;
            node.outputIndex = viewDisposableCount;
            node.renderParent = currentRenderParent;
            viewNodeFlags |= node.flags;
            viewMatchedQueries |= node.matchedQueryIds;
            if (node.element) {
                var elDef = node.element;
                elDef.publicProviders =
                    currentParent ? currentParent.element.publicProviders : Object.create(null);
                elDef.allProviders = elDef.publicProviders;
                // Note: We assume that all providers of an element are before any child element!
                currentElementHasPublicProviders = false;
                currentElementHasPrivateProviders = false;
                if (node.element.template) {
                    viewMatchedQueries |= node.element.template.nodeMatchedQueries;
                }
            }
            validateNode(currentParent, node, nodes.length);
            viewBindingCount += node.bindings.length;
            viewDisposableCount += node.outputs.length;
            if (!currentRenderParent && (node.flags & 3 /* CatRenderNode */)) {
                lastRenderRootNode = node;
            }
            if (node.flags & 20224 /* CatProvider */) {
                if (!currentElementHasPublicProviders) {
                    currentElementHasPublicProviders = true;
                    // Use prototypical inheritance to not get O(n^2) complexity...
                    currentParent.element.publicProviders =
                        Object.create(currentParent.element.publicProviders);
                    currentParent.element.allProviders = currentParent.element.publicProviders;
                }
                var isPrivateService = (node.flags & 8192 /* PrivateProvider */) !== 0;
                var isComponent = (node.flags & 32768 /* Component */) !== 0;
                if (!isPrivateService || isComponent) {
                    currentParent.element.publicProviders[tokenKey(node.provider.token)] = node;
                }
                else {
                    if (!currentElementHasPrivateProviders) {
                        currentElementHasPrivateProviders = true;
                        // Use prototypical inheritance to not get O(n^2) complexity...
                        currentParent.element.allProviders =
                            Object.create(currentParent.element.publicProviders);
                    }
                    currentParent.element.allProviders[tokenKey(node.provider.token)] = node;
                }
                if (isComponent) {
                    currentParent.element.componentProvider = node;
                }
            }
            if (currentParent) {
                currentParent.childFlags |= node.flags;
                currentParent.directChildFlags |= node.flags;
                currentParent.childMatchedQueries |= node.matchedQueryIds;
                if (node.element && node.element.template) {
                    currentParent.childMatchedQueries |= node.element.template.nodeMatchedQueries;
                }
            }
            else {
                viewRootNodeFlags |= node.flags;
            }
            if (node.childCount > 0) {
                currentParent = node;
                if (!isNgContainer(node)) {
                    currentRenderParent = node;
                }
            }
            else {
                // When the current node has no children, check if it is the last children of its parent.
                // When it is, propagate the flags up.
                // The loop is required because an element could be the last transitive children of several
                // elements. We loop to either the root or the highest opened element (= with remaining
                // children)
                while (currentParent && i === currentParent.nodeIndex + currentParent.childCount) {
                    var newParent = currentParent.parent;
                    if (newParent) {
                        newParent.childFlags |= currentParent.childFlags;
                        newParent.childMatchedQueries |= currentParent.childMatchedQueries;
                    }
                    currentParent = newParent;
                    // We also need to update the render parent & account for ng-container
                    if (currentParent && isNgContainer(currentParent)) {
                        currentRenderParent = currentParent.renderParent;
                    }
                    else {
                        currentRenderParent = currentParent;
                    }
                }
            }
        }
        var handleEvent = function (view, nodeIndex, eventName, event) {
            return nodes[nodeIndex].element.handleEvent(view, eventName, event);
        };
        return {
            // Will be filled later...
            factory: null,
            nodeFlags: viewNodeFlags,
            rootNodeFlags: viewRootNodeFlags,
            nodeMatchedQueries: viewMatchedQueries, flags: flags,
            nodes: nodes,
            updateDirectives: updateDirectives || NOOP,
            updateRenderer: updateRenderer || NOOP, handleEvent: handleEvent,
            bindingCount: viewBindingCount,
            outputCount: viewDisposableCount, lastRenderRootNode: lastRenderRootNode
        };
    }
    function isNgContainer(node) {
        return (node.flags & 1 /* TypeElement */) !== 0 && node.element.name === null;
    }
    function validateNode(parent, node, nodeCount) {
        var template = node.element && node.element.template;
        if (template) {
            if (!template.lastRenderRootNode) {
                throw new Error("Illegal State: Embedded templates without nodes are not allowed!");
            }
            if (template.lastRenderRootNode &&
                template.lastRenderRootNode.flags & 16777216 /* EmbeddedViews */) {
                throw new Error("Illegal State: Last root node of a template can't have embedded views, at index " + node.nodeIndex + "!");
            }
        }
        if (node.flags & 20224 /* CatProvider */) {
            var parentFlags = parent ? parent.flags : 0;
            if ((parentFlags & 1 /* TypeElement */) === 0) {
                throw new Error("Illegal State: StaticProvider/Directive nodes need to be children of elements or anchors, at index " + node.nodeIndex + "!");
            }
        }
        if (node.query) {
            if (node.flags & 67108864 /* TypeContentQuery */ &&
                (!parent || (parent.flags & 16384 /* TypeDirective */) === 0)) {
                throw new Error("Illegal State: Content Query nodes need to be children of directives, at index " + node.nodeIndex + "!");
            }
            if (node.flags & 134217728 /* TypeViewQuery */ && parent) {
                throw new Error("Illegal State: View Query nodes have to be top level nodes, at index " + node.nodeIndex + "!");
            }
        }
        if (node.childCount) {
            var parentEnd = parent ? parent.nodeIndex + parent.childCount : nodeCount - 1;
            if (node.nodeIndex <= parentEnd && node.nodeIndex + node.childCount > parentEnd) {
                throw new Error("Illegal State: childCount of node leads outside of parent, at index " + node.nodeIndex + "!");
            }
        }
    }
    function createEmbeddedView(parent, anchorDef, viewDef, context) {
        // embedded views are seen as siblings to the anchor, so we need
        // to get the parent of the anchor and use it as parentIndex.
        var view = createView(parent.root, parent.renderer, parent, anchorDef, viewDef);
        initView(view, parent.component, context);
        createViewNodes(view);
        return view;
    }
    function createRootView(root, def, context) {
        var view = createView(root, root.renderer, null, null, def);
        initView(view, context, context);
        createViewNodes(view);
        return view;
    }
    function createComponentView(parentView, nodeDef, viewDef, hostElement) {
        var rendererType = nodeDef.element.componentRendererType;
        var compRenderer;
        if (!rendererType) {
            compRenderer = parentView.root.renderer;
        }
        else {
            compRenderer = parentView.root.rendererFactory.createRenderer(hostElement, rendererType);
        }
        return createView(parentView.root, compRenderer, parentView, nodeDef.element.componentProvider, viewDef);
    }
    function createView(root, renderer, parent, parentNodeDef, def) {
        var nodes = new Array(def.nodes.length);
        var disposables = def.outputCount ? new Array(def.outputCount) : null;
        var view = {
            def: def,
            parent: parent,
            viewContainerParent: null, parentNodeDef: parentNodeDef,
            context: null,
            component: null, nodes: nodes,
            state: 13 /* CatInit */, root: root, renderer: renderer,
            oldValues: new Array(def.bindingCount), disposables: disposables,
            initIndex: -1
        };
        return view;
    }
    function initView(view, component, context) {
        view.component = component;
        view.context = context;
    }
    function createViewNodes(view) {
        var renderHost;
        if (isComponentView(view)) {
            var hostDef = view.parentNodeDef;
            renderHost = asElementData(view.parent, hostDef.parent.nodeIndex).renderElement;
        }
        var def = view.def;
        var nodes = view.nodes;
        for (var i = 0; i < def.nodes.length; i++) {
            var nodeDef = def.nodes[i];
            Services.setCurrentNode(view, i);
            var nodeData = void 0;
            switch (nodeDef.flags & 201347067 /* Types */) {
                case 1 /* TypeElement */:
                    var el = createElement(view, renderHost, nodeDef);
                    var componentView = undefined;
                    if (nodeDef.flags & 33554432 /* ComponentView */) {
                        var compViewDef = resolveDefinition(nodeDef.element.componentView);
                        componentView = Services.createComponentView(view, nodeDef, compViewDef, el);
                    }
                    listenToElementOutputs(view, componentView, nodeDef, el);
                    nodeData = {
                        renderElement: el,
                        componentView: componentView,
                        viewContainer: null,
                        template: nodeDef.element.template ? createTemplateData(view, nodeDef) : undefined
                    };
                    if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
                        nodeData.viewContainer = createViewContainerData(view, nodeDef, nodeData);
                    }
                    break;
                case 2 /* TypeText */:
                    nodeData = createText(view, renderHost, nodeDef);
                    break;
                case 512 /* TypeClassProvider */:
                case 1024 /* TypeFactoryProvider */:
                case 2048 /* TypeUseExistingProvider */:
                case 256 /* TypeValueProvider */: {
                    nodeData = nodes[i];
                    if (!nodeData && !(nodeDef.flags & 4096 /* LazyProvider */)) {
                        var instance = createProviderInstance(view, nodeDef);
                        nodeData = { instance: instance };
                    }
                    break;
                }
                case 16 /* TypePipe */: {
                    var instance = createPipeInstance(view, nodeDef);
                    nodeData = { instance: instance };
                    break;
                }
                case 16384 /* TypeDirective */: {
                    nodeData = nodes[i];
                    if (!nodeData) {
                        var instance = createDirectiveInstance(view, nodeDef);
                        nodeData = { instance: instance };
                    }
                    if (nodeDef.flags & 32768 /* Component */) {
                        var compView = asElementData(view, nodeDef.parent.nodeIndex).componentView;
                        initView(compView, nodeData.instance, nodeData.instance);
                    }
                    break;
                }
                case 32 /* TypePureArray */:
                case 64 /* TypePureObject */:
                case 128 /* TypePurePipe */:
                    nodeData = createPureExpression(view, nodeDef);
                    break;
                case 67108864 /* TypeContentQuery */:
                case 134217728 /* TypeViewQuery */:
                    nodeData = createQuery();
                    break;
                case 8 /* TypeNgContent */:
                    appendNgContent(view, renderHost, nodeDef);
                    // no runtime data needed for NgContent...
                    nodeData = undefined;
                    break;
            }
            nodes[i] = nodeData;
        }
        // Create the ViewData.nodes of component views after we created everything else,
        // so that e.g. ng-content works
        execComponentViewsAction(view, ViewAction.CreateViewNodes);
        // fill static content and view queries
        execQueriesAction(view, 67108864 /* TypeContentQuery */ | 134217728 /* TypeViewQuery */, 268435456 /* StaticQuery */, 0 /* CheckAndUpdate */);
    }
    function checkNoChangesView(view) {
        markProjectedViewsForCheck(view);
        Services.updateDirectives(view, 1 /* CheckNoChanges */);
        execEmbeddedViewsAction(view, ViewAction.CheckNoChanges);
        Services.updateRenderer(view, 1 /* CheckNoChanges */);
        execComponentViewsAction(view, ViewAction.CheckNoChanges);
        // Note: We don't check queries for changes as we didn't do this in v2.x.
        // TODO(tbosch): investigate if we can enable the check again in v5.x with a nicer error message.
        view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
    }
    function checkAndUpdateView(view) {
        if (view.state & 1 /* BeforeFirstCheck */) {
            view.state &= ~1 /* BeforeFirstCheck */;
            view.state |= 2 /* FirstCheck */;
        }
        else {
            view.state &= ~2 /* FirstCheck */;
        }
        shiftInitState(view, 0 /* InitState_BeforeInit */, 256 /* InitState_CallingOnInit */);
        markProjectedViewsForCheck(view);
        Services.updateDirectives(view, 0 /* CheckAndUpdate */);
        execEmbeddedViewsAction(view, ViewAction.CheckAndUpdate);
        execQueriesAction(view, 67108864 /* TypeContentQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
        var callInit = shiftInitState(view, 256 /* InitState_CallingOnInit */, 512 /* InitState_CallingAfterContentInit */);
        callLifecycleHooksChildrenFirst(view, 2097152 /* AfterContentChecked */ | (callInit ? 1048576 /* AfterContentInit */ : 0));
        Services.updateRenderer(view, 0 /* CheckAndUpdate */);
        execComponentViewsAction(view, ViewAction.CheckAndUpdate);
        execQueriesAction(view, 134217728 /* TypeViewQuery */, 536870912 /* DynamicQuery */, 0 /* CheckAndUpdate */);
        callInit = shiftInitState(view, 512 /* InitState_CallingAfterContentInit */, 768 /* InitState_CallingAfterViewInit */);
        callLifecycleHooksChildrenFirst(view, 8388608 /* AfterViewChecked */ | (callInit ? 4194304 /* AfterViewInit */ : 0));
        if (view.def.flags & 2 /* OnPush */) {
            view.state &= ~8 /* ChecksEnabled */;
        }
        view.state &= ~(64 /* CheckProjectedViews */ | 32 /* CheckProjectedView */);
        shiftInitState(view, 768 /* InitState_CallingAfterViewInit */, 1024 /* InitState_AfterInit */);
    }
    function checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        if (argStyle === 0 /* Inline */) {
            return checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
        }
        else {
            return checkAndUpdateNodeDynamic(view, nodeDef, v0);
        }
    }
    function markProjectedViewsForCheck(view) {
        var def = view.def;
        if (!(def.nodeFlags & 4 /* ProjectedTemplate */)) {
            return;
        }
        for (var i = 0; i < def.nodes.length; i++) {
            var nodeDef = def.nodes[i];
            if (nodeDef.flags & 4 /* ProjectedTemplate */) {
                var projectedViews = asElementData(view, i).template._projectedViews;
                if (projectedViews) {
                    for (var i_1 = 0; i_1 < projectedViews.length; i_1++) {
                        var projectedView = projectedViews[i_1];
                        projectedView.state |= 32 /* CheckProjectedView */;
                        markParentViewsForCheckProjectedViews(projectedView, view);
                    }
                }
            }
            else if ((nodeDef.childFlags & 4 /* ProjectedTemplate */) === 0) {
                // a parent with leafs
                // no child is a component,
                // then skip the children
                i += nodeDef.childCount;
            }
        }
    }
    function checkAndUpdateNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        switch (nodeDef.flags & 201347067 /* Types */) {
            case 1 /* TypeElement */:
                return checkAndUpdateElementInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
            case 2 /* TypeText */:
                return checkAndUpdateTextInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
            case 16384 /* TypeDirective */:
                return checkAndUpdateDirectiveInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
            case 32 /* TypePureArray */:
            case 64 /* TypePureObject */:
            case 128 /* TypePurePipe */:
                return checkAndUpdatePureExpressionInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
            default:
                throw 'unreachable';
        }
    }
    function checkAndUpdateNodeDynamic(view, nodeDef, values) {
        switch (nodeDef.flags & 201347067 /* Types */) {
            case 1 /* TypeElement */:
                return checkAndUpdateElementDynamic(view, nodeDef, values);
            case 2 /* TypeText */:
                return checkAndUpdateTextDynamic(view, nodeDef, values);
            case 16384 /* TypeDirective */:
                return checkAndUpdateDirectiveDynamic(view, nodeDef, values);
            case 32 /* TypePureArray */:
            case 64 /* TypePureObject */:
            case 128 /* TypePurePipe */:
                return checkAndUpdatePureExpressionDynamic(view, nodeDef, values);
            default:
                throw 'unreachable';
        }
    }
    function checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        if (argStyle === 0 /* Inline */) {
            checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
        }
        else {
            checkNoChangesNodeDynamic(view, nodeDef, v0);
        }
        // Returning false is ok here as we would have thrown in case of a change.
        return false;
    }
    function checkNoChangesNodeInline(view, nodeDef, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        var bindLen = nodeDef.bindings.length;
        if (bindLen > 0)
            checkBindingNoChanges(view, nodeDef, 0, v0);
        if (bindLen > 1)
            checkBindingNoChanges(view, nodeDef, 1, v1);
        if (bindLen > 2)
            checkBindingNoChanges(view, nodeDef, 2, v2);
        if (bindLen > 3)
            checkBindingNoChanges(view, nodeDef, 3, v3);
        if (bindLen > 4)
            checkBindingNoChanges(view, nodeDef, 4, v4);
        if (bindLen > 5)
            checkBindingNoChanges(view, nodeDef, 5, v5);
        if (bindLen > 6)
            checkBindingNoChanges(view, nodeDef, 6, v6);
        if (bindLen > 7)
            checkBindingNoChanges(view, nodeDef, 7, v7);
        if (bindLen > 8)
            checkBindingNoChanges(view, nodeDef, 8, v8);
        if (bindLen > 9)
            checkBindingNoChanges(view, nodeDef, 9, v9);
    }
    function checkNoChangesNodeDynamic(view, nodeDef, values) {
        for (var i = 0; i < values.length; i++) {
            checkBindingNoChanges(view, nodeDef, i, values[i]);
        }
    }
    /**
     * Workaround https://github.com/angular/tsickle/issues/497
     * @suppress {misplacedTypeAnnotation}
     */
    function checkNoChangesQuery(view, nodeDef) {
        var queryList = asQueryList(view, nodeDef.nodeIndex);
        if (queryList.dirty) {
            throw expressionChangedAfterItHasBeenCheckedError(Services.createDebugContext(view, nodeDef.nodeIndex), "Query " + nodeDef.query.id + " not dirty", "Query " + nodeDef.query.id + " dirty", (view.state & 1 /* BeforeFirstCheck */) !== 0);
        }
    }
    function destroyView(view) {
        if (view.state & 128 /* Destroyed */) {
            return;
        }
        execEmbeddedViewsAction(view, ViewAction.Destroy);
        execComponentViewsAction(view, ViewAction.Destroy);
        callLifecycleHooksChildrenFirst(view, 131072 /* OnDestroy */);
        if (view.disposables) {
            for (var i = 0; i < view.disposables.length; i++) {
                view.disposables[i]();
            }
        }
        detachProjectedView(view);
        if (view.renderer.destroyNode) {
            destroyViewNodes(view);
        }
        if (isComponentView(view)) {
            view.renderer.destroy();
        }
        view.state |= 128 /* Destroyed */;
    }
    function destroyViewNodes(view) {
        var len = view.def.nodes.length;
        for (var i = 0; i < len; i++) {
            var def = view.def.nodes[i];
            if (def.flags & 1 /* TypeElement */) {
                view.renderer.destroyNode(asElementData(view, i).renderElement);
            }
            else if (def.flags & 2 /* TypeText */) {
                view.renderer.destroyNode(asTextData(view, i).renderText);
            }
            else if (def.flags & 67108864 /* TypeContentQuery */ || def.flags & 134217728 /* TypeViewQuery */) {
                asQueryList(view, i).destroy();
            }
        }
    }
    var ViewAction;
    (function (ViewAction) {
        ViewAction[ViewAction["CreateViewNodes"] = 0] = "CreateViewNodes";
        ViewAction[ViewAction["CheckNoChanges"] = 1] = "CheckNoChanges";
        ViewAction[ViewAction["CheckNoChangesProjectedViews"] = 2] = "CheckNoChangesProjectedViews";
        ViewAction[ViewAction["CheckAndUpdate"] = 3] = "CheckAndUpdate";
        ViewAction[ViewAction["CheckAndUpdateProjectedViews"] = 4] = "CheckAndUpdateProjectedViews";
        ViewAction[ViewAction["Destroy"] = 5] = "Destroy";
    })(ViewAction || (ViewAction = {}));
    function execComponentViewsAction(view, action) {
        var def = view.def;
        if (!(def.nodeFlags & 33554432 /* ComponentView */)) {
            return;
        }
        for (var i = 0; i < def.nodes.length; i++) {
            var nodeDef = def.nodes[i];
            if (nodeDef.flags & 33554432 /* ComponentView */) {
                // a leaf
                callViewAction(asElementData(view, i).componentView, action);
            }
            else if ((nodeDef.childFlags & 33554432 /* ComponentView */) === 0) {
                // a parent with leafs
                // no child is a component,
                // then skip the children
                i += nodeDef.childCount;
            }
        }
    }
    function execEmbeddedViewsAction(view, action) {
        var def = view.def;
        if (!(def.nodeFlags & 16777216 /* EmbeddedViews */)) {
            return;
        }
        for (var i = 0; i < def.nodes.length; i++) {
            var nodeDef = def.nodes[i];
            if (nodeDef.flags & 16777216 /* EmbeddedViews */) {
                // a leaf
                var embeddedViews = asElementData(view, i).viewContainer._embeddedViews;
                for (var k = 0; k < embeddedViews.length; k++) {
                    callViewAction(embeddedViews[k], action);
                }
            }
            else if ((nodeDef.childFlags & 16777216 /* EmbeddedViews */) === 0) {
                // a parent with leafs
                // no child is a component,
                // then skip the children
                i += nodeDef.childCount;
            }
        }
    }
    function callViewAction(view, action) {
        var viewState = view.state;
        switch (action) {
            case ViewAction.CheckNoChanges:
                if ((viewState & 128 /* Destroyed */) === 0) {
                    if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
                        checkNoChangesView(view);
                    }
                    else if (viewState & 64 /* CheckProjectedViews */) {
                        execProjectedViewsAction(view, ViewAction.CheckNoChangesProjectedViews);
                    }
                }
                break;
            case ViewAction.CheckNoChangesProjectedViews:
                if ((viewState & 128 /* Destroyed */) === 0) {
                    if (viewState & 32 /* CheckProjectedView */) {
                        checkNoChangesView(view);
                    }
                    else if (viewState & 64 /* CheckProjectedViews */) {
                        execProjectedViewsAction(view, action);
                    }
                }
                break;
            case ViewAction.CheckAndUpdate:
                if ((viewState & 128 /* Destroyed */) === 0) {
                    if ((viewState & 12 /* CatDetectChanges */) === 12 /* CatDetectChanges */) {
                        checkAndUpdateView(view);
                    }
                    else if (viewState & 64 /* CheckProjectedViews */) {
                        execProjectedViewsAction(view, ViewAction.CheckAndUpdateProjectedViews);
                    }
                }
                break;
            case ViewAction.CheckAndUpdateProjectedViews:
                if ((viewState & 128 /* Destroyed */) === 0) {
                    if (viewState & 32 /* CheckProjectedView */) {
                        checkAndUpdateView(view);
                    }
                    else if (viewState & 64 /* CheckProjectedViews */) {
                        execProjectedViewsAction(view, action);
                    }
                }
                break;
            case ViewAction.Destroy:
                // Note: destroyView recurses over all views,
                // so we don't need to special case projected views here.
                destroyView(view);
                break;
            case ViewAction.CreateViewNodes:
                createViewNodes(view);
                break;
        }
    }
    function execProjectedViewsAction(view, action) {
        execEmbeddedViewsAction(view, action);
        execComponentViewsAction(view, action);
    }
    function execQueriesAction(view, queryFlags, staticDynamicQueryFlag, checkType) {
        if (!(view.def.nodeFlags & queryFlags) || !(view.def.nodeFlags & staticDynamicQueryFlag)) {
            return;
        }
        var nodeCount = view.def.nodes.length;
        for (var i = 0; i < nodeCount; i++) {
            var nodeDef = view.def.nodes[i];
            if ((nodeDef.flags & queryFlags) && (nodeDef.flags & staticDynamicQueryFlag)) {
                Services.setCurrentNode(view, nodeDef.nodeIndex);
                switch (checkType) {
                    case 0 /* CheckAndUpdate */:
                        checkAndUpdateQuery(view, nodeDef);
                        break;
                    case 1 /* CheckNoChanges */:
                        checkNoChangesQuery(view, nodeDef);
                        break;
                }
            }
            if (!(nodeDef.childFlags & queryFlags) || !(nodeDef.childFlags & staticDynamicQueryFlag)) {
                // no child has a matching query
                // then skip the children
                i += nodeDef.childCount;
            }
        }
    }

    /**
     * @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
     */
    var initialized = false;
    function initServicesIfNeeded() {
        if (initialized) {
            return;
        }
        initialized = true;
        var services = isDevMode() ? createDebugServices() : createProdServices();
        Services.setCurrentNode = services.setCurrentNode;
        Services.createRootView = services.createRootView;
        Services.createEmbeddedView = services.createEmbeddedView;
        Services.createComponentView = services.createComponentView;
        Services.createNgModuleRef = services.createNgModuleRef;
        Services.overrideProvider = services.overrideProvider;
        Services.overrideComponentView = services.overrideComponentView;
        Services.clearOverrides = services.clearOverrides;
        Services.checkAndUpdateView = services.checkAndUpdateView;
        Services.checkNoChangesView = services.checkNoChangesView;
        Services.destroyView = services.destroyView;
        Services.resolveDep = resolveDep;
        Services.createDebugContext = services.createDebugContext;
        Services.handleEvent = services.handleEvent;
        Services.updateDirectives = services.updateDirectives;
        Services.updateRenderer = services.updateRenderer;
        Services.dirtyParentQueries = dirtyParentQueries;
    }
    function createProdServices() {
        return {
            setCurrentNode: function () { },
            createRootView: createProdRootView,
            createEmbeddedView: createEmbeddedView,
            createComponentView: createComponentView,
            createNgModuleRef: createNgModuleRef,
            overrideProvider: NOOP,
            overrideComponentView: NOOP,
            clearOverrides: NOOP,
            checkAndUpdateView: checkAndUpdateView,
            checkNoChangesView: checkNoChangesView,
            destroyView: destroyView,
            createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
            handleEvent: function (view, nodeIndex, eventName, event) {
                return view.def.handleEvent(view, nodeIndex, eventName, event);
            },
            updateDirectives: function (view, checkType) { return view.def.updateDirectives(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
                prodCheckNoChangesNode, view); },
            updateRenderer: function (view, checkType) { return view.def.updateRenderer(checkType === 0 /* CheckAndUpdate */ ? prodCheckAndUpdateNode :
                prodCheckNoChangesNode, view); },
        };
    }
    function createDebugServices() {
        return {
            setCurrentNode: debugSetCurrentNode,
            createRootView: debugCreateRootView,
            createEmbeddedView: debugCreateEmbeddedView,
            createComponentView: debugCreateComponentView,
            createNgModuleRef: debugCreateNgModuleRef,
            overrideProvider: debugOverrideProvider,
            overrideComponentView: debugOverrideComponentView,
            clearOverrides: debugClearOverrides,
            checkAndUpdateView: debugCheckAndUpdateView,
            checkNoChangesView: debugCheckNoChangesView,
            destroyView: debugDestroyView,
            createDebugContext: function (view, nodeIndex) { return new DebugContext_(view, nodeIndex); },
            handleEvent: debugHandleEvent,
            updateDirectives: debugUpdateDirectives,
            updateRenderer: debugUpdateRenderer,
        };
    }
    function createProdRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
        var rendererFactory = ngModule.injector.get(RendererFactory2);
        return createRootView(createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode), def, context);
    }
    function debugCreateRootView(elInjector, projectableNodes, rootSelectorOrNode, def, ngModule, context) {
        var rendererFactory = ngModule.injector.get(RendererFactory2);
        var root = createRootData(elInjector, ngModule, new DebugRendererFactory2(rendererFactory), projectableNodes, rootSelectorOrNode);
        var defWithOverride = applyProviderOverridesToView(def);
        return callWithDebugContext(DebugAction.create, createRootView, null, [root, defWithOverride, context]);
    }
    function createRootData(elInjector, ngModule, rendererFactory, projectableNodes, rootSelectorOrNode) {
        var sanitizer = ngModule.injector.get(Sanitizer);
        var errorHandler = ngModule.injector.get(ErrorHandler);
        var renderer = rendererFactory.createRenderer(null, null);
        return {
            ngModule: ngModule,
            injector: elInjector, projectableNodes: projectableNodes,
            selectorOrNode: rootSelectorOrNode, sanitizer: sanitizer, rendererFactory: rendererFactory, renderer: renderer, errorHandler: errorHandler
        };
    }
    function debugCreateEmbeddedView(parentView, anchorDef, viewDef, context) {
        var defWithOverride = applyProviderOverridesToView(viewDef);
        return callWithDebugContext(DebugAction.create, createEmbeddedView, null, [parentView, anchorDef, defWithOverride, context]);
    }
    function debugCreateComponentView(parentView, nodeDef, viewDef, hostElement) {
        var overrideComponentView = viewDefOverrides.get(nodeDef.element.componentProvider.provider.token);
        if (overrideComponentView) {
            viewDef = overrideComponentView;
        }
        else {
            viewDef = applyProviderOverridesToView(viewDef);
        }
        return callWithDebugContext(DebugAction.create, createComponentView, null, [parentView, nodeDef, viewDef, hostElement]);
    }
    function debugCreateNgModuleRef(moduleType, parentInjector, bootstrapComponents, def) {
        var defWithOverride = applyProviderOverridesToNgModule(def);
        return createNgModuleRef(moduleType, parentInjector, bootstrapComponents, defWithOverride);
    }
    var providerOverrides = new Map();
    var providerOverridesWithScope = new Map();
    var viewDefOverrides = new Map();
    function debugOverrideProvider(override) {
        providerOverrides.set(override.token, override);
        var injectableDef;
        if (typeof override.token === 'function' && (injectableDef = getInjectableDef(override.token)) &&
            typeof injectableDef.providedIn === 'function') {
            providerOverridesWithScope.set(override.token, override);
        }
    }
    function debugOverrideComponentView(comp, compFactory) {
        var hostViewDef = resolveDefinition(getComponentViewDefinitionFactory(compFactory));
        var compViewDef = resolveDefinition(hostViewDef.nodes[0].element.componentView);
        viewDefOverrides.set(comp, compViewDef);
    }
    function debugClearOverrides() {
        providerOverrides.clear();
        providerOverridesWithScope.clear();
        viewDefOverrides.clear();
    }
    // Notes about the algorithm:
    // 1) Locate the providers of an element and check if one of them was overwritten
    // 2) Change the providers of that element
    //
    // We only create new datastructures if we need to, to keep perf impact
    // reasonable.
    function applyProviderOverridesToView(def) {
        if (providerOverrides.size === 0) {
            return def;
        }
        var elementIndicesWithOverwrittenProviders = findElementIndicesWithOverwrittenProviders(def);
        if (elementIndicesWithOverwrittenProviders.length === 0) {
            return def;
        }
        // clone the whole view definition,
        // as it maintains references between the nodes that are hard to update.
        def = def.factory(function () { return NOOP; });
        for (var i = 0; i < elementIndicesWithOverwrittenProviders.length; i++) {
            applyProviderOverridesToElement(def, elementIndicesWithOverwrittenProviders[i]);
        }
        return def;
        function findElementIndicesWithOverwrittenProviders(def) {
            var elIndicesWithOverwrittenProviders = [];
            var lastElementDef = null;
            for (var i = 0; i < def.nodes.length; i++) {
                var nodeDef = def.nodes[i];
                if (nodeDef.flags & 1 /* TypeElement */) {
                    lastElementDef = nodeDef;
                }
                if (lastElementDef && nodeDef.flags & 3840 /* CatProviderNoDirective */ &&
                    providerOverrides.has(nodeDef.provider.token)) {
                    elIndicesWithOverwrittenProviders.push(lastElementDef.nodeIndex);
                    lastElementDef = null;
                }
            }
            return elIndicesWithOverwrittenProviders;
        }
        function applyProviderOverridesToElement(viewDef, elIndex) {
            for (var i = elIndex + 1; i < viewDef.nodes.length; i++) {
                var nodeDef = viewDef.nodes[i];
                if (nodeDef.flags & 1 /* TypeElement */) {
                    // stop at the next element
                    return;
                }
                if (nodeDef.flags & 3840 /* CatProviderNoDirective */) {
                    var provider = nodeDef.provider;
                    var override = providerOverrides.get(provider.token);
                    if (override) {
                        nodeDef.flags = (nodeDef.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
                        provider.deps = splitDepsDsl(override.deps);
                        provider.value = override.value;
                    }
                }
            }
        }
    }
    // Notes about the algorithm:
    // We only create new datastructures if we need to, to keep perf impact
    // reasonable.
    function applyProviderOverridesToNgModule(def) {
        var _a = calcHasOverrides(def), hasOverrides = _a.hasOverrides, hasDeprecatedOverrides = _a.hasDeprecatedOverrides;
        if (!hasOverrides) {
            return def;
        }
        // clone the whole view definition,
        // as it maintains references between the nodes that are hard to update.
        def = def.factory(function () { return NOOP; });
        applyProviderOverrides(def);
        return def;
        function calcHasOverrides(def) {
            var hasOverrides = false;
            var hasDeprecatedOverrides = false;
            if (providerOverrides.size === 0) {
                return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
            }
            def.providers.forEach(function (node) {
                var override = providerOverrides.get(node.token);
                if ((node.flags & 3840 /* CatProviderNoDirective */) && override) {
                    hasOverrides = true;
                    hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
                }
            });
            def.modules.forEach(function (module) {
                providerOverridesWithScope.forEach(function (override, token) {
                    if (getInjectableDef(token).providedIn === module) {
                        hasOverrides = true;
                        hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
                    }
                });
            });
            return { hasOverrides: hasOverrides, hasDeprecatedOverrides: hasDeprecatedOverrides };
        }
        function applyProviderOverrides(def) {
            for (var i = 0; i < def.providers.length; i++) {
                var provider = def.providers[i];
                if (hasDeprecatedOverrides) {
                    // We had a bug where me made
                    // all providers lazy. Keep this logic behind a flag
                    // for migrating existing users.
                    provider.flags |= 4096 /* LazyProvider */;
                }
                var override = providerOverrides.get(provider.token);
                if (override) {
                    provider.flags = (provider.flags & ~3840 /* CatProviderNoDirective */) | override.flags;
                    provider.deps = splitDepsDsl(override.deps);
                    provider.value = override.value;
                }
            }
            if (providerOverridesWithScope.size > 0) {
                var moduleSet_1 = new Set(def.modules);
                providerOverridesWithScope.forEach(function (override, token) {
                    if (moduleSet_1.has(getInjectableDef(token).providedIn)) {
                        var provider = {
                            token: token,
                            flags: override.flags | (hasDeprecatedOverrides ? 4096 /* LazyProvider */ : 0 /* None */),
                            deps: splitDepsDsl(override.deps),
                            value: override.value,
                            index: def.providers.length,
                        };
                        def.providers.push(provider);
                        def.providersByKey[tokenKey(token)] = provider;
                    }
                });
            }
        }
    }
    function prodCheckAndUpdateNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        var nodeDef = view.def.nodes[checkIndex];
        checkAndUpdateNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
        return (nodeDef.flags & 224 /* CatPureExpression */) ?
            asPureExpressionData(view, checkIndex).value :
            undefined;
    }
    function prodCheckNoChangesNode(view, checkIndex, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {
        var nodeDef = view.def.nodes[checkIndex];
        checkNoChangesNode(view, nodeDef, argStyle, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9);
        return (nodeDef.flags & 224 /* CatPureExpression */) ?
            asPureExpressionData(view, checkIndex).value :
            undefined;
    }
    function debugCheckAndUpdateView(view) {
        return callWithDebugContext(DebugAction.detectChanges, checkAndUpdateView, null, [view]);
    }
    function debugCheckNoChangesView(view) {
        return callWithDebugContext(DebugAction.checkNoChanges, checkNoChangesView, null, [view]);
    }
    function debugDestroyView(view) {
        return callWithDebugContext(DebugAction.destroy, destroyView, null, [view]);
    }
    var DebugAction;
    (function (DebugAction) {
        DebugAction[DebugAction["create"] = 0] = "create";
        DebugAction[DebugAction["detectChanges"] = 1] = "detectChanges";
        DebugAction[DebugAction["checkNoChanges"] = 2] = "checkNoChanges";
        DebugAction[DebugAction["destroy"] = 3] = "destroy";
        DebugAction[DebugAction["handleEvent"] = 4] = "handleEvent";
    })(DebugAction || (DebugAction = {}));
    var _currentAction;
    var _currentView;
    var _currentNodeIndex;
    function debugSetCurrentNode(view, nodeIndex) {
        _currentView = view;
        _currentNodeIndex = nodeIndex;
    }
    function debugHandleEvent(view, nodeIndex, eventName, event) {
        debugSetCurrentNode(view, nodeIndex);
        return callWithDebugContext(DebugAction.handleEvent, view.def.handleEvent, null, [view, nodeIndex, eventName, event]);
    }
    function debugUpdateDirectives(view, checkType) {
        if (view.state & 128 /* Destroyed */) {
            throw viewDestroyedError(DebugAction[_currentAction]);
        }
        debugSetCurrentNode(view, nextDirectiveWithBinding(view, 0));
        return view.def.updateDirectives(debugCheckDirectivesFn, view);
        function debugCheckDirectivesFn(view, nodeIndex, argStyle) {
            var values = [];
            for (var _i = 3; _i < arguments.length; _i++) {
                values[_i - 3] = arguments[_i];
            }
            var nodeDef = view.def.nodes[nodeIndex];
            if (checkType === 0 /* CheckAndUpdate */) {
                debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
            }
            else {
                debugCheckNoChangesNode(view, nodeDef, argStyle, values);
            }
            if (nodeDef.flags & 16384 /* TypeDirective */) {
                debugSetCurrentNode(view, nextDirectiveWithBinding(view, nodeIndex));
            }
            return (nodeDef.flags & 224 /* CatPureExpression */) ?
                asPureExpressionData(view, nodeDef.nodeIndex).value :
                undefined;
        }
    }
    function debugUpdateRenderer(view, checkType) {
        if (view.state & 128 /* Destroyed */) {
            throw viewDestroyedError(DebugAction[_currentAction]);
        }
        debugSetCurrentNode(view, nextRenderNodeWithBinding(view, 0));
        return view.def.updateRenderer(debugCheckRenderNodeFn, view);
        function debugCheckRenderNodeFn(view, nodeIndex, argStyle) {
            var values = [];
            for (var _i = 3; _i < arguments.length; _i++) {
                values[_i - 3] = arguments[_i];
            }
            var nodeDef = view.def.nodes[nodeIndex];
            if (checkType === 0 /* CheckAndUpdate */) {
                debugCheckAndUpdateNode(view, nodeDef, argStyle, values);
            }
            else {
                debugCheckNoChangesNode(view, nodeDef, argStyle, values);
            }
            if (nodeDef.flags & 3 /* CatRenderNode */) {
                debugSetCurrentNode(view, nextRenderNodeWithBinding(view, nodeIndex));
            }
            return (nodeDef.flags & 224 /* CatPureExpression */) ?
                asPureExpressionData(view, nodeDef.nodeIndex).value :
                undefined;
        }
    }
    function debugCheckAndUpdateNode(view, nodeDef, argStyle, givenValues) {
        var changed = checkAndUpdateNode.apply(void 0, __spread([view, nodeDef, argStyle], givenValues));
        if (changed) {
            var values = argStyle === 1 /* Dynamic */ ? givenValues[0] : givenValues;
            if (nodeDef.flags & 16384 /* TypeDirective */) {
                var bindingValues = {};
                for (var i = 0; i < nodeDef.bindings.length; i++) {
                    var binding = nodeDef.bindings[i];
                    var value = values[i];
                    if (binding.flags & 8 /* TypeProperty */) {
                        bindingValues[normalizeDebugBindingName(binding.nonMinifiedName)] =
                            normalizeDebugBindingValue(value);
                    }
                }
                var elDef = nodeDef.parent;
                var el = asElementData(view, elDef.nodeIndex).renderElement;
                if (!elDef.element.name) {
                    // a comment.
                    view.renderer.setValue(el, "bindings=" + JSON.stringify(bindingValues, null, 2));
                }
                else {
                    // a regular element.
                    for (var attr in bindingValues) {
                        var value = bindingValues[attr];
                        if (value != null) {
                            view.renderer.setAttribute(el, attr, value);
                        }
                        else {
                            view.renderer.removeAttribute(el, attr);
                        }
                    }
                }
            }
        }
    }
    function debugCheckNoChangesNode(view, nodeDef, argStyle, values) {
        checkNoChangesNode.apply(void 0, __spread([view, nodeDef, argStyle], values));
    }
    function nextDirectiveWithBinding(view, nodeIndex) {
        for (var i = nodeIndex; i < view.def.nodes.length; i++) {
            var nodeDef = view.def.nodes[i];
            if (nodeDef.flags & 16384 /* TypeDirective */ && nodeDef.bindings && nodeDef.bindings.length) {
                return i;
            }
        }
        return null;
    }
    function nextRenderNodeWithBinding(view, nodeIndex) {
        for (var i = nodeIndex; i < view.def.nodes.length; i++) {
            var nodeDef = view.def.nodes[i];
            if ((nodeDef.flags & 3 /* CatRenderNode */) && nodeDef.bindings && nodeDef.bindings.length) {
                return i;
            }
        }
        return null;
    }
    var DebugContext_ = /** @class */ (function () {
        function DebugContext_(view, nodeIndex) {
            this.view = view;
            this.nodeIndex = nodeIndex;
            if (nodeIndex == null) {
                this.nodeIndex = nodeIndex = 0;
            }
            this.nodeDef = view.def.nodes[nodeIndex];
            var elDef = this.nodeDef;
            var elView = view;
            while (elDef && (elDef.flags & 1 /* TypeElement */) === 0) {
                elDef = elDef.parent;
            }
            if (!elDef) {
                while (!elDef && elView) {
                    elDef = viewParentEl(elView);
                    elView = elView.parent;
                }
            }
            this.elDef = elDef;
            this.elView = elView;
        }
        Object.defineProperty(DebugContext_.prototype, "elOrCompView", {
            get: function () {
                // Has to be done lazily as we use the DebugContext also during creation of elements...
                return asElementData(this.elView, this.elDef.nodeIndex).componentView || this.view;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugContext_.prototype, "injector", {
            get: function () { return createInjector$1(this.elView, this.elDef); },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugContext_.prototype, "component", {
            get: function () { return this.elOrCompView.component; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugContext_.prototype, "context", {
            get: function () { return this.elOrCompView.context; },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugContext_.prototype, "providerTokens", {
            get: function () {
                var tokens = [];
                if (this.elDef) {
                    for (var i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
                        var childDef = this.elView.def.nodes[i];
                        if (childDef.flags & 20224 /* CatProvider */) {
                            tokens.push(childDef.provider.token);
                        }
                        i += childDef.childCount;
                    }
                }
                return tokens;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugContext_.prototype, "references", {
            get: function () {
                var references = {};
                if (this.elDef) {
                    collectReferences(this.elView, this.elDef, references);
                    for (var i = this.elDef.nodeIndex + 1; i <= this.elDef.nodeIndex + this.elDef.childCount; i++) {
                        var childDef = this.elView.def.nodes[i];
                        if (childDef.flags & 20224 /* CatProvider */) {
                            collectReferences(this.elView, childDef, references);
                        }
                        i += childDef.childCount;
                    }
                }
                return references;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugContext_.prototype, "componentRenderElement", {
            get: function () {
                var elData = findHostElement(this.elOrCompView);
                return elData ? elData.renderElement : undefined;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(DebugContext_.prototype, "renderNode", {
            get: function () {
                return this.nodeDef.flags & 2 /* TypeText */ ? renderNode(this.view, this.nodeDef) :
                    renderNode(this.elView, this.elDef);
            },
            enumerable: true,
            configurable: true
        });
        DebugContext_.prototype.logError = function (console) {
            var values = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                values[_i - 1] = arguments[_i];
            }
            var logViewDef;
            var logNodeIndex;
            if (this.nodeDef.flags & 2 /* TypeText */) {
                logViewDef = this.view.def;
                logNodeIndex = this.nodeDef.nodeIndex;
            }
            else {
                logViewDef = this.elView.def;
                logNodeIndex = this.elDef.nodeIndex;
            }
            // Note: we only generate a log function for text and element nodes
            // to make the generated code as small as possible.
            var renderNodeIndex = getRenderNodeIndex(logViewDef, logNodeIndex);
            var currRenderNodeIndex = -1;
            var nodeLogger = function () {
                var _a;
                currRenderNodeIndex++;
                if (currRenderNodeIndex === renderNodeIndex) {
                    return (_a = console.error).bind.apply(_a, __spread([console], values));
                }
                else {
                    return NOOP;
                }
            };
            logViewDef.factory(nodeLogger);
            if (currRenderNodeIndex < renderNodeIndex) {
                console.error('Illegal state: the ViewDefinitionFactory did not call the logger!');
                console.error.apply(console, __spread(values));
            }
        };
        return DebugContext_;
    }());
    function getRenderNodeIndex(viewDef, nodeIndex) {
        var renderNodeIndex = -1;
        for (var i = 0; i <= nodeIndex; i++) {
            var nodeDef = viewDef.nodes[i];
            if (nodeDef.flags & 3 /* CatRenderNode */) {
                renderNodeIndex++;
            }
        }
        return renderNodeIndex;
    }
    function findHostElement(view) {
        while (view && !isComponentView(view)) {
            view = view.parent;
        }
        if (view.parent) {
            return asElementData(view.parent, viewParentEl(view).nodeIndex);
        }
        return null;
    }
    function collectReferences(view, nodeDef, references) {
        for (var refName in nodeDef.references) {
            references[refName] = getQueryValue(view, nodeDef, nodeDef.references[refName]);
        }
    }
    function callWithDebugContext(action, fn, self, args) {
        var oldAction = _currentAction;
        var oldView = _currentView;
        var oldNodeIndex = _currentNodeIndex;
        try {
            _currentAction = action;
            var result = fn.apply(self, args);
            _currentView = oldView;
            _currentNodeIndex = oldNodeIndex;
            _currentAction = oldAction;
            return result;
        }
        catch (e) {
            if (isViewDebugError(e) || !_currentView) {
                throw e;
            }
            throw viewWrappedDebugError(e, getCurrentDebugContext());
        }
    }
    function getCurrentDebugContext() {
        return _currentView ? new DebugContext_(_currentView, _currentNodeIndex) : null;
    }
    var DebugRendererFactory2 = /** @class */ (function () {
        function DebugRendererFactory2(delegate) {
            this.delegate = delegate;
        }
        DebugRendererFactory2.prototype.createRenderer = function (element, renderData) {
            return new DebugRenderer2(this.delegate.createRenderer(element, renderData));
        };
        DebugRendererFactory2.prototype.begin = function () {
            if (this.delegate.begin) {
                this.delegate.begin();
            }
        };
        DebugRendererFactory2.prototype.end = function () {
            if (this.delegate.end) {
                this.delegate.end();
            }
        };
        DebugRendererFactory2.prototype.whenRenderingDone = function () {
            if (this.delegate.whenRenderingDone) {
                return this.delegate.whenRenderingDone();
            }
            return Promise.resolve(null);
        };
        return DebugRendererFactory2;
    }());
    var DebugRenderer2 = /** @class */ (function () {
        function DebugRenderer2(delegate) {
            this.delegate = delegate;
            /**
             * Factory function used to create a `DebugContext` when a node is created.
             *
             * The `DebugContext` allows to retrieve information about the nodes that are useful in tests.
             *
             * The factory is configurable so that the `DebugRenderer2` could instantiate either a View Engine
             * or a Render context.
             */
            this.debugContextFactory = getCurrentDebugContext;
            this.data = this.delegate.data;
        }
        DebugRenderer2.prototype.createDebugContext = function (nativeElement) { return this.debugContextFactory(nativeElement); };
        DebugRenderer2.prototype.destroyNode = function (node) {
            var debugNode = getDebugNode(node);
            removeDebugNodeFromIndex(debugNode);
            if (debugNode instanceof DebugNode__PRE_R3__) {
                debugNode.listeners.length = 0;
            }
            if (this.delegate.destroyNode) {
                this.delegate.destroyNode(node);
            }
        };
        DebugRenderer2.prototype.destroy = function () { this.delegate.destroy(); };
        DebugRenderer2.prototype.createElement = function (name, namespace) {
            var el = this.delegate.createElement(name, namespace);
            var debugCtx = this.createDebugContext(el);
            if (debugCtx) {
                var debugEl = new DebugElement__PRE_R3__(el, null, debugCtx);
                debugEl.name = name;
                indexDebugNode(debugEl);
            }
            return el;
        };
        DebugRenderer2.prototype.createComment = function (value) {
            var comment = this.delegate.createComment(value);
            var debugCtx = this.createDebugContext(comment);
            if (debugCtx) {
                indexDebugNode(new DebugNode__PRE_R3__(comment, null, debugCtx));
            }
            return comment;
        };
        DebugRenderer2.prototype.createText = function (value) {
            var text = this.delegate.createText(value);
            var debugCtx = this.createDebugContext(text);
            if (debugCtx) {
                indexDebugNode(new DebugNode__PRE_R3__(text, null, debugCtx));
            }
            return text;
        };
        DebugRenderer2.prototype.appendChild = function (parent, newChild) {
            var debugEl = getDebugNode(parent);
            var debugChildEl = getDebugNode(newChild);
            if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.addChild(debugChildEl);
            }
            this.delegate.appendChild(parent, newChild);
        };
        DebugRenderer2.prototype.insertBefore = function (parent, newChild, refChild) {
            var debugEl = getDebugNode(parent);
            var debugChildEl = getDebugNode(newChild);
            var debugRefEl = getDebugNode(refChild);
            if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.insertBefore(debugRefEl, debugChildEl);
            }
            this.delegate.insertBefore(parent, newChild, refChild);
        };
        DebugRenderer2.prototype.removeChild = function (parent, oldChild) {
            var debugEl = getDebugNode(parent);
            var debugChildEl = getDebugNode(oldChild);
            if (debugEl && debugChildEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.removeChild(debugChildEl);
            }
            this.delegate.removeChild(parent, oldChild);
        };
        DebugRenderer2.prototype.selectRootElement = function (selectorOrNode, preserveContent) {
            var el = this.delegate.selectRootElement(selectorOrNode, preserveContent);
            var debugCtx = getCurrentDebugContext();
            if (debugCtx) {
                indexDebugNode(new DebugElement__PRE_R3__(el, null, debugCtx));
            }
            return el;
        };
        DebugRenderer2.prototype.setAttribute = function (el, name, value, namespace) {
            var debugEl = getDebugNode(el);
            if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
                var fullName = namespace ? namespace + ':' + name : name;
                debugEl.attributes[fullName] = value;
            }
            this.delegate.setAttribute(el, name, value, namespace);
        };
        DebugRenderer2.prototype.removeAttribute = function (el, name, namespace) {
            var debugEl = getDebugNode(el);
            if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
                var fullName = namespace ? namespace + ':' + name : name;
                debugEl.attributes[fullName] = null;
            }
            this.delegate.removeAttribute(el, name, namespace);
        };
        DebugRenderer2.prototype.addClass = function (el, name) {
            var debugEl = getDebugNode(el);
            if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.classes[name] = true;
            }
            this.delegate.addClass(el, name);
        };
        DebugRenderer2.prototype.removeClass = function (el, name) {
            var debugEl = getDebugNode(el);
            if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.classes[name] = false;
            }
            this.delegate.removeClass(el, name);
        };
        DebugRenderer2.prototype.setStyle = function (el, style, value, flags) {
            var debugEl = getDebugNode(el);
            if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.styles[style] = value;
            }
            this.delegate.setStyle(el, style, value, flags);
        };
        DebugRenderer2.prototype.removeStyle = function (el, style, flags) {
            var debugEl = getDebugNode(el);
            if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.styles[style] = null;
            }
            this.delegate.removeStyle(el, style, flags);
        };
        DebugRenderer2.prototype.setProperty = function (el, name, value) {
            var debugEl = getDebugNode(el);
            if (debugEl && debugEl instanceof DebugElement__PRE_R3__) {
                debugEl.properties[name] = value;
            }
            this.delegate.setProperty(el, name, value);
        };
        DebugRenderer2.prototype.listen = function (target, eventName, callback) {
            if (typeof target !== 'string') {
                var debugEl = getDebugNode(target);
                if (debugEl) {
                    debugEl.listeners.push(new DebugEventListener(eventName, callback));
                }
            }
            return this.delegate.listen(target, eventName, callback);
        };
        DebugRenderer2.prototype.parentNode = function (node) { return this.delegate.parentNode(node); };
        DebugRenderer2.prototype.nextSibling = function (node) { return this.delegate.nextSibling(node); };
        DebugRenderer2.prototype.setValue = function (node, value) { return this.delegate.setValue(node, value); };
        return DebugRenderer2;
    }());

    /**
     * @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
     */
    function overrideProvider(override) {
        initServicesIfNeeded();
        return Services.overrideProvider(override);
    }
    function overrideComponentView(comp, componentFactory) {
        initServicesIfNeeded();
        return Services.overrideComponentView(comp, componentFactory);
    }
    function clearOverrides() {
        initServicesIfNeeded();
        return Services.clearOverrides();
    }
    // Attention: this function is called as top level function.
    // Putting any logic in here will destroy closure tree shaking!
    function createNgModuleFactory(ngModuleType, bootstrapComponents, defFactory) {
        return new NgModuleFactory_(ngModuleType, bootstrapComponents, defFactory);
    }
    function cloneNgModuleDefinition(def) {
        var providers = Array.from(def.providers);
        var modules = Array.from(def.modules);
        var providersByKey = {};
        for (var key in def.providersByKey) {
            providersByKey[key] = def.providersByKey[key];
        }
        return {
            factory: def.factory,
            isRoot: def.isRoot, providers: providers, modules: modules, providersByKey: providersByKey,
        };
    }
    var NgModuleFactory_ = /** @class */ (function (_super) {
        __extends(NgModuleFactory_, _super);
        function NgModuleFactory_(moduleType, _bootstrapComponents, _ngModuleDefFactory) {
            var _this = 
            // Attention: this ctor is called as top level function.
            // Putting any logic in here will destroy closure tree shaking!
            _super.call(this) || this;
            _this.moduleType = moduleType;
            _this._bootstrapComponents = _bootstrapComponents;
            _this._ngModuleDefFactory = _ngModuleDefFactory;
            return _this;
        }
        NgModuleFactory_.prototype.create = function (parentInjector) {
            initServicesIfNeeded();
            // Clone the NgModuleDefinition so that any tree shakeable provider definition
            // added to this instance of the NgModuleRef doesn't affect the cached copy.
            // See https://github.com/angular/angular/issues/25018.
            var def = cloneNgModuleDefinition(resolveDefinition(this._ngModuleDefFactory));
            return Services.createNgModuleRef(this.moduleType, parentInjector || Injector.NULL, this._bootstrapComponents, def);
        };
        return NgModuleFactory_;
    }(NgModuleFactory));

    /**
     * @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
     */

    /**
     * @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
     */

    /**
     * @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
     */
    // clang-format on

    /**
     * @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
     */

    /**
     * @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
     */

    /**
     * @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 only reexports content of the `src` folder. Keep it that way.

    /**
     * @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
     */

    /**
     * Generated bundle index. Do not edit.
     */

    exports.ɵangular_packages_core_core_q = APPLICATION_MODULE_PROVIDERS;
    exports.ɵangular_packages_core_core_n = _iterableDiffersFactory;
    exports.ɵangular_packages_core_core_o = _keyValueDiffersFactory;
    exports.ɵangular_packages_core_core_p = _localeFactory;
    exports.ɵangular_packages_core_core_r = zoneSchedulerFactory;
    exports.ɵangular_packages_core_core_f = _appIdRandomProviderFactory;
    exports.ɵangular_packages_core_core_l = DefaultIterableDifferFactory;
    exports.ɵangular_packages_core_core_m = DefaultKeyValueDifferFactory;
    exports.ɵangular_packages_core_core_k = DebugElement__PRE_R3__;
    exports.ɵangular_packages_core_core_j = DebugNode__PRE_R3__;
    exports.ɵangular_packages_core_core_b = NullInjector;
    exports.ɵangular_packages_core_core_a = injectInjectorOnly;
    exports.ɵangular_packages_core_core_c = ReflectiveInjector_;
    exports.ɵangular_packages_core_core_d = ReflectiveDependency;
    exports.ɵangular_packages_core_core_e = resolveReflectiveProviders;
    exports.ɵangular_packages_core_core_i = getModuleFactory__PRE_R3__;
    exports.ɵangular_packages_core_core_s = wtfEnabled;
    exports.ɵangular_packages_core_core_u = createScope;
    exports.ɵangular_packages_core_core_t = detectWTF;
    exports.ɵangular_packages_core_core_x = endTimeRange;
    exports.ɵangular_packages_core_core_v = leave;
    exports.ɵangular_packages_core_core_w = startTimeRange;
    exports.ɵangular_packages_core_core_ba = SCHEDULER;
    exports.ɵangular_packages_core_core_bb = injectAttributeImpl;
    exports.ɵangular_packages_core_core_bc = getLView;
    exports.ɵangular_packages_core_core_bd = getPreviousOrParentTNode;
    exports.ɵangular_packages_core_core_be = nextContextImpl;
    exports.ɵangular_packages_core_core_bm = getRootContext;
    exports.ɵangular_packages_core_core_bl = loadInternal;
    exports.ɵangular_packages_core_core_g = createElementRef;
    exports.ɵangular_packages_core_core_h = createTemplateRef;
    exports.ɵangular_packages_core_core_bg = getUrlSanitizer;
    exports.ɵangular_packages_core_core_bk = noSideEffects;
    exports.ɵangular_packages_core_core_bh = makeParamDecorator;
    exports.ɵangular_packages_core_core_bi = makePropDecorator;
    exports.ɵangular_packages_core_core_bn = getClosureSafeProperty;
    exports.ɵangular_packages_core_core_y = _def;
    exports.ɵangular_packages_core_core_z = DebugContext;
    exports.createPlatform = createPlatform;
    exports.assertPlatform = assertPlatform;
    exports.destroyPlatform = destroyPlatform;
    exports.getPlatform = getPlatform;
    exports.PlatformRef = PlatformRef;
    exports.ApplicationRef = ApplicationRef;
    exports.createPlatformFactory = createPlatformFactory;
    exports.NgProbeToken = NgProbeToken;
    exports.enableProdMode = enableProdMode;
    exports.isDevMode = isDevMode;
    exports.APP_ID = APP_ID;
    exports.PACKAGE_ROOT_URL = PACKAGE_ROOT_URL;
    exports.PLATFORM_INITIALIZER = PLATFORM_INITIALIZER;
    exports.PLATFORM_ID = PLATFORM_ID;
    exports.APP_BOOTSTRAP_LISTENER = APP_BOOTSTRAP_LISTENER;
    exports.APP_INITIALIZER = APP_INITIALIZER;
    exports.ApplicationInitStatus = ApplicationInitStatus;
    exports.DebugElement = DebugElement;
    exports.DebugEventListener = DebugEventListener;
    exports.DebugNode = DebugNode;
    exports.asNativeElements = asNativeElements;
    exports.getDebugNode = getDebugNode;
    exports.Testability = Testability;
    exports.TestabilityRegistry = TestabilityRegistry;
    exports.setTestabilityGetter = setTestabilityGetter;
    exports.TRANSLATIONS = TRANSLATIONS$1;
    exports.TRANSLATIONS_FORMAT = TRANSLATIONS_FORMAT;
    exports.LOCALE_ID = LOCALE_ID$1;
    exports.ApplicationModule = ApplicationModule;
    exports.wtfCreateScope = wtfCreateScope;
    exports.wtfLeave = wtfLeave;
    exports.wtfStartTimeRange = wtfStartTimeRange;
    exports.wtfEndTimeRange = wtfEndTimeRange;
    exports.Type = Type;
    exports.EventEmitter = EventEmitter;
    exports.ErrorHandler = ErrorHandler;
    exports.Sanitizer = Sanitizer;
    exports.Attribute = Attribute;
    exports.ANALYZE_FOR_ENTRY_COMPONENTS = ANALYZE_FOR_ENTRY_COMPONENTS;
    exports.ContentChild = ContentChild;
    exports.ContentChildren = ContentChildren;
    exports.Query = Query;
    exports.ViewChild = ViewChild;
    exports.ViewChildren = ViewChildren;
    exports.Component = Component;
    exports.Directive = Directive;
    exports.HostBinding = HostBinding;
    exports.HostListener = HostListener;
    exports.Input = Input;
    exports.Output = Output;
    exports.Pipe = Pipe;
    exports.NgModule = NgModule;
    exports.CUSTOM_ELEMENTS_SCHEMA = CUSTOM_ELEMENTS_SCHEMA;
    exports.NO_ERRORS_SCHEMA = NO_ERRORS_SCHEMA;
    exports.Version = Version;
    exports.VERSION = VERSION;
    exports.ɵɵdefineInjectable = ɵɵdefineInjectable;
    exports.defineInjectable = defineInjectable;
    exports.ɵɵdefineInjector = ɵɵdefineInjector;
    exports.forwardRef = forwardRef;
    exports.resolveForwardRef = resolveForwardRef;
    exports.Injectable = Injectable;
    exports.Injector = Injector;
    exports.ɵɵinject = ɵɵinject;
    exports.inject = inject;
    exports.INJECTOR = INJECTOR;
    exports.ReflectiveInjector = ReflectiveInjector;
    exports.ResolvedReflectiveFactory = ResolvedReflectiveFactory;
    exports.ReflectiveKey = ReflectiveKey;
    exports.InjectionToken = InjectionToken;
    exports.Inject = Inject;
    exports.Optional = Optional;
    exports.Self = Self;
    exports.SkipSelf = SkipSelf;
    exports.Host = Host;
    exports.ɵ0 = ɵ0;
    exports.ɵ1 = ɵ1;
    exports.NgZone = NgZone;
    exports.ɵNoopNgZone = NoopNgZone;
    exports.RenderComponentType = RenderComponentType;
    exports.Renderer = Renderer;
    exports.Renderer2 = Renderer2;
    exports.RendererFactory2 = RendererFactory2;
    exports.RootRenderer = RootRenderer;
    exports.COMPILER_OPTIONS = COMPILER_OPTIONS;
    exports.Compiler = Compiler;
    exports.CompilerFactory = CompilerFactory;
    exports.ModuleWithComponentFactories = ModuleWithComponentFactories;
    exports.ComponentFactory = ComponentFactory;
    exports.ɵComponentFactory = ComponentFactory;
    exports.ComponentRef = ComponentRef;
    exports.ComponentFactoryResolver = ComponentFactoryResolver;
    exports.ElementRef = ElementRef;
    exports.NgModuleFactory = NgModuleFactory;
    exports.NgModuleRef = NgModuleRef;
    exports.NgModuleFactoryLoader = NgModuleFactoryLoader;
    exports.getModuleFactory = getModuleFactory;
    exports.QueryList = QueryList;
    exports.SystemJsNgModuleLoader = SystemJsNgModuleLoader;
    exports.SystemJsNgModuleLoaderConfig = SystemJsNgModuleLoaderConfig;
    exports.TemplateRef = TemplateRef;
    exports.ViewContainerRef = ViewContainerRef;
    exports.EmbeddedViewRef = EmbeddedViewRef;
    exports.ViewRef = ViewRef$1;
    exports.ChangeDetectorRef = ChangeDetectorRef;
    exports.DefaultIterableDiffer = DefaultIterableDiffer;
    exports.IterableDiffers = IterableDiffers;
    exports.KeyValueDiffers = KeyValueDiffers;
    exports.SimpleChange = SimpleChange;
    exports.WrappedValue = WrappedValue;
    exports.platformCore = platformCore;
    exports.ɵALLOW_MULTIPLE_PLATFORMS = ALLOW_MULTIPLE_PLATFORMS;
    exports.ɵAPP_ID_RANDOM_PROVIDER = APP_ID_RANDOM_PROVIDER;
    exports.ɵdefaultIterableDiffers = defaultIterableDiffers;
    exports.ɵdefaultKeyValueDiffers = defaultKeyValueDiffers;
    exports.ɵdevModeEqual = devModeEqual$1;
    exports.ɵisListLikeIterable = isListLikeIterable$1;
    exports.ɵisDefaultChangeDetectionStrategy = isDefaultChangeDetectionStrategy;
    exports.ɵConsole = Console;
    exports.ɵsetCurrentInjector = setCurrentInjector;
    exports.ɵgetInjectableDef = getInjectableDef;
    exports.ɵAPP_ROOT = APP_ROOT;
    exports.ɵDEFAULT_LOCALE_ID = DEFAULT_LOCALE_ID;
    exports.ɵivyEnabled = ivyEnabled;
    exports.ɵCodegenComponentFactoryResolver = CodegenComponentFactoryResolver;
    exports.ɵclearResolutionOfComponentResourcesQueue = clearResolutionOfComponentResourcesQueue;
    exports.ɵresolveComponentResources = resolveComponentResources;
    exports.ɵReflectionCapabilities = ReflectionCapabilities;
    exports.ɵRenderDebugInfo = RenderDebugInfo;
    exports.ɵ_sanitizeHtml = _sanitizeHtml;
    exports.ɵ_sanitizeStyle = _sanitizeStyle;
    exports.ɵ_sanitizeUrl = _sanitizeUrl;
    exports.ɵglobal = _global;
    exports.ɵlooseIdentical = looseIdentical;
    exports.ɵstringify = stringify;
    exports.ɵmakeDecorator = makeDecorator;
    exports.ɵisObservable = isObservable;
    exports.ɵisPromise = isPromise;
    exports.ɵclearOverrides = clearOverrides;
    exports.ɵinitServicesIfNeeded = initServicesIfNeeded;
    exports.ɵoverrideComponentView = overrideComponentView;
    exports.ɵoverrideProvider = overrideProvider;
    exports.ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR;
    exports.ɵgetLocalePluralCase = getLocalePluralCase;
    exports.ɵfindLocaleData = findLocaleData;
    exports.ɵLOCALE_DATA = LOCALE_DATA;
    exports.ɵɵattribute = ɵɵattribute;
    exports.ɵɵattributeInterpolate1 = ɵɵattributeInterpolate1;
    exports.ɵɵattributeInterpolate2 = ɵɵattributeInterpolate2;
    exports.ɵɵattributeInterpolate3 = ɵɵattributeInterpolate3;
    exports.ɵɵattributeInterpolate4 = ɵɵattributeInterpolate4;
    exports.ɵɵattributeInterpolate5 = ɵɵattributeInterpolate5;
    exports.ɵɵattributeInterpolate6 = ɵɵattributeInterpolate6;
    exports.ɵɵattributeInterpolate7 = ɵɵattributeInterpolate7;
    exports.ɵɵattributeInterpolate8 = ɵɵattributeInterpolate8;
    exports.ɵɵattributeInterpolateV = ɵɵattributeInterpolateV;
    exports.ɵɵdefineBase = ɵɵdefineBase;
    exports.ɵɵdefineComponent = ɵɵdefineComponent;
    exports.ɵɵdefineDirective = ɵɵdefineDirective;
    exports.ɵɵdefinePipe = ɵɵdefinePipe;
    exports.ɵɵdefineNgModule = ɵɵdefineNgModule;
    exports.ɵdetectChanges = detectChanges;
    exports.ɵrenderComponent = renderComponent;
    exports.ɵRender3ComponentFactory = ComponentFactory$1;
    exports.ɵRender3ComponentRef = ComponentRef$1;
    exports.ɵɵdirectiveInject = ɵɵdirectiveInject;
    exports.ɵɵinjectAttribute = ɵɵinjectAttribute;
    exports.ɵɵinjectPipeChangeDetectorRef = ɵɵinjectPipeChangeDetectorRef;
    exports.ɵɵgetFactoryOf = ɵɵgetFactoryOf;
    exports.ɵɵgetInheritedFactory = ɵɵgetInheritedFactory;
    exports.ɵɵsetComponentScope = ɵɵsetComponentScope;
    exports.ɵɵsetNgModuleScope = ɵɵsetNgModuleScope;
    exports.ɵɵtemplateRefExtractor = ɵɵtemplateRefExtractor;
    exports.ɵɵProvidersFeature = ɵɵProvidersFeature;
    exports.ɵɵInheritDefinitionFeature = ɵɵInheritDefinitionFeature;
    exports.ɵɵNgOnChangesFeature = ɵɵNgOnChangesFeature;
    exports.ɵLifecycleHooksFeature = LifecycleHooksFeature;
    exports.ɵRender3NgModuleRef = NgModuleRef$1;
    exports.ɵmarkDirty = markDirty;
    exports.ɵNgModuleFactory = NgModuleFactory$1;
    exports.ɵNO_CHANGE = NO_CHANGE;
    exports.ɵɵcontainer = ɵɵcontainer;
    exports.ɵɵnextContext = ɵɵnextContext;
    exports.ɵɵelementStart = ɵɵelementStart;
    exports.ɵɵnamespaceHTML = ɵɵnamespaceHTML;
    exports.ɵɵnamespaceMathML = ɵɵnamespaceMathML;
    exports.ɵɵnamespaceSVG = ɵɵnamespaceSVG;
    exports.ɵɵelement = ɵɵelement;
    exports.ɵɵlistener = ɵɵlistener;
    exports.ɵɵtext = ɵɵtext;
    exports.ɵɵtextInterpolate = ɵɵtextInterpolate;
    exports.ɵɵtextInterpolate1 = ɵɵtextInterpolate1;
    exports.ɵɵtextInterpolate2 = ɵɵtextInterpolate2;
    exports.ɵɵtextInterpolate3 = ɵɵtextInterpolate3;
    exports.ɵɵtextInterpolate4 = ɵɵtextInterpolate4;
    exports.ɵɵtextInterpolate5 = ɵɵtextInterpolate5;
    exports.ɵɵtextInterpolate6 = ɵɵtextInterpolate6;
    exports.ɵɵtextInterpolate7 = ɵɵtextInterpolate7;
    exports.ɵɵtextInterpolate8 = ɵɵtextInterpolate8;
    exports.ɵɵtextInterpolateV = ɵɵtextInterpolateV;
    exports.ɵɵembeddedViewStart = ɵɵembeddedViewStart;
    exports.ɵɵprojection = ɵɵprojection;
    exports.ɵɵpipeBind1 = ɵɵpipeBind1;
    exports.ɵɵpipeBind2 = ɵɵpipeBind2;
    exports.ɵɵpipeBind3 = ɵɵpipeBind3;
    exports.ɵɵpipeBind4 = ɵɵpipeBind4;
    exports.ɵɵpipeBindV = ɵɵpipeBindV;
    exports.ɵɵpureFunction0 = ɵɵpureFunction0;
    exports.ɵɵpureFunction1 = ɵɵpureFunction1;
    exports.ɵɵpureFunction2 = ɵɵpureFunction2;
    exports.ɵɵpureFunction3 = ɵɵpureFunction3;
    exports.ɵɵpureFunction4 = ɵɵpureFunction4;
    exports.ɵɵpureFunction5 = ɵɵpureFunction5;
    exports.ɵɵpureFunction6 = ɵɵpureFunction6;
    exports.ɵɵpureFunction7 = ɵɵpureFunction7;
    exports.ɵɵpureFunction8 = ɵɵpureFunction8;
    exports.ɵɵpureFunctionV = ɵɵpureFunctionV;
    exports.ɵɵgetCurrentView = ɵɵgetCurrentView;
    exports.ɵgetDirectives = getDirectives;
    exports.ɵgetHostElement = getHostElement;
    exports.ɵɵrestoreView = ɵɵrestoreView;
    exports.ɵɵcontainerRefreshStart = ɵɵcontainerRefreshStart;
    exports.ɵɵcontainerRefreshEnd = ɵɵcontainerRefreshEnd;
    exports.ɵɵqueryRefresh = ɵɵqueryRefresh;
    exports.ɵɵviewQuery = ɵɵviewQuery;
    exports.ɵɵstaticViewQuery = ɵɵstaticViewQuery;
    exports.ɵɵstaticContentQuery = ɵɵstaticContentQuery;
    exports.ɵɵloadViewQuery = ɵɵloadViewQuery;
    exports.ɵɵcontentQuery = ɵɵcontentQuery;
    exports.ɵɵloadContentQuery = ɵɵloadContentQuery;
    exports.ɵɵelementEnd = ɵɵelementEnd;
    exports.ɵɵhostProperty = ɵɵhostProperty;
    exports.ɵɵproperty = ɵɵproperty;
    exports.ɵɵpropertyInterpolate = ɵɵpropertyInterpolate;
    exports.ɵɵpropertyInterpolate1 = ɵɵpropertyInterpolate1;
    exports.ɵɵpropertyInterpolate2 = ɵɵpropertyInterpolate2;
    exports.ɵɵpropertyInterpolate3 = ɵɵpropertyInterpolate3;
    exports.ɵɵpropertyInterpolate4 = ɵɵpropertyInterpolate4;
    exports.ɵɵpropertyInterpolate5 = ɵɵpropertyInterpolate5;
    exports.ɵɵpropertyInterpolate6 = ɵɵpropertyInterpolate6;
    exports.ɵɵpropertyInterpolate7 = ɵɵpropertyInterpolate7;
    exports.ɵɵpropertyInterpolate8 = ɵɵpropertyInterpolate8;
    exports.ɵɵpropertyInterpolateV = ɵɵpropertyInterpolateV;
    exports.ɵɵupdateSyntheticHostBinding = ɵɵupdateSyntheticHostBinding;
    exports.ɵɵcomponentHostSyntheticListener = ɵɵcomponentHostSyntheticListener;
    exports.ɵɵprojectionDef = ɵɵprojectionDef;
    exports.ɵɵreference = ɵɵreference;
    exports.ɵɵenableBindings = ɵɵenableBindings;
    exports.ɵɵdisableBindings = ɵɵdisableBindings;
    exports.ɵɵallocHostVars = ɵɵallocHostVars;
    exports.ɵɵelementContainerStart = ɵɵelementContainerStart;
    exports.ɵɵelementContainerEnd = ɵɵelementContainerEnd;
    exports.ɵɵelementContainer = ɵɵelementContainer;
    exports.ɵɵstyling = ɵɵstyling;
    exports.ɵɵstyleMap = ɵɵstyleMap;
    exports.ɵɵstyleSanitizer = ɵɵstyleSanitizer;
    exports.ɵɵclassMap = ɵɵclassMap;
    exports.ɵɵclassMapInterpolate1 = ɵɵclassMapInterpolate1;
    exports.ɵɵclassMapInterpolate2 = ɵɵclassMapInterpolate2;
    exports.ɵɵclassMapInterpolate3 = ɵɵclassMapInterpolate3;
    exports.ɵɵclassMapInterpolate4 = ɵɵclassMapInterpolate4;
    exports.ɵɵclassMapInterpolate5 = ɵɵclassMapInterpolate5;
    exports.ɵɵclassMapInterpolate6 = ɵɵclassMapInterpolate6;
    exports.ɵɵclassMapInterpolate7 = ɵɵclassMapInterpolate7;
    exports.ɵɵclassMapInterpolate8 = ɵɵclassMapInterpolate8;
    exports.ɵɵclassMapInterpolateV = ɵɵclassMapInterpolateV;
    exports.ɵɵstyleProp = ɵɵstyleProp;
    exports.ɵɵstylePropInterpolate1 = ɵɵstylePropInterpolate1;
    exports.ɵɵstylePropInterpolate2 = ɵɵstylePropInterpolate2;
    exports.ɵɵstylePropInterpolate3 = ɵɵstylePropInterpolate3;
    exports.ɵɵstylePropInterpolate4 = ɵɵstylePropInterpolate4;
    exports.ɵɵstylePropInterpolate5 = ɵɵstylePropInterpolate5;
    exports.ɵɵstylePropInterpolate6 = ɵɵstylePropInterpolate6;
    exports.ɵɵstylePropInterpolate7 = ɵɵstylePropInterpolate7;
    exports.ɵɵstylePropInterpolate8 = ɵɵstylePropInterpolate8;
    exports.ɵɵstylePropInterpolateV = ɵɵstylePropInterpolateV;
    exports.ɵɵstylingApply = ɵɵstylingApply;
    exports.ɵɵclassProp = ɵɵclassProp;
    exports.ɵɵelementHostAttrs = ɵɵelementHostAttrs;
    exports.ɵɵselect = ɵɵselect;
    exports.ɵɵtextBinding = ɵɵtextBinding;
    exports.ɵɵtemplate = ɵɵtemplate;
    exports.ɵɵembeddedViewEnd = ɵɵembeddedViewEnd;
    exports.ɵstore = store;
    exports.ɵɵload = ɵɵload;
    exports.ɵɵpipe = ɵɵpipe;
    exports.ɵwhenRendered = whenRendered;
    exports.ɵɵi18n = ɵɵi18n;
    exports.ɵɵi18nAttributes = ɵɵi18nAttributes;
    exports.ɵɵi18nExp = ɵɵi18nExp;
    exports.ɵɵi18nStart = ɵɵi18nStart;
    exports.ɵɵi18nEnd = ɵɵi18nEnd;
    exports.ɵɵi18nApply = ɵɵi18nApply;
    exports.ɵɵi18nPostprocess = ɵɵi18nPostprocess;
    exports.ɵi18nConfigureLocalize = i18nConfigureLocalize;
    exports.ɵɵi18nLocalize = ɵɵi18nLocalize;
    exports.ɵsetLocaleId = setLocaleId;
    exports.ɵsetClassMetadata = setClassMetadata;
    exports.ɵɵresolveWindow = ɵɵresolveWindow;
    exports.ɵɵresolveDocument = ɵɵresolveDocument;
    exports.ɵɵresolveBody = ɵɵresolveBody;
    exports.ɵcompileComponent = compileComponent;
    exports.ɵcompileDirective = compileDirective;
    exports.ɵcompileNgModule = compileNgModule;
    exports.ɵcompileNgModuleDefs = compileNgModuleDefs;
    exports.ɵpatchComponentDefWithScope = patchComponentDefWithScope;
    exports.ɵresetCompiledComponents = resetCompiledComponents;
    exports.ɵflushModuleScopingQueueAsMuchAsPossible = flushModuleScopingQueueAsMuchAsPossible;
    exports.ɵtransitiveScopesFor = transitiveScopesFor;
    exports.ɵcompilePipe = compilePipe;
    exports.ɵɵsanitizeHtml = ɵɵsanitizeHtml;
    exports.ɵɵsanitizeStyle = ɵɵsanitizeStyle;
    exports.ɵɵdefaultStyleSanitizer = ɵɵdefaultStyleSanitizer;
    exports.ɵɵsanitizeScript = ɵɵsanitizeScript;
    exports.ɵɵsanitizeUrl = ɵɵsanitizeUrl;
    exports.ɵɵsanitizeResourceUrl = ɵɵsanitizeResourceUrl;
    exports.ɵɵsanitizeUrlOrResourceUrl = ɵɵsanitizeUrlOrResourceUrl;
    exports.ɵbypassSanitizationTrustHtml = bypassSanitizationTrustHtml;
    exports.ɵbypassSanitizationTrustStyle = bypassSanitizationTrustStyle;
    exports.ɵbypassSanitizationTrustScript = bypassSanitizationTrustScript;
    exports.ɵbypassSanitizationTrustUrl = bypassSanitizationTrustUrl;
    exports.ɵbypassSanitizationTrustResourceUrl = bypassSanitizationTrustResourceUrl;
    exports.ɵgetLContext = getLContext;
    exports.ɵNG_ELEMENT_ID = NG_ELEMENT_ID;
    exports.ɵNG_COMPONENT_DEF = NG_COMPONENT_DEF;
    exports.ɵNG_DIRECTIVE_DEF = NG_DIRECTIVE_DEF;
    exports.ɵNG_PIPE_DEF = NG_PIPE_DEF;
    exports.ɵNG_MODULE_DEF = NG_MODULE_DEF;
    exports.ɵNG_BASE_DEF = NG_BASE_DEF;
    exports.ɵNG_INJECTABLE_DEF = NG_INJECTABLE_DEF;
    exports.ɵNG_INJECTOR_DEF = NG_INJECTOR_DEF;
    exports.ɵcompileNgModuleFactory__POST_R3__ = compileNgModuleFactory__POST_R3__;
    exports.ɵisBoundToModule__POST_R3__ = isBoundToModule__POST_R3__;
    exports.ɵSWITCH_COMPILE_COMPONENT__POST_R3__ = SWITCH_COMPILE_COMPONENT__POST_R3__;
    exports.ɵSWITCH_COMPILE_DIRECTIVE__POST_R3__ = SWITCH_COMPILE_DIRECTIVE__POST_R3__;
    exports.ɵSWITCH_COMPILE_PIPE__POST_R3__ = SWITCH_COMPILE_PIPE__POST_R3__;
    exports.ɵSWITCH_COMPILE_NGMODULE__POST_R3__ = SWITCH_COMPILE_NGMODULE__POST_R3__;
    exports.ɵgetDebugNode__POST_R3__ = getDebugNode__POST_R3__;
    exports.ɵSWITCH_COMPILE_INJECTABLE__POST_R3__ = SWITCH_COMPILE_INJECTABLE__POST_R3__;
    exports.ɵSWITCH_IVY_ENABLED__POST_R3__ = SWITCH_IVY_ENABLED__POST_R3__;
    exports.ɵSWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__ = SWITCH_CHANGE_DETECTOR_REF_FACTORY__POST_R3__;
    exports.ɵCompiler_compileModuleSync__POST_R3__ = Compiler_compileModuleSync__POST_R3__;
    exports.ɵCompiler_compileModuleAsync__POST_R3__ = Compiler_compileModuleAsync__POST_R3__;
    exports.ɵCompiler_compileModuleAndAllComponentsSync__POST_R3__ = Compiler_compileModuleAndAllComponentsSync__POST_R3__;
    exports.ɵCompiler_compileModuleAndAllComponentsAsync__POST_R3__ = Compiler_compileModuleAndAllComponentsAsync__POST_R3__;
    exports.ɵSWITCH_ELEMENT_REF_FACTORY__POST_R3__ = SWITCH_ELEMENT_REF_FACTORY__POST_R3__;
    exports.ɵSWITCH_TEMPLATE_REF_FACTORY__POST_R3__ = SWITCH_TEMPLATE_REF_FACTORY__POST_R3__;
    exports.ɵSWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__ = SWITCH_VIEW_CONTAINER_REF_FACTORY__POST_R3__;
    exports.ɵSWITCH_RENDERER2_FACTORY__POST_R3__ = SWITCH_RENDERER2_FACTORY__POST_R3__;
    exports.ɵgetModuleFactory__POST_R3__ = getModuleFactory__POST_R3__;
    exports.ɵregisterNgModuleType = registerNgModuleType;
    exports.ɵpublishGlobalUtil = publishGlobalUtil;
    exports.ɵpublishDefaultGlobalUtils = publishDefaultGlobalUtils;
    exports.ɵcreateInjector = createInjector;
    exports.ɵINJECTOR_IMPL__POST_R3__ = INJECTOR_IMPL__POST_R3__;
    exports.ɵregisterModuleFactory = registerModuleFactory;
    exports.ɵEMPTY_ARRAY = EMPTY_ARRAY$3;
    exports.ɵEMPTY_MAP = EMPTY_MAP;
    exports.ɵand = anchorDef;
    exports.ɵccf = createComponentFactory;
    exports.ɵcmf = createNgModuleFactory;
    exports.ɵcrt = createRendererType2;
    exports.ɵdid = directiveDef;
    exports.ɵeld = elementDef;
    exports.ɵgetComponentViewDefinitionFactory = getComponentViewDefinitionFactory;
    exports.ɵinlineInterpolate = inlineInterpolate;
    exports.ɵinterpolate = interpolate;
    exports.ɵmod = moduleDef;
    exports.ɵmpd = moduleProvideDef;
    exports.ɵncd = ngContentDef;
    exports.ɵnov = nodeValue;
    exports.ɵpid = pipeDef;
    exports.ɵprd = providerDef;
    exports.ɵpad = pureArrayDef;
    exports.ɵpod = pureObjectDef;
    exports.ɵppd = purePipeDef;
    exports.ɵqud = queryDef;
    exports.ɵted = textDef;
    exports.ɵunv = unwrapValue;
    exports.ɵvid = viewDef;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=core.umd.js.map
