/**
 * @license Angular v11.2.14
 * (c) 2010-2021 Google LLC. https://angular.io/
 * License: MIT
 */
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define("@angular/animations",["exports"],n):n(((t=t||self).ng=t.ng||{},t.ng.animations={}))}(this,(function(t){"use strict";var n=function n(){},o=function o(){};
/**
     * @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 i(t){Promise.resolve(null).then(t)}
/**
     * @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 e=function(){function t(t,n){void 0===t&&(t=0),void 0===n&&(n=0),this._onDoneFns=[],this._onStartFns=[],this._onDestroyFns=[],this._started=!1,this._destroyed=!1,this._finished=!1,this._position=0,this.parentPlayer=null,this.totalTime=t+n}return t.prototype._onFinish=function(){this._finished||(this._finished=!0,this._onDoneFns.forEach((function(t){return t()})),this._onDoneFns=[])},t.prototype.onStart=function(t){this._onStartFns.push(t)},t.prototype.onDone=function(t){this._onDoneFns.push(t)},t.prototype.onDestroy=function(t){this._onDestroyFns.push(t)},t.prototype.hasStarted=function(){return this._started},t.prototype.init=function(){},t.prototype.play=function(){this.hasStarted()||(this._onStart(),this.triggerMicrotask()),this._started=!0},t.prototype.triggerMicrotask=function(){var t=this;i((function(){return t._onFinish()}))},t.prototype._onStart=function(){this._onStartFns.forEach((function(t){return t()})),this._onStartFns=[]},t.prototype.pause=function(){},t.prototype.restart=function(){},t.prototype.finish=function(){this._onFinish()},t.prototype.destroy=function(){this._destroyed||(this._destroyed=!0,this.hasStarted()||this._onStart(),this.finish(),this._onDestroyFns.forEach((function(t){return t()})),this._onDestroyFns=[])},t.prototype.reset=function(){},t.prototype.setPosition=function(t){this._position=this.totalTime?t*this.totalTime:1},t.prototype.getPosition=function(){return this.totalTime?this._position/this.totalTime:1},t.prototype.triggerCallback=function(t){var n="start"==t?this._onStartFns:this._onDoneFns;n.forEach((function(t){return t()})),n.length=0},t}(),s=function(){function t(t){var n=this;this._onDoneFns=[],this._onStartFns=[],this._finished=!1,this._started=!1,this._destroyed=!1,this._onDestroyFns=[],this.parentPlayer=null,this.totalTime=0,this.players=t;var o=0,e=0,s=0,r=this.players.length;0==r?i((function(){return n._onFinish()})):this.players.forEach((function(t){t.onDone((function(){++o==r&&n._onFinish()})),t.onDestroy((function(){++e==r&&n._onDestroy()})),t.onStart((function(){++s==r&&n._onStart()}))})),this.totalTime=this.players.reduce((function(t,n){return Math.max(t,n.totalTime)}),0)}return t.prototype._onFinish=function(){this._finished||(this._finished=!0,this._onDoneFns.forEach((function(t){return t()})),this._onDoneFns=[])},t.prototype.init=function(){this.players.forEach((function(t){return t.init()}))},t.prototype.onStart=function(t){this._onStartFns.push(t)},t.prototype._onStart=function(){this.hasStarted()||(this._started=!0,this._onStartFns.forEach((function(t){return t()})),this._onStartFns=[])},t.prototype.onDone=function(t){this._onDoneFns.push(t)},t.prototype.onDestroy=function(t){this._onDestroyFns.push(t)},t.prototype.hasStarted=function(){return this._started},t.prototype.play=function(){this.parentPlayer||this.init(),this._onStart(),this.players.forEach((function(t){return t.play()}))},t.prototype.pause=function(){this.players.forEach((function(t){return t.pause()}))},t.prototype.restart=function(){this.players.forEach((function(t){return t.restart()}))},t.prototype.finish=function(){this._onFinish(),this.players.forEach((function(t){return t.finish()}))},t.prototype.destroy=function(){this._onDestroy()},t.prototype._onDestroy=function(){this._destroyed||(this._destroyed=!0,this._onFinish(),this.players.forEach((function(t){return t.destroy()})),this._onDestroyFns.forEach((function(t){return t()})),this._onDestroyFns=[])},t.prototype.reset=function(){this.players.forEach((function(t){return t.reset()})),this._destroyed=!1,this._finished=!1,this._started=!1},t.prototype.setPosition=function(t){var n=t*this.totalTime;this.players.forEach((function(t){var o=t.totalTime?Math.min(1,n/t.totalTime):1;t.setPosition(o)}))},t.prototype.getPosition=function(){var t=this.players.reduce((function(t,n){return null===t||n.totalTime>t.totalTime?n:t}),null);return null!=t?t.getPosition():0},t.prototype.beforeDestroy=function(){this.players.forEach((function(t){t.beforeDestroy&&t.beforeDestroy()}))},t.prototype.triggerCallback=function(t){var n="start"==t?this._onStartFns:this._onDoneFns;n.forEach((function(t){return t()})),n.length=0},t}();
/**
     * @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
     */
t.AUTO_STYLE="*",t.AnimationBuilder=n,t.AnimationFactory=o,t.NoopAnimationPlayer=e,t.animate=function r(t,n){return void 0===n&&(n=null),{type:4,styles:n,timings:t}},t.animateChild=function u(t){return void 0===t&&(t=null),{type:9,options:t}},t.animation=function a(t,n){return void 0===n&&(n=null),{type:8,animation:t,options:n}},t.group=function h(t,n){return void 0===n&&(n=null),{type:3,steps:t,options:n}},t.keyframes=function p(t){return{type:5,steps:t}},t.query=function f(t,n,o){return void 0===o&&(o=null),{type:11,selector:t,animation:n,options:o}},t.sequence=function c(t,n){return void 0===n&&(n=null),{type:2,steps:t,options:n}},t.stagger=function y(t,n){return{type:12,timings:t,animation:n}},t.state=function l(t,n,o){return{type:0,name:t,styles:n,options:o}},t.style=function _(t){return{type:6,styles:t,offset:null}},t.transition=function d(t,n,o){return void 0===o&&(o=null),{type:1,expr:t,animation:n,options:o}},t.trigger=function m(t,n){return{type:7,name:t,definitions:n,options:{}}},t.useAnimation=function F(t,n){return void 0===n&&(n=null),{type:10,animation:t,options:n}},t.ɵAnimationGroupPlayer=s,t.ɵPRE_STYLE="!",Object.defineProperty(t,"__esModule",{value:!0})}));