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

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

    /**
     * @license
     * Copyright Google LLC 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 isBrowser() {
        return (typeof window !== 'undefined' && typeof window.document !== 'undefined');
    }
    function isNode() {
        // Checking only for `process` isn't enough to identify whether or not we're in a Node
        // environment, because Webpack by default will polyfill the `process`. While we can discern
        // that Webpack polyfilled it by looking at `process.browser`, it's very Webpack-specific and
        // might not be future-proof. Instead we look at the stringified version of `process` which
        // is `[object process]` in Node and `[object Object]` when polyfilled.
        return typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
    }
    function optimizeGroupPlayer(players) {
        switch (players.length) {
            case 0:
                return new animations.NoopAnimationPlayer();
            case 1:
                return players[0];
            default:
                return new animations.ɵAnimationGroupPlayer(players);
        }
    }
    function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles, postStyles) {
        if (preStyles === void 0) { preStyles = {}; }
        if (postStyles === void 0) { postStyles = {}; }
        var errors = [];
        var normalizedKeyframes = [];
        var previousOffset = -1;
        var previousKeyframe = null;
        keyframes.forEach(function (kf) {
            var offset = kf['offset'];
            var isSameOffset = offset == previousOffset;
            var normalizedKeyframe = (isSameOffset && previousKeyframe) || {};
            Object.keys(kf).forEach(function (prop) {
                var normalizedProp = prop;
                var normalizedValue = kf[prop];
                if (prop !== 'offset') {
                    normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
                    switch (normalizedValue) {
                        case animations.ɵPRE_STYLE:
                            normalizedValue = preStyles[prop];
                            break;
                        case animations.AUTO_STYLE:
                            normalizedValue = postStyles[prop];
                            break;
                        default:
                            normalizedValue =
                                normalizer.normalizeStyleValue(prop, normalizedProp, normalizedValue, errors);
                            break;
                    }
                }
                normalizedKeyframe[normalizedProp] = normalizedValue;
            });
            if (!isSameOffset) {
                normalizedKeyframes.push(normalizedKeyframe);
            }
            previousKeyframe = normalizedKeyframe;
            previousOffset = offset;
        });
        if (errors.length) {
            var LINE_START = '\n - ';
            throw new Error("Unable to animate due to the following errors:" + LINE_START + errors.join(LINE_START));
        }
        return normalizedKeyframes;
    }
    function listenOnPlayer(player, eventName, event, callback) {
        switch (eventName) {
            case 'start':
                player.onStart(function () { return callback(event && copyAnimationEvent(event, 'start', player)); });
                break;
            case 'done':
                player.onDone(function () { return callback(event && copyAnimationEvent(event, 'done', player)); });
                break;
            case 'destroy':
                player.onDestroy(function () { return callback(event && copyAnimationEvent(event, 'destroy', player)); });
                break;
        }
    }
    function copyAnimationEvent(e, phaseName, player) {
        var totalTime = player.totalTime;
        var disabled = player.disabled ? true : false;
        var event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime, disabled);
        var data = e['_data'];
        if (data != null) {
            event['_data'] = data;
        }
        return event;
    }
    function makeAnimationEvent(element, triggerName, fromState, toState, phaseName, totalTime, disabled) {
        if (phaseName === void 0) { phaseName = ''; }
        if (totalTime === void 0) { totalTime = 0; }
        return { element: element, triggerName: triggerName, fromState: fromState, toState: toState, phaseName: phaseName, totalTime: totalTime, disabled: !!disabled };
    }
    function getOrSetAsInMap(map, key, defaultValue) {
        var value;
        if (map instanceof Map) {
            value = map.get(key);
            if (!value) {
                map.set(key, value = defaultValue);
            }
        }
        else {
            value = map[key];
            if (!value) {
                value = map[key] = defaultValue;
            }
        }
        return value;
    }
    function parseTimelineCommand(command) {
        var separatorPos = command.indexOf(':');
        var id = command.substring(1, separatorPos);
        var action = command.substr(separatorPos + 1);
        return [id, action];
    }
    var _contains = function (elm1, elm2) { return false; };
    var ɵ0 = _contains;
    var _matches = function (element, selector) { return false; };
    var ɵ1 = _matches;
    var _query = function (element, selector, multi) {
        return [];
    };
    var ɵ2 = _query;
    // Define utility methods for browsers and platform-server(domino) where Element
    // and utility methods exist.
    var _isNode = isNode();
    if (_isNode || typeof Element !== 'undefined') {
        // this is well supported in all browsers
        _contains = function (elm1, elm2) {
            return elm1.contains(elm2);
        };
        _matches = (function () {
            if (_isNode || Element.prototype.matches) {
                return function (element, selector) { return element.matches(selector); };
            }
            else {
                var proto = Element.prototype;
                var fn_1 = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector ||
                    proto.oMatchesSelector || proto.webkitMatchesSelector;
                if (fn_1) {
                    return function (element, selector) { return fn_1.apply(element, [selector]); };
                }
                else {
                    return _matches;
                }
            }
        })();
        _query = function (element, selector, multi) {
            var results = [];
            if (multi) {
                // DO NOT REFACTOR TO USE SPREAD SYNTAX.
                // For element queries that return sufficiently large NodeList objects,
                // using spread syntax to populate the results array causes a RangeError
                // due to the call stack limit being reached. `Array.from` can not be used
                // as well, since NodeList is not iterable in IE 11, see
                // https://developer.mozilla.org/en-US/docs/Web/API/NodeList
                // More info is available in #38551.
                var elems = element.querySelectorAll(selector);
                for (var i = 0; i < elems.length; i++) {
                    results.push(elems[i]);
                }
            }
            else {
                var elm = element.querySelector(selector);
                if (elm) {
                    results.push(elm);
                }
            }
            return results;
        };
    }
    function containsVendorPrefix(prop) {
        // Webkit is the only real popular vendor prefix nowadays
        // cc: http://shouldiprefix.com/
        return prop.substring(1, 6) == 'ebkit'; // webkit or Webkit
    }
    var _CACHED_BODY = null;
    var _IS_WEBKIT = false;
    function validateStyleProperty(prop) {
        if (!_CACHED_BODY) {
            _CACHED_BODY = getBodyNode() || {};
            _IS_WEBKIT = _CACHED_BODY.style ? ('WebkitAppearance' in _CACHED_BODY.style) : false;
        }
        var result = true;
        if (_CACHED_BODY.style && !containsVendorPrefix(prop)) {
            result = prop in _CACHED_BODY.style;
            if (!result && _IS_WEBKIT) {
                var camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.substr(1);
                result = camelProp in _CACHED_BODY.style;
            }
        }
        return result;
    }
    function getBodyNode() {
        if (typeof document != 'undefined') {
            return document.body;
        }
        return null;
    }
    var matchesElement = _matches;
    var containsElement = _contains;
    var invokeQuery = _query;
    function hypenatePropsObject(object) {
        var newObj = {};
        Object.keys(object).forEach(function (prop) {
            var newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');
            newObj[newProp] = object[prop];
        });
        return newObj;
    }

    /**
     * @license
     * Copyright Google LLC 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 NoopAnimationDriver = /** @class */ (function () {
        function NoopAnimationDriver() {
        }
        NoopAnimationDriver.prototype.validateStyleProperty = function (prop) {
            return validateStyleProperty(prop);
        };
        NoopAnimationDriver.prototype.matchesElement = function (element, selector) {
            return matchesElement(element, selector);
        };
        NoopAnimationDriver.prototype.containsElement = function (elm1, elm2) {
            return containsElement(elm1, elm2);
        };
        NoopAnimationDriver.prototype.query = function (element, selector, multi) {
            return invokeQuery(element, selector, multi);
        };
        NoopAnimationDriver.prototype.computeStyle = function (element, prop, defaultValue) {
            return defaultValue || '';
        };
        NoopAnimationDriver.prototype.animate = function (element, keyframes, duration, delay, easing, previousPlayers, scrubberAccessRequested) {
            if (previousPlayers === void 0) { previousPlayers = []; }
            return new animations.NoopAnimationPlayer(duration, delay);
        };
        return NoopAnimationDriver;
    }());
    NoopAnimationDriver.decorators = [
        { type: core.Injectable }
    ];
    /**
     * @publicApi
     */
    var AnimationDriver = /** @class */ (function () {
        function AnimationDriver() {
        }
        return AnimationDriver;
    }());
    AnimationDriver.NOOP = new NoopAnimationDriver();

    /**
     * @license
     * Copyright Google LLC 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 ONE_SECOND = 1000;
    var SUBSTITUTION_EXPR_START = '{{';
    var SUBSTITUTION_EXPR_END = '}}';
    var ENTER_CLASSNAME = 'ng-enter';
    var LEAVE_CLASSNAME = 'ng-leave';
    var ENTER_SELECTOR = '.ng-enter';
    var LEAVE_SELECTOR = '.ng-leave';
    var NG_TRIGGER_CLASSNAME = 'ng-trigger';
    var NG_TRIGGER_SELECTOR = '.ng-trigger';
    var NG_ANIMATING_CLASSNAME = 'ng-animating';
    var NG_ANIMATING_SELECTOR = '.ng-animating';
    function resolveTimingValue(value) {
        if (typeof value == 'number')
            return value;
        var matches = value.match(/^(-?[\.\d]+)(m?s)/);
        if (!matches || matches.length < 2)
            return 0;
        return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
    }
    function _convertTimeValueToMS(value, unit) {
        switch (unit) {
            case 's':
                return value * ONE_SECOND;
            default: // ms or something else
                return value;
        }
    }
    function resolveTiming(timings, errors, allowNegativeValues) {
        return timings.hasOwnProperty('duration') ?
            timings :
            parseTimeExpression(timings, errors, allowNegativeValues);
    }
    function parseTimeExpression(exp, errors, allowNegativeValues) {
        var regex = /^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i;
        var duration;
        var delay = 0;
        var easing = '';
        if (typeof exp === 'string') {
            var matches = exp.match(regex);
            if (matches === null) {
                errors.push("The provided timing value \"" + exp + "\" is invalid.");
                return { duration: 0, delay: 0, easing: '' };
            }
            duration = _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
            var delayMatch = matches[3];
            if (delayMatch != null) {
                delay = _convertTimeValueToMS(parseFloat(delayMatch), matches[4]);
            }
            var easingVal = matches[5];
            if (easingVal) {
                easing = easingVal;
            }
        }
        else {
            duration = exp;
        }
        if (!allowNegativeValues) {
            var containsErrors = false;
            var startIndex = errors.length;
            if (duration < 0) {
                errors.push("Duration values below 0 are not allowed for this animation step.");
                containsErrors = true;
            }
            if (delay < 0) {
                errors.push("Delay values below 0 are not allowed for this animation step.");
                containsErrors = true;
            }
            if (containsErrors) {
                errors.splice(startIndex, 0, "The provided timing value \"" + exp + "\" is invalid.");
            }
        }
        return { duration: duration, delay: delay, easing: easing };
    }
    function copyObj(obj, destination) {
        if (destination === void 0) { destination = {}; }
        Object.keys(obj).forEach(function (prop) {
            destination[prop] = obj[prop];
        });
        return destination;
    }
    function normalizeStyles(styles) {
        var normalizedStyles = {};
        if (Array.isArray(styles)) {
            styles.forEach(function (data) { return copyStyles(data, false, normalizedStyles); });
        }
        else {
            copyStyles(styles, false, normalizedStyles);
        }
        return normalizedStyles;
    }
    function copyStyles(styles, readPrototype, destination) {
        if (destination === void 0) { destination = {}; }
        if (readPrototype) {
            // we make use of a for-in loop so that the
            // prototypically inherited properties are
            // revealed from the backFill map
            for (var prop in styles) {
                destination[prop] = styles[prop];
            }
        }
        else {
            copyObj(styles, destination);
        }
        return destination;
    }
    function getStyleAttributeString(element, key, value) {
        // Return the key-value pair string to be added to the style attribute for the
        // given CSS style key.
        if (value) {
            return key + ':' + value + ';';
        }
        else {
            return '';
        }
    }
    function writeStyleAttribute(element) {
        // Read the style property of the element and manually reflect it to the
        // style attribute. This is needed because Domino on platform-server doesn't
        // understand the full set of allowed CSS properties and doesn't reflect some
        // of them automatically.
        var styleAttrValue = '';
        for (var i = 0; i < element.style.length; i++) {
            var key = element.style.item(i);
            styleAttrValue += getStyleAttributeString(element, key, element.style.getPropertyValue(key));
        }
        for (var key in element.style) {
            // Skip internal Domino properties that don't need to be reflected.
            if (!element.style.hasOwnProperty(key) || key.startsWith('_')) {
                continue;
            }
            var dashKey = camelCaseToDashCase(key);
            styleAttrValue += getStyleAttributeString(element, dashKey, element.style[key]);
        }
        element.setAttribute('style', styleAttrValue);
    }
    function setStyles(element, styles, formerStyles) {
        if (element['style']) {
            Object.keys(styles).forEach(function (prop) {
                var camelProp = dashCaseToCamelCase(prop);
                if (formerStyles && !formerStyles.hasOwnProperty(prop)) {
                    formerStyles[prop] = element.style[camelProp];
                }
                element.style[camelProp] = styles[prop];
            });
            // On the server set the 'style' attribute since it's not automatically reflected.
            if (isNode()) {
                writeStyleAttribute(element);
            }
        }
    }
    function eraseStyles(element, styles) {
        if (element['style']) {
            Object.keys(styles).forEach(function (prop) {
                var camelProp = dashCaseToCamelCase(prop);
                element.style[camelProp] = '';
            });
            // On the server set the 'style' attribute since it's not automatically reflected.
            if (isNode()) {
                writeStyleAttribute(element);
            }
        }
    }
    function normalizeAnimationEntry(steps) {
        if (Array.isArray(steps)) {
            if (steps.length == 1)
                return steps[0];
            return animations.sequence(steps);
        }
        return steps;
    }
    function validateStyleParams(value, options, errors) {
        var params = options.params || {};
        var matches = extractStyleParams(value);
        if (matches.length) {
            matches.forEach(function (varName) {
                if (!params.hasOwnProperty(varName)) {
                    errors.push("Unable to resolve the local animation param " + varName + " in the given list of values");
                }
            });
        }
    }
    var PARAM_REGEX = new RegExp(SUBSTITUTION_EXPR_START + "\\s*(.+?)\\s*" + SUBSTITUTION_EXPR_END, 'g');
    function extractStyleParams(value) {
        var params = [];
        if (typeof value === 'string') {
            var match = void 0;
            while (match = PARAM_REGEX.exec(value)) {
                params.push(match[1]);
            }
            PARAM_REGEX.lastIndex = 0;
        }
        return params;
    }
    function interpolateParams(value, params, errors) {
        var original = value.toString();
        var str = original.replace(PARAM_REGEX, function (_, varName) {
            var localVal = params[varName];
            // this means that the value was never overridden by the data passed in by the user
            if (!params.hasOwnProperty(varName)) {
                errors.push("Please provide a value for the animation param " + varName);
                localVal = '';
            }
            return localVal.toString();
        });
        // we do this to assert that numeric values stay as they are
        return str == original ? value : str;
    }
    function iteratorToArray(iterator) {
        var arr = [];
        var item = iterator.next();
        while (!item.done) {
            arr.push(item.value);
            item = iterator.next();
        }
        return arr;
    }
    var DASH_CASE_REGEXP = /-+([a-z0-9])/g;
    function dashCaseToCamelCase(input) {
        return input.replace(DASH_CASE_REGEXP, function () {
            var m = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                m[_i] = arguments[_i];
            }
            return m[1].toUpperCase();
        });
    }
    function camelCaseToDashCase(input) {
        return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
    }
    function allowPreviousPlayerStylesMerge(duration, delay) {
        return duration === 0 || delay === 0;
    }
    function balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {
        var previousStyleProps = Object.keys(previousStyles);
        if (previousStyleProps.length && keyframes.length) {
            var startingKeyframe_1 = keyframes[0];
            var missingStyleProps_1 = [];
            previousStyleProps.forEach(function (prop) {
                if (!startingKeyframe_1.hasOwnProperty(prop)) {
                    missingStyleProps_1.push(prop);
                }
                startingKeyframe_1[prop] = previousStyles[prop];
            });
            if (missingStyleProps_1.length) {
                var _loop_1 = function () {
                    var kf = keyframes[i];
                    missingStyleProps_1.forEach(function (prop) {
                        kf[prop] = computeStyle(element, prop);
                    });
                };
                // tslint:disable-next-line
                for (var i = 1; i < keyframes.length; i++) {
                    _loop_1();
                }
            }
        }
        return keyframes;
    }
    function visitDslNode(visitor, node, context) {
        switch (node.type) {
            case 7 /* Trigger */:
                return visitor.visitTrigger(node, context);
            case 0 /* State */:
                return visitor.visitState(node, context);
            case 1 /* Transition */:
                return visitor.visitTransition(node, context);
            case 2 /* Sequence */:
                return visitor.visitSequence(node, context);
            case 3 /* Group */:
                return visitor.visitGroup(node, context);
            case 4 /* Animate */:
                return visitor.visitAnimate(node, context);
            case 5 /* Keyframes */:
                return visitor.visitKeyframes(node, context);
            case 6 /* Style */:
                return visitor.visitStyle(node, context);
            case 8 /* Reference */:
                return visitor.visitReference(node, context);
            case 9 /* AnimateChild */:
                return visitor.visitAnimateChild(node, context);
            case 10 /* AnimateRef */:
                return visitor.visitAnimateRef(node, context);
            case 11 /* Query */:
                return visitor.visitQuery(node, context);
            case 12 /* Stagger */:
                return visitor.visitStagger(node, context);
            default:
                throw new Error("Unable to resolve animation metadata node #" + node.type);
        }
    }
    function computeStyle(element, prop) {
        return window.getComputedStyle(element)[prop];
    }

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* 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 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                    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) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        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) : adopt(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 };
        }
    }
    var __createBinding = Object.create ? (function (o, m, k, k2) {
        if (k2 === undefined)
            k2 = k;
        Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
    }) : (function (o, m, k, k2) {
        if (k2 === undefined)
            k2 = k;
        o[k2] = m[k];
    });
    function __exportStar(m, exports) {
        for (var p in m)
            if (p !== "default" && !exports.hasOwnProperty(p))
                __createBinding(exports, m, p);
    }
    function __values(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m)
            return m.call(o);
        if (o && typeof o.length === "number")
            return {
                next: function () {
                    if (o && i >= o.length)
                        o = void 0;
                    return { value: o && o[i++], done: !o };
                }
            };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    }
    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 __spreadArrays() {
        for (var s = 0, i = 0, il = arguments.length; i < il; i++)
            s += arguments[i].length;
        for (var r = Array(s), k = 0, i = 0; i < il; i++)
            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                r[k] = a[j];
        return r;
    }
    ;
    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;
    }
    ;
    var __setModuleDefault = Object.create ? (function (o, v) {
        Object.defineProperty(o, "default", { enumerable: true, value: v });
    }) : function (o, v) {
        o["default"] = v;
    };
    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))
                    __createBinding(result, mod, k);
        __setModuleDefault(result, mod);
        return result;
    }
    function __importDefault(mod) {
        return (mod && mod.__esModule) ? mod : { default: mod };
    }
    function __classPrivateFieldGet(receiver, privateMap) {
        if (!privateMap.has(receiver)) {
            throw new TypeError("attempted to get private field on non-instance");
        }
        return privateMap.get(receiver);
    }
    function __classPrivateFieldSet(receiver, privateMap, value) {
        if (!privateMap.has(receiver)) {
            throw new TypeError("attempted to set private field on non-instance");
        }
        privateMap.set(receiver, value);
        return value;
    }

    /**
     * @license
     * Copyright Google LLC 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 ANY_STATE = '*';
    function parseTransitionExpr(transitionValue, errors) {
        var expressions = [];
        if (typeof transitionValue == 'string') {
            transitionValue.split(/\s*,\s*/).forEach(function (str) { return parseInnerTransitionStr(str, expressions, errors); });
        }
        else {
            expressions.push(transitionValue);
        }
        return expressions;
    }
    function parseInnerTransitionStr(eventStr, expressions, errors) {
        if (eventStr[0] == ':') {
            var result = parseAnimationAlias(eventStr, errors);
            if (typeof result == 'function') {
                expressions.push(result);
                return;
            }
            eventStr = result;
        }
        var match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
        if (match == null || match.length < 4) {
            errors.push("The provided transition expression \"" + eventStr + "\" is not supported");
            return expressions;
        }
        var fromState = match[1];
        var separator = match[2];
        var toState = match[3];
        expressions.push(makeLambdaFromStates(fromState, toState));
        var isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE;
        if (separator[0] == '<' && !isFullAnyStateExpr) {
            expressions.push(makeLambdaFromStates(toState, fromState));
        }
    }
    function parseAnimationAlias(alias, errors) {
        switch (alias) {
            case ':enter':
                return 'void => *';
            case ':leave':
                return '* => void';
            case ':increment':
                return function (fromState, toState) { return parseFloat(toState) > parseFloat(fromState); };
            case ':decrement':
                return function (fromState, toState) { return parseFloat(toState) < parseFloat(fromState); };
            default:
                errors.push("The transition alias value \"" + alias + "\" is not supported");
                return '* => *';
        }
    }
    // DO NOT REFACTOR ... keep the follow set instantiations
    // with the values intact (closure compiler for some reason
    // removes follow-up lines that add the values outside of
    // the constructor...
    var TRUE_BOOLEAN_VALUES = new Set(['true', '1']);
    var FALSE_BOOLEAN_VALUES = new Set(['false', '0']);
    function makeLambdaFromStates(lhs, rhs) {
        var LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs);
        var RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs);
        return function (fromState, toState) {
            var lhsMatch = lhs == ANY_STATE || lhs == fromState;
            var rhsMatch = rhs == ANY_STATE || rhs == toState;
            if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') {
                lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs);
            }
            if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') {
                rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs);
            }
            return lhsMatch && rhsMatch;
        };
    }

    var SELF_TOKEN = ':self';
    var SELF_TOKEN_REGEX = new RegExp("s*" + SELF_TOKEN + "s*,?", 'g');
    /*
     * [Validation]
     * The visitor code below will traverse the animation AST generated by the animation verb functions
     * (the output is a tree of objects) and attempt to perform a series of validations on the data. The
     * following corner-cases will be validated:
     *
     * 1. Overlap of animations
     * Given that a CSS property cannot be animated in more than one place at the same time, it's
     * important that this behavior is detected and validated. The way in which this occurs is that
     * each time a style property is examined, a string-map containing the property will be updated with
     * the start and end times for when the property is used within an animation step.
     *
     * If there are two or more parallel animations that are currently running (these are invoked by the
     * group()) on the same element then the validator will throw an error. Since the start/end timing
     * values are collected for each property then if the current animation step is animating the same
     * property and its timing values fall anywhere into the window of time that the property is
     * currently being animated within then this is what causes an error.
     *
     * 2. Timing values
     * The validator will validate to see if a timing value of `duration delay easing` or
     * `durationNumber` is valid or not.
     *
     * (note that upon validation the code below will replace the timing data with an object containing
     * {duration,delay,easing}.
     *
     * 3. Offset Validation
     * Each of the style() calls are allowed to have an offset value when placed inside of keyframes().
     * Offsets within keyframes() are considered valid when:
     *
     *   - No offsets are used at all
     *   - Each style() entry contains an offset value
     *   - Each offset is between 0 and 1
     *   - Each offset is greater to or equal than the previous one
     *
     * Otherwise an error will be thrown.
     */
    function buildAnimationAst(driver, metadata, errors) {
        return new AnimationAstBuilderVisitor(driver).build(metadata, errors);
    }
    var ROOT_SELECTOR = '';
    var AnimationAstBuilderVisitor = /** @class */ (function () {
        function AnimationAstBuilderVisitor(_driver) {
            this._driver = _driver;
        }
        AnimationAstBuilderVisitor.prototype.build = function (metadata, errors) {
            var context = new AnimationAstBuilderContext(errors);
            this._resetContextStyleTimingState(context);
            return visitDslNode(this, normalizeAnimationEntry(metadata), context);
        };
        AnimationAstBuilderVisitor.prototype._resetContextStyleTimingState = function (context) {
            context.currentQuerySelector = ROOT_SELECTOR;
            context.collectedStyles = {};
            context.collectedStyles[ROOT_SELECTOR] = {};
            context.currentTime = 0;
        };
        AnimationAstBuilderVisitor.prototype.visitTrigger = function (metadata, context) {
            var _this = this;
            var queryCount = context.queryCount = 0;
            var depCount = context.depCount = 0;
            var states = [];
            var transitions = [];
            if (metadata.name.charAt(0) == '@') {
                context.errors.push('animation triggers cannot be prefixed with an `@` sign (e.g. trigger(\'@foo\', [...]))');
            }
            metadata.definitions.forEach(function (def) {
                _this._resetContextStyleTimingState(context);
                if (def.type == 0 /* State */) {
                    var stateDef_1 = def;
                    var name = stateDef_1.name;
                    name.toString().split(/\s*,\s*/).forEach(function (n) {
                        stateDef_1.name = n;
                        states.push(_this.visitState(stateDef_1, context));
                    });
                    stateDef_1.name = name;
                }
                else if (def.type == 1 /* Transition */) {
                    var transition = _this.visitTransition(def, context);
                    queryCount += transition.queryCount;
                    depCount += transition.depCount;
                    transitions.push(transition);
                }
                else {
                    context.errors.push('only state() and transition() definitions can sit inside of a trigger()');
                }
            });
            return {
                type: 7 /* Trigger */,
                name: metadata.name,
                states: states,
                transitions: transitions,
                queryCount: queryCount,
                depCount: depCount,
                options: null
            };
        };
        AnimationAstBuilderVisitor.prototype.visitState = function (metadata, context) {
            var styleAst = this.visitStyle(metadata.styles, context);
            var astParams = (metadata.options && metadata.options.params) || null;
            if (styleAst.containsDynamicStyles) {
                var missingSubs_1 = new Set();
                var params_1 = astParams || {};
                styleAst.styles.forEach(function (value) {
                    if (isObject(value)) {
                        var stylesObj_1 = value;
                        Object.keys(stylesObj_1).forEach(function (prop) {
                            extractStyleParams(stylesObj_1[prop]).forEach(function (sub) {
                                if (!params_1.hasOwnProperty(sub)) {
                                    missingSubs_1.add(sub);
                                }
                            });
                        });
                    }
                });
                if (missingSubs_1.size) {
                    var missingSubsArr = iteratorToArray(missingSubs_1.values());
                    context.errors.push("state(\"" + metadata
                        .name + "\", ...) must define default values for all the following style substitutions: " + missingSubsArr.join(', '));
                }
            }
            return {
                type: 0 /* State */,
                name: metadata.name,
                style: styleAst,
                options: astParams ? { params: astParams } : null
            };
        };
        AnimationAstBuilderVisitor.prototype.visitTransition = function (metadata, context) {
            context.queryCount = 0;
            context.depCount = 0;
            var animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
            var matchers = parseTransitionExpr(metadata.expr, context.errors);
            return {
                type: 1 /* Transition */,
                matchers: matchers,
                animation: animation,
                queryCount: context.queryCount,
                depCount: context.depCount,
                options: normalizeAnimationOptions(metadata.options)
            };
        };
        AnimationAstBuilderVisitor.prototype.visitSequence = function (metadata, context) {
            var _this = this;
            return {
                type: 2 /* Sequence */,
                steps: metadata.steps.map(function (s) { return visitDslNode(_this, s, context); }),
                options: normalizeAnimationOptions(metadata.options)
            };
        };
        AnimationAstBuilderVisitor.prototype.visitGroup = function (metadata, context) {
            var _this = this;
            var currentTime = context.currentTime;
            var furthestTime = 0;
            var steps = metadata.steps.map(function (step) {
                context.currentTime = currentTime;
                var innerAst = visitDslNode(_this, step, context);
                furthestTime = Math.max(furthestTime, context.currentTime);
                return innerAst;
            });
            context.currentTime = furthestTime;
            return {
                type: 3 /* Group */,
                steps: steps,
                options: normalizeAnimationOptions(metadata.options)
            };
        };
        AnimationAstBuilderVisitor.prototype.visitAnimate = function (metadata, context) {
            var timingAst = constructTimingAst(metadata.timings, context.errors);
            context.currentAnimateTimings = timingAst;
            var styleAst;
            var styleMetadata = metadata.styles ? metadata.styles : animations.style({});
            if (styleMetadata.type == 5 /* Keyframes */) {
                styleAst = this.visitKeyframes(styleMetadata, context);
            }
            else {
                var styleMetadata_1 = metadata.styles;
                var isEmpty = false;
                if (!styleMetadata_1) {
                    isEmpty = true;
                    var newStyleData = {};
                    if (timingAst.easing) {
                        newStyleData['easing'] = timingAst.easing;
                    }
                    styleMetadata_1 = animations.style(newStyleData);
                }
                context.currentTime += timingAst.duration + timingAst.delay;
                var _styleAst = this.visitStyle(styleMetadata_1, context);
                _styleAst.isEmptyStep = isEmpty;
                styleAst = _styleAst;
            }
            context.currentAnimateTimings = null;
            return {
                type: 4 /* Animate */,
                timings: timingAst,
                style: styleAst,
                options: null
            };
        };
        AnimationAstBuilderVisitor.prototype.visitStyle = function (metadata, context) {
            var ast = this._makeStyleAst(metadata, context);
            this._validateStyleAst(ast, context);
            return ast;
        };
        AnimationAstBuilderVisitor.prototype._makeStyleAst = function (metadata, context) {
            var styles = [];
            if (Array.isArray(metadata.styles)) {
                metadata.styles.forEach(function (styleTuple) {
                    if (typeof styleTuple == 'string') {
                        if (styleTuple == animations.AUTO_STYLE) {
                            styles.push(styleTuple);
                        }
                        else {
                            context.errors.push("The provided style string value " + styleTuple + " is not allowed.");
                        }
                    }
                    else {
                        styles.push(styleTuple);
                    }
                });
            }
            else {
                styles.push(metadata.styles);
            }
            var containsDynamicStyles = false;
            var collectedEasing = null;
            styles.forEach(function (styleData) {
                if (isObject(styleData)) {
                    var styleMap = styleData;
                    var easing = styleMap['easing'];
                    if (easing) {
                        collectedEasing = easing;
                        delete styleMap['easing'];
                    }
                    if (!containsDynamicStyles) {
                        for (var prop in styleMap) {
                            var value = styleMap[prop];
                            if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
                                containsDynamicStyles = true;
                                break;
                            }
                        }
                    }
                }
            });
            return {
                type: 6 /* Style */,
                styles: styles,
                easing: collectedEasing,
                offset: metadata.offset,
                containsDynamicStyles: containsDynamicStyles,
                options: null
            };
        };
        AnimationAstBuilderVisitor.prototype._validateStyleAst = function (ast, context) {
            var _this = this;
            var timings = context.currentAnimateTimings;
            var endTime = context.currentTime;
            var startTime = context.currentTime;
            if (timings && startTime > 0) {
                startTime -= timings.duration + timings.delay;
            }
            ast.styles.forEach(function (tuple) {
                if (typeof tuple == 'string')
                    return;
                Object.keys(tuple).forEach(function (prop) {
                    if (!_this._driver.validateStyleProperty(prop)) {
                        context.errors.push("The provided animation property \"" + prop + "\" is not a supported CSS property for animations");
                        return;
                    }
                    var collectedStyles = context.collectedStyles[context.currentQuerySelector];
                    var collectedEntry = collectedStyles[prop];
                    var updateCollectedStyle = true;
                    if (collectedEntry) {
                        if (startTime != endTime && startTime >= collectedEntry.startTime &&
                            endTime <= collectedEntry.endTime) {
                            context.errors.push("The CSS property \"" + prop + "\" that exists between the times of \"" + collectedEntry.startTime + "ms\" and \"" + collectedEntry
                                .endTime + "ms\" is also being animated in a parallel animation between the times of \"" + startTime + "ms\" and \"" + endTime + "ms\"");
                            updateCollectedStyle = false;
                        }
                        // we always choose the smaller start time value since we
                        // want to have a record of the entire animation window where
                        // the style property is being animated in between
                        startTime = collectedEntry.startTime;
                    }
                    if (updateCollectedStyle) {
                        collectedStyles[prop] = { startTime: startTime, endTime: endTime };
                    }
                    if (context.options) {
                        validateStyleParams(tuple[prop], context.options, context.errors);
                    }
                });
            });
        };
        AnimationAstBuilderVisitor.prototype.visitKeyframes = function (metadata, context) {
            var _this = this;
            var ast = { type: 5 /* Keyframes */, styles: [], options: null };
            if (!context.currentAnimateTimings) {
                context.errors.push("keyframes() must be placed inside of a call to animate()");
                return ast;
            }
            var MAX_KEYFRAME_OFFSET = 1;
            var totalKeyframesWithOffsets = 0;
            var offsets = [];
            var offsetsOutOfOrder = false;
            var keyframesOutOfRange = false;
            var previousOffset = 0;
            var keyframes = metadata.steps.map(function (styles) {
                var style = _this._makeStyleAst(styles, context);
                var offsetVal = style.offset != null ? style.offset : consumeOffset(style.styles);
                var offset = 0;
                if (offsetVal != null) {
                    totalKeyframesWithOffsets++;
                    offset = style.offset = offsetVal;
                }
                keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1;
                offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset;
                previousOffset = offset;
                offsets.push(offset);
                return style;
            });
            if (keyframesOutOfRange) {
                context.errors.push("Please ensure that all keyframe offsets are between 0 and 1");
            }
            if (offsetsOutOfOrder) {
                context.errors.push("Please ensure that all keyframe offsets are in order");
            }
            var length = metadata.steps.length;
            var generatedOffset = 0;
            if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) {
                context.errors.push("Not all style() steps within the declared keyframes() contain offsets");
            }
            else if (totalKeyframesWithOffsets == 0) {
                generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1);
            }
            var limit = length - 1;
            var currentTime = context.currentTime;
            var currentAnimateTimings = context.currentAnimateTimings;
            var animateDuration = currentAnimateTimings.duration;
            keyframes.forEach(function (kf, i) {
                var offset = generatedOffset > 0 ? (i == limit ? 1 : (generatedOffset * i)) : offsets[i];
                var durationUpToThisFrame = offset * animateDuration;
                context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame;
                currentAnimateTimings.duration = durationUpToThisFrame;
                _this._validateStyleAst(kf, context);
                kf.offset = offset;
                ast.styles.push(kf);
            });
            return ast;
        };
        AnimationAstBuilderVisitor.prototype.visitReference = function (metadata, context) {
            return {
                type: 8 /* Reference */,
                animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
                options: normalizeAnimationOptions(metadata.options)
            };
        };
        AnimationAstBuilderVisitor.prototype.visitAnimateChild = function (metadata, context) {
            context.depCount++;
            return {
                type: 9 /* AnimateChild */,
                options: normalizeAnimationOptions(metadata.options)
            };
        };
        AnimationAstBuilderVisitor.prototype.visitAnimateRef = function (metadata, context) {
            return {
                type: 10 /* AnimateRef */,
                animation: this.visitReference(metadata.animation, context),
                options: normalizeAnimationOptions(metadata.options)
            };
        };
        AnimationAstBuilderVisitor.prototype.visitQuery = function (metadata, context) {
            var parentSelector = context.currentQuerySelector;
            var options = (metadata.options || {});
            context.queryCount++;
            context.currentQuery = metadata;
            var _a = __read(normalizeSelector(metadata.selector), 2), selector = _a[0], includeSelf = _a[1];
            context.currentQuerySelector =
                parentSelector.length ? (parentSelector + ' ' + selector) : selector;
            getOrSetAsInMap(context.collectedStyles, context.currentQuerySelector, {});
            var animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
            context.currentQuery = null;
            context.currentQuerySelector = parentSelector;
            return {
                type: 11 /* Query */,
                selector: selector,
                limit: options.limit || 0,
                optional: !!options.optional,
                includeSelf: includeSelf,
                animation: animation,
                originalSelector: metadata.selector,
                options: normalizeAnimationOptions(metadata.options)
            };
        };
        AnimationAstBuilderVisitor.prototype.visitStagger = function (metadata, context) {
            if (!context.currentQuery) {
                context.errors.push("stagger() can only be used inside of query()");
            }
            var timings = metadata.timings === 'full' ?
                { duration: 0, delay: 0, easing: 'full' } :
                resolveTiming(metadata.timings, context.errors, true);
            return {
                type: 12 /* Stagger */,
                animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
                timings: timings,
                options: null
            };
        };
        return AnimationAstBuilderVisitor;
    }());
    function normalizeSelector(selector) {
        var hasAmpersand = selector.split(/\s*,\s*/).find(function (token) { return token == SELF_TOKEN; }) ? true : false;
        if (hasAmpersand) {
            selector = selector.replace(SELF_TOKEN_REGEX, '');
        }
        // the :enter and :leave selectors are filled in at runtime during timeline building
        selector = selector.replace(/@\*/g, NG_TRIGGER_SELECTOR)
            .replace(/@\w+/g, function (match) { return NG_TRIGGER_SELECTOR + '-' + match.substr(1); })
            .replace(/:animating/g, NG_ANIMATING_SELECTOR);
        return [selector, hasAmpersand];
    }
    function normalizeParams(obj) {
        return obj ? copyObj(obj) : null;
    }
    var AnimationAstBuilderContext = /** @class */ (function () {
        function AnimationAstBuilderContext(errors) {
            this.errors = errors;
            this.queryCount = 0;
            this.depCount = 0;
            this.currentTransition = null;
            this.currentQuery = null;
            this.currentQuerySelector = null;
            this.currentAnimateTimings = null;
            this.currentTime = 0;
            this.collectedStyles = {};
            this.options = null;
        }
        return AnimationAstBuilderContext;
    }());
    function consumeOffset(styles) {
        if (typeof styles == 'string')
            return null;
        var offset = null;
        if (Array.isArray(styles)) {
            styles.forEach(function (styleTuple) {
                if (isObject(styleTuple) && styleTuple.hasOwnProperty('offset')) {
                    var obj = styleTuple;
                    offset = parseFloat(obj['offset']);
                    delete obj['offset'];
                }
            });
        }
        else if (isObject(styles) && styles.hasOwnProperty('offset')) {
            var obj = styles;
            offset = parseFloat(obj['offset']);
            delete obj['offset'];
        }
        return offset;
    }
    function isObject(value) {
        return !Array.isArray(value) && typeof value == 'object';
    }
    function constructTimingAst(value, errors) {
        var timings = null;
        if (value.hasOwnProperty('duration')) {
            timings = value;
        }
        else if (typeof value == 'number') {
            var duration = resolveTiming(value, errors).duration;
            return makeTimingAst(duration, 0, '');
        }
        var strValue = value;
        var isDynamic = strValue.split(/\s+/).some(function (v) { return v.charAt(0) == '{' && v.charAt(1) == '{'; });
        if (isDynamic) {
            var ast = makeTimingAst(0, 0, '');
            ast.dynamic = true;
            ast.strValue = strValue;
            return ast;
        }
        timings = timings || resolveTiming(strValue, errors);
        return makeTimingAst(timings.duration, timings.delay, timings.easing);
    }
    function normalizeAnimationOptions(options) {
        if (options) {
            options = copyObj(options);
            if (options['params']) {
                options['params'] = normalizeParams(options['params']);
            }
        }
        else {
            options = {};
        }
        return options;
    }
    function makeTimingAst(duration, delay, easing) {
        return { duration: duration, delay: delay, easing: easing };
    }

    function createTimelineInstruction(element, keyframes, preStyleProps, postStyleProps, duration, delay, easing, subTimeline) {
        if (easing === void 0) { easing = null; }
        if (subTimeline === void 0) { subTimeline = false; }
        return {
            type: 1 /* TimelineAnimation */,
            element: element,
            keyframes: keyframes,
            preStyleProps: preStyleProps,
            postStyleProps: postStyleProps,
            duration: duration,
            delay: delay,
            totalTime: duration + delay,
            easing: easing,
            subTimeline: subTimeline
        };
    }

    var ElementInstructionMap = /** @class */ (function () {
        function ElementInstructionMap() {
            this._map = new Map();
        }
        ElementInstructionMap.prototype.consume = function (element) {
            var instructions = this._map.get(element);
            if (instructions) {
                this._map.delete(element);
            }
            else {
                instructions = [];
            }
            return instructions;
        };
        ElementInstructionMap.prototype.append = function (element, instructions) {
            var existingInstructions = this._map.get(element);
            if (!existingInstructions) {
                this._map.set(element, existingInstructions = []);
            }
            existingInstructions.push.apply(existingInstructions, __spread(instructions));
        };
        ElementInstructionMap.prototype.has = function (element) {
            return this._map.has(element);
        };
        ElementInstructionMap.prototype.clear = function () {
            this._map.clear();
        };
        return ElementInstructionMap;
    }());

    var ONE_FRAME_IN_MILLISECONDS = 1;
    var ENTER_TOKEN = ':enter';
    var ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g');
    var LEAVE_TOKEN = ':leave';
    var LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
    /*
     * The code within this file aims to generate web-animations-compatible keyframes from Angular's
     * animation DSL code.
     *
     * The code below will be converted from:
     *
     * ```
     * sequence([
     *   style({ opacity: 0 }),
     *   animate(1000, style({ opacity: 0 }))
     * ])
     * ```
     *
     * To:
     * ```
     * keyframes = [{ opacity: 0, offset: 0 }, { opacity: 1, offset: 1 }]
     * duration = 1000
     * delay = 0
     * easing = ''
     * ```
     *
     * For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
     * combination of prototypical inheritance, AST traversal and merge-sort-like algorithms are used.
     *
     * [AST Traversal]
     * Each of the animation verbs, when executed, will return an string-map object representing what
     * type of action it is (style, animate, group, etc...) and the data associated with it. This means
     * that when functional composition mix of these functions is evaluated (like in the example above)
     * then it will end up producing a tree of objects representing the animation itself.
     *
     * When this animation object tree is processed by the visitor code below it will visit each of the
     * verb statements within the visitor. And during each visit it will build the context of the
     * animation keyframes by interacting with the `TimelineBuilder`.
     *
     * [TimelineBuilder]
     * This class is responsible for tracking the styles and building a series of keyframe objects for a
     * timeline between a start and end time. The builder starts off with an initial timeline and each
     * time the AST comes across a `group()`, `keyframes()` or a combination of the two wihtin a
     * `sequence()` then it will generate a sub timeline for each step as well as a new one after
     * they are complete.
     *
     * As the AST is traversed, the timing state on each of the timelines will be incremented. If a sub
     * timeline was created (based on one of the cases above) then the parent timeline will attempt to
     * merge the styles used within the sub timelines into itself (only with group() this will happen).
     * This happens with a merge operation (much like how the merge works in mergesort) and it will only
     * copy the most recently used styles from the sub timelines into the parent timeline. This ensures
     * that if the styles are used later on in another phase of the animation then they will be the most
     * up-to-date values.
     *
     * [How Missing Styles Are Updated]
     * Each timeline has a `backFill` property which is responsible for filling in new styles into
     * already processed keyframes if a new style shows up later within the animation sequence.
     *
     * ```
     * sequence([
     *   style({ width: 0 }),
     *   animate(1000, style({ width: 100 })),
     *   animate(1000, style({ width: 200 })),
     *   animate(1000, style({ width: 300 }))
     *   animate(1000, style({ width: 400, height: 400 })) // notice how `height` doesn't exist anywhere
     * else
     * ])
     * ```
     *
     * What is happening here is that the `height` value is added later in the sequence, but is missing
     * from all previous animation steps. Therefore when a keyframe is created it would also be missing
     * from all previous keyframes up until where it is first used. For the timeline keyframe generation
     * to properly fill in the style it will place the previous value (the value from the parent
     * timeline) or a default value of `*` into the backFill object. Given that each of the keyframe
     * styles are objects that prototypically inhert from the backFill object, this means that if a
     * value is added into the backFill then it will automatically propagate any missing values to all
     * keyframes. Therefore the missing `height` value will be properly filled into the already
     * processed keyframes.
     *
     * When a sub-timeline is created it will have its own backFill property. This is done so that
     * styles present within the sub-timeline do not accidentally seep into the previous/future timeline
     * keyframes
     *
     * (For prototypically-inherited contents to be detected a `for(i in obj)` loop must be used.)
     *
     * [Validation]
     * The code in this file is not responsible for validation. That functionality happens with within
     * the `AnimationValidatorVisitor` code.
     */
    function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors) {
        if (startingStyles === void 0) { startingStyles = {}; }
        if (finalStyles === void 0) { finalStyles = {}; }
        if (errors === void 0) { errors = []; }
        return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
    }
    var AnimationTimelineBuilderVisitor = /** @class */ (function () {
        function AnimationTimelineBuilderVisitor() {
        }
        AnimationTimelineBuilderVisitor.prototype.buildKeyframes = function (driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors) {
            if (errors === void 0) { errors = []; }
            subInstructions = subInstructions || new ElementInstructionMap();
            var context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
            context.options = options;
            context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
            visitDslNode(this, ast, context);
            // this checks to see if an actual animation happened
            var timelines = context.timelines.filter(function (timeline) { return timeline.containsAnimation(); });
            if (timelines.length && Object.keys(finalStyles).length) {
                var tl = timelines[timelines.length - 1];
                if (!tl.allowOnlyTimelineStyles()) {
                    tl.setStyles([finalStyles], null, context.errors, options);
                }
            }
            return timelines.length ? timelines.map(function (timeline) { return timeline.buildKeyframes(); }) :
                [createTimelineInstruction(rootElement, [], [], [], 0, 0, '', false)];
        };
        AnimationTimelineBuilderVisitor.prototype.visitTrigger = function (ast, context) {
            // these values are not visited in this AST
        };
        AnimationTimelineBuilderVisitor.prototype.visitState = function (ast, context) {
            // these values are not visited in this AST
        };
        AnimationTimelineBuilderVisitor.prototype.visitTransition = function (ast, context) {
            // these values are not visited in this AST
        };
        AnimationTimelineBuilderVisitor.prototype.visitAnimateChild = function (ast, context) {
            var elementInstructions = context.subInstructions.consume(context.element);
            if (elementInstructions) {
                var innerContext = context.createSubContext(ast.options);
                var startTime = context.currentTimeline.currentTime;
                var endTime = this._visitSubInstructions(elementInstructions, innerContext, innerContext.options);
                if (startTime != endTime) {
                    // we do this on the upper context because we created a sub context for
                    // the sub child animations
                    context.transformIntoNewTimeline(endTime);
                }
            }
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype.visitAnimateRef = function (ast, context) {
            var innerContext = context.createSubContext(ast.options);
            innerContext.transformIntoNewTimeline();
            this.visitReference(ast.animation, innerContext);
            context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime);
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype._visitSubInstructions = function (instructions, context, options) {
            var startTime = context.currentTimeline.currentTime;
            var furthestTime = startTime;
            // this is a special-case for when a user wants to skip a sub
            // animation from being fired entirely.
            var duration = options.duration != null ? resolveTimingValue(options.duration) : null;
            var delay = options.delay != null ? resolveTimingValue(options.delay) : null;
            if (duration !== 0) {
                instructions.forEach(function (instruction) {
                    var instructionTimings = context.appendInstructionToTimeline(instruction, duration, delay);
                    furthestTime =
                        Math.max(furthestTime, instructionTimings.duration + instructionTimings.delay);
                });
            }
            return furthestTime;
        };
        AnimationTimelineBuilderVisitor.prototype.visitReference = function (ast, context) {
            context.updateOptions(ast.options, true);
            visitDslNode(this, ast.animation, context);
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype.visitSequence = function (ast, context) {
            var _this = this;
            var subContextCount = context.subContextCount;
            var ctx = context;
            var options = ast.options;
            if (options && (options.params || options.delay)) {
                ctx = context.createSubContext(options);
                ctx.transformIntoNewTimeline();
                if (options.delay != null) {
                    if (ctx.previousNode.type == 6 /* Style */) {
                        ctx.currentTimeline.snapshotCurrentStyles();
                        ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
                    }
                    var delay = resolveTimingValue(options.delay);
                    ctx.delayNextStep(delay);
                }
            }
            if (ast.steps.length) {
                ast.steps.forEach(function (s) { return visitDslNode(_this, s, ctx); });
                // this is here just incase the inner steps only contain or end with a style() call
                ctx.currentTimeline.applyStylesToKeyframe();
                // this means that some animation function within the sequence
                // ended up creating a sub timeline (which means the current
                // timeline cannot overlap with the contents of the sequence)
                if (ctx.subContextCount > subContextCount) {
                    ctx.transformIntoNewTimeline();
                }
            }
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype.visitGroup = function (ast, context) {
            var _this = this;
            var innerTimelines = [];
            var furthestTime = context.currentTimeline.currentTime;
            var delay = ast.options && ast.options.delay ? resolveTimingValue(ast.options.delay) : 0;
            ast.steps.forEach(function (s) {
                var innerContext = context.createSubContext(ast.options);
                if (delay) {
                    innerContext.delayNextStep(delay);
                }
                visitDslNode(_this, s, innerContext);
                furthestTime = Math.max(furthestTime, innerContext.currentTimeline.currentTime);
                innerTimelines.push(innerContext.currentTimeline);
            });
            // this operation is run after the AST loop because otherwise
            // if the parent timeline's collected styles were updated then
            // it would pass in invalid data into the new-to-be forked items
            innerTimelines.forEach(function (timeline) { return context.currentTimeline.mergeTimelineCollectedStyles(timeline); });
            context.transformIntoNewTimeline(furthestTime);
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype._visitTiming = function (ast, context) {
            if (ast.dynamic) {
                var strValue = ast.strValue;
                var timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue;
                return resolveTiming(timingValue, context.errors);
            }
            else {
                return { duration: ast.duration, delay: ast.delay, easing: ast.easing };
            }
        };
        AnimationTimelineBuilderVisitor.prototype.visitAnimate = function (ast, context) {
            var timings = context.currentAnimateTimings = this._visitTiming(ast.timings, context);
            var timeline = context.currentTimeline;
            if (timings.delay) {
                context.incrementTime(timings.delay);
                timeline.snapshotCurrentStyles();
            }
            var style = ast.style;
            if (style.type == 5 /* Keyframes */) {
                this.visitKeyframes(style, context);
            }
            else {
                context.incrementTime(timings.duration);
                this.visitStyle(style, context);
                timeline.applyStylesToKeyframe();
            }
            context.currentAnimateTimings = null;
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype.visitStyle = function (ast, context) {
            var timeline = context.currentTimeline;
            var timings = context.currentAnimateTimings;
            // this is a special case for when a style() call
            // directly follows  an animate() call (but not inside of an animate() call)
            if (!timings && timeline.getCurrentStyleProperties().length) {
                timeline.forwardFrame();
            }
            var easing = (timings && timings.easing) || ast.easing;
            if (ast.isEmptyStep) {
                timeline.applyEmptyStep(easing);
            }
            else {
                timeline.setStyles(ast.styles, easing, context.errors, context.options);
            }
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype.visitKeyframes = function (ast, context) {
            var currentAnimateTimings = context.currentAnimateTimings;
            var startTime = (context.currentTimeline).duration;
            var duration = currentAnimateTimings.duration;
            var innerContext = context.createSubContext();
            var innerTimeline = innerContext.currentTimeline;
            innerTimeline.easing = currentAnimateTimings.easing;
            ast.styles.forEach(function (step) {
                var offset = step.offset || 0;
                innerTimeline.forwardTime(offset * duration);
                innerTimeline.setStyles(step.styles, step.easing, context.errors, context.options);
                innerTimeline.applyStylesToKeyframe();
            });
            // this will ensure that the parent timeline gets all the styles from
            // the child even if the new timeline below is not used
            context.currentTimeline.mergeTimelineCollectedStyles(innerTimeline);
            // we do this because the window between this timeline and the sub timeline
            // should ensure that the styles within are exactly the same as they were before
            context.transformIntoNewTimeline(startTime + duration);
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype.visitQuery = function (ast, context) {
            var _this = this;
            // in the event that the first step before this is a style step we need
            // to ensure the styles are applied before the children are animated
            var startTime = context.currentTimeline.currentTime;
            var options = (ast.options || {});
            var delay = options.delay ? resolveTimingValue(options.delay) : 0;
            if (delay &&
                (context.previousNode.type === 6 /* Style */ ||
                    (startTime == 0 && context.currentTimeline.getCurrentStyleProperties().length))) {
                context.currentTimeline.snapshotCurrentStyles();
                context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
            }
            var furthestTime = startTime;
            var elms = context.invokeQuery(ast.selector, ast.originalSelector, ast.limit, ast.includeSelf, options.optional ? true : false, context.errors);
            context.currentQueryTotal = elms.length;
            var sameElementTimeline = null;
            elms.forEach(function (element, i) {
                context.currentQueryIndex = i;
                var innerContext = context.createSubContext(ast.options, element);
                if (delay) {
                    innerContext.delayNextStep(delay);
                }
                if (element === context.element) {
                    sameElementTimeline = innerContext.currentTimeline;
                }
                visitDslNode(_this, ast.animation, innerContext);
                // this is here just incase the inner steps only contain or end
                // with a style() call (which is here to signal that this is a preparatory
                // call to style an element before it is animated again)
                innerContext.currentTimeline.applyStylesToKeyframe();
                var endTime = innerContext.currentTimeline.currentTime;
                furthestTime = Math.max(furthestTime, endTime);
            });
            context.currentQueryIndex = 0;
            context.currentQueryTotal = 0;
            context.transformIntoNewTimeline(furthestTime);
            if (sameElementTimeline) {
                context.currentTimeline.mergeTimelineCollectedStyles(sameElementTimeline);
                context.currentTimeline.snapshotCurrentStyles();
            }
            context.previousNode = ast;
        };
        AnimationTimelineBuilderVisitor.prototype.visitStagger = function (ast, context) {
            var parentContext = context.parentContext;
            var tl = context.currentTimeline;
            var timings = ast.timings;
            var duration = Math.abs(timings.duration);
            var maxTime = duration * (context.currentQueryTotal - 1);
            var delay = duration * context.currentQueryIndex;
            var staggerTransformer = timings.duration < 0 ? 'reverse' : timings.easing;
            switch (staggerTransformer) {
                case 'reverse':
                    delay = maxTime - delay;
                    break;
                case 'full':
                    delay = parentContext.currentStaggerTime;
                    break;
            }
            var timeline = context.currentTimeline;
            if (delay) {
                timeline.delayNextStep(delay);
            }
            var startingTime = timeline.currentTime;
            visitDslNode(this, ast.animation, context);
            context.previousNode = ast;
            // time = duration + delay
            // the reason why this computation is so complex is because
            // the inner timeline may either have a delay value or a stretched
            // keyframe depending on if a subtimeline is not used or is used.
            parentContext.currentStaggerTime =
                (tl.currentTime - startingTime) + (tl.startTime - parentContext.currentTimeline.startTime);
        };
        return AnimationTimelineBuilderVisitor;
    }());
    var DEFAULT_NOOP_PREVIOUS_NODE = {};
    var AnimationTimelineContext = /** @class */ (function () {
        function AnimationTimelineContext(_driver, element, subInstructions, _enterClassName, _leaveClassName, errors, timelines, initialTimeline) {
            this._driver = _driver;
            this.element = element;
            this.subInstructions = subInstructions;
            this._enterClassName = _enterClassName;
            this._leaveClassName = _leaveClassName;
            this.errors = errors;
            this.timelines = timelines;
            this.parentContext = null;
            this.currentAnimateTimings = null;
            this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
            this.subContextCount = 0;
            this.options = {};
            this.currentQueryIndex = 0;
            this.currentQueryTotal = 0;
            this.currentStaggerTime = 0;
            this.currentTimeline = initialTimeline || new TimelineBuilder(this._driver, element, 0);
            timelines.push(this.currentTimeline);
        }
        Object.defineProperty(AnimationTimelineContext.prototype, "params", {
            get: function () {
                return this.options.params;
            },
            enumerable: false,
            configurable: true
        });
        AnimationTimelineContext.prototype.updateOptions = function (options, skipIfExists) {
            var _this = this;
            if (!options)
                return;
            var newOptions = options;
            var optionsToUpdate = this.options;
            // NOTE: this will get patched up when other animation methods support duration overrides
            if (newOptions.duration != null) {
                optionsToUpdate.duration = resolveTimingValue(newOptions.duration);
            }
            if (newOptions.delay != null) {
                optionsToUpdate.delay = resolveTimingValue(newOptions.delay);
            }
            var newParams = newOptions.params;
            if (newParams) {
                var paramsToUpdate_1 = optionsToUpdate.params;
                if (!paramsToUpdate_1) {
                    paramsToUpdate_1 = this.options.params = {};
                }
                Object.keys(newParams).forEach(function (name) {
                    if (!skipIfExists || !paramsToUpdate_1.hasOwnProperty(name)) {
                        paramsToUpdate_1[name] = interpolateParams(newParams[name], paramsToUpdate_1, _this.errors);
                    }
                });
            }
        };
        AnimationTimelineContext.prototype._copyOptions = function () {
            var options = {};
            if (this.options) {
                var oldParams_1 = this.options.params;
                if (oldParams_1) {
                    var params_1 = options['params'] = {};
                    Object.keys(oldParams_1).forEach(function (name) {
                        params_1[name] = oldParams_1[name];
                    });
                }
            }
            return options;
        };
        AnimationTimelineContext.prototype.createSubContext = function (options, element, newTime) {
            if (options === void 0) { options = null; }
            var target = element || this.element;
            var context = new AnimationTimelineContext(this._driver, target, this.subInstructions, this._enterClassName, this._leaveClassName, this.errors, this.timelines, this.currentTimeline.fork(target, newTime || 0));
            context.previousNode = this.previousNode;
            context.currentAnimateTimings = this.currentAnimateTimings;
            context.options = this._copyOptions();
            context.updateOptions(options);
            context.currentQueryIndex = this.currentQueryIndex;
            context.currentQueryTotal = this.currentQueryTotal;
            context.parentContext = this;
            this.subContextCount++;
            return context;
        };
        AnimationTimelineContext.prototype.transformIntoNewTimeline = function (newTime) {
            this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
            this.currentTimeline = this.currentTimeline.fork(this.element, newTime);
            this.timelines.push(this.currentTimeline);
            return this.currentTimeline;
        };
        AnimationTimelineContext.prototype.appendInstructionToTimeline = function (instruction, duration, delay) {
            var updatedTimings = {
                duration: duration != null ? duration : instruction.duration,
                delay: this.currentTimeline.currentTime + (delay != null ? delay : 0) + instruction.delay,
                easing: ''
            };
            var builder = new SubTimelineBuilder(this._driver, instruction.element, instruction.keyframes, instruction.preStyleProps, instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe);
            this.timelines.push(builder);
            return updatedTimings;
        };
        AnimationTimelineContext.prototype.incrementTime = function (time) {
            this.currentTimeline.forwardTime(this.currentTimeline.duration + time);
        };
        AnimationTimelineContext.prototype.delayNextStep = function (delay) {
            // negative delays are not yet supported
            if (delay > 0) {
                this.currentTimeline.delayNextStep(delay);
            }
        };
        AnimationTimelineContext.prototype.invokeQuery = function (selector, originalSelector, limit, includeSelf, optional, errors) {
            var results = [];
            if (includeSelf) {
                results.push(this.element);
            }
            if (selector.length > 0) { // if :self is only used then the selector is empty
                selector = selector.replace(ENTER_TOKEN_REGEX, '.' + this._enterClassName);
                selector = selector.replace(LEAVE_TOKEN_REGEX, '.' + this._leaveClassName);
                var multi = limit != 1;
                var elements = this._driver.query(this.element, selector, multi);
                if (limit !== 0) {
                    elements = limit < 0 ? elements.slice(elements.length + limit, elements.length) :
                        elements.slice(0, limit);
                }
                results.push.apply(results, __spread(elements));
            }
            if (!optional && results.length == 0) {
                errors.push("`query(\"" + originalSelector + "\")` returned zero elements. (Use `query(\"" + originalSelector + "\", { optional: true })` if you wish to allow this.)");
            }
            return results;
        };
        return AnimationTimelineContext;
    }());
    var TimelineBuilder = /** @class */ (function () {
        function TimelineBuilder(_driver, element, startTime, _elementTimelineStylesLookup) {
            this._driver = _driver;
            this.element = element;
            this.startTime = startTime;
            this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
            this.duration = 0;
            this._previousKeyframe = {};
            this._currentKeyframe = {};
            this._keyframes = new Map();
            this._styleSummary = {};
            this._pendingStyles = {};
            this._backFill = {};
            this._currentEmptyStepKeyframe = null;
            if (!this._elementTimelineStylesLookup) {
                this._elementTimelineStylesLookup = new Map();
            }
            this._localTimelineStyles = Object.create(this._backFill, {});
            this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);
            if (!this._globalTimelineStyles) {
                this._globalTimelineStyles = this._localTimelineStyles;
                this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);
            }
            this._loadKeyframe();
        }
        TimelineBuilder.prototype.containsAnimation = function () {
            switch (this._keyframes.size) {
                case 0:
                    return false;
                case 1:
                    return this.getCurrentStyleProperties().length > 0;
                default:
                    return true;
            }
        };
        TimelineBuilder.prototype.getCurrentStyleProperties = function () {
            return Object.keys(this._currentKeyframe);
        };
        Object.defineProperty(TimelineBuilder.prototype, "currentTime", {
            get: function () {
                return this.startTime + this.duration;
            },
            enumerable: false,
            configurable: true
        });
        TimelineBuilder.prototype.delayNextStep = function (delay) {
            // in the event that a style() step is placed right before a stagger()
            // and that style() step is the very first style() value in the animation
            // then we need to make a copy of the keyframe [0, copy, 1] so that the delay
            // properly applies the style() values to work with the stagger...
            var hasPreStyleStep = this._keyframes.size == 1 && Object.keys(this._pendingStyles).length;
            if (this.duration || hasPreStyleStep) {
                this.forwardTime(this.currentTime + delay);
                if (hasPreStyleStep) {
                    this.snapshotCurrentStyles();
                }
            }
            else {
                this.startTime += delay;
            }
        };
        TimelineBuilder.prototype.fork = function (element, currentTime) {
            this.applyStylesToKeyframe();
            return new TimelineBuilder(this._driver, element, currentTime || this.currentTime, this._elementTimelineStylesLookup);
        };
        TimelineBuilder.prototype._loadKeyframe = function () {
            if (this._currentKeyframe) {
                this._previousKeyframe = this._currentKeyframe;
            }
            this._currentKeyframe = this._keyframes.get(this.duration);
            if (!this._currentKeyframe) {
                this._currentKeyframe = Object.create(this._backFill, {});
                this._keyframes.set(this.duration, this._currentKeyframe);
            }
        };
        TimelineBuilder.prototype.forwardFrame = function () {
            this.duration += ONE_FRAME_IN_MILLISECONDS;
            this._loadKeyframe();
        };
        TimelineBuilder.prototype.forwardTime = function (time) {
            this.applyStylesToKeyframe();
            this.duration = time;
            this._loadKeyframe();
        };
        TimelineBuilder.prototype._updateStyle = function (prop, value) {
            this._localTimelineStyles[prop] = value;
            this._globalTimelineStyles[prop] = value;
            this._styleSummary[prop] = { time: this.currentTime, value: value };
        };
        TimelineBuilder.prototype.allowOnlyTimelineStyles = function () {
            return this._currentEmptyStepKeyframe !== this._currentKeyframe;
        };
        TimelineBuilder.prototype.applyEmptyStep = function (easing) {
            var _this = this;
            if (easing) {
                this._previousKeyframe['easing'] = easing;
            }
            // special case for animate(duration):
            // all missing styles are filled with a `*` value then
            // if any destination styles are filled in later on the same
            // keyframe then they will override the overridden styles
            // We use `_globalTimelineStyles` here because there may be
            // styles in previous keyframes that are not present in this timeline
            Object.keys(this._globalTimelineStyles).forEach(function (prop) {
                _this._backFill[prop] = _this._globalTimelineStyles[prop] || animations.AUTO_STYLE;
                _this._currentKeyframe[prop] = animations.AUTO_STYLE;
            });
            this._currentEmptyStepKeyframe = this._currentKeyframe;
        };
        TimelineBuilder.prototype.setStyles = function (input, easing, errors, options) {
            var _this = this;
            if (easing) {
                this._previousKeyframe['easing'] = easing;
            }
            var params = (options && options.params) || {};
            var styles = flattenStyles(input, this._globalTimelineStyles);
            Object.keys(styles).forEach(function (prop) {
                var val = interpolateParams(styles[prop], params, errors);
                _this._pendingStyles[prop] = val;
                if (!_this._localTimelineStyles.hasOwnProperty(prop)) {
                    _this._backFill[prop] = _this._globalTimelineStyles.hasOwnProperty(prop) ?
                        _this._globalTimelineStyles[prop] :
                        animations.AUTO_STYLE;
                }
                _this._updateStyle(prop, val);
            });
        };
        TimelineBuilder.prototype.applyStylesToKeyframe = function () {
            var _this = this;
            var styles = this._pendingStyles;
            var props = Object.keys(styles);
            if (props.length == 0)
                return;
            this._pendingStyles = {};
            props.forEach(function (prop) {
                var val = styles[prop];
                _this._currentKeyframe[prop] = val;
            });
            Object.keys(this._localTimelineStyles).forEach(function (prop) {
                if (!_this._currentKeyframe.hasOwnProperty(prop)) {
                    _this._currentKeyframe[prop] = _this._localTimelineStyles[prop];
                }
            });
        };
        TimelineBuilder.prototype.snapshotCurrentStyles = function () {
            var _this = this;
            Object.keys(this._localTimelineStyles).forEach(function (prop) {
                var val = _this._localTimelineStyles[prop];
                _this._pendingStyles[prop] = val;
                _this._updateStyle(prop, val);
            });
        };
        TimelineBuilder.prototype.getFinalKeyframe = function () {
            return this._keyframes.get(this.duration);
        };
        Object.defineProperty(TimelineBuilder.prototype, "properties", {
            get: function () {
                var properties = [];
                for (var prop in this._currentKeyframe) {
                    properties.push(prop);
                }
                return properties;
            },
            enumerable: false,
            configurable: true
        });
        TimelineBuilder.prototype.mergeTimelineCollectedStyles = function (timeline) {
            var _this = this;
            Object.keys(timeline._styleSummary).forEach(function (prop) {
                var details0 = _this._styleSummary[prop];
                var details1 = timeline._styleSummary[prop];
                if (!details0 || details1.time > details0.time) {
                    _this._updateStyle(prop, details1.value);
                }
            });
        };
        TimelineBuilder.prototype.buildKeyframes = function () {
            var _this = this;
            this.applyStylesToKeyframe();
            var preStyleProps = new Set();
            var postStyleProps = new Set();
            var isEmpty = this._keyframes.size === 1 && this.duration === 0;
            var finalKeyframes = [];
            this._keyframes.forEach(function (keyframe, time) {
                var finalKeyframe = copyStyles(keyframe, true);
                Object.keys(finalKeyframe).forEach(function (prop) {
                    var value = finalKeyframe[prop];
                    if (value == animations.ɵPRE_STYLE) {
                        preStyleProps.add(prop);
                    }
                    else if (value == animations.AUTO_STYLE) {
                        postStyleProps.add(prop);
                    }
                });
                if (!isEmpty) {
                    finalKeyframe['offset'] = time / _this.duration;
                }
                finalKeyframes.push(finalKeyframe);
            });
            var preProps = preStyleProps.size ? iteratorToArray(preStyleProps.values()) : [];
            var postProps = postStyleProps.size ? iteratorToArray(postStyleProps.values()) : [];
            // special case for a 0-second animation (which is designed just to place styles onscreen)
            if (isEmpty) {
                var kf0 = finalKeyframes[0];
                var kf1 = copyObj(kf0);
                kf0['offset'] = 0;
                kf1['offset'] = 1;
                finalKeyframes = [kf0, kf1];
            }
            return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
        };
        return TimelineBuilder;
    }());
    var SubTimelineBuilder = /** @class */ (function (_super) {
        __extends(SubTimelineBuilder, _super);
        function SubTimelineBuilder(driver, element, keyframes, preStyleProps, postStyleProps, timings, _stretchStartingKeyframe) {
            if (_stretchStartingKeyframe === void 0) { _stretchStartingKeyframe = false; }
            var _this = _super.call(this, driver, element, timings.delay) || this;
            _this.element = element;
            _this.keyframes = keyframes;
            _this.preStyleProps = preStyleProps;
            _this.postStyleProps = postStyleProps;
            _this._stretchStartingKeyframe = _stretchStartingKeyframe;
            _this.timings = { duration: timings.duration, delay: timings.delay, easing: timings.easing };
            return _this;
        }
        SubTimelineBuilder.prototype.containsAnimation = function () {
            return this.keyframes.length > 1;
        };
        SubTimelineBuilder.prototype.buildKeyframes = function () {
            var keyframes = this.keyframes;
            var _a = this.timings, delay = _a.delay, duration = _a.duration, easing = _a.easing;
            if (this._stretchStartingKeyframe && delay) {
                var newKeyframes = [];
                var totalTime = duration + delay;
                var startingGap = delay / totalTime;
                // the original starting keyframe now starts once the delay is done
                var newFirstKeyframe = copyStyles(keyframes[0], false);
                newFirstKeyframe['offset'] = 0;
                newKeyframes.push(newFirstKeyframe);
                var oldFirstKeyframe = copyStyles(keyframes[0], false);
                oldFirstKeyframe['offset'] = roundOffset(startingGap);
                newKeyframes.push(oldFirstKeyframe);
                /*
                  When the keyframe is stretched then it means that the delay before the animation
                  starts is gone. Instead the first keyframe is placed at the start of the animation
                  and it is then copied to where it starts when the original delay is over. This basically
                  means nothing animates during that delay, but the styles are still renderered. For this
                  to work the original offset values that exist in the original keyframes must be "warped"
                  so that they can take the new keyframe + delay into account.
          
                  delay=1000, duration=1000, keyframes = 0 .5 1
          
                  turns into
          
                  delay=0, duration=2000, keyframes = 0 .33 .66 1
                 */
                // offsets between 1 ... n -1 are all warped by the keyframe stretch
                var limit = keyframes.length - 1;
                for (var i = 1; i <= limit; i++) {
                    var kf = copyStyles(keyframes[i], false);
                    var oldOffset = kf['offset'];
                    var timeAtKeyframe = delay + oldOffset * duration;
                    kf['offset'] = roundOffset(timeAtKeyframe / totalTime);
                    newKeyframes.push(kf);
                }
                // the new starting keyframe should be added at the start
                duration = totalTime;
                delay = 0;
                easing = '';
                keyframes = newKeyframes;
            }
            return createTimelineInstruction(this.element, keyframes, this.preStyleProps, this.postStyleProps, duration, delay, easing, true);
        };
        return SubTimelineBuilder;
    }(TimelineBuilder));
    function roundOffset(offset, decimalPoints) {
        if (decimalPoints === void 0) { decimalPoints = 3; }
        var mult = Math.pow(10, decimalPoints - 1);
        return Math.round(offset * mult) / mult;
    }
    function flattenStyles(input, allStyles) {
        var styles = {};
        var allProperties;
        input.forEach(function (token) {
            if (token === '*') {
                allProperties = allProperties || Object.keys(allStyles);
                allProperties.forEach(function (prop) {
                    styles[prop] = animations.AUTO_STYLE;
                });
            }
            else {
                copyStyles(token, false, styles);
            }
        });
        return styles;
    }

    var Animation = /** @class */ (function () {
        function Animation(_driver, input) {
            this._driver = _driver;
            var errors = [];
            var ast = buildAnimationAst(_driver, input, errors);
            if (errors.length) {
                var errorMessage = "animation validation failed:\n" + errors.join('\n');
                throw new Error(errorMessage);
            }
            this._animationAst = ast;
        }
        Animation.prototype.buildTimelines = function (element, startingStyles, destinationStyles, options, subInstructions) {
            var start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) :
                startingStyles;
            var dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) :
                destinationStyles;
            var errors = [];
            subInstructions = subInstructions || new ElementInstructionMap();
            var result = buildAnimationTimelines(this._driver, element, this._animationAst, ENTER_CLASSNAME, LEAVE_CLASSNAME, start, dest, options, subInstructions, errors);
            if (errors.length) {
                var errorMessage = "animation building failed:\n" + errors.join('\n');
                throw new Error(errorMessage);
            }
            return result;
        };
        return Animation;
    }());

    /**
     * @license
     * Copyright Google LLC 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 AnimationStyleNormalizer = /** @class */ (function () {
        function AnimationStyleNormalizer() {
        }
        return AnimationStyleNormalizer;
    }());
    /**
     * @publicApi
     */
    var NoopAnimationStyleNormalizer = /** @class */ (function () {
        function NoopAnimationStyleNormalizer() {
        }
        NoopAnimationStyleNormalizer.prototype.normalizePropertyName = function (propertyName, errors) {
            return propertyName;
        };
        NoopAnimationStyleNormalizer.prototype.normalizeStyleValue = function (userProvidedProperty, normalizedProperty, value, errors) {
            return value;
        };
        return NoopAnimationStyleNormalizer;
    }());

    var WebAnimationsStyleNormalizer = /** @class */ (function (_super) {
        __extends(WebAnimationsStyleNormalizer, _super);
        function WebAnimationsStyleNormalizer() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        WebAnimationsStyleNormalizer.prototype.normalizePropertyName = function (propertyName, errors) {
            return dashCaseToCamelCase(propertyName);
        };
        WebAnimationsStyleNormalizer.prototype.normalizeStyleValue = function (userProvidedProperty, normalizedProperty, value, errors) {
            var unit = '';
            var strVal = value.toString().trim();
            if (DIMENSIONAL_PROP_MAP[normalizedProperty] && value !== 0 && value !== '0') {
                if (typeof value === 'number') {
                    unit = 'px';
                }
                else {
                    var valAndSuffixMatch = value.match(/^[+-]?[\d\.]+([a-z]*)$/);
                    if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) {
                        errors.push("Please provide a CSS unit value for " + userProvidedProperty + ":" + value);
                    }
                }
            }
            return strVal + unit;
        };
        return WebAnimationsStyleNormalizer;
    }(AnimationStyleNormalizer));
    var ɵ0$1 = function () { return makeBooleanMap('width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective'
        .split(',')); };
    var DIMENSIONAL_PROP_MAP = (ɵ0$1)();
    function makeBooleanMap(keys) {
        var map = {};
        keys.forEach(function (key) { return map[key] = true; });
        return map;
    }

    function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {
        return {
            type: 0 /* TransitionAnimation */,
            element: element,
            triggerName: triggerName,
            isRemovalTransition: isRemovalTransition,
            fromState: fromState,
            fromStyles: fromStyles,
            toState: toState,
            toStyles: toStyles,
            timelines: timelines,
            queriedElements: queriedElements,
            preStyleProps: preStyleProps,
            postStyleProps: postStyleProps,
            totalTime: totalTime,
            errors: errors
        };
    }

    var EMPTY_OBJECT = {};
    var AnimationTransitionFactory = /** @class */ (function () {
        function AnimationTransitionFactory(_triggerName, ast, _stateStyles) {
            this._triggerName = _triggerName;
            this.ast = ast;
            this._stateStyles = _stateStyles;
        }
        AnimationTransitionFactory.prototype.match = function (currentState, nextState, element, params) {
            return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);
        };
        AnimationTransitionFactory.prototype.buildStyles = function (stateName, params, errors) {
            var backupStateStyler = this._stateStyles['*'];
            var stateStyler = this._stateStyles[stateName];
            var backupStyles = backupStateStyler ? backupStateStyler.buildStyles(params, errors) : {};
            return stateStyler ? stateStyler.buildStyles(params, errors) : backupStyles;
        };
        AnimationTransitionFactory.prototype.build = function (driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions, skipAstBuild) {
            var errors = [];
            var transitionAnimationParams = this.ast.options && this.ast.options.params || EMPTY_OBJECT;
            var currentAnimationParams = currentOptions && currentOptions.params || EMPTY_OBJECT;
            var currentStateStyles = this.buildStyles(currentState, currentAnimationParams, errors);
            var nextAnimationParams = nextOptions && nextOptions.params || EMPTY_OBJECT;
            var nextStateStyles = this.buildStyles(nextState, nextAnimationParams, errors);
            var queriedElements = new Set();
            var preStyleMap = new Map();
            var postStyleMap = new Map();
            var isRemoval = nextState === 'void';
            var animationOptions = { params: Object.assign(Object.assign({}, transitionAnimationParams), nextAnimationParams) };
            var timelines = skipAstBuild ?
                [] :
                buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
            var totalTime = 0;
            timelines.forEach(function (tl) {
                totalTime = Math.max(tl.duration + tl.delay, totalTime);
            });
            if (errors.length) {
                return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, [], [], preStyleMap, postStyleMap, totalTime, errors);
            }
            timelines.forEach(function (tl) {
                var elm = tl.element;
                var preProps = getOrSetAsInMap(preStyleMap, elm, {});
                tl.preStyleProps.forEach(function (prop) { return preProps[prop] = true; });
                var postProps = getOrSetAsInMap(postStyleMap, elm, {});
                tl.postStyleProps.forEach(function (prop) { return postProps[prop] = true; });
                if (elm !== element) {
                    queriedElements.add(elm);
                }
            });
            var queriedElementsList = iteratorToArray(queriedElements.values());
            return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, timelines, queriedElementsList, preStyleMap, postStyleMap, totalTime);
        };
        return AnimationTransitionFactory;
    }());
    function oneOrMoreTransitionsMatch(matchFns, currentState, nextState, element, params) {
        return matchFns.some(function (fn) { return fn(currentState, nextState, element, params); });
    }
    var AnimationStateStyles = /** @class */ (function () {
        function AnimationStateStyles(styles, defaultParams) {
            this.styles = styles;
            this.defaultParams = defaultParams;
        }
        AnimationStateStyles.prototype.buildStyles = function (params, errors) {
            var finalStyles = {};
            var combinedParams = copyObj(this.defaultParams);
            Object.keys(params).forEach(function (key) {
                var value = params[key];
                if (value != null) {
                    combinedParams[key] = value;
                }
            });
            this.styles.styles.forEach(function (value) {
                if (typeof value !== 'string') {
                    var styleObj_1 = value;
                    Object.keys(styleObj_1).forEach(function (prop) {
                        var val = styleObj_1[prop];
                        if (val.length > 1) {
                            val = interpolateParams(val, combinedParams, errors);
                        }
                        finalStyles[prop] = val;
                    });
                }
            });
            return finalStyles;
        };
        return AnimationStateStyles;
    }());

    /**
     * @publicApi
     */
    function buildTrigger(name, ast) {
        return new AnimationTrigger(name, ast);
    }
    /**
     * @publicApi
     */
    var AnimationTrigger = /** @class */ (function () {
        function AnimationTrigger(name, ast) {
            var _this = this;
            this.name = name;
            this.ast = ast;
            this.transitionFactories = [];
            this.states = {};
            ast.states.forEach(function (ast) {
                var defaultParams = (ast.options && ast.options.params) || {};
                _this.states[ast.name] = new AnimationStateStyles(ast.style, defaultParams);
            });
            balanceProperties(this.states, 'true', '1');
            balanceProperties(this.states, 'false', '0');
            ast.transitions.forEach(function (ast) {
                _this.transitionFactories.push(new AnimationTransitionFactory(name, ast, _this.states));
            });
            this.fallbackTransition = createFallbackTransition(name, this.states);
        }
        Object.defineProperty(AnimationTrigger.prototype, "containsQueries", {
            get: function () {
                return this.ast.queryCount > 0;
            },
            enumerable: false,
            configurable: true
        });
        AnimationTrigger.prototype.matchTransition = function (currentState, nextState, element, params) {
            var entry = this.transitionFactories.find(function (f) { return f.match(currentState, nextState, element, params); });
            return entry || null;
        };
        AnimationTrigger.prototype.matchStyles = function (currentState, params, errors) {
            return this.fallbackTransition.buildStyles(currentState, params, errors);
        };
        return AnimationTrigger;
    }());
    function createFallbackTransition(triggerName, states) {
        var matchers = [function (fromState, toState) { return true; }];
        var animation = { type: 2 /* Sequence */, steps: [], options: null };
        var transition = {
            type: 1 /* Transition */,
            animation: animation,
            matchers: matchers,
            options: null,
            queryCount: 0,
            depCount: 0
        };
        return new AnimationTransitionFactory(triggerName, transition, states);
    }
    function balanceProperties(obj, key1, key2) {
        if (obj.hasOwnProperty(key1)) {
            if (!obj.hasOwnProperty(key2)) {
                obj[key2] = obj[key1];
            }
        }
        else if (obj.hasOwnProperty(key2)) {
            obj[key1] = obj[key2];
        }
    }

    /**
     * @license
     * Copyright Google LLC 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_INSTRUCTION_MAP = new ElementInstructionMap();
    var TimelineAnimationEngine = /** @class */ (function () {
        function TimelineAnimationEngine(bodyNode, _driver, _normalizer) {
            this.bodyNode = bodyNode;
            this._driver = _driver;
            this._normalizer = _normalizer;
            this._animations = {};
            this._playersById = {};
            this.players = [];
        }
        TimelineAnimationEngine.prototype.register = function (id, metadata) {
            var errors = [];
            var ast = buildAnimationAst(this._driver, metadata, errors);
            if (errors.length) {
                throw new Error("Unable to build the animation due to the following errors: " + errors.join('\n'));
            }
            else {
                this._animations[id] = ast;
            }
        };
        TimelineAnimationEngine.prototype._buildPlayer = function (i, preStyles, postStyles) {
            var element = i.element;
            var keyframes = normalizeKeyframes(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
            return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);
        };
        TimelineAnimationEngine.prototype.create = function (id, element, options) {
            var _this = this;
            if (options === void 0) { options = {}; }
            var errors = [];
            var ast = this._animations[id];
            var instructions;
            var autoStylesMap = new Map();
            if (ast) {
                instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, {}, {}, options, EMPTY_INSTRUCTION_MAP, errors);
                instructions.forEach(function (inst) {
                    var styles = getOrSetAsInMap(autoStylesMap, inst.element, {});
                    inst.postStyleProps.forEach(function (prop) { return styles[prop] = null; });
                });
            }
            else {
                errors.push('The requested animation doesn\'t exist or has already been destroyed');
                instructions = [];
            }
            if (errors.length) {
                throw new Error("Unable to create the animation due to the following errors: " + errors.join('\n'));
            }
            autoStylesMap.forEach(function (styles, element) {
                Object.keys(styles).forEach(function (prop) {
                    styles[prop] = _this._driver.computeStyle(element, prop, animations.AUTO_STYLE);
                });
            });
            var players = instructions.map(function (i) {
                var styles = autoStylesMap.get(i.element);
                return _this._buildPlayer(i, {}, styles);
            });
            var player = optimizeGroupPlayer(players);
            this._playersById[id] = player;
            player.onDestroy(function () { return _this.destroy(id); });
            this.players.push(player);
            return player;
        };
        TimelineAnimationEngine.prototype.destroy = function (id) {
            var player = this._getPlayer(id);
            player.destroy();
            delete this._playersById[id];
            var index = this.players.indexOf(player);
            if (index >= 0) {
                this.players.splice(index, 1);
            }
        };
        TimelineAnimationEngine.prototype._getPlayer = function (id) {
            var player = this._playersById[id];
            if (!player) {
                throw new Error("Unable to find the timeline player referenced by " + id);
            }
            return player;
        };
        TimelineAnimationEngine.prototype.listen = function (id, element, eventName, callback) {
            // triggerName, fromState, toState are all ignored for timeline animations
            var baseEvent = makeAnimationEvent(element, '', '', '');
            listenOnPlayer(this._getPlayer(id), eventName, baseEvent, callback);
            return function () { };
        };
        TimelineAnimationEngine.prototype.command = function (id, element, command, args) {
            if (command == 'register') {
                this.register(id, args[0]);
                return;
            }
            if (command == 'create') {
                var options = (args[0] || {});
                this.create(id, element, options);
                return;
            }
            var player = this._getPlayer(id);
            switch (command) {
                case 'play':
                    player.play();
                    break;
                case 'pause':
                    player.pause();
                    break;
                case 'reset':
                    player.reset();
                    break;
                case 'restart':
                    player.restart();
                    break;
                case 'finish':
                    player.finish();
                    break;
                case 'init':
                    player.init();
                    break;
                case 'setPosition':
                    player.setPosition(parseFloat(args[0]));
                    break;
                case 'destroy':
                    this.destroy(id);
                    break;
            }
        };
        return TimelineAnimationEngine;
    }());

    var QUEUED_CLASSNAME = 'ng-animate-queued';
    var QUEUED_SELECTOR = '.ng-animate-queued';
    var DISABLED_CLASSNAME = 'ng-animate-disabled';
    var DISABLED_SELECTOR = '.ng-animate-disabled';
    var STAR_CLASSNAME = 'ng-star-inserted';
    var STAR_SELECTOR = '.ng-star-inserted';
    var EMPTY_PLAYER_ARRAY = [];
    var NULL_REMOVAL_STATE = {
        namespaceId: '',
        setForRemoval: false,
        setForMove: false,
        hasAnimation: false,
        removedBeforeQueried: false
    };
    var NULL_REMOVED_QUERIED_STATE = {
        namespaceId: '',
        setForMove: false,
        setForRemoval: false,
        hasAnimation: false,
        removedBeforeQueried: true
    };
    var REMOVAL_FLAG = '__ng_removed';
    var StateValue = /** @class */ (function () {
        function StateValue(input, namespaceId) {
            if (namespaceId === void 0) { namespaceId = ''; }
            this.namespaceId = namespaceId;
            var isObj = input && input.hasOwnProperty('value');
            var value = isObj ? input['value'] : input;
            this.value = normalizeTriggerValue(value);
            if (isObj) {
                var options = copyObj(input);
                delete options['value'];
                this.options = options;
            }
            else {
                this.options = {};
            }
            if (!this.options.params) {
                this.options.params = {};
            }
        }
        Object.defineProperty(StateValue.prototype, "params", {
            get: function () {
                return this.options.params;
            },
            enumerable: false,
            configurable: true
        });
        StateValue.prototype.absorbOptions = function (options) {
            var newParams = options.params;
            if (newParams) {
                var oldParams_1 = this.options.params;
                Object.keys(newParams).forEach(function (prop) {
                    if (oldParams_1[prop] == null) {
                        oldParams_1[prop] = newParams[prop];
                    }
                });
            }
        };
        return StateValue;
    }());
    var VOID_VALUE = 'void';
    var DEFAULT_STATE_VALUE = new StateValue(VOID_VALUE);
    var AnimationTransitionNamespace = /** @class */ (function () {
        function AnimationTransitionNamespace(id, hostElement, _engine) {
            this.id = id;
            this.hostElement = hostElement;
            this._engine = _engine;
            this.players = [];
            this._triggers = {};
            this._queue = [];
            this._elementListeners = new Map();
            this._hostClassName = 'ng-tns-' + id;
            addClass(hostElement, this._hostClassName);
        }
        AnimationTransitionNamespace.prototype.listen = function (element, name, phase, callback) {
            var _this = this;
            if (!this._triggers.hasOwnProperty(name)) {
                throw new Error("Unable to listen on the animation trigger event \"" + phase + "\" because the animation trigger \"" + name + "\" doesn't exist!");
            }
            if (phase == null || phase.length == 0) {
                throw new Error("Unable to listen on the animation trigger \"" + name + "\" because the provided event is undefined!");
            }
            if (!isTriggerEventValid(phase)) {
                throw new Error("The provided animation trigger event \"" + phase + "\" for the animation trigger \"" + name + "\" is not supported!");
            }
            var listeners = getOrSetAsInMap(this._elementListeners, element, []);
            var data = { name: name, phase: phase, callback: callback };
            listeners.push(data);
            var triggersWithStates = getOrSetAsInMap(this._engine.statesByElement, element, {});
            if (!triggersWithStates.hasOwnProperty(name)) {
                addClass(element, NG_TRIGGER_CLASSNAME);
                addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
                triggersWithStates[name] = DEFAULT_STATE_VALUE;
            }
            return function () {
                // the event listener is removed AFTER the flush has occurred such
                // that leave animations callbacks can fire (otherwise if the node
                // is removed in between then the listeners would be deregistered)
                _this._engine.afterFlush(function () {
                    var index = listeners.indexOf(data);
                    if (index >= 0) {
                        listeners.splice(index, 1);
                    }
                    if (!_this._triggers[name]) {
                        delete triggersWithStates[name];
                    }
                });
            };
        };
        AnimationTransitionNamespace.prototype.register = function (name, ast) {
            if (this._triggers[name]) {
                // throw
                return false;
            }
            else {
                this._triggers[name] = ast;
                return true;
            }
        };
        AnimationTransitionNamespace.prototype._getTrigger = function (name) {
            var trigger = this._triggers[name];
            if (!trigger) {
                throw new Error("The provided animation trigger \"" + name + "\" has not been registered!");
            }
            return trigger;
        };
        AnimationTransitionNamespace.prototype.trigger = function (element, triggerName, value, defaultToFallback) {
            var _this = this;
            if (defaultToFallback === void 0) { defaultToFallback = true; }
            var trigger = this._getTrigger(triggerName);
            var player = new TransitionAnimationPlayer(this.id, triggerName, element);
            var triggersWithStates = this._engine.statesByElement.get(element);
            if (!triggersWithStates) {
                addClass(element, NG_TRIGGER_CLASSNAME);
                addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
                this._engine.statesByElement.set(element, triggersWithStates = {});
            }
            var fromState = triggersWithStates[triggerName];
            var toState = new StateValue(value, this.id);
            var isObj = value && value.hasOwnProperty('value');
            if (!isObj && fromState) {
                toState.absorbOptions(fromState.options);
            }
            triggersWithStates[triggerName] = toState;
            if (!fromState) {
                fromState = DEFAULT_STATE_VALUE;
            }
            var isRemoval = toState.value === VOID_VALUE;
            // normally this isn't reached by here, however, if an object expression
            // is passed in then it may be a new object each time. Comparing the value
            // is important since that will stay the same despite there being a new object.
            // The removal arc here is special cased because the same element is triggered
            // twice in the event that it contains animations on the outer/inner portions
            // of the host container
            if (!isRemoval && fromState.value === toState.value) {
                // this means that despite the value not changing, some inner params
                // have changed which means that the animation final styles need to be applied
                if (!objEquals(fromState.params, toState.params)) {
                    var errors = [];
                    var fromStyles_1 = trigger.matchStyles(fromState.value, fromState.params, errors);
                    var toStyles_1 = trigger.matchStyles(toState.value, toState.params, errors);
                    if (errors.length) {
                        this._engine.reportError(errors);
                    }
                    else {
                        this._engine.afterFlush(function () {
                            eraseStyles(element, fromStyles_1);
                            setStyles(element, toStyles_1);
                        });
                    }
                }
                return;
            }
            var playersOnElement = getOrSetAsInMap(this._engine.playersByElement, element, []);
            playersOnElement.forEach(function (player) {
                // only remove the player if it is queued on the EXACT same trigger/namespace
                // we only also deal with queued players here because if the animation has
                // started then we want to keep the player alive until the flush happens
                // (which is where the previousPlayers are passed into the new palyer)
                if (player.namespaceId == _this.id && player.triggerName == triggerName && player.queued) {
                    player.destroy();
                }
            });
            var transition = trigger.matchTransition(fromState.value, toState.value, element, toState.params);
            var isFallbackTransition = false;
            if (!transition) {
                if (!defaultToFallback)
                    return;
                transition = trigger.fallbackTransition;
                isFallbackTransition = true;
            }
            this._engine.totalQueuedPlayers++;
            this._queue.push({ element: element, triggerName: triggerName, transition: transition, fromState: fromState, toState: toState, player: player, isFallbackTransition: isFallbackTransition });
            if (!isFallbackTransition) {
                addClass(element, QUEUED_CLASSNAME);
                player.onStart(function () {
                    removeClass(element, QUEUED_CLASSNAME);
                });
            }
            player.onDone(function () {
                var index = _this.players.indexOf(player);
                if (index >= 0) {
                    _this.players.splice(index, 1);
                }
                var players = _this._engine.playersByElement.get(element);
                if (players) {
                    var index_1 = players.indexOf(player);
                    if (index_1 >= 0) {
                        players.splice(index_1, 1);
                    }
                }
            });
            this.players.push(player);
            playersOnElement.push(player);
            return player;
        };
        AnimationTransitionNamespace.prototype.deregister = function (name) {
            var _this = this;
            delete this._triggers[name];
            this._engine.statesByElement.forEach(function (stateMap, element) {
                delete stateMap[name];
            });
            this._elementListeners.forEach(function (listeners, element) {
                _this._elementListeners.set(element, listeners.filter(function (entry) {
                    return entry.name != name;
                }));
            });
        };
        AnimationTransitionNamespace.prototype.clearElementCache = function (element) {
            this._engine.statesByElement.delete(element);
            this._elementListeners.delete(element);
            var elementPlayers = this._engine.playersByElement.get(element);
            if (elementPlayers) {
                elementPlayers.forEach(function (player) { return player.destroy(); });
                this._engine.playersByElement.delete(element);
            }
        };
        AnimationTransitionNamespace.prototype._signalRemovalForInnerTriggers = function (rootElement, context) {
            var _this = this;
            var elements = this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true);
            // emulate a leave animation for all inner nodes within this node.
            // If there are no animations found for any of the nodes then clear the cache
            // for the element.
            elements.forEach(function (elm) {
                // this means that an inner remove() operation has already kicked off
                // the animation on this element...
                if (elm[REMOVAL_FLAG])
                    return;
                var namespaces = _this._engine.fetchNamespacesByElement(elm);
                if (namespaces.size) {
                    namespaces.forEach(function (ns) { return ns.triggerLeaveAnimation(elm, context, false, true); });
                }
                else {
                    _this.clearElementCache(elm);
                }
            });
            // If the child elements were removed along with the parent, their animations might not
            // have completed. Clear all the elements from the cache so we don't end up with a memory leak.
            this._engine.afterFlushAnimationsDone(function () { return elements.forEach(function (elm) { return _this.clearElementCache(elm); }); });
        };
        AnimationTransitionNamespace.prototype.triggerLeaveAnimation = function (element, context, destroyAfterComplete, defaultToFallback) {
            var _this = this;
            var triggerStates = this._engine.statesByElement.get(element);
            if (triggerStates) {
                var players_1 = [];
                Object.keys(triggerStates).forEach(function (triggerName) {
                    // this check is here in the event that an element is removed
                    // twice (both on the host level and the component level)
                    if (_this._triggers[triggerName]) {
                        var player = _this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
                        if (player) {
                            players_1.push(player);
                        }
                    }
                });
                if (players_1.length) {
                    this._engine.markElementAsRemoved(this.id, element, true, context);
                    if (destroyAfterComplete) {
                        optimizeGroupPlayer(players_1).onDone(function () { return _this._engine.processLeaveNode(element); });
                    }
                    return true;
                }
            }
            return false;
        };
        AnimationTransitionNamespace.prototype.prepareLeaveAnimationListeners = function (element) {
            var _this = this;
            var listeners = this._elementListeners.get(element);
            var elementStates = this._engine.statesByElement.get(element);
            // if this statement fails then it means that the element was picked up
            // by an earlier flush (or there are no listeners at all to track the leave).
            if (listeners && elementStates) {
                var visitedTriggers_1 = new Set();
                listeners.forEach(function (listener) {
                    var triggerName = listener.name;
                    if (visitedTriggers_1.has(triggerName))
                        return;
                    visitedTriggers_1.add(triggerName);
                    var trigger = _this._triggers[triggerName];
                    var transition = trigger.fallbackTransition;
                    var fromState = elementStates[triggerName] || DEFAULT_STATE_VALUE;
                    var toState = new StateValue(VOID_VALUE);
                    var player = new TransitionAnimationPlayer(_this.id, triggerName, element);
                    _this._engine.totalQueuedPlayers++;
                    _this._queue.push({
                        element: element,
                        triggerName: triggerName,
                        transition: transition,
                        fromState: fromState,
                        toState: toState,
                        player: player,
                        isFallbackTransition: true
                    });
                });
            }
        };
        AnimationTransitionNamespace.prototype.removeNode = function (element, context) {
            var _this = this;
            var engine = this._engine;
            if (element.childElementCount) {
                this._signalRemovalForInnerTriggers(element, context);
            }
            // this means that a * => VOID animation was detected and kicked off
            if (this.triggerLeaveAnimation(element, context, true))
                return;
            // find the player that is animating and make sure that the
            // removal is delayed until that player has completed
            var containsPotentialParentTransition = false;
            if (engine.totalAnimations) {
                var currentPlayers = engine.players.length ? engine.playersByQueriedElement.get(element) : [];
                // when this `if statement` does not continue forward it means that
                // a previous animation query has selected the current element and
                // is animating it. In this situation want to continue forwards and
                // allow the element to be queued up for animation later.
                if (currentPlayers && currentPlayers.length) {
                    containsPotentialParentTransition = true;
                }
                else {
                    var parent = element;
                    while (parent = parent.parentNode) {
                        var triggers = engine.statesByElement.get(parent);
                        if (triggers) {
                            containsPotentialParentTransition = true;
                            break;
                        }
                    }
                }
            }
            // at this stage we know that the element will either get removed
            // during flush or will be picked up by a parent query. Either way
            // we need to fire the listeners for this element when it DOES get
            // removed (once the query parent animation is done or after flush)
            this.prepareLeaveAnimationListeners(element);
            // whether or not a parent has an animation we need to delay the deferral of the leave
            // operation until we have more information (which we do after flush() has been called)
            if (containsPotentialParentTransition) {
                engine.markElementAsRemoved(this.id, element, false, context);
            }
            else {
                var removalFlag = element[REMOVAL_FLAG];
                if (!removalFlag || removalFlag === NULL_REMOVAL_STATE) {
                    // we do this after the flush has occurred such
                    // that the callbacks can be fired
                    engine.afterFlush(function () { return _this.clearElementCache(element); });
                    engine.destroyInnerAnimations(element);
                    engine._onRemovalComplete(element, context);
                }
            }
        };
        AnimationTransitionNamespace.prototype.insertNode = function (element, parent) {
            addClass(element, this._hostClassName);
        };
        AnimationTransitionNamespace.prototype.drainQueuedTransitions = function (microtaskId) {
            var _this = this;
            var instructions = [];
            this._queue.forEach(function (entry) {
                var player = entry.player;
                if (player.destroyed)
                    return;
                var element = entry.element;
                var listeners = _this._elementListeners.get(element);
                if (listeners) {
                    listeners.forEach(function (listener) {
                        if (listener.name == entry.triggerName) {
                            var baseEvent = makeAnimationEvent(element, entry.triggerName, entry.fromState.value, entry.toState.value);
                            baseEvent['_data'] = microtaskId;
                            listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback);
                        }
                    });
                }
                if (player.markedForDestroy) {
                    _this._engine.afterFlush(function () {
                        // now we can destroy the element properly since the event listeners have
                        // been bound to the player
                        player.destroy();
                    });
                }
                else {
                    instructions.push(entry);
                }
            });
            this._queue = [];
            return instructions.sort(function (a, b) {
                // if depCount == 0 them move to front
                // otherwise if a contains b then move back
                var d0 = a.transition.ast.depCount;
                var d1 = b.transition.ast.depCount;
                if (d0 == 0 || d1 == 0) {
                    return d0 - d1;
                }
                return _this._engine.driver.containsElement(a.element, b.element) ? 1 : -1;
            });
        };
        AnimationTransitionNamespace.prototype.destroy = function (context) {
            this.players.forEach(function (p) { return p.destroy(); });
            this._signalRemovalForInnerTriggers(this.hostElement, context);
        };
        AnimationTransitionNamespace.prototype.elementContainsData = function (element) {
            var containsData = false;
            if (this._elementListeners.has(element))
                containsData = true;
            containsData =
                (this._queue.find(function (entry) { return entry.element === element; }) ? true : false) || containsData;
            return containsData;
        };
        return AnimationTransitionNamespace;
    }());
    var TransitionAnimationEngine = /** @class */ (function () {
        function TransitionAnimationEngine(bodyNode, driver, _normalizer) {
            this.bodyNode = bodyNode;
            this.driver = driver;
            this._normalizer = _normalizer;
            this.players = [];
            this.newHostElements = new Map();
            this.playersByElement = new Map();
            this.playersByQueriedElement = new Map();
            this.statesByElement = new Map();
            this.disabledNodes = new Set();
            this.totalAnimations = 0;
            this.totalQueuedPlayers = 0;
            this._namespaceLookup = {};
            this._namespaceList = [];
            this._flushFns = [];
            this._whenQuietFns = [];
            this.namespacesByHostElement = new Map();
            this.collectedEnterElements = [];
            this.collectedLeaveElements = [];
            // this method is designed to be overridden by the code that uses this engine
            this.onRemovalComplete = function (element, context) { };
        }
        /** @internal */
        TransitionAnimationEngine.prototype._onRemovalComplete = function (element, context) {
            this.onRemovalComplete(element, context);
        };
        Object.defineProperty(TransitionAnimationEngine.prototype, "queuedPlayers", {
            get: function () {
                var players = [];
                this._namespaceList.forEach(function (ns) {
                    ns.players.forEach(function (player) {
                        if (player.queued) {
                            players.push(player);
                        }
                    });
                });
                return players;
            },
            enumerable: false,
            configurable: true
        });
        TransitionAnimationEngine.prototype.createNamespace = function (namespaceId, hostElement) {
            var ns = new AnimationTransitionNamespace(namespaceId, hostElement, this);
            if (this.bodyNode && this.driver.containsElement(this.bodyNode, hostElement)) {
                this._balanceNamespaceList(ns, hostElement);
            }
            else {
                // defer this later until flush during when the host element has
                // been inserted so that we know exactly where to place it in
                // the namespace list
                this.newHostElements.set(hostElement, ns);
                // given that this host element is apart of the animation code, it
                // may or may not be inserted by a parent node that is of an
                // animation renderer type. If this happens then we can still have
                // access to this item when we query for :enter nodes. If the parent
                // is a renderer then the set data-structure will normalize the entry
                this.collectEnterElement(hostElement);
            }
            return this._namespaceLookup[namespaceId] = ns;
        };
        TransitionAnimationEngine.prototype._balanceNamespaceList = function (ns, hostElement) {
            var limit = this._namespaceList.length - 1;
            if (limit >= 0) {
                var found = false;
                for (var i = limit; i >= 0; i--) {
                    var nextNamespace = this._namespaceList[i];
                    if (this.driver.containsElement(nextNamespace.hostElement, hostElement)) {
                        this._namespaceList.splice(i + 1, 0, ns);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    this._namespaceList.splice(0, 0, ns);
                }
            }
            else {
                this._namespaceList.push(ns);
            }
            this.namespacesByHostElement.set(hostElement, ns);
            return ns;
        };
        TransitionAnimationEngine.prototype.register = function (namespaceId, hostElement) {
            var ns = this._namespaceLookup[namespaceId];
            if (!ns) {
                ns = this.createNamespace(namespaceId, hostElement);
            }
            return ns;
        };
        TransitionAnimationEngine.prototype.registerTrigger = function (namespaceId, name, trigger) {
            var ns = this._namespaceLookup[namespaceId];
            if (ns && ns.register(name, trigger)) {
                this.totalAnimations++;
            }
        };
        TransitionAnimationEngine.prototype.destroy = function (namespaceId, context) {
            var _this = this;
            if (!namespaceId)
                return;
            var ns = this._fetchNamespace(namespaceId);
            this.afterFlush(function () {
                _this.namespacesByHostElement.delete(ns.hostElement);
                delete _this._namespaceLookup[namespaceId];
                var index = _this._namespaceList.indexOf(ns);
                if (index >= 0) {
                    _this._namespaceList.splice(index, 1);
                }
            });
            this.afterFlushAnimationsDone(function () { return ns.destroy(context); });
        };
        TransitionAnimationEngine.prototype._fetchNamespace = function (id) {
            return this._namespaceLookup[id];
        };
        TransitionAnimationEngine.prototype.fetchNamespacesByElement = function (element) {
            // normally there should only be one namespace per element, however
            // if @triggers are placed on both the component element and then
            // its host element (within the component code) then there will be
            // two namespaces returned. We use a set here to simply the dedupe
            // of namespaces incase there are multiple triggers both the elm and host
            var namespaces = new Set();
            var elementStates = this.statesByElement.get(element);
            if (elementStates) {
                var keys = Object.keys(elementStates);
                for (var i = 0; i < keys.length; i++) {
                    var nsId = elementStates[keys[i]].namespaceId;
                    if (nsId) {
                        var ns = this._fetchNamespace(nsId);
                        if (ns) {
                            namespaces.add(ns);
                        }
                    }
                }
            }
            return namespaces;
        };
        TransitionAnimationEngine.prototype.trigger = function (namespaceId, element, name, value) {
            if (isElementNode(element)) {
                var ns = this._fetchNamespace(namespaceId);
                if (ns) {
                    ns.trigger(element, name, value);
                    return true;
                }
            }
            return false;
        };
        TransitionAnimationEngine.prototype.insertNode = function (namespaceId, element, parent, insertBefore) {
            if (!isElementNode(element))
                return;
            // special case for when an element is removed and reinserted (move operation)
            // when this occurs we do not want to use the element for deletion later
            var details = element[REMOVAL_FLAG];
            if (details && details.setForRemoval) {
                details.setForRemoval = false;
                details.setForMove = true;
                var index = this.collectedLeaveElements.indexOf(element);
                if (index >= 0) {
                    this.collectedLeaveElements.splice(index, 1);
                }
            }
            // in the event that the namespaceId is blank then the caller
            // code does not contain any animation code in it, but it is
            // just being called so that the node is marked as being inserted
            if (namespaceId) {
                var ns = this._fetchNamespace(namespaceId);
                // This if-statement is a workaround for router issue #21947.
                // The router sometimes hits a race condition where while a route
                // is being instantiated a new navigation arrives, triggering leave
                // animation of DOM that has not been fully initialized, until this
                // is resolved, we need to handle the scenario when DOM is not in a
                // consistent state during the animation.
                if (ns) {
                    ns.insertNode(element, parent);
                }
            }
            // only *directives and host elements are inserted before
            if (insertBefore) {
                this.collectEnterElement(element);
            }
        };
        TransitionAnimationEngine.prototype.collectEnterElement = function (element) {
            this.collectedEnterElements.push(element);
        };
        TransitionAnimationEngine.prototype.markElementAsDisabled = function (element, value) {
            if (value) {
                if (!this.disabledNodes.has(element)) {
                    this.disabledNodes.add(element);
                    addClass(element, DISABLED_CLASSNAME);
                }
            }
            else if (this.disabledNodes.has(element)) {
                this.disabledNodes.delete(element);
                removeClass(element, DISABLED_CLASSNAME);
            }
        };
        TransitionAnimationEngine.prototype.removeNode = function (namespaceId, element, isHostElement, context) {
            if (isElementNode(element)) {
                var ns = namespaceId ? this._fetchNamespace(namespaceId) : null;
                if (ns) {
                    ns.removeNode(element, context);
                }
                else {
                    this.markElementAsRemoved(namespaceId, element, false, context);
                }
                if (isHostElement) {
                    var hostNS = this.namespacesByHostElement.get(element);
                    if (hostNS && hostNS.id !== namespaceId) {
                        hostNS.removeNode(element, context);
                    }
                }
            }
            else {
                this._onRemovalComplete(element, context);
            }
        };
        TransitionAnimationEngine.prototype.markElementAsRemoved = function (namespaceId, element, hasAnimation, context) {
            this.collectedLeaveElements.push(element);
            element[REMOVAL_FLAG] =
                { namespaceId: namespaceId, setForRemoval: context, hasAnimation: hasAnimation, removedBeforeQueried: false };
        };
        TransitionAnimationEngine.prototype.listen = function (namespaceId, element, name, phase, callback) {
            if (isElementNode(element)) {
                return this._fetchNamespace(namespaceId).listen(element, name, phase, callback);
            }
            return function () { };
        };
        TransitionAnimationEngine.prototype._buildInstruction = function (entry, subTimelines, enterClassName, leaveClassName, skipBuildAst) {
            return entry.transition.build(this.driver, entry.element, entry.fromState.value, entry.toState.value, enterClassName, leaveClassName, entry.fromState.options, entry.toState.options, subTimelines, skipBuildAst);
        };
        TransitionAnimationEngine.prototype.destroyInnerAnimations = function (containerElement) {
            var _this = this;
            var elements = this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true);
            elements.forEach(function (element) { return _this.destroyActiveAnimationsForElement(element); });
            if (this.playersByQueriedElement.size == 0)
                return;
            elements = this.driver.query(containerElement, NG_ANIMATING_SELECTOR, true);
            elements.forEach(function (element) { return _this.finishActiveQueriedAnimationOnElement(element); });
        };
        TransitionAnimationEngine.prototype.destroyActiveAnimationsForElement = function (element) {
            var players = this.playersByElement.get(element);
            if (players) {
                players.forEach(function (player) {
                    // special case for when an element is set for destruction, but hasn't started.
                    // in this situation we want to delay the destruction until the flush occurs
                    // so that any event listeners attached to the player are triggered.
                    if (player.queued) {
                        player.markedForDestroy = true;
                    }
                    else {
                        player.destroy();
                    }
                });
            }
        };
        TransitionAnimationEngine.prototype.finishActiveQueriedAnimationOnElement = function (element) {
            var players = this.playersByQueriedElement.get(element);
            if (players) {
                players.forEach(function (player) { return player.finish(); });
            }
        };
        TransitionAnimationEngine.prototype.whenRenderingDone = function () {
            var _this = this;
            return new Promise(function (resolve) {
                if (_this.players.length) {
                    return optimizeGroupPlayer(_this.players).onDone(function () { return resolve(); });
                }
                else {
                    resolve();
                }
            });
        };
        TransitionAnimationEngine.prototype.processLeaveNode = function (element) {
            var _this = this;
            var details = element[REMOVAL_FLAG];
            if (details && details.setForRemoval) {
                // this will prevent it from removing it twice
                element[REMOVAL_FLAG] = NULL_REMOVAL_STATE;
                if (details.namespaceId) {
                    this.destroyInnerAnimations(element);
                    var ns = this._fetchNamespace(details.namespaceId);
                    if (ns) {
                        ns.clearElementCache(element);
                    }
                }
                this._onRemovalComplete(element, details.setForRemoval);
            }
            if (this.driver.matchesElement(element, DISABLED_SELECTOR)) {
                this.markElementAsDisabled(element, false);
            }
            this.driver.query(element, DISABLED_SELECTOR, true).forEach(function (node) {
                _this.markElementAsDisabled(node, false);
            });
        };
        TransitionAnimationEngine.prototype.flush = function (microtaskId) {
            var _this = this;
            if (microtaskId === void 0) { microtaskId = -1; }
            var players = [];
            if (this.newHostElements.size) {
                this.newHostElements.forEach(function (ns, element) { return _this._balanceNamespaceList(ns, element); });
                this.newHostElements.clear();
            }
            if (this.totalAnimations && this.collectedEnterElements.length) {
                for (var i = 0; i < this.collectedEnterElements.length; i++) {
                    var elm = this.collectedEnterElements[i];
                    addClass(elm, STAR_CLASSNAME);
                }
            }
            if (this._namespaceList.length &&
                (this.totalQueuedPlayers || this.collectedLeaveElements.length)) {
                var cleanupFns = [];
                try {
                    players = this._flushAnimations(cleanupFns, microtaskId);
                }
                finally {
                    for (var i = 0; i < cleanupFns.length; i++) {
                        cleanupFns[i]();
                    }
                }
            }
            else {
                for (var i = 0; i < this.collectedLeaveElements.length; i++) {
                    var element = this.collectedLeaveElements[i];
                    this.processLeaveNode(element);
                }
            }
            this.totalQueuedPlayers = 0;
            this.collectedEnterElements.length = 0;
            this.collectedLeaveElements.length = 0;
            this._flushFns.forEach(function (fn) { return fn(); });
            this._flushFns = [];
            if (this._whenQuietFns.length) {
                // we move these over to a variable so that
                // if any new callbacks are registered in another
                // flush they do not populate the existing set
                var quietFns_1 = this._whenQuietFns;
                this._whenQuietFns = [];
                if (players.length) {
                    optimizeGroupPlayer(players).onDone(function () {
                        quietFns_1.forEach(function (fn) { return fn(); });
                    });
                }
                else {
                    quietFns_1.forEach(function (fn) { return fn(); });
                }
            }
        };
        TransitionAnimationEngine.prototype.reportError = function (errors) {
            throw new Error("Unable to process animations due to the following failed trigger transitions\n " + errors.join('\n'));
        };
        TransitionAnimationEngine.prototype._flushAnimations = function (cleanupFns, microtaskId) {
            var _this = this;
            var subTimelines = new ElementInstructionMap();
            var skippedPlayers = [];
            var skippedPlayersMap = new Map();
            var queuedInstructions = [];
            var queriedElements = new Map();
            var allPreStyleElements = new Map();
            var allPostStyleElements = new Map();
            var disabledElementsSet = new Set();
            this.disabledNodes.forEach(function (node) {
                disabledElementsSet.add(node);
                var nodesThatAreDisabled = _this.driver.query(node, QUEUED_SELECTOR, true);
                for (var i_1 = 0; i_1 < nodesThatAreDisabled.length; i_1++) {
                    disabledElementsSet.add(nodesThatAreDisabled[i_1]);
                }
            });
            var bodyNode = this.bodyNode;
            var allTriggerElements = Array.from(this.statesByElement.keys());
            var enterNodeMap = buildRootMap(allTriggerElements, this.collectedEnterElements);
            // this must occur before the instructions are built below such that
            // the :enter queries match the elements (since the timeline queries
            // are fired during instruction building).
            var enterNodeMapIds = new Map();
            var i = 0;
            enterNodeMap.forEach(function (nodes, root) {
                var className = ENTER_CLASSNAME + i++;
                enterNodeMapIds.set(root, className);
                nodes.forEach(function (node) { return addClass(node, className); });
            });
            var allLeaveNodes = [];
            var mergedLeaveNodes = new Set();
            var leaveNodesWithoutAnimations = new Set();
            for (var i_2 = 0; i_2 < this.collectedLeaveElements.length; i_2++) {
                var element = this.collectedLeaveElements[i_2];
                var details = element[REMOVAL_FLAG];
                if (details && details.setForRemoval) {
                    allLeaveNodes.push(element);
                    mergedLeaveNodes.add(element);
                    if (details.hasAnimation) {
                        this.driver.query(element, STAR_SELECTOR, true).forEach(function (elm) { return mergedLeaveNodes.add(elm); });
                    }
                    else {
                        leaveNodesWithoutAnimations.add(element);
                    }
                }
            }
            var leaveNodeMapIds = new Map();
            var leaveNodeMap = buildRootMap(allTriggerElements, Array.from(mergedLeaveNodes));
            leaveNodeMap.forEach(function (nodes, root) {
                var className = LEAVE_CLASSNAME + i++;
                leaveNodeMapIds.set(root, className);
                nodes.forEach(function (node) { return addClass(node, className); });
            });
            cleanupFns.push(function () {
                enterNodeMap.forEach(function (nodes, root) {
                    var className = enterNodeMapIds.get(root);
                    nodes.forEach(function (node) { return removeClass(node, className); });
                });
                leaveNodeMap.forEach(function (nodes, root) {
                    var className = leaveNodeMapIds.get(root);
                    nodes.forEach(function (node) { return removeClass(node, className); });
                });
                allLeaveNodes.forEach(function (element) {
                    _this.processLeaveNode(element);
                });
            });
            var allPlayers = [];
            var erroneousTransitions = [];
            for (var i_3 = this._namespaceList.length - 1; i_3 >= 0; i_3--) {
                var ns = this._namespaceList[i_3];
                ns.drainQueuedTransitions(microtaskId).forEach(function (entry) {
                    var player = entry.player;
                    var element = entry.element;
                    allPlayers.push(player);
                    if (_this.collectedEnterElements.length) {
                        var details = element[REMOVAL_FLAG];
                        // move animations are currently not supported...
                        if (details && details.setForMove) {
                            player.destroy();
                            return;
                        }
                    }
                    var nodeIsOrphaned = !bodyNode || !_this.driver.containsElement(bodyNode, element);
                    var leaveClassName = leaveNodeMapIds.get(element);
                    var enterClassName = enterNodeMapIds.get(element);
                    var instruction = _this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned);
                    if (instruction.errors && instruction.errors.length) {
                        erroneousTransitions.push(instruction);
                        return;
                    }
                    // even though the element may not be apart of the DOM, it may
                    // still be added at a later point (due to the mechanics of content
                    // projection and/or dynamic component insertion) therefore it's
                    // important we still style the element.
                    if (nodeIsOrphaned) {
                        player.onStart(function () { return eraseStyles(element, instruction.fromStyles); });
                        player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
                        skippedPlayers.push(player);
                        return;
                    }
                    // if a unmatched transition is queued to go then it SHOULD NOT render
                    // an animation and cancel the previously running animations.
                    if (entry.isFallbackTransition) {
                        player.onStart(function () { return eraseStyles(element, instruction.fromStyles); });
                        player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
                        skippedPlayers.push(player);
                        return;
                    }
                    // this means that if a parent animation uses this animation as a sub trigger
                    // then it will instruct the timeline builder to not add a player delay, but
                    // instead stretch the first keyframe gap up until the animation starts. The
                    // reason this is important is to prevent extra initialization styles from being
                    // required by the user in the animation.
                    instruction.timelines.forEach(function (tl) { return tl.stretchStartingKeyframe = true; });
                    subTimelines.append(element, instruction.timelines);
                    var tuple = { instruction: instruction, player: player, element: element };
                    queuedInstructions.push(tuple);
                    instruction.queriedElements.forEach(function (element) { return getOrSetAsInMap(queriedElements, element, []).push(player); });
                    instruction.preStyleProps.forEach(function (stringMap, element) {
                        var props = Object.keys(stringMap);
                        if (props.length) {
                            var setVal_1 = allPreStyleElements.get(element);
                            if (!setVal_1) {
                                allPreStyleElements.set(element, setVal_1 = new Set());
                            }
                            props.forEach(function (prop) { return setVal_1.add(prop); });
                        }
                    });
                    instruction.postStyleProps.forEach(function (stringMap, element) {
                        var props = Object.keys(stringMap);
                        var setVal = allPostStyleElements.get(element);
                        if (!setVal) {
                            allPostStyleElements.set(element, setVal = new Set());
                        }
                        props.forEach(function (prop) { return setVal.add(prop); });
                    });
                });
            }
            if (erroneousTransitions.length) {
                var errors_1 = [];
                erroneousTransitions.forEach(function (instruction) {
                    errors_1.push("@" + instruction.triggerName + " has failed due to:\n");
                    instruction.errors.forEach(function (error) { return errors_1.push("- " + error + "\n"); });
                });
                allPlayers.forEach(function (player) { return player.destroy(); });
                this.reportError(errors_1);
            }
            var allPreviousPlayersMap = new Map();
            // this map works to tell which element in the DOM tree is contained by
            // which animation. Further down below this map will get populated once
            // the players are built and in doing so it can efficiently figure out
            // if a sub player is skipped due to a parent player having priority.
            var animationElementMap = new Map();
            queuedInstructions.forEach(function (entry) {
                var element = entry.element;
                if (subTimelines.has(element)) {
                    animationElementMap.set(element, element);
                    _this._beforeAnimationBuild(entry.player.namespaceId, entry.instruction, allPreviousPlayersMap);
                }
            });
            skippedPlayers.forEach(function (player) {
                var element = player.element;
                var previousPlayers = _this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
                previousPlayers.forEach(function (prevPlayer) {
                    getOrSetAsInMap(allPreviousPlayersMap, element, []).push(prevPlayer);
                    prevPlayer.destroy();
                });
            });
            // this is a special case for nodes that will be removed (either by)
            // having their own leave animations or by being queried in a container
            // that will be removed once a parent animation is complete. The idea
            // here is that * styles must be identical to ! styles because of
            // backwards compatibility (* is also filled in by default in many places).
            // Otherwise * styles will return an empty value or auto since the element
            // that is being getComputedStyle'd will not be visible (since * = destination)
            var replaceNodes = allLeaveNodes.filter(function (node) {
                return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);
            });
            // POST STAGE: fill the * styles
            var postStylesMap = new Map();
            var allLeaveQueriedNodes = cloakAndComputeStyles(postStylesMap, this.driver, leaveNodesWithoutAnimations, allPostStyleElements, animations.AUTO_STYLE);
            allLeaveQueriedNodes.forEach(function (node) {
                if (replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements)) {
                    replaceNodes.push(node);
                }
            });
            // PRE STAGE: fill the ! styles
            var preStylesMap = new Map();
            enterNodeMap.forEach(function (nodes, root) {
                cloakAndComputeStyles(preStylesMap, _this.driver, new Set(nodes), allPreStyleElements, animations.ɵPRE_STYLE);
            });
            replaceNodes.forEach(function (node) {
                var post = postStylesMap.get(node);
                var pre = preStylesMap.get(node);
                postStylesMap.set(node, Object.assign(Object.assign({}, post), pre));
            });
            var rootPlayers = [];
            var subPlayers = [];
            var NO_PARENT_ANIMATION_ELEMENT_DETECTED = {};
            queuedInstructions.forEach(function (entry) {
                var element = entry.element, player = entry.player, instruction = entry.instruction;
                // this means that it was never consumed by a parent animation which
                // means that it is independent and therefore should be set for animation
                if (subTimelines.has(element)) {
                    if (disabledElementsSet.has(element)) {
                        player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
                        player.disabled = true;
                        player.overrideTotalTime(instruction.totalTime);
                        skippedPlayers.push(player);
                        return;
                    }
                    // this will flow up the DOM and query the map to figure out
                    // if a parent animation has priority over it. In the situation
                    // that a parent is detected then it will cancel the loop. If
                    // nothing is detected, or it takes a few hops to find a parent,
                    // then it will fill in the missing nodes and signal them as having
                    // a detected parent (or a NO_PARENT value via a special constant).
                    var parentWithAnimation_1 = NO_PARENT_ANIMATION_ELEMENT_DETECTED;
                    if (animationElementMap.size > 1) {
                        var elm = element;
                        var parentsToAdd = [];
                        while (elm = elm.parentNode) {
                            var detectedParent = animationElementMap.get(elm);
                            if (detectedParent) {
                                parentWithAnimation_1 = detectedParent;
                                break;
                            }
                            parentsToAdd.push(elm);
                        }
                        parentsToAdd.forEach(function (parent) { return animationElementMap.set(parent, parentWithAnimation_1); });
                    }
                    var innerPlayer = _this._buildAnimation(player.namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap);
                    player.setRealPlayer(innerPlayer);
                    if (parentWithAnimation_1 === NO_PARENT_ANIMATION_ELEMENT_DETECTED) {
                        rootPlayers.push(player);
                    }
                    else {
                        var parentPlayers = _this.playersByElement.get(parentWithAnimation_1);
                        if (parentPlayers && parentPlayers.length) {
                            player.parentPlayer = optimizeGroupPlayer(parentPlayers);
                        }
                        skippedPlayers.push(player);
                    }
                }
                else {
                    eraseStyles(element, instruction.fromStyles);
                    player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
                    // there still might be a ancestor player animating this
                    // element therefore we will still add it as a sub player
                    // even if its animation may be disabled
                    subPlayers.push(player);
                    if (disabledElementsSet.has(element)) {
                        skippedPlayers.push(player);
                    }
                }
            });
            // find all of the sub players' corresponding inner animation player
            subPlayers.forEach(function (player) {
                // even if any players are not found for a sub animation then it
                // will still complete itself after the next tick since it's Noop
                var playersForElement = skippedPlayersMap.get(player.element);
                if (playersForElement && playersForElement.length) {
                    var innerPlayer = optimizeGroupPlayer(playersForElement);
                    player.setRealPlayer(innerPlayer);
                }
            });
            // the reason why we don't actually play the animation is
            // because all that a skipped player is designed to do is to
            // fire the start/done transition callback events
            skippedPlayers.forEach(function (player) {
                if (player.parentPlayer) {
                    player.syncPlayerEvents(player.parentPlayer);
                }
                else {
                    player.destroy();
                }
            });
            // run through all of the queued removals and see if they
            // were picked up by a query. If not then perform the removal
            // operation right away unless a parent animation is ongoing.
            for (var i_4 = 0; i_4 < allLeaveNodes.length; i_4++) {
                var element = allLeaveNodes[i_4];
                var details = element[REMOVAL_FLAG];
                removeClass(element, LEAVE_CLASSNAME);
                // this means the element has a removal animation that is being
                // taken care of and therefore the inner elements will hang around
                // until that animation is over (or the parent queried animation)
                if (details && details.hasAnimation)
                    continue;
                var players = [];
                // if this element is queried or if it contains queried children
                // then we want for the element not to be removed from the page
                // until the queried animations have finished
                if (queriedElements.size) {
                    var queriedPlayerResults = queriedElements.get(element);
                    if (queriedPlayerResults && queriedPlayerResults.length) {
                        players.push.apply(players, __spread(queriedPlayerResults));
                    }
                    var queriedInnerElements = this.driver.query(element, NG_ANIMATING_SELECTOR, true);
                    for (var j = 0; j < queriedInnerElements.length; j++) {
                        var queriedPlayers = queriedElements.get(queriedInnerElements[j]);
                        if (queriedPlayers && queriedPlayers.length) {
                            players.push.apply(players, __spread(queriedPlayers));
                        }
                    }
                }
                var activePlayers = players.filter(function (p) { return !p.destroyed; });
                if (activePlayers.length) {
                    removeNodesAfterAnimationDone(this, element, activePlayers);
                }
                else {
                    this.processLeaveNode(element);
                }
            }
            // this is required so the cleanup method doesn't remove them
            allLeaveNodes.length = 0;
            rootPlayers.forEach(function (player) {
                _this.players.push(player);
                player.onDone(function () {
                    player.destroy();
                    var index = _this.players.indexOf(player);
                    _this.players.splice(index, 1);
                });
                player.play();
            });
            return rootPlayers;
        };
        TransitionAnimationEngine.prototype.elementContainsData = function (namespaceId, element) {
            var containsData = false;
            var details = element[REMOVAL_FLAG];
            if (details && details.setForRemoval)
                containsData = true;
            if (this.playersByElement.has(element))
                containsData = true;
            if (this.playersByQueriedElement.has(element))
                containsData = true;
            if (this.statesByElement.has(element))
                containsData = true;
            return this._fetchNamespace(namespaceId).elementContainsData(element) || containsData;
        };
        TransitionAnimationEngine.prototype.afterFlush = function (callback) {
            this._flushFns.push(callback);
        };
        TransitionAnimationEngine.prototype.afterFlushAnimationsDone = function (callback) {
            this._whenQuietFns.push(callback);
        };
        TransitionAnimationEngine.prototype._getPreviousPlayers = function (element, isQueriedElement, namespaceId, triggerName, toStateValue) {
            var players = [];
            if (isQueriedElement) {
                var queriedElementPlayers = this.playersByQueriedElement.get(element);
                if (queriedElementPlayers) {
                    players = queriedElementPlayers;
                }
            }
            else {
                var elementPlayers = this.playersByElement.get(element);
                if (elementPlayers) {
                    var isRemovalAnimation_1 = !toStateValue || toStateValue == VOID_VALUE;
                    elementPlayers.forEach(function (player) {
                        if (player.queued)
                            return;
                        if (!isRemovalAnimation_1 && player.triggerName != triggerName)
                            return;
                        players.push(player);
                    });
                }
            }
            if (namespaceId || triggerName) {
                players = players.filter(function (player) {
                    if (namespaceId && namespaceId != player.namespaceId)
                        return false;
                    if (triggerName && triggerName != player.triggerName)
                        return false;
                    return true;
                });
            }
            return players;
        };
        TransitionAnimationEngine.prototype._beforeAnimationBuild = function (namespaceId, instruction, allPreviousPlayersMap) {
            var e_1, _a;
            var triggerName = instruction.triggerName;
            var rootElement = instruction.element;
            // when a removal animation occurs, ALL previous players are collected
            // and destroyed (even if they are outside of the current namespace)
            var targetNameSpaceId = instruction.isRemovalTransition ? undefined : namespaceId;
            var targetTriggerName = instruction.isRemovalTransition ? undefined : triggerName;
            var _loop_1 = function (timelineInstruction) {
                var element = timelineInstruction.element;
                var isQueriedElement = element !== rootElement;
                var players = getOrSetAsInMap(allPreviousPlayersMap, element, []);
                var previousPlayers = this_1._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
                previousPlayers.forEach(function (player) {
                    var realPlayer = player.getRealPlayer();
                    if (realPlayer.beforeDestroy) {
                        realPlayer.beforeDestroy();
                    }
                    player.destroy();
                    players.push(player);
                });
            };
            var this_1 = this;
            try {
                for (var _b = __values(instruction.timelines), _c = _b.next(); !_c.done; _c = _b.next()) {
                    var timelineInstruction = _c.value;
                    _loop_1(timelineInstruction);
                }
            }
            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; }
            }
            // this needs to be done so that the PRE/POST styles can be
            // computed properly without interfering with the previous animation
            eraseStyles(rootElement, instruction.fromStyles);
        };
        TransitionAnimationEngine.prototype._buildAnimation = function (namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap) {
            var _this = this;
            var triggerName = instruction.triggerName;
            var rootElement = instruction.element;
            // we first run this so that the previous animation player
            // data can be passed into the successive animation players
            var allQueriedPlayers = [];
            var allConsumedElements = new Set();
            var allSubElements = new Set();
            var allNewPlayers = instruction.timelines.map(function (timelineInstruction) {
                var element = timelineInstruction.element;
                allConsumedElements.add(element);
                // FIXME (matsko): make sure to-be-removed animations are removed properly
                var details = element[REMOVAL_FLAG];
                if (details && details.removedBeforeQueried)
                    return new animations.NoopAnimationPlayer(timelineInstruction.duration, timelineInstruction.delay);
                var isQueriedElement = element !== rootElement;
                var previousPlayers = flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY)
                    .map(function (p) { return p.getRealPlayer(); }))
                    .filter(function (p) {
                    // the `element` is not apart of the AnimationPlayer definition, but
                    // Mock/WebAnimations
                    // use the element within their implementation. This will be added in Angular5 to
                    // AnimationPlayer
                    var pp = p;
                    return pp.element ? pp.element === element : false;
                });
                var preStyles = preStylesMap.get(element);
                var postStyles = postStylesMap.get(element);
                var keyframes = normalizeKeyframes(_this.driver, _this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
                var player = _this._buildPlayer(timelineInstruction, keyframes, previousPlayers);
                // this means that this particular player belongs to a sub trigger. It is
                // important that we match this player up with the corresponding (@trigger.listener)
                if (timelineInstruction.subTimeline && skippedPlayersMap) {
                    allSubElements.add(element);
                }
                if (isQueriedElement) {
                    var wrappedPlayer = new TransitionAnimationPlayer(namespaceId, triggerName, element);
                    wrappedPlayer.setRealPlayer(player);
                    allQueriedPlayers.push(wrappedPlayer);
                }
                return player;
            });
            allQueriedPlayers.forEach(function (player) {
                getOrSetAsInMap(_this.playersByQueriedElement, player.element, []).push(player);
                player.onDone(function () { return deleteOrUnsetInMap(_this.playersByQueriedElement, player.element, player); });
            });
            allConsumedElements.forEach(function (element) { return addClass(element, NG_ANIMATING_CLASSNAME); });
            var player = optimizeGroupPlayer(allNewPlayers);
            player.onDestroy(function () {
                allConsumedElements.forEach(function (element) { return removeClass(element, NG_ANIMATING_CLASSNAME); });
                setStyles(rootElement, instruction.toStyles);
            });
            // this basically makes all of the callbacks for sub element animations
            // be dependent on the upper players for when they finish
            allSubElements.forEach(function (element) {
                getOrSetAsInMap(skippedPlayersMap, element, []).push(player);
            });
            return player;
        };
        TransitionAnimationEngine.prototype._buildPlayer = function (instruction, keyframes, previousPlayers) {
            if (keyframes.length > 0) {
                return this.driver.animate(instruction.element, keyframes, instruction.duration, instruction.delay, instruction.easing, previousPlayers);
            }
            // special case for when an empty transition|definition is provided
            // ... there is no point in rendering an empty animation
            return new animations.NoopAnimationPlayer(instruction.duration, instruction.delay);
        };
        return TransitionAnimationEngine;
    }());
    var TransitionAnimationPlayer = /** @class */ (function () {
        function TransitionAnimationPlayer(namespaceId, triggerName, element) {
            this.namespaceId = namespaceId;
            this.triggerName = triggerName;
            this.element = element;
            this._player = new animations.NoopAnimationPlayer();
            this._containsRealPlayer = false;
            this._queuedCallbacks = {};
            this.destroyed = false;
            this.markedForDestroy = false;
            this.disabled = false;
            this.queued = true;
            this.totalTime = 0;
        }
        TransitionAnimationPlayer.prototype.setRealPlayer = function (player) {
            var _this = this;
            if (this._containsRealPlayer)
                return;
            this._player = player;
            Object.keys(this._queuedCallbacks).forEach(function (phase) {
                _this._queuedCallbacks[phase].forEach(function (callback) { return listenOnPlayer(player, phase, undefined, callback); });
            });
            this._queuedCallbacks = {};
            this._containsRealPlayer = true;
            this.overrideTotalTime(player.totalTime);
            this.queued = false;
        };
        TransitionAnimationPlayer.prototype.getRealPlayer = function () {
            return this._player;
        };
        TransitionAnimationPlayer.prototype.overrideTotalTime = function (totalTime) {
            this.totalTime = totalTime;
        };
        TransitionAnimationPlayer.prototype.syncPlayerEvents = function (player) {
            var _this = this;
            var p = this._player;
            if (p.triggerCallback) {
                player.onStart(function () { return p.triggerCallback('start'); });
            }
            player.onDone(function () { return _this.finish(); });
            player.onDestroy(function () { return _this.destroy(); });
        };
        TransitionAnimationPlayer.prototype._queueEvent = function (name, callback) {
            getOrSetAsInMap(this._queuedCallbacks, name, []).push(callback);
        };
        TransitionAnimationPlayer.prototype.onDone = function (fn) {
            if (this.queued) {
                this._queueEvent('done', fn);
            }
            this._player.onDone(fn);
        };
        TransitionAnimationPlayer.prototype.onStart = function (fn) {
            if (this.queued) {
                this._queueEvent('start', fn);
            }
            this._player.onStart(fn);
        };
        TransitionAnimationPlayer.prototype.onDestroy = function (fn) {
            if (this.queued) {
                this._queueEvent('destroy', fn);
            }
            this._player.onDestroy(fn);
        };
        TransitionAnimationPlayer.prototype.init = function () {
            this._player.init();
        };
        TransitionAnimationPlayer.prototype.hasStarted = function () {
            return this.queued ? false : this._player.hasStarted();
        };
        TransitionAnimationPlayer.prototype.play = function () {
            !this.queued && this._player.play();
        };
        TransitionAnimationPlayer.prototype.pause = function () {
            !this.queued && this._player.pause();
        };
        TransitionAnimationPlayer.prototype.restart = function () {
            !this.queued && this._player.restart();
        };
        TransitionAnimationPlayer.prototype.finish = function () {
            this._player.finish();
        };
        TransitionAnimationPlayer.prototype.destroy = function () {
            this.destroyed = true;
            this._player.destroy();
        };
        TransitionAnimationPlayer.prototype.reset = function () {
            !this.queued && this._player.reset();
        };
        TransitionAnimationPlayer.prototype.setPosition = function (p) {
            if (!this.queued) {
                this._player.setPosition(p);
            }
        };
        TransitionAnimationPlayer.prototype.getPosition = function () {
            return this.queued ? 0 : this._player.getPosition();
        };
        /** @internal */
        TransitionAnimationPlayer.prototype.triggerCallback = function (phaseName) {
            var p = this._player;
            if (p.triggerCallback) {
                p.triggerCallback(phaseName);
            }
        };
        return TransitionAnimationPlayer;
    }());
    function deleteOrUnsetInMap(map, key, value) {
        var currentValues;
        if (map instanceof Map) {
            currentValues = map.get(key);
            if (currentValues) {
                if (currentValues.length) {
                    var index = currentValues.indexOf(value);
                    currentValues.splice(index, 1);
                }
                if (currentValues.length == 0) {
                    map.delete(key);
                }
            }
        }
        else {
            currentValues = map[key];
            if (currentValues) {
                if (currentValues.length) {
                    var index = currentValues.indexOf(value);
                    currentValues.splice(index, 1);
                }
                if (currentValues.length == 0) {
                    delete map[key];
                }
            }
        }
        return currentValues;
    }
    function normalizeTriggerValue(value) {
        // we use `!= null` here because it's the most simple
        // way to test against a "falsy" value without mixing
        // in empty strings or a zero value. DO NOT OPTIMIZE.
        return value != null ? value : null;
    }
    function isElementNode(node) {
        return node && node['nodeType'] === 1;
    }
    function isTriggerEventValid(eventName) {
        return eventName == 'start' || eventName == 'done';
    }
    function cloakElement(element, value) {
        var oldValue = element.style.display;
        element.style.display = value != null ? value : 'none';
        return oldValue;
    }
    function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, defaultStyle) {
        var cloakVals = [];
        elements.forEach(function (element) { return cloakVals.push(cloakElement(element)); });
        var failedElements = [];
        elementPropsMap.forEach(function (props, element) {
            var styles = {};
            props.forEach(function (prop) {
                var value = styles[prop] = driver.computeStyle(element, prop, defaultStyle);
                // there is no easy way to detect this because a sub element could be removed
                // by a parent animation element being detached.
                if (!value || value.length == 0) {
                    element[REMOVAL_FLAG] = NULL_REMOVED_QUERIED_STATE;
                    failedElements.push(element);
                }
            });
            valuesMap.set(element, styles);
        });
        // we use a index variable here since Set.forEach(a, i) does not return
        // an index value for the closure (but instead just the value)
        var i = 0;
        elements.forEach(function (element) { return cloakElement(element, cloakVals[i++]); });
        return failedElements;
    }
    /*
    Since the Angular renderer code will return a collection of inserted
    nodes in all areas of a DOM tree, it's up to this algorithm to figure
    out which nodes are roots for each animation @trigger.

    By placing each inserted node into a Set and traversing upwards, it
    is possible to find the @trigger elements and well any direct *star
    insertion nodes, if a @trigger root is found then the enter element
    is placed into the Map[@trigger] spot.
     */
    function buildRootMap(roots, nodes) {
        var rootMap = new Map();
        roots.forEach(function (root) { return rootMap.set(root, []); });
        if (nodes.length == 0)
            return rootMap;
        var NULL_NODE = 1;
        var nodeSet = new Set(nodes);
        var localRootMap = new Map();
        function getRoot(node) {
            if (!node)
                return NULL_NODE;
            var root = localRootMap.get(node);
            if (root)
                return root;
            var parent = node.parentNode;
            if (rootMap.has(parent)) { // ngIf inside @trigger
                root = parent;
            }
            else if (nodeSet.has(parent)) { // ngIf inside ngIf
                root = NULL_NODE;
            }
            else { // recurse upwards
                root = getRoot(parent);
            }
            localRootMap.set(node, root);
            return root;
        }
        nodes.forEach(function (node) {
            var root = getRoot(node);
            if (root !== NULL_NODE) {
                rootMap.get(root).push(node);
            }
        });
        return rootMap;
    }
    var CLASSES_CACHE_KEY = '$$classes';
    function containsClass(element, className) {
        if (element.classList) {
            return element.classList.contains(className);
        }
        else {
            var classes = element[CLASSES_CACHE_KEY];
            return classes && classes[className];
        }
    }
    function addClass(element, className) {
        if (element.classList) {
            element.classList.add(className);
        }
        else {
            var classes = element[CLASSES_CACHE_KEY];
            if (!classes) {
                classes = element[CLASSES_CACHE_KEY] = {};
            }
            classes[className] = true;
        }
    }
    function removeClass(element, className) {
        if (element.classList) {
            element.classList.remove(className);
        }
        else {
            var classes = element[CLASSES_CACHE_KEY];
            if (classes) {
                delete classes[className];
            }
        }
    }
    function removeNodesAfterAnimationDone(engine, element, players) {
        optimizeGroupPlayer(players).onDone(function () { return engine.processLeaveNode(element); });
    }
    function flattenGroupPlayers(players) {
        var finalPlayers = [];
        _flattenGroupPlayersRecur(players, finalPlayers);
        return finalPlayers;
    }
    function _flattenGroupPlayersRecur(players, finalPlayers) {
        for (var i = 0; i < players.length; i++) {
            var player = players[i];
            if (player instanceof animations.ɵAnimationGroupPlayer) {
                _flattenGroupPlayersRecur(player.players, finalPlayers);
            }
            else {
                finalPlayers.push(player);
            }
        }
    }
    function objEquals(a, b) {
        var k1 = Object.keys(a);
        var k2 = Object.keys(b);
        if (k1.length != k2.length)
            return false;
        for (var i = 0; i < k1.length; i++) {
            var prop = k1[i];
            if (!b.hasOwnProperty(prop) || a[prop] !== b[prop])
                return false;
        }
        return true;
    }
    function replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElements) {
        var postEntry = allPostStyleElements.get(element);
        if (!postEntry)
            return false;
        var preEntry = allPreStyleElements.get(element);
        if (preEntry) {
            postEntry.forEach(function (data) { return preEntry.add(data); });
        }
        else {
            allPreStyleElements.set(element, postEntry);
        }
        allPostStyleElements.delete(element);
        return true;
    }

    var AnimationEngine = /** @class */ (function () {
        function AnimationEngine(bodyNode, _driver, normalizer) {
            var _this = this;
            this.bodyNode = bodyNode;
            this._driver = _driver;
            this._triggerCache = {};
            // this method is designed to be overridden by the code that uses this engine
            this.onRemovalComplete = function (element, context) { };
            this._transitionEngine = new TransitionAnimationEngine(bodyNode, _driver, normalizer);
            this._timelineEngine = new TimelineAnimationEngine(bodyNode, _driver, normalizer);
            this._transitionEngine.onRemovalComplete = function (element, context) { return _this.onRemovalComplete(element, context); };
        }
        AnimationEngine.prototype.registerTrigger = function (componentId, namespaceId, hostElement, name, metadata) {
            var cacheKey = componentId + '-' + name;
            var trigger = this._triggerCache[cacheKey];
            if (!trigger) {
                var errors = [];
                var ast = buildAnimationAst(this._driver, metadata, errors);
                if (errors.length) {
                    throw new Error("The animation trigger \"" + name + "\" has failed to build due to the following errors:\n - " + errors.join('\n - '));
                }
                trigger = buildTrigger(name, ast);
                this._triggerCache[cacheKey] = trigger;
            }
            this._transitionEngine.registerTrigger(namespaceId, name, trigger);
        };
        AnimationEngine.prototype.register = function (namespaceId, hostElement) {
            this._transitionEngine.register(namespaceId, hostElement);
        };
        AnimationEngine.prototype.destroy = function (namespaceId, context) {
            this._transitionEngine.destroy(namespaceId, context);
        };
        AnimationEngine.prototype.onInsert = function (namespaceId, element, parent, insertBefore) {
            this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore);
        };
        AnimationEngine.prototype.onRemove = function (namespaceId, element, context, isHostElement) {
            this._transitionEngine.removeNode(namespaceId, element, isHostElement || false, context);
        };
        AnimationEngine.prototype.disableAnimations = function (element, disable) {
            this._transitionEngine.markElementAsDisabled(element, disable);
        };
        AnimationEngine.prototype.process = function (namespaceId, element, property, value) {
            if (property.charAt(0) == '@') {
                var _a = __read(parseTimelineCommand(property), 2), id = _a[0], action = _a[1];
                var args = value;
                this._timelineEngine.command(id, element, action, args);
            }
            else {
                this._transitionEngine.trigger(namespaceId, element, property, value);
            }
        };
        AnimationEngine.prototype.listen = function (namespaceId, element, eventName, eventPhase, callback) {
            // @@listen
            if (eventName.charAt(0) == '@') {
                var _a = __read(parseTimelineCommand(eventName), 2), id = _a[0], action = _a[1];
                return this._timelineEngine.listen(id, element, action, callback);
            }
            return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback);
        };
        AnimationEngine.prototype.flush = function (microtaskId) {
            if (microtaskId === void 0) { microtaskId = -1; }
            this._transitionEngine.flush(microtaskId);
        };
        Object.defineProperty(AnimationEngine.prototype, "players", {
            get: function () {
                return this._transitionEngine.players
                    .concat(this._timelineEngine.players);
            },
            enumerable: false,
            configurable: true
        });
        AnimationEngine.prototype.whenRenderingDone = function () {
            return this._transitionEngine.whenRenderingDone();
        };
        return AnimationEngine;
    }());

    /**
     * @license
     * Copyright Google LLC 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 an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are
     * detected.
     *
     * In CSS there exist properties that cannot be animated within a keyframe animation
     * (whether it be via CSS keyframes or web-animations) and the animation implementation
     * will ignore them. This function is designed to detect those special cased styles and
     * return a container that will be executed at the start and end of the animation.
     *
     * @returns an instance of `SpecialCasedStyles` if any special styles are detected otherwise `null`
     */
    function packageNonAnimatableStyles(element, styles) {
        var startStyles = null;
        var endStyles = null;
        if (Array.isArray(styles) && styles.length) {
            startStyles = filterNonAnimatableStyles(styles[0]);
            if (styles.length > 1) {
                endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);
            }
        }
        else if (styles) {
            startStyles = filterNonAnimatableStyles(styles);
        }
        return (startStyles || endStyles) ? new SpecialCasedStyles(element, startStyles, endStyles) :
            null;
    }
    /**
     * Designed to be executed during a keyframe-based animation to apply any special-cased styles.
     *
     * When started (when the `start()` method is run) then the provided `startStyles`
     * will be applied. When finished (when the `finish()` method is called) the
     * `endStyles` will be applied as well any any starting styles. Finally when
     * `destroy()` is called then all styles will be removed.
     */
    var SpecialCasedStyles = /** @class */ (function () {
        function SpecialCasedStyles(_element, _startStyles, _endStyles) {
            this._element = _element;
            this._startStyles = _startStyles;
            this._endStyles = _endStyles;
            this._state = 0 /* Pending */;
            var initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);
            if (!initialStyles) {
                SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = {});
            }
            this._initialStyles = initialStyles;
        }
        SpecialCasedStyles.prototype.start = function () {
            if (this._state < 1 /* Started */) {
                if (this._startStyles) {
                    setStyles(this._element, this._startStyles, this._initialStyles);
                }
                this._state = 1 /* Started */;
            }
        };
        SpecialCasedStyles.prototype.finish = function () {
            this.start();
            if (this._state < 2 /* Finished */) {
                setStyles(this._element, this._initialStyles);
                if (this._endStyles) {
                    setStyles(this._element, this._endStyles);
                    this._endStyles = null;
                }
                this._state = 1 /* Started */;
            }
        };
        SpecialCasedStyles.prototype.destroy = function () {
            this.finish();
            if (this._state < 3 /* Destroyed */) {
                SpecialCasedStyles.initialStylesByElement.delete(this._element);
                if (this._startStyles) {
                    eraseStyles(this._element, this._startStyles);
                    this._endStyles = null;
                }
                if (this._endStyles) {
                    eraseStyles(this._element, this._endStyles);
                    this._endStyles = null;
                }
                setStyles(this._element, this._initialStyles);
                this._state = 3 /* Destroyed */;
            }
        };
        return SpecialCasedStyles;
    }());
    SpecialCasedStyles.initialStylesByElement = new WeakMap();
    function filterNonAnimatableStyles(styles) {
        var result = null;
        var props = Object.keys(styles);
        for (var i = 0; i < props.length; i++) {
            var prop = props[i];
            if (isNonAnimatableStyle(prop)) {
                result = result || {};
                result[prop] = styles[prop];
            }
        }
        return result;
    }
    function isNonAnimatableStyle(prop) {
        return prop === 'display' || prop === 'position';
    }

    /**
     * @license
     * Copyright Google LLC 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 ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
    var ANIMATION_PROP = 'animation';
    var ANIMATIONEND_EVENT = 'animationend';
    var ONE_SECOND$1 = 1000;
    var ElementAnimationStyleHandler = /** @class */ (function () {
        function ElementAnimationStyleHandler(_element, _name, _duration, _delay, _easing, _fillMode, _onDoneFn) {
            var _this = this;
            this._element = _element;
            this._name = _name;
            this._duration = _duration;
            this._delay = _delay;
            this._easing = _easing;
            this._fillMode = _fillMode;
            this._onDoneFn = _onDoneFn;
            this._finished = false;
            this._destroyed = false;
            this._startTime = 0;
            this._position = 0;
            this._eventFn = function (e) { return _this._handleCallback(e); };
        }
        ElementAnimationStyleHandler.prototype.apply = function () {
            applyKeyframeAnimation(this._element, this._duration + "ms " + this._easing + " " + this._delay + "ms 1 normal " + this._fillMode + " " + this._name);
            addRemoveAnimationEvent(this._element, this._eventFn, false);
            this._startTime = Date.now();
        };
        ElementAnimationStyleHandler.prototype.pause = function () {
            playPauseAnimation(this._element, this._name, 'paused');
        };
        ElementAnimationStyleHandler.prototype.resume = function () {
            playPauseAnimation(this._element, this._name, 'running');
        };
        ElementAnimationStyleHandler.prototype.setPosition = function (position) {
            var index = findIndexForAnimation(this._element, this._name);
            this._position = position * this._duration;
            setAnimationStyle(this._element, 'Delay', "-" + this._position + "ms", index);
        };
        ElementAnimationStyleHandler.prototype.getPosition = function () {
            return this._position;
        };
        ElementAnimationStyleHandler.prototype._handleCallback = function (event) {
            var timestamp = event._ngTestManualTimestamp || Date.now();
            var elapsedTime = parseFloat(event.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)) * ONE_SECOND$1;
            if (event.animationName == this._name &&
                Math.max(timestamp - this._startTime, 0) >= this._delay && elapsedTime >= this._duration) {
                this.finish();
            }
        };
        ElementAnimationStyleHandler.prototype.finish = function () {
            if (this._finished)
                return;
            this._finished = true;
            this._onDoneFn();
            addRemoveAnimationEvent(this._element, this._eventFn, true);
        };
        ElementAnimationStyleHandler.prototype.destroy = function () {
            if (this._destroyed)
                return;
            this._destroyed = true;
            this.finish();
            removeKeyframeAnimation(this._element, this._name);
        };
        return ElementAnimationStyleHandler;
    }());
    function playPauseAnimation(element, name, status) {
        var index = findIndexForAnimation(element, name);
        setAnimationStyle(element, 'PlayState', status, index);
    }
    function applyKeyframeAnimation(element, value) {
        var anim = getAnimationStyle(element, '').trim();
        var index = 0;
        if (anim.length) {
            index = countChars(anim, ',') + 1;
            value = anim + ", " + value;
        }
        setAnimationStyle(element, '', value);
        return index;
    }
    function removeKeyframeAnimation(element, name) {
        var anim = getAnimationStyle(element, '');
        var tokens = anim.split(',');
        var index = findMatchingTokenIndex(tokens, name);
        if (index >= 0) {
            tokens.splice(index, 1);
            var newValue = tokens.join(',');
            setAnimationStyle(element, '', newValue);
        }
    }
    function findIndexForAnimation(element, value) {
        var anim = getAnimationStyle(element, '');
        if (anim.indexOf(',') > 0) {
            var tokens = anim.split(',');
            return findMatchingTokenIndex(tokens, value);
        }
        return findMatchingTokenIndex([anim], value);
    }
    function findMatchingTokenIndex(tokens, searchToken) {
        for (var i = 0; i < tokens.length; i++) {
            if (tokens[i].indexOf(searchToken) >= 0) {
                return i;
            }
        }
        return -1;
    }
    function addRemoveAnimationEvent(element, fn, doRemove) {
        doRemove ? element.removeEventListener(ANIMATIONEND_EVENT, fn) :
            element.addEventListener(ANIMATIONEND_EVENT, fn);
    }
    function setAnimationStyle(element, name, value, index) {
        var prop = ANIMATION_PROP + name;
        if (index != null) {
            var oldValue = element.style[prop];
            if (oldValue.length) {
                var tokens = oldValue.split(',');
                tokens[index] = value;
                value = tokens.join(',');
            }
        }
        element.style[prop] = value;
    }
    function getAnimationStyle(element, name) {
        return element.style[ANIMATION_PROP + name] || '';
    }
    function countChars(value, char) {
        var count = 0;
        for (var i = 0; i < value.length; i++) {
            var c = value.charAt(i);
            if (c === char)
                count++;
        }
        return count;
    }

    var DEFAULT_FILL_MODE = 'forwards';
    var DEFAULT_EASING = 'linear';
    var CssKeyframesPlayer = /** @class */ (function () {
        function CssKeyframesPlayer(element, keyframes, animationName, _duration, _delay, easing, _finalStyles, _specialStyles) {
            this.element = element;
            this.keyframes = keyframes;
            this.animationName = animationName;
            this._duration = _duration;
            this._delay = _delay;
            this._finalStyles = _finalStyles;
            this._specialStyles = _specialStyles;
            this._onDoneFns = [];
            this._onStartFns = [];
            this._onDestroyFns = [];
            this._started = false;
            this.currentSnapshot = {};
            this._state = 0;
            this.easing = easing || DEFAULT_EASING;
            this.totalTime = _duration + _delay;
            this._buildStyler();
        }
        CssKeyframesPlayer.prototype.onStart = function (fn) {
            this._onStartFns.push(fn);
        };
        CssKeyframesPlayer.prototype.onDone = function (fn) {
            this._onDoneFns.push(fn);
        };
        CssKeyframesPlayer.prototype.onDestroy = function (fn) {
            this._onDestroyFns.push(fn);
        };
        CssKeyframesPlayer.prototype.destroy = function () {
            this.init();
            if (this._state >= 4 /* DESTROYED */)
                return;
            this._state = 4 /* DESTROYED */;
            this._styler.destroy();
            this._flushStartFns();
            this._flushDoneFns();
            if (this._specialStyles) {
                this._specialStyles.destroy();
            }
            this._onDestroyFns.forEach(function (fn) { return fn(); });
            this._onDestroyFns = [];
        };
        CssKeyframesPlayer.prototype._flushDoneFns = function () {
            this._onDoneFns.forEach(function (fn) { return fn(); });
            this._onDoneFns = [];
        };
        CssKeyframesPlayer.prototype._flushStartFns = function () {
            this._onStartFns.forEach(function (fn) { return fn(); });
            this._onStartFns = [];
        };
        CssKeyframesPlayer.prototype.finish = function () {
            this.init();
            if (this._state >= 3 /* FINISHED */)
                return;
            this._state = 3 /* FINISHED */;
            this._styler.finish();
            this._flushStartFns();
            if (this._specialStyles) {
                this._specialStyles.finish();
            }
            this._flushDoneFns();
        };
        CssKeyframesPlayer.prototype.setPosition = function (value) {
            this._styler.setPosition(value);
        };
        CssKeyframesPlayer.prototype.getPosition = function () {
            return this._styler.getPosition();
        };
        CssKeyframesPlayer.prototype.hasStarted = function () {
            return this._state >= 2 /* STARTED */;
        };
        CssKeyframesPlayer.prototype.init = function () {
            if (this._state >= 1 /* INITIALIZED */)
                return;
            this._state = 1 /* INITIALIZED */;
            var elm = this.element;
            this._styler.apply();
            if (this._delay) {
                this._styler.pause();
            }
        };
        CssKeyframesPlayer.prototype.play = function () {
            this.init();
            if (!this.hasStarted()) {
                this._flushStartFns();
                this._state = 2 /* STARTED */;
                if (this._specialStyles) {
                    this._specialStyles.start();
                }
            }
            this._styler.resume();
        };
        CssKeyframesPlayer.prototype.pause = function () {
            this.init();
            this._styler.pause();
        };
        CssKeyframesPlayer.prototype.restart = function () {
            this.reset();
            this.play();
        };
        CssKeyframesPlayer.prototype.reset = function () {
            this._styler.destroy();
            this._buildStyler();
            this._styler.apply();
        };
        CssKeyframesPlayer.prototype._buildStyler = function () {
            var _this = this;
            this._styler = new ElementAnimationStyleHandler(this.element, this.animationName, this._duration, this._delay, this.easing, DEFAULT_FILL_MODE, function () { return _this.finish(); });
        };
        /** @internal */
        CssKeyframesPlayer.prototype.triggerCallback = function (phaseName) {
            var methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
            methods.forEach(function (fn) { return fn(); });
            methods.length = 0;
        };
        CssKeyframesPlayer.prototype.beforeDestroy = function () {
            var _this = this;
            this.init();
            var styles = {};
            if (this.hasStarted()) {
                var finished_1 = this._state >= 3 /* FINISHED */;
                Object.keys(this._finalStyles).forEach(function (prop) {
                    if (prop != 'offset') {
                        styles[prop] = finished_1 ? _this._finalStyles[prop] : computeStyle(_this.element, prop);
                    }
                });
            }
            this.currentSnapshot = styles;
        };
        return CssKeyframesPlayer;
    }());

    var DirectStylePlayer = /** @class */ (function (_super) {
        __extends(DirectStylePlayer, _super);
        function DirectStylePlayer(element, styles) {
            var _this = _super.call(this) || this;
            _this.element = element;
            _this._startingStyles = {};
            _this.__initialized = false;
            _this._styles = hypenatePropsObject(styles);
            return _this;
        }
        DirectStylePlayer.prototype.init = function () {
            var _this = this;
            if (this.__initialized || !this._startingStyles)
                return;
            this.__initialized = true;
            Object.keys(this._styles).forEach(function (prop) {
                _this._startingStyles[prop] = _this.element.style[prop];
            });
            _super.prototype.init.call(this);
        };
        DirectStylePlayer.prototype.play = function () {
            var _this = this;
            if (!this._startingStyles)
                return;
            this.init();
            Object.keys(this._styles)
                .forEach(function (prop) { return _this.element.style.setProperty(prop, _this._styles[prop]); });
            _super.prototype.play.call(this);
        };
        DirectStylePlayer.prototype.destroy = function () {
            var _this = this;
            if (!this._startingStyles)
                return;
            Object.keys(this._startingStyles).forEach(function (prop) {
                var value = _this._startingStyles[prop];
                if (value) {
                    _this.element.style.setProperty(prop, value);
                }
                else {
                    _this.element.style.removeProperty(prop);
                }
            });
            this._startingStyles = null;
            _super.prototype.destroy.call(this);
        };
        return DirectStylePlayer;
    }(animations.NoopAnimationPlayer));

    var KEYFRAMES_NAME_PREFIX = 'gen_css_kf_';
    var TAB_SPACE = ' ';
    var CssKeyframesDriver = /** @class */ (function () {
        function CssKeyframesDriver() {
            this._count = 0;
            this._head = document.querySelector('head');
        }
        CssKeyframesDriver.prototype.validateStyleProperty = function (prop) {
            return validateStyleProperty(prop);
        };
        CssKeyframesDriver.prototype.matchesElement = function (element, selector) {
            return matchesElement(element, selector);
        };
        CssKeyframesDriver.prototype.containsElement = function (elm1, elm2) {
            return containsElement(elm1, elm2);
        };
        CssKeyframesDriver.prototype.query = function (element, selector, multi) {
            return invokeQuery(element, selector, multi);
        };
        CssKeyframesDriver.prototype.computeStyle = function (element, prop, defaultValue) {
            return window.getComputedStyle(element)[prop];
        };
        CssKeyframesDriver.prototype.buildKeyframeElement = function (element, name, keyframes) {
            keyframes = keyframes.map(function (kf) { return hypenatePropsObject(kf); });
            var keyframeStr = "@keyframes " + name + " {\n";
            var tab = '';
            keyframes.forEach(function (kf) {
                tab = TAB_SPACE;
                var offset = parseFloat(kf['offset']);
                keyframeStr += "" + tab + offset * 100 + "% {\n";
                tab += TAB_SPACE;
                Object.keys(kf).forEach(function (prop) {
                    var value = kf[prop];
                    switch (prop) {
                        case 'offset':
                            return;
                        case 'easing':
                            if (value) {
                                keyframeStr += tab + "animation-timing-function: " + value + ";\n";
                            }
                            return;
                        default:
                            keyframeStr += "" + tab + prop + ": " + value + ";\n";
                            return;
                    }
                });
                keyframeStr += tab + "}\n";
            });
            keyframeStr += "}\n";
            var kfElm = document.createElement('style');
            kfElm.textContent = keyframeStr;
            return kfElm;
        };
        CssKeyframesDriver.prototype.animate = function (element, keyframes, duration, delay, easing, previousPlayers, scrubberAccessRequested) {
            if (previousPlayers === void 0) { previousPlayers = []; }
            if ((typeof ngDevMode === 'undefined' || ngDevMode) && scrubberAccessRequested) {
                notifyFaultyScrubber();
            }
            var previousCssKeyframePlayers = previousPlayers.filter(function (player) { return player instanceof CssKeyframesPlayer; });
            var previousStyles = {};
            if (allowPreviousPlayerStylesMerge(duration, delay)) {
                previousCssKeyframePlayers.forEach(function (player) {
                    var styles = player.currentSnapshot;
                    Object.keys(styles).forEach(function (prop) { return previousStyles[prop] = styles[prop]; });
                });
            }
            keyframes = balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles);
            var finalStyles = flattenKeyframesIntoStyles(keyframes);
            // if there is no animation then there is no point in applying
            // styles and waiting for an event to get fired. This causes lag.
            // It's better to just directly apply the styles to the element
            // via the direct styling animation player.
            if (duration == 0) {
                return new DirectStylePlayer(element, finalStyles);
            }
            var animationName = "" + KEYFRAMES_NAME_PREFIX + this._count++;
            var kfElm = this.buildKeyframeElement(element, animationName, keyframes);
            document.querySelector('head').appendChild(kfElm);
            var specialStyles = packageNonAnimatableStyles(element, keyframes);
            var player = new CssKeyframesPlayer(element, keyframes, animationName, duration, delay, easing, finalStyles, specialStyles);
            player.onDestroy(function () { return removeElement(kfElm); });
            return player;
        };
        return CssKeyframesDriver;
    }());
    function flattenKeyframesIntoStyles(keyframes) {
        var flatKeyframes = {};
        if (keyframes) {
            var kfs = Array.isArray(keyframes) ? keyframes : [keyframes];
            kfs.forEach(function (kf) {
                Object.keys(kf).forEach(function (prop) {
                    if (prop == 'offset' || prop == 'easing')
                        return;
                    flatKeyframes[prop] = kf[prop];
                });
            });
        }
        return flatKeyframes;
    }
    function removeElement(node) {
        node.parentNode.removeChild(node);
    }
    var warningIssued = false;
    function notifyFaultyScrubber() {
        if (warningIssued)
            return;
        console.warn('@angular/animations: please load the web-animations.js polyfill to allow programmatic access...\n', '  visit https://bit.ly/IWukam to learn more about using the web-animation-js polyfill.');
        warningIssued = true;
    }

    var WebAnimationsPlayer = /** @class */ (function () {
        function WebAnimationsPlayer(element, keyframes, options, _specialStyles) {
            this.element = element;
            this.keyframes = keyframes;
            this.options = options;
            this._specialStyles = _specialStyles;
            this._onDoneFns = [];
            this._onStartFns = [];
            this._onDestroyFns = [];
            this._initialized = false;
            this._finished = false;
            this._started = false;
            this._destroyed = false;
            this.time = 0;
            this.parentPlayer = null;
            this.currentSnapshot = {};
            this._duration = options['duration'];
            this._delay = options['delay'] || 0;
            this.time = this._duration + this._delay;
        }
        WebAnimationsPlayer.prototype._onFinish = function () {
            if (!this._finished) {
                this._finished = true;
                this._onDoneFns.forEach(function (fn) { return fn(); });
                this._onDoneFns = [];
            }
        };
        WebAnimationsPlayer.prototype.init = function () {
            this._buildPlayer();
            this._preparePlayerBeforeStart();
        };
        WebAnimationsPlayer.prototype._buildPlayer = function () {
            var _this = this;
            if (this._initialized)
                return;
            this._initialized = true;
            var keyframes = this.keyframes;
            this.domPlayer =
                this._triggerWebAnimation(this.element, keyframes, this.options);
            this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : {};
            this.domPlayer.addEventListener('finish', function () { return _this._onFinish(); });
        };
        WebAnimationsPlayer.prototype._preparePlayerBeforeStart = function () {
            // this is required so that the player doesn't start to animate right away
            if (this._delay) {
                this._resetDomPlayerState();
            }
            else {
                this.domPlayer.pause();
            }
        };
        /** @internal */
        WebAnimationsPlayer.prototype._triggerWebAnimation = function (element, keyframes, options) {
            // jscompiler doesn't seem to know animate is a native property because it's not fully
            // supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
            return element['animate'](keyframes, options);
        };
        WebAnimationsPlayer.prototype.onStart = function (fn) {
            this._onStartFns.push(fn);
        };
        WebAnimationsPlayer.prototype.onDone = function (fn) {
            this._onDoneFns.push(fn);
        };
        WebAnimationsPlayer.prototype.onDestroy = function (fn) {
            this._onDestroyFns.push(fn);
        };
        WebAnimationsPlayer.prototype.play = function () {
            this._buildPlayer();
            if (!this.hasStarted()) {
                this._onStartFns.forEach(function (fn) { return fn(); });
                this._onStartFns = [];
                this._started = true;
                if (this._specialStyles) {
                    this._specialStyles.start();
                }
            }
            this.domPlayer.play();
        };
        WebAnimationsPlayer.prototype.pause = function () {
            this.init();
            this.domPlayer.pause();
        };
        WebAnimationsPlayer.prototype.finish = function () {
            this.init();
            if (this._specialStyles) {
                this._specialStyles.finish();
            }
            this._onFinish();
            this.domPlayer.finish();
        };
        WebAnimationsPlayer.prototype.reset = function () {
            this._resetDomPlayerState();
            this._destroyed = false;
            this._finished = false;
            this._started = false;
        };
        WebAnimationsPlayer.prototype._resetDomPlayerState = function () {
            if (this.domPlayer) {
                this.domPlayer.cancel();
            }
        };
        WebAnimationsPlayer.prototype.restart = function () {
            this.reset();
            this.play();
        };
        WebAnimationsPlayer.prototype.hasStarted = function () {
            return this._started;
        };
        WebAnimationsPlayer.prototype.destroy = function () {
            if (!this._destroyed) {
                this._destroyed = true;
                this._resetDomPlayerState();
                this._onFinish();
                if (this._specialStyles) {
                    this._specialStyles.destroy();
                }
                this._onDestroyFns.forEach(function (fn) { return fn(); });
                this._onDestroyFns = [];
            }
        };
        WebAnimationsPlayer.prototype.setPosition = function (p) {
            if (this.domPlayer === undefined) {
                this.init();
            }
            this.domPlayer.currentTime = p * this.time;
        };
        WebAnimationsPlayer.prototype.getPosition = function () {
            return this.domPlayer.currentTime / this.time;
        };
        Object.defineProperty(WebAnimationsPlayer.prototype, "totalTime", {
            get: function () {
                return this._delay + this._duration;
            },
            enumerable: false,
            configurable: true
        });
        WebAnimationsPlayer.prototype.beforeDestroy = function () {
            var _this = this;
            var styles = {};
            if (this.hasStarted()) {
                Object.keys(this._finalKeyframe).forEach(function (prop) {
                    if (prop != 'offset') {
                        styles[prop] =
                            _this._finished ? _this._finalKeyframe[prop] : computeStyle(_this.element, prop);
                    }
                });
            }
            this.currentSnapshot = styles;
        };
        /** @internal */
        WebAnimationsPlayer.prototype.triggerCallback = function (phaseName) {
            var methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
            methods.forEach(function (fn) { return fn(); });
            methods.length = 0;
        };
        return WebAnimationsPlayer;
    }());

    var WebAnimationsDriver = /** @class */ (function () {
        function WebAnimationsDriver() {
            this._isNativeImpl = /\{\s*\[native\s+code\]\s*\}/.test(getElementAnimateFn().toString());
            this._cssKeyframesDriver = new CssKeyframesDriver();
        }
        WebAnimationsDriver.prototype.validateStyleProperty = function (prop) {
            return validateStyleProperty(prop);
        };
        WebAnimationsDriver.prototype.matchesElement = function (element, selector) {
            return matchesElement(element, selector);
        };
        WebAnimationsDriver.prototype.containsElement = function (elm1, elm2) {
            return containsElement(elm1, elm2);
        };
        WebAnimationsDriver.prototype.query = function (element, selector, multi) {
            return invokeQuery(element, selector, multi);
        };
        WebAnimationsDriver.prototype.computeStyle = function (element, prop, defaultValue) {
            return window.getComputedStyle(element)[prop];
        };
        WebAnimationsDriver.prototype.overrideWebAnimationsSupport = function (supported) {
            this._isNativeImpl = supported;
        };
        WebAnimationsDriver.prototype.animate = function (element, keyframes, duration, delay, easing, previousPlayers, scrubberAccessRequested) {
            if (previousPlayers === void 0) { previousPlayers = []; }
            var useKeyframes = !scrubberAccessRequested && !this._isNativeImpl;
            if (useKeyframes) {
                return this._cssKeyframesDriver.animate(element, keyframes, duration, delay, easing, previousPlayers);
            }
            var fill = delay == 0 ? 'both' : 'forwards';
            var playerOptions = { duration: duration, delay: delay, fill: fill };
            // we check for this to avoid having a null|undefined value be present
            // for the easing (which results in an error for certain browsers #9752)
            if (easing) {
                playerOptions['easing'] = easing;
            }
            var previousStyles = {};
            var previousWebAnimationPlayers = previousPlayers.filter(function (player) { return player instanceof WebAnimationsPlayer; });
            if (allowPreviousPlayerStylesMerge(duration, delay)) {
                previousWebAnimationPlayers.forEach(function (player) {
                    var styles = player.currentSnapshot;
                    Object.keys(styles).forEach(function (prop) { return previousStyles[prop] = styles[prop]; });
                });
            }
            keyframes = keyframes.map(function (styles) { return copyStyles(styles, false); });
            keyframes = balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles);
            var specialStyles = packageNonAnimatableStyles(element, keyframes);
            return new WebAnimationsPlayer(element, keyframes, playerOptions, specialStyles);
        };
        return WebAnimationsDriver;
    }());
    function supportsWebAnimations() {
        return typeof getElementAnimateFn() === 'function';
    }
    function getElementAnimateFn() {
        return (isBrowser() && Element.prototype['animate']) || {};
    }

    /**
     * @license
     * Copyright Google LLC 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 LLC 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 LLC 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 LLC 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.AnimationDriver = AnimationDriver;
    exports.ɵAnimation = Animation;
    exports.ɵAnimationEngine = AnimationEngine;
    exports.ɵAnimationStyleNormalizer = AnimationStyleNormalizer;
    exports.ɵCssKeyframesDriver = CssKeyframesDriver;
    exports.ɵCssKeyframesPlayer = CssKeyframesPlayer;
    exports.ɵNoopAnimationDriver = NoopAnimationDriver;
    exports.ɵNoopAnimationStyleNormalizer = NoopAnimationStyleNormalizer;
    exports.ɵWebAnimationsDriver = WebAnimationsDriver;
    exports.ɵWebAnimationsPlayer = WebAnimationsPlayer;
    exports.ɵWebAnimationsStyleNormalizer = WebAnimationsStyleNormalizer;
    exports.ɵallowPreviousPlayerStylesMerge = allowPreviousPlayerStylesMerge;
    exports.ɵangular_packages_animations_browser_browser_a = SpecialCasedStyles;
    exports.ɵcontainsElement = containsElement;
    exports.ɵinvokeQuery = invokeQuery;
    exports.ɵmatchesElement = matchesElement;
    exports.ɵsupportsWebAnimations = supportsWebAnimations;
    exports.ɵvalidateStyleProperty = validateStyleProperty;

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

})));
//# sourceMappingURL=animations-browser.umd.js.map
