text: /**
   * @license Angular v6.1.9
   * (c) 2010-2018 Google, Inc. https://angular.io/
   * License: MIT
   */
  
  (function (global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/platform-browser-dynamic')) :
      typeof define === 'function' && define.amd ? define('@angular/upgrade', ['exports', '@angular/core', '@angular/platform-browser-dynamic'], factory) :
      (factory((global.ng = global.ng || {}, global.ng.upgrade = {}),global.ng.core,global.ng.platformBrowserDynamic));
  }(this, (function (exports,core,platformBrowserDynamic) { 'use strict';
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      var VERSION = new core.Version('6.1.9');
  
      /*! *****************************************************************************
      Copyright (c) Microsoft Corporation. All rights reserved.
      Licensed under the Apache License, Version 2.0 (the "License"); you may not use
      this file except in compliance with the License. You may obtain a copy of the
      License at http://www.apache.org/licenses/LICENSE-2.0
  
      THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
      WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
      MERCHANTABLITY OR NON-INFRINGEMENT.
  
      See the Apache Version 2.0 License for specific language governing permissions
      and limitations under the License.
      ***************************************************************************** */
  
      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 __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 __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;
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      function noNg() {
          throw new Error('AngularJS v1.x is not loaded!');
      }
      var angular = {
          bootstrap: noNg,
          module: noNg,
          element: noNg,
          version: undefined,
          resumeBootstrap: noNg,
          getTestability: noNg
      };
      try {
          if (window.hasOwnProperty('angular')) {
              angular = window.angular;
          }
      }
      catch (e) {
          // ignore in CJS mode.
      }
      var bootstrap = function (e, modules, config) {
          return angular.bootstrap(e, modules, config);
      };
      var module$1 = function (prefix, dependencies) {
          return angular.module(prefix, dependencies);
      };
      var element = function (e) { return angular.element(e); };
      var version = angular.version;
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      var $COMPILE = '$compile';
      var $CONTROLLER = '$controller';
      var $HTTP_BACKEND = '$httpBackend';
      var $INJECTOR = '$injector';
      var $PARSE = '$parse';
      var $ROOT_SCOPE = '$rootScope';
      var $SCOPE = '$scope';
      var $TEMPLATE_CACHE = '$templateCache';
      var $$TESTABILITY = '$$testability';
      var COMPILER_KEY = '$$angularCompiler';
      var INJECTOR_KEY = '$$angularInjector';
      var LAZY_MODULE_REF = '$$angularLazyModuleRef';
      var NG_ZONE_KEY = '$$angularNgZone';
      var REQUIRE_INJECTOR = '?^^' + INJECTOR_KEY;
      var REQUIRE_NG_MODEL = '?ngModel';
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * A `PropertyBinding` represents a mapping between a property name
       * and an attribute name. It is parsed from a string of the form
       * `"prop: attr"`; or simply `"propAndAttr" where the property
       * and attribute have the same identifier.
       */
      var PropertyBinding = /** @class */ (function () {
          function PropertyBinding(prop, attr) {
              this.prop = prop;
              this.attr = attr;
              this.parseBinding();
          }
          PropertyBinding.prototype.parseBinding = function () {
              this.bracketAttr = "[" + this.attr + "]";
              this.parenAttr = "(" + this.attr + ")";
              this.bracketParenAttr = "[(" + this.attr + ")]";
              var capitalAttr = this.attr.charAt(0).toUpperCase() + this.attr.substr(1);
              this.onAttr = "on" + capitalAttr;
              this.bindAttr = "bind" + capitalAttr;
              this.bindonAttr = "bindon" + capitalAttr;
          };
          return PropertyBinding;
      }());
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      var DIRECTIVE_PREFIX_REGEXP = /^(?:x|data)[:\-_]/i;
      var DIRECTIVE_SPECIAL_CHARS_REGEXP = /[:\-_]+(.)/g;
      function onError(e) {
          // TODO: (misko): We seem to not have a stack trace here!
          if (console.error) {
              console.error(e, e.stack);
          }
          else {
              // tslint:disable-next-line:no-console
              console.log(e, e.stack);
          }
          throw e;
      }
      function controllerKey(name) {
          return '$' + name + 'Controller';
      }
      function directiveNormalize(name) {
          return name.replace(DIRECTIVE_PREFIX_REGEXP, '')
              .replace(DIRECTIVE_SPECIAL_CHARS_REGEXP, function (_, letter) { return letter.toUpperCase(); });
      }
      function getComponentName(component) {
          // Return the name of the component or the first line of its stringified version.
          return component.overriddenName || component.name || component.toString().split('\n')[0];
      }
      function isFunction(value) {
          return typeof value === 'function';
      }
      var Deferred = /** @class */ (function () {
          function Deferred() {
              var _this = this;
              this.promise = new Promise(function (res, rej) {
                  _this.resolve = res;
                  _this.reject = rej;
              });
          }
          return Deferred;
      }());
      /**
       * @return Whether the passed-in component implements the subset of the
       *     `ControlValueAccessor` interface needed for AngularJS `ng-model`
       *     compatibility.
       */
      function supportsNgModel(component) {
          return typeof component.writeValue === 'function' &&
              typeof component.registerOnChange === 'function';
      }
      /**
       * Glue the AngularJS `NgModelController` (if it exists) to the component
       * (if it implements the needed subset of the `ControlValueAccessor` interface).
       */
      function hookupNgModel(ngModel, component) {
          if (ngModel && supportsNgModel(component)) {
              ngModel.$render = function () { component.writeValue(ngModel.$viewValue); };
              component.registerOnChange(ngModel.$setViewValue.bind(ngModel));
              if (typeof component.registerOnTouched === 'function') {
                  component.registerOnTouched(ngModel.$setTouched.bind(ngModel));
              }
          }
      }
      /**
       * Test two values for strict equality, accounting for the fact that `NaN !== NaN`.
       */
      function strictEquals(val1, val2) {
          return val1 === val2 || (val1 !== val1 && val2 !== val2);
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      var INITIAL_VALUE = {
          __UNINITIALIZED__: true
      };
      var DowngradeComponentAdapter = /** @class */ (function () {
          function DowngradeComponentAdapter(element, attrs, scope, ngModel, parentInjector, $injector, $compile, $parse, componentFactory, wrapCallback) {
              this.element = element;
              this.attrs = attrs;
              this.scope = scope;
              this.ngModel = ngModel;
              this.parentInjector = parentInjector;
              this.$injector = $injector;
              this.$compile = $compile;
              this.$parse = $parse;
              this.componentFactory = componentFactory;
              this.wrapCallback = wrapCallback;
              this.implementsOnChanges = false;
              this.inputChangeCount = 0;
              this.inputChanges = {};
              this.componentScope = scope.$new();
          }
          DowngradeComponentAdapter.prototype.compileContents = function () {
              var _this = this;
              var compiledProjectableNodes = [];
              var projectableNodes = this.groupProjectableNodes();
              var linkFns = projectableNodes.map(function (nodes) { return _this.$compile(nodes); });
              this.element.empty();
              linkFns.forEach(function (linkFn) {
                  linkFn(_this.scope, function (clone) {
                      compiledProjectableNodes.push(clone);
                      _this.element.append(clone);
                  });
              });
              return compiledProjectableNodes;
          };
          DowngradeComponentAdapter.prototype.createComponent = function (projectableNodes) {
              var providers = [{ provide: $SCOPE, useValue: this.componentScope }];
              var childInjector = core.Injector.create({ providers: providers, parent: this.parentInjector, name: 'DowngradeComponentAdapter' });
              this.componentRef =
                  this.componentFactory.create(childInjector, projectableNodes, this.element[0]);
              this.viewChangeDetector = this.componentRef.injector.get(core.ChangeDetectorRef);
              this.changeDetector = this.componentRef.changeDetectorRef;
              this.component = this.componentRef.instance;
              // testability hook is commonly added during component bootstrap in
              // packages/core/src/application_ref.bootstrap()
              // in downgraded application, component creation will take place here as well as adding the
              // testability hook.
              var testability = this.componentRef.injector.get(core.Testability, null);
              if (testability) {
                  this.componentRef.injector.get(core.TestabilityRegistry)
                      .registerApplication(this.componentRef.location.nativeElement, testability);
              }
              hookupNgModel(this.ngModel, this.component);
          };
          DowngradeComponentAdapter.prototype.setupInputs = function (needsNgZone, propagateDigest) {
              var _this = this;
              if (propagateDigest === void 0) { propagateDigest = true; }
              var attrs = this.attrs;
              var inputs = this.componentFactory.inputs || [];
              var _loop_1 = function (i) {
                  var input = new PropertyBinding(inputs[i].propName, inputs[i].templateName);
                  var expr = null;
                  if (attrs.hasOwnProperty(input.attr)) {
                      var observeFn_1 = (function (prop) {
                          var prevValue = INITIAL_VALUE;
                          return function (currValue) {
                              // Initially, both `$observe()` and `$watch()` will call this function.
                              if (!strictEquals(prevValue, currValue)) {
                                  if (prevValue === INITIAL_VALUE) {
                                      prevValue = currValue;
                                  }
                                  _this.updateInput(prop, prevValue, currValue);
                                  prevValue = currValue;
                              }
                          };
                      })(input.prop);
                      attrs.$observe(input.attr, observeFn_1);
                      // Use `$watch()` (in addition to `$observe()`) in order to initialize the input in time
                      // for `ngOnChanges()`. This is necessary if we are already in a `$digest`, which means that
                      // `ngOnChanges()` (which is called by a watcher) will run before the `$observe()` callback.
                      var unwatch_1 = this_1.componentScope.$watch(function () {
                          unwatch_1();
                          unwatch_1 = null;
                          observeFn_1(attrs[input.attr]);
                      });
                  }
                  else if (attrs.hasOwnProperty(input.bindAttr)) {
                      expr = attrs[input.bindAttr];
                  }
                  else if (attrs.hasOwnProperty(input.bracketAttr)) {
                      expr = attrs[input.bracketAttr];
                  }
                  else if (attrs.hasOwnProperty(input.bindonAttr)) {
                      expr = attrs[input.bindonAttr];
                  }
                  else if (attrs.hasOwnProperty(input.bracketParenAttr)) {
                      expr = attrs[input.bracketParenAttr];
                  }
                  if (expr != null) {
                      var watchFn = (function (prop) { return function (currValue, prevValue) {
                          return _this.updateInput(prop, prevValue, currValue);
                      }; })(input.prop);
                      this_1.componentScope.$watch(expr, watchFn);
                  }
              };
              var this_1 = this;
              for (var i = 0; i < inputs.length; i++) {
                  _loop_1(i);
              }
              // Invoke `ngOnChanges()` and Change Detection (when necessary)
              var detectChanges = function () { return _this.changeDetector.detectChanges(); };
              var prototype = this.componentFactory.componentType.prototype;
              this.implementsOnChanges = !!(prototype && prototype.ngOnChanges);
              this.componentScope.$watch(function () { return _this.inputChangeCount; }, this.wrapCallback(function () {
                  // Invoke `ngOnChanges()`
                  if (_this.implementsOnChanges) {
                      var inputChanges = _this.inputChanges;
                      _this.inputChanges = {};
                      _this.component.ngOnChanges(inputChanges);
                  }
                  _this.viewChangeDetector.markForCheck();
                  // If opted out of propagating digests, invoke change detection when inputs change.
                  if (!propagateDigest) {
                      detectChanges();
                  }
              }));
              // If not opted out of propagating digests, invoke change detection on every digest
              if (propagateDigest) {
                  this.componentScope.$watch(this.wrapCallback(detectChanges));
              }
              // If necessary, attach the view so that it will be dirty-checked.
              // (Allow time for the initial input values to be set and `ngOnChanges()` to be called.)
              if (needsNgZone || !propagateDigest) {
                  var unwatch_2 = this.componentScope.$watch(function () {
                      unwatch_2();
                      unwatch_2 = null;
                      var appRef = _this.parentInjector.get(core.ApplicationRef);
                      appRef.attachView(_this.componentRef.hostView);
                  });
              }
          };
          DowngradeComponentAdapter.prototype.setupOutputs = function () {
              var attrs = this.attrs;
              var outputs = this.componentFactory.outputs || [];
              for (var j = 0; j < outputs.length; j++) {
                  var output = new PropertyBinding(outputs[j].propName, outputs[j].templateName);
                  var bindonAttr = output.bindonAttr.substring(0, output.bindonAttr.length - 6);
                  var bracketParenAttr = "[(" + output.bracketParenAttr.substring(2, output.bracketParenAttr.length - 8) + ")]";
                  // order below is important - first update bindings then evaluate expressions
                  if (attrs.hasOwnProperty(bindonAttr)) {
                      this.subscribeToOutput(output, attrs[bindonAttr], true);
                  }
                  if (attrs.hasOwnProperty(bracketParenAttr)) {
                      this.subscribeToOutput(output, attrs[bracketParenAttr], true);
                  }
                  if (attrs.hasOwnProperty(output.onAttr)) {
                      this.subscribeToOutput(output, attrs[output.onAttr]);
                  }
                  if (attrs.hasOwnProperty(output.parenAttr)) {
                      this.subscribeToOutput(output, attrs[output.parenAttr]);
                  }
              }
          };
          DowngradeComponentAdapter.prototype.subscribeToOutput = function (output, expr, isAssignment) {
              var _this = this;
              if (isAssignment === void 0) { isAssignment = false; }
              var getter = this.$parse(expr);
              var setter = getter.assign;
              if (isAssignment && !setter) {
                  throw new Error("Expression '" + expr + "' is not assignable!");
              }
              var emitter = this.component[output.prop];
              if (emitter) {
                  emitter.subscribe({
                      next: isAssignment ? function (v) { return setter(_this.scope, v); } :
                          function (v) { return getter(_this.scope, { '$event': v }); }
                  });
              }
              else {
                  throw new Error("Missing emitter '" + output.prop + "' on component '" + getComponentName(this.componentFactory.componentType) + "'!");
              }
          };
          DowngradeComponentAdapter.prototype.registerCleanup = function () {
              var _this = this;
              var destroyComponentRef = this.wrapCallback(function () { return _this.componentRef.destroy(); });
              var destroyed = false;
              this.element.on('$destroy', function () { return _this.componentScope.$destroy(); });
              this.componentScope.$on('$destroy', function () {
                  if (!destroyed) {
                      destroyed = true;
                      _this.componentRef.injector.get(core.TestabilityRegistry)
                          .unregisterApplication(_this.componentRef.location.nativeElement);
                      destroyComponentRef();
                  }
              });
          };
          DowngradeComponentAdapter.prototype.getInjector = function () { return this.componentRef.injector; };
          DowngradeComponentAdapter.prototype.updateInput = function (prop, prevValue, currValue) {
              if (this.implementsOnChanges) {
                  this.inputChanges[prop] = new core.SimpleChange(prevValue, currValue, prevValue === currValue);
              }
              this.inputChangeCount++;
              this.component[prop] = currValue;
          };
          DowngradeComponentAdapter.prototype.groupProjectableNodes = function () {
              var ngContentSelectors = this.componentFactory.ngContentSelectors;
              return groupNodesBySelector(ngContentSelectors, this.element.contents());
          };
          return DowngradeComponentAdapter;
      }());
      /**
       * Group a set of DOM nodes into `ngContent` groups, based on the given content selectors.
       */
      function groupNodesBySelector(ngContentSelectors, nodes) {
          var projectableNodes = [];
          for (var i = 0, ii = ngContentSelectors.length; i < ii; ++i) {
              projectableNodes[i] = [];
          }
          for (var j = 0, jj = nodes.length; j < jj; ++j) {
              var node = nodes[j];
              var ngContentIndex = findMatchingNgContentIndex(node, ngContentSelectors);
              if (ngContentIndex != null) {
                  projectableNodes[ngContentIndex].push(node);
              }
          }
          return projectableNodes;
      }
      function findMatchingNgContentIndex(element, ngContentSelectors) {
          var ngContentIndices = [];
          var wildcardNgContentIndex = -1;
          for (var i = 0; i < ngContentSelectors.length; i++) {
              var selector = ngContentSelectors[i];
              if (selector === '*') {
                  wildcardNgContentIndex = i;
              }
              else {
                  if (matchesSelector(element, selector)) {
                      ngContentIndices.push(i);
                  }
              }
          }
          ngContentIndices.sort();
          if (wildcardNgContentIndex !== -1) {
              ngContentIndices.push(wildcardNgContentIndex);
          }
          return ngContentIndices.length ? ngContentIndices[0] : null;
      }
      var _matches;
      function matchesSelector(el, selector) {
          if (!_matches) {
              var elProto = Element.prototype;
              _matches = elProto.matches || elProto.matchesSelector || elProto.mozMatchesSelector ||
                  elProto.msMatchesSelector || elProto.oMatchesSelector || elProto.webkitMatchesSelector;
          }
          return el.nodeType === Node.ELEMENT_NODE ? _matches.call(el, selector) : false;
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * @description
       *
       * A helper function that allows an Angular component to be used from AngularJS.
       *
       * *Part of the [upgrade/static](api?query=upgrade%2Fstatic)
       * library for hybrid upgrade apps that support AoT compilation*
       *
       * This helper function returns a factory function to be used for registering
       * an AngularJS wrapper directive for "downgrading" an Angular component.
       *
       * @usageNotes
       * ### Examples
       *
       * Let's assume that you have an Angular component called `ng2Heroes` that needs
       * to be made available in AngularJS templates.
       *
       * {@example upgrade/static/ts/full/module.ts region="ng2-heroes"}
       *
       * We must create an AngularJS [directive](https://docs.angularjs.org/guide/directive)
       * that will make this Angular component available inside AngularJS templates.
       * The `downgradeComponent()` function returns a factory function that we
       * can use to define the AngularJS directive that wraps the "downgraded" component.
       *
       * {@example upgrade/static/ts/full/module.ts region="ng2-heroes-wrapper"}
       *
       * @param info contains information about the Component that is being downgraded:
       *
       * * `component: Type<any>`: The type of the Component that will be downgraded
       * * `propagateDigest?: boolean`: Whether to perform {@link ChangeDetectorRef#detectChanges
       *   change detection} on the component on every
       *   [$digest](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest). If set to `false`,
       *   change detection will still be performed when any of the component's inputs changes.
       *   (Default: true)
       *
       * @returns a factory function that can be used to register the component in an
       * AngularJS module.
       *
       * @experimental
       */
      function downgradeComponent(info) {
          var directiveFactory = function ($compile, $injector, $parse) {
              // When using `UpgradeModule`, we don't need to ensure callbacks to Angular APIs (e.g. change
              // detection) are run inside the Angular zone, because `$digest()` will be run inside the zone
              // (except if explicitly escaped, in which case we shouldn't force it back in).
              // When using `downgradeModule()` though, we need to ensure such callbacks are run inside the
              // Angular zone.
              var needsNgZone = false;
              var wrapCallback = function (cb) { return cb; };
              var ngZone;
              return {
                  restrict: 'E',
                  terminal: true,
                  require: [REQUIRE_INJECTOR, REQUIRE_NG_MODEL],
                  link: function (scope, element, attrs, required) {
                      // We might have to compile the contents asynchronously, because this might have been
                      // triggered by `UpgradeNg1ComponentAdapterBuilder`, before the Angular templates have
                      // been compiled.
                      var ngModel = required[1];
                      var parentInjector = required[0];
                      var ranAsync = false;
                      if (!parentInjector) {
                          var lazyModuleRef = $injector.get(LAZY_MODULE_REF);
                          needsNgZone = lazyModuleRef.needsNgZone;
                          parentInjector = lazyModuleRef.injector || lazyModuleRef.promise;
                      }
                      var doDowngrade = function (injector) {
                          var componentFactoryResolver = injector.get(core.ComponentFactoryResolver);
                          var componentFactory = componentFactoryResolver.resolveComponentFactory(info.component);
                          if (!componentFactory) {
                              throw new Error('Expecting ComponentFactory for: ' + getComponentName(info.component));
                          }
                          var injectorPromise = new ParentInjectorPromise(element);
                          var facade = new DowngradeComponentAdapter(element, attrs, scope, ngModel, injector, $injector, $compile, $parse, componentFactory, wrapCallback);
                          var projectableNodes = facade.compileContents();
                          facade.createComponent(projectableNodes);
                          facade.setupInputs(needsNgZone, info.propagateDigest);
                          facade.setupOutputs();
                          facade.registerCleanup();
                          injectorPromise.resolve(facade.getInjector());
                          if (ranAsync) {
                              // If this is run async, it is possible that it is not run inside a
                              // digest and initial input values will not be detected.
                              scope.$evalAsync(function () { });
                          }
                      };
                      var downgradeFn = !needsNgZone ? doDowngrade : function (injector) {
                          if (!ngZone) {
                              ngZone = injector.get(core.NgZone);
                              wrapCallback = function (cb) { return function () {
                                  return core.NgZone.isInAngularZone() ? cb() : ngZone.run(cb);
                              }; };
                          }
                          wrapCallback(function () { return doDowngrade(injector); })();
                      };
                      if (isThenable(parentInjector)) {
                          parentInjector.then(downgradeFn);
                      }
                      else {
                          downgradeFn(parentInjector);
                      }
                      ranAsync = true;
                  }
              };
          };
          // bracket-notation because of closure - see #14441
          directiveFactory['$inject'] = [$COMPILE, $INJECTOR, $PARSE];
          return directiveFactory;
      }
      /**
       * Synchronous promise-like object to wrap parent injectors,
       * to preserve the synchronous nature of Angular 1's $compile.
       */
      var ParentInjectorPromise = /** @class */ (function () {
          function ParentInjectorPromise(element) {
              this.element = element;
              this.injectorKey = controllerKey(INJECTOR_KEY);
              this.callbacks = [];
              // Store the promise on the element.
              element.data(this.injectorKey, this);
          }
          ParentInjectorPromise.prototype.then = function (callback) {
              if (this.injector) {
                  callback(this.injector);
              }
              else {
                  this.callbacks.push(callback);
              }
          };
          ParentInjectorPromise.prototype.resolve = function (injector) {
              this.injector = injector;
              // Store the real injector on the element.
              this.element.data(this.injectorKey, injector);
              // Release the element to prevent memory leaks.
              this.element = null;
              // Run the queued callbacks.
              this.callbacks.forEach(function (callback) { return callback(injector); });
              this.callbacks.length = 0;
          };
          return ParentInjectorPromise;
      }());
      function isThenable(obj) {
          return isFunction(obj.then);
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * @description
       *
       * A helper function to allow an Angular service to be accessible from AngularJS.
       *
       * *Part of the [upgrade/static](api?query=upgrade%2Fstatic)
       * library for hybrid upgrade apps that support AoT compilation*
       *
       * This helper function returns a factory function that provides access to the Angular
       * service identified by the `token` parameter.
       *
       * @usageNotes
       * ### Examples
       *
       * First ensure that the service to be downgraded is provided in an `NgModule`
       * that will be part of the upgrade application. For example, let's assume we have
       * defined `HeroesService`
       *
       * {@example upgrade/static/ts/full/module.ts region="ng2-heroes-service"}
       *
       * and that we have included this in our upgrade app `NgModule`
       *
       * {@example upgrade/static/ts/full/module.ts region="ng2-module"}
       *
       * Now we can register the `downgradeInjectable` factory function for the service
       * on an AngularJS module.
       *
       * {@example upgrade/static/ts/full/module.ts region="downgrade-ng2-heroes-service"}
       *
       * Inside an AngularJS component's controller we can get hold of the
       * downgraded service via the name we gave when downgrading.
       *
       * {@example upgrade/static/ts/full/module.ts region="example-app"}
       *
       * @param token an `InjectionToken` that identifies a service provided from Angular.
       *
       * @returns a [factory function](https://docs.angularjs.org/guide/di) that can be
       * used to register the service on an AngularJS module.
       *
       * @experimental
       */
      function downgradeInjectable(token) {
          var factory = function (i) { return i.get(token); };
          factory['$inject'] = [INJECTOR_KEY];
          return factory;
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      // Constants
      var REQUIRE_PREFIX_RE = /^(\^\^?)?(\?)?(\^\^?)?/;
      // Classes
      var UpgradeHelper = /** @class */ (function () {
          function UpgradeHelper(injector, name, elementRef, directive) {
              this.injector = injector;
              this.name = name;
              this.$injector = injector.get($INJECTOR);
              this.$compile = this.$injector.get($COMPILE);
              this.$controller = this.$injector.get($CONTROLLER);
              this.element = elementRef.nativeElement;
              this.$element = element(this.element);
              this.directive = directive || UpgradeHelper.getDirective(this.$injector, name);
          }
          UpgradeHelper.getDirective = function ($injector, name) {
              var directives = $injector.get(name + 'Directive');
              if (directives.length > 1) {
                  throw new Error("Only support single directive definition for: " + name);
              }
              var directive = directives[0];
              // AngularJS will transform `link: xyz` to `compile: () => xyz`. So we can only tell there was a
              // user-defined `compile` if there is no `link`. In other cases, we will just ignore `compile`.
              if (directive.compile && !directive.link)
                  notSupported(name, 'compile');
              if (directive.replace)
                  notSupported(name, 'replace');
              if (directive.terminal)
                  notSupported(name, 'terminal');
              return directive;
          };
          UpgradeHelper.getTemplate = function ($injector, directive, fetchRemoteTemplate) {
              if (fetchRemoteTemplate === void 0) { fetchRemoteTemplate = false; }
              if (directive.template !== undefined) {
                  return getOrCall(directive.template);
              }
              else if (directive.templateUrl) {
                  var $templateCache_1 = $injector.get($TEMPLATE_CACHE);
                  var url_1 = getOrCall(directive.templateUrl);
                  var template = $templateCache_1.get(url_1);
                  if (template !== undefined) {
                      return template;
                  }
                  else if (!fetchRemoteTemplate) {
                      throw new Error('loading directive templates asynchronously is not supported');
                  }
                  return new Promise(function (resolve, reject) {
                      var $httpBackend = $injector.get($HTTP_BACKEND);
                      $httpBackend('GET', url_1, null, function (status, response) {
                          if (status === 200) {
                              resolve($templateCache_1.put(url_1, response));
                          }
                          else {
                              reject("GET component template from '" + url_1 + "' returned '" + status + ": " + response + "'");
                          }
                      });
                  });
              }
              else {
                  throw new Error("Directive '" + directive.name + "' is not a component, it is missing template.");
              }
          };
          UpgradeHelper.prototype.buildController = function (controllerType, $scope) {
              // TODO: Document that we do not pre-assign bindings on the controller instance.
              // Quoted properties below so that this code can be optimized with Closure Compiler.
              var locals = { '$scope': $scope, '$element': this.$element };
              var controller = this.$controller(controllerType, locals, null, this.directive.controllerAs);
              this.$element.data(controllerKey(this.directive.name), controller);
              return controller;
          };
          UpgradeHelper.prototype.compileTemplate = function (template) {
              if (template === undefined) {
                  template = UpgradeHelper.getTemplate(this.$injector, this.directive);
              }
              return this.compileHtml(template);
          };
          UpgradeHelper.prototype.onDestroy = function ($scope, controllerInstance) {
              if (controllerInstance && isFunction(controllerInstance.$onDestroy)) {
                  controllerInstance.$onDestroy();
              }
              $scope.$destroy();
              this.$element.triggerHandler('$destroy');
          };
          UpgradeHelper.prototype.prepareTransclusion = function () {
              var _this = this;
              var transclude = this.directive.transclude;
              var contentChildNodes = this.extractChildNodes();
              var attachChildrenFn = function (scope, cloneAttachFn) {
                  // Since AngularJS v1.5.8, `cloneAttachFn` will try to destroy the transclusion scope if
                  // `$template` is empty. Since the transcluded content comes from Angular, not AngularJS,
                  // there will be no transclusion scope here.
                  // Provide a dummy `scope.$destroy()` method to prevent `cloneAttachFn` from throwing.
                  scope = scope || { $destroy: function () { return undefined; } };
                  return cloneAttachFn($template, scope);
              };
              var $template = contentChildNodes;
              if (transclude) {
                  var slots_1 = Object.create(null);
                  if (typeof transclude === 'object') {
                      $template = [];
                      var slotMap_1 = Object.create(null);
                      var filledSlots_1 = Object.create(null);
                      // Parse the element selectors.
                      Object.keys(transclude).forEach(function (slotName) {
                          var selector = transclude[slotName];
                          var optional = selector.charAt(0) === '?';
                          selector = optional ? selector.substring(1) : selector;
                          slotMap_1[selector] = slotName;
                          slots_1[slotName] = null; // `null`: Defined but not yet filled.
                          filledSlots_1[slotName] = optional; // Consider optional slots as filled.
                      });
                      // Add the matching elements into their slot.
                      contentChildNodes.forEach(function (node) {
                          var slotName = slotMap_1[directiveNormalize(node.nodeName.toLowerCase())];
                          if (slotName) {
                              filledSlots_1[slotName] = true;
                              slots_1[slotName] = slots_1[slotName] || [];
                              slots_1[slotName].push(node);
                          }
                          else {
                              $template.push(node);
                          }
                      });
                      // Check for required slots that were not filled.
                      Object.keys(filledSlots_1).forEach(function (slotName) {
                          if (!filledSlots_1[slotName]) {
                              throw new Error("Required transclusion slot '" + slotName + "' on directive: " + _this.name);
                          }
                      });
                      Object.keys(slots_1).filter(function (slotName) { return slots_1[slotName]; }).forEach(function (slotName) {
                          var nodes = slots_1[slotName];
                          slots_1[slotName] = function (scope, cloneAttach) {
                              return cloneAttach(nodes, scope);
                          };
                      });
                  }
                  // Attach `$$slots` to default slot transclude fn.
                  attachChildrenFn.$$slots = slots_1;
                  // AngularJS v1.6+ ignores empty or whitespace-only transcluded text nodes. But Angular
                  // removes all text content after the first interpolation and updates it later, after
                  // evaluating the expressions. This would result in AngularJS failing to recognize text
                  // nodes that start with an interpolation as transcluded content and use the fallback
                  // content instead.
                  // To avoid this issue, we add a
                  // [zero-width non-joiner character](https://en.wikipedia.org/wiki/Zero-width_non-joiner)
                  // to empty text nodes (which can only be a result of Angular removing their initial content).
                  // NOTE: Transcluded text content that starts with whitespace followed by an interpolation
                  //       will still fail to be detected by AngularJS v1.6+
                  $template.forEach(function (node) {
                      if (node.nodeType === Node.TEXT_NODE && !node.nodeValue) {
                          node.nodeValue = '\u200C';
                      }
                  });
              }
              return attachChildrenFn;
          };
          UpgradeHelper.prototype.resolveAndBindRequiredControllers = function (controllerInstance) {
              var directiveRequire = this.getDirectiveRequire();
              var requiredControllers = this.resolveRequire(directiveRequire);
              if (controllerInstance && this.directive.bindToController && isMap(directiveRequire)) {
                  var requiredControllersMap_1 = requiredControllers;
                  Object.keys(requiredControllersMap_1).forEach(function (key) {
                      controllerInstance[key] = requiredControllersMap_1[key];
                  });
              }
              return requiredControllers;
          };
          UpgradeHelper.prototype.compileHtml = function (html) {
              this.element.innerHTML = html;
              return this.$compile(this.element.childNodes);
          };
          UpgradeHelper.prototype.extractChildNodes = function () {
              var childNodes = [];
              var childNode;
              while (childNode = this.element.firstChild) {
                  this.element.removeChild(childNode);
                  childNodes.push(childNode);
              }
              return childNodes;
          };
          UpgradeHelper.prototype.getDirectiveRequire = function () {
              var require = this.directive.require || (this.directive.controller && this.directive.name);
              if (isMap(require)) {
                  Object.keys(require).forEach(function (key) {
                      var value = require[key];
                      var match = value.match(REQUIRE_PREFIX_RE);
                      var name = value.substring(match[0].length);
                      if (!name) {
                          require[key] = match[0] + key;
                      }
                  });
              }
              return require;
          };
          UpgradeHelper.prototype.resolveRequire = function (require, controllerInstance) {
              var _this = this;
              if (!require) {
                  return null;
              }
              else if (Array.isArray(require)) {
                  return require.map(function (req) { return _this.resolveRequire(req); });
              }
              else if (typeof require === 'object') {
                  var value_1 = {};
                  Object.keys(require).forEach(function (key) { return value_1[key] = _this.resolveRequire(require[key]); });
                  return value_1;
              }
              else if (typeof require === 'string') {
                  var match = require.match(REQUIRE_PREFIX_RE);
                  var inheritType = match[1] || match[3];
                  var name_1 = require.substring(match[0].length);
                  var isOptional = !!match[2];
                  var searchParents = !!inheritType;
                  var startOnParent = inheritType === '^^';
                  var ctrlKey = controllerKey(name_1);
                  var elem = startOnParent ? this.$element.parent() : this.$element;
                  var value = searchParents ? elem.inheritedData(ctrlKey) : elem.data(ctrlKey);
                  if (!value && !isOptional) {
                      throw new Error("Unable to find required '" + require + "' in upgraded directive '" + this.name + "'.");
                  }
                  return value;
              }
              else {
                  throw new Error("Unrecognized 'require' syntax on upgraded directive '" + this.name + "': " + require);
              }
          };
          return UpgradeHelper;
      }());
      function getOrCall(property) {
          return isFunction(property) ? property() : property;
      }
      // NOTE: Only works for `typeof T !== 'object'`.
      function isMap(value) {
          return value && !Array.isArray(value) && typeof value === 'object';
      }
      function notSupported(name, feature) {
          throw new Error("Upgraded directive '" + name + "' contains unsupported feature: '" + feature + "'.");
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      var CAMEL_CASE = /([A-Z])/g;
      var INITIAL_VALUE$1 = {
          __UNINITIALIZED__: true
      };
      var NOT_SUPPORTED = 'NOT_SUPPORTED';
      var UpgradeNg1ComponentAdapterBuilder = /** @class */ (function () {
          function UpgradeNg1ComponentAdapterBuilder(name) {
              this.name = name;
              this.inputs = [];
              this.inputsRename = [];
              this.outputs = [];
              this.outputsRename = [];
              this.propertyOutputs = [];
              this.checkProperties = [];
              this.propertyMap = {};
              this.directive = null;
              var selector = name.replace(CAMEL_CASE, function (all, next) { return '-' + next.toLowerCase(); });
              var self = this;
              // Note: There is a bug in TS 2.4 that prevents us from
              // inlining this into @Directive
              // TODO(tbosch): find or file a bug against TypeScript for this.
              var directive = { selector: selector, inputs: this.inputsRename, outputs: this.outputsRename };
              var MyClass = /** @class */ (function () {
                  function MyClass(scope, injector, elementRef) {
                      var helper = new UpgradeHelper(injector, name, elementRef, this.directive);
                      return new UpgradeNg1ComponentAdapter(helper, scope, self.template, self.inputs, self.outputs, self.propertyOutputs, self.checkProperties, self.propertyMap);
                  }
                  MyClass.prototype.ngOnInit = function () {
                  };
                  MyClass.prototype.ngOnChanges = function () {
                  };
                  MyClass.prototype.ngDoCheck = function () {
                  };
                  MyClass.prototype.ngOnDestroy = function () {
                  };
                  MyClass = __decorate([
                      core.Directive(__assign({ jit: true }, directive)),
                      __param(0, core.Inject($SCOPE)),
                      __metadata("design:paramtypes", [Object, core.Injector, core.ElementRef])
                  ], MyClass);
                  return MyClass;
              }());
              this.type = MyClass;
          }
          UpgradeNg1ComponentAdapterBuilder.prototype.extractBindings = function () {
              var _this = this;
              var btcIsObject = typeof this.directive.bindToController === 'object';
              if (btcIsObject && Object.keys(this.directive.scope).length) {
                  throw new Error("Binding definitions on scope and controller at the same time are not supported.");
              }
              var context = (btcIsObject) ? this.directive.bindToController : this.directive.scope;
              if (typeof context == 'object') {
                  Object.keys(context).forEach(function (propName) {
                      var definition = context[propName];
                      var bindingType = definition.charAt(0);
                      var bindingOptions = definition.charAt(1);
                      var attrName = definition.substring(bindingOptions === '?' ? 2 : 1) || propName;
                      // QUESTION: What about `=*`? Ignore? Throw? Support?
                      var inputName = "input_" + attrName;
                      var inputNameRename = inputName + ": " + attrName;
                      var outputName = "output_" + attrName;
                      var outputNameRename = outputName + ": " + attrName;
                      var outputNameRenameChange = outputNameRename + "Change";
                      switch (bindingType) {
                          case '@':
                          case '<':
                              _this.inputs.push(inputName);
                              _this.inputsRename.push(inputNameRename);
                              _this.propertyMap[inputName] = propName;
                              break;
                          case '=':
                              _this.inputs.push(inputName);
                              _this.inputsRename.push(inputNameRename);
                              _this.propertyMap[inputName] = propName;
                              _this.outputs.push(outputName);
                              _this.outputsRename.push(outputNameRenameChange);
                              _this.propertyMap[outputName] = propName;
                              _this.checkProperties.push(propName);
                              _this.propertyOutputs.push(outputName);
                              break;
                          case '&':
                              _this.outputs.push(outputName);
                              _this.outputsRename.push(outputNameRename);
                              _this.propertyMap[outputName] = propName;
                              break;
                          default:
                              var json = JSON.stringify(context);
                              throw new Error("Unexpected mapping '" + bindingType + "' in '" + json + "' in '" + _this.name + "' directive.");
                      }
                  });
              }
          };
          /**
           * Upgrade ng1 components into Angular.
           */
          UpgradeNg1ComponentAdapterBuilder.resolve = function (exportedComponents, $injector) {
              var promises = Object.keys(exportedComponents).map(function (name) {
                  var exportedComponent = exportedComponents[name];
                  exportedComponent.directive = UpgradeHelper.getDirective($injector, name);
                  exportedComponent.extractBindings();
                  return Promise
                      .resolve(UpgradeHelper.getTemplate($injector, exportedComponent.directive, true))
                      .then(function (template) { return exportedComponent.template = template; });
              });
              return Promise.all(promises);
          };
          return UpgradeNg1ComponentAdapterBuilder;
      }());
      var UpgradeNg1ComponentAdapter = /** @class */ (function () {
          function UpgradeNg1ComponentAdapter(helper, scope, template, inputs, outputs, propOuts, checkProperties, propertyMap) {
              this.helper = helper;
              this.template = template;
              this.inputs = inputs;
              this.outputs = outputs;
              this.propOuts = propOuts;
              this.checkProperties = checkProperties;
              this.propertyMap = propertyMap;
              this.controllerInstance = null;
              this.destinationObj = null;
              this.checkLastValues = [];
              this.$element = null;
              this.directive = helper.directive;
              this.element = helper.element;
              this.$element = helper.$element;
              this.componentScope = scope.$new(!!this.directive.scope);
              var controllerType = this.directive.controller;
              if (this.directive.bindToController && controllerType) {
                  this.controllerInstance = this.helper.buildController(controllerType, this.componentScope);
                  this.destinationObj = this.controllerInstance;
              }
              else {
                  this.destinationObj = this.componentScope;
              }
              for (var i = 0; i < inputs.length; i++) {
                  this[inputs[i]] = null;
              }
              for (var j = 0; j < outputs.length; j++) {
                  var emitter = this[outputs[j]] = new core.EventEmitter();
                  if (this.propOuts.indexOf(outputs[j]) === -1) {
                      this.setComponentProperty(outputs[j], (function (emitter) { return function (value) { return emitter.emit(value); }; })(emitter));
                  }
              }
              for (var k = 0; k < propOuts.length; k++) {
                  this.checkLastValues.push(INITIAL_VALUE$1);
              }
          }
          UpgradeNg1ComponentAdapter.prototype.ngOnInit = function () {
              // Collect contents, insert and compile template
              var attachChildNodes = this.helper.prepareTransclusion();
              var linkFn = this.helper.compileTemplate(this.template);
              // Instantiate controller (if not already done so)
              var controllerType = this.directive.controller;
              var bindToController = this.directive.bindToController;
              if (controllerType && !bindToController) {
                  this.controllerInstance = this.helper.buildController(controllerType, this.componentScope);
              }
              // Require other controllers
              var requiredControllers = this.helper.resolveAndBindRequiredControllers(this.controllerInstance);
              // Hook: $onInit
              if (this.controllerInstance && isFunction(this.controllerInstance.$onInit)) {
                  this.controllerInstance.$onInit();
              }
              // Linking
              var link = this.directive.link;
              var preLink = (typeof link == 'object') && link.pre;
              var postLink = (typeof link == 'object') ? link.post : link;
              var attrs = NOT_SUPPORTED;
              var transcludeFn = NOT_SUPPORTED;
              if (preLink) {
                  preLink(this.componentScope, this.$element, attrs, requiredControllers, transcludeFn);
              }
              linkFn(this.componentScope, null, { parentBoundTranscludeFn: attachChildNodes });
              if (postLink) {
                  postLink(this.componentScope, this.$element, attrs, requiredControllers, transcludeFn);
              }
              // Hook: $postLink
              if (this.controllerInstance && isFunction(this.controllerInstance.$postLink)) {
                  this.controllerInstance.$postLink();
              }
          };
          UpgradeNg1ComponentAdapter.prototype.ngOnChanges = function (changes) {
              var _this = this;
              var ng1Changes = {};
              Object.keys(changes).forEach(function (name) {
                  var change = changes[name];
                  _this.setComponentProperty(name, change.currentValue);
                  ng1Changes[_this.propertyMap[name]] = change;
              });
              if (isFunction(this.destinationObj.$onChanges)) {
                  this.destinationObj.$onChanges(ng1Changes);
              }
          };
          UpgradeNg1ComponentAdapter.prototype.ngDoCheck = function () {
              var _this = this;
              var destinationObj = this.destinationObj;
              var lastValues = this.checkLastValues;
              var checkProperties = this.checkProperties;
              var propOuts = this.propOuts;
              checkProperties.forEach(function (propName, i) {
                  var value = destinationObj[propName];
                  var last = lastValues[i];
                  if (!strictEquals(last, value)) {
                      var eventEmitter = _this[propOuts[i]];
                      eventEmitter.emit(lastValues[i] = value);
                  }
              });
              if (this.controllerInstance && isFunction(this.controllerInstance.$doCheck)) {
                  this.controllerInstance.$doCheck();
              }
          };
          UpgradeNg1ComponentAdapter.prototype.ngOnDestroy = function () { this.helper.onDestroy(this.componentScope, this.controllerInstance); };
          UpgradeNg1ComponentAdapter.prototype.setComponentProperty = function (name, value) {
              this.destinationObj[this.propertyMap[name]] = value;
          };
          return UpgradeNg1ComponentAdapter;
      }());
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      var upgradeCount = 0;
      /**
       * Use `UpgradeAdapter` to allow AngularJS and Angular to coexist in a single application.
       *
       * The `UpgradeAdapter` allows:
       * 1. creation of Angular component from AngularJS component directive
       *    (See [UpgradeAdapter#upgradeNg1Component()])
       * 2. creation of AngularJS directive from Angular component.
       *    (See [UpgradeAdapter#downgradeNg2Component()])
       * 3. Bootstrapping of a hybrid Angular application which contains both of the frameworks
       *    coexisting in a single application.
       *
       * @usageNotes
       * ### Mental Model
       *
       * When reasoning about how a hybrid application works it is useful to have a mental model which
       * describes what is happening and explains what is happening at the lowest level.
       *
       * 1. There are two independent frameworks running in a single application, each framework treats
       *    the other as a black box.
       * 2. Each DOM element on the page is owned exactly by one framework. Whichever framework
       *    instantiated the element is the owner. Each framework only updates/interacts with its own
       *    DOM elements and ignores others.
       * 3. AngularJS directives always execute inside AngularJS framework codebase regardless of
       *    where they are instantiated.
       * 4. Angular components always execute inside Angular framework codebase regardless of
       *    where they are instantiated.
       * 5. An AngularJS component can be upgraded to an Angular component. This creates an
       *    Angular directive, which bootstraps the AngularJS component directive in that location.
       * 6. An Angular component can be downgraded to an AngularJS component directive. This creates
       *    an AngularJS directive, which bootstraps the Angular component in that location.
       * 7. Whenever an adapter component is instantiated the host element is owned by the framework
       *    doing the instantiation. The other framework then instantiates and owns the view for that
       *    component. This implies that component bindings will always follow the semantics of the
       *    instantiation framework. The syntax is always that of Angular syntax.
       * 8. AngularJS is always bootstrapped first and owns the bottom most view.
       * 9. The new application is running in Angular zone, and therefore it no longer needs calls to
       *    `$apply()`.
       *
       * ### Example
       *
       * ```
       * const adapter = new UpgradeAdapter(forwardRef(() => MyNg2Module), myCompilerOptions);
       * const module = angular.module('myExample', []);
       * module.directive('ng2Comp', adapter.downgradeNg2Component(Ng2Component));
       *
       * module.directive('ng1Hello', function() {
       *   return {
       *      scope: { title: '=' },
       *      template: 'ng1[Hello {{title}}!](<span ng-transclude></span>)'
       *   };
       * });
       *
       *
       * @Component({
       *   selector: 'ng2-comp',
       *   inputs: ['name'],
       *   template: 'ng2[<ng1-hello [title]="name">transclude</ng1-hello>](<ng-content></ng-content>)',
       *   directives:
       * })
       * class Ng2Component {
       * }
       *
       * @NgModule({
       *   declarations: [Ng2Component, adapter.upgradeNg1Component('ng1Hello')],
       *   imports: [BrowserModule]
       * })
       * class MyNg2Module {}
       *
       *
       * document.body.innerHTML = '<ng2-comp name="World">project</ng2-comp>';
       *
       * adapter.bootstrap(document.body, ['myExample']).ready(function() {
       *   expect(document.body.textContent).toEqual(
       *       "ng2[ng1[Hello World!](transclude)](project)");
       * });
       *
       * ```
       *
       * @deprecated Deprecated since v5. Use `upgrade/static` instead, which also supports
       * [Ahead-of-Time compilation](guide/aot-compiler).
       */
      var UpgradeAdapter = /** @class */ (function () {
          function UpgradeAdapter(ng2AppModule, compilerOptions) {
              this.ng2AppModule = ng2AppModule;
              this.compilerOptions = compilerOptions;
              this.idPrefix = "NG2_UPGRADE_" + upgradeCount++ + "_";
              this.downgradedComponents = [];
              /**
               * An internal map of ng1 components which need to up upgraded to ng2.
               *
               * We can't upgrade until injector is instantiated and we can retrieve the component metadata.
               * For this reason we keep a list of components to upgrade until ng1 injector is bootstrapped.
               *
               * @internal
               */
              this.ng1ComponentsToBeUpgraded = {};
              this.upgradedProviders = [];
              this.moduleRef = null;
              if (!ng2AppModule) {
                  throw new Error('UpgradeAdapter cannot be instantiated without an NgModule of the Angular app.');
              }
          }
          /**
           * Allows Angular Component to be used from AngularJS.
           *
           * Use `downgradeNg2Component` to create an AngularJS Directive Definition Factory from
           * Angular Component. The adapter will bootstrap Angular component from within the
           * AngularJS template.
           *
           * @usageNotes
           * ### Mental Model
           *
           * 1. The component is instantiated by being listed in AngularJS template. This means that the
           *    host element is controlled by AngularJS, but the component's view will be controlled by
           *    Angular.
           * 2. Even thought the component is instantiated in AngularJS, it will be using Angular
           *    syntax. This has to be done, this way because we must follow Angular components do not
           *    declare how the attributes should be interpreted.
           * 3. `ng-model` is controlled by AngularJS and communicates with the downgraded Angular component
           *    by way of the `ControlValueAccessor` interface from @angular/forms. Only components that
           *    implement this interface are eligible.
           *
           * ### Supported Features
           *
           * - Bindings:
           *   - Attribute: `<comp name="World">`
           *   - Interpolation:  `<comp greeting="Hello {{name}}!">`
           *   - Expression:  `<comp [name]="username">`
           *   - Event:  `<comp (close)="doSomething()">`
           *   - ng-model: `<comp ng-model="name">`
           * - Content projection: yes
           *
           * ### Example
           *
           * ```
           * const adapter = new UpgradeAdapter(forwardRef(() => MyNg2Module));
           * const module = angular.module('myExample', []);
           * module.directive('greet', adapter.downgradeNg2Component(Greeter));
           *
           * @Component({
           *   selector: 'greet',
           *   template: '{{salutation}} {{name}}! - <ng-content></ng-content>'
           * })
           * class Greeter {
           *   @Input() salutation: string;
           *   @Input() name: string;
           * }
           *
           * @NgModule({
           *   declarations: [Greeter],
           *   imports: [BrowserModule]
           * })
           * class MyNg2Module {}
           *
           * document.body.innerHTML =
           *   'ng1 template: <greet salutation="Hello" [name]="world">text</greet>';
           *
           * adapter.bootstrap(document.body, ['myExample']).ready(function() {
           *   expect(document.body.textContent).toEqual("ng1 template: Hello world! - text");
           * });
           * ```
           */
          UpgradeAdapter.prototype.downgradeNg2Component = function (component) {
              this.downgradedComponents.push(component);
              return downgradeComponent({ component: component });
          };
          /**
           * Allows AngularJS Component to be used from Angular.
           *
           * Use `upgradeNg1Component` to create an Angular component from AngularJS Component
           * directive. The adapter will bootstrap AngularJS component from within the Angular
           * template.
           *
           * @usageNotes
           * ### Mental Model
           *
           * 1. The component is instantiated by being listed in Angular template. This means that the
           *    host element is controlled by Angular, but the component's view will be controlled by
           *    AngularJS.
           *
           * ### Supported Features
           *
           * - Bindings:
           *   - Attribute: `<comp name="World">`
           *   - Interpolation:  `<comp greeting="Hello {{name}}!">`
           *   - Expression:  `<comp [name]="username">`
           *   - Event:  `<comp (close)="doSomething()">`
           * - Transclusion: yes
           * - Only some of the features of
           *   [Directive Definition Object](https://docs.angularjs.org/api/ng/service/$compile) are
           *   supported:
           *   - `compile`: not supported because the host element is owned by Angular, which does
           *     not allow modifying DOM structure during compilation.
           *   - `controller`: supported. (NOTE: injection of `$attrs` and `$transclude` is not supported.)
           *   - `controllerAs`: supported.
           *   - `bindToController`: supported.
           *   - `link`: supported. (NOTE: only pre-link function is supported.)
           *   - `name`: supported.
           *   - `priority`: ignored.
           *   - `replace`: not supported.
           *   - `require`: supported.
           *   - `restrict`: must be set to 'E'.
           *   - `scope`: supported.
           *   - `template`: supported.
           *   - `templateUrl`: supported.
           *   - `terminal`: ignored.
           *   - `transclude`: supported.
           *
           *
           * ### Example
           *
           * ```
           * const adapter = new UpgradeAdapter(forwardRef(() => MyNg2Module));
           * const module = angular.module('myExample', []);
           *
           * module.directive('greet', function() {
           *   return {
           *     scope: {salutation: '=', name: '=' },
           *     template: '{{salutation}} {{name}}! - <span ng-transclude></span>'
           *   };
           * });
           *
           * module.directive('ng2', adapter.downgradeNg2Component(Ng2Component));
           *
           * @Component({
           *   selector: 'ng2',
           *   template: 'ng2 template: <greet salutation="Hello" [name]="world">text</greet>'
           * })
           * class Ng2Component {
           * }
           *
           * @NgModule({
           *   declarations: [Ng2Component, adapter.upgradeNg1Component('greet')],
           *   imports: [BrowserModule]
           * })
           * class MyNg2Module {}
           *
           * document.body.innerHTML = '<ng2></ng2>';
           *
           * adapter.bootstrap(document.body, ['myExample']).ready(function() {
           *   expect(document.body.textContent).toEqual("ng2 template: Hello world! - text");
           * });
           * ```
           */
          UpgradeAdapter.prototype.upgradeNg1Component = function (name) {
              if (this.ng1ComponentsToBeUpgraded.hasOwnProperty(name)) {
                  return this.ng1ComponentsToBeUpgraded[name].type;
              }
              else {
                  return (this.ng1ComponentsToBeUpgraded[name] = new UpgradeNg1ComponentAdapterBuilder(name))
                      .type;
              }
          };
          /**
           * Registers the adapter's AngularJS upgrade module for unit testing in AngularJS.
           * Use this instead of `angular.mock.module()` to load the upgrade module into
           * the AngularJS testing injector.
           *
           * @usageNotes
           * ### Example
           *
           * ```
           * const upgradeAdapter = new UpgradeAdapter(MyNg2Module);
           *
           * // configure the adapter with upgrade/downgrade components and services
           * upgradeAdapter.downgradeNg2Component(MyComponent);
           *
           * let upgradeAdapterRef: UpgradeAdapterRef;
           * let $compile, $rootScope;
           *
           * // We must register the adapter before any calls to `inject()`
           * beforeEach(() => {
           *   upgradeAdapterRef = upgradeAdapter.registerForNg1Tests(['heroApp']);
           * });
           *
           * beforeEach(inject((_$compile_, _$rootScope_) => {
           *   $compile = _$compile_;
           *   $rootScope = _$rootScope_;
           * }));
           *
           * it("says hello", (done) => {
           *   upgradeAdapterRef.ready(() => {
           *     const element = $compile("<my-component></my-component>")($rootScope);
           *     $rootScope.$apply();
           *     expect(element.html()).toContain("Hello World");
           *     done();
           *   })
           * });
           *
           * ```
           *
           * @param modules any AngularJS modules that the upgrade module should depend upon
           * @returns an `UpgradeAdapterRef`, which lets you register a `ready()` callback to
           * run assertions once the Angular components are ready to test through AngularJS.
           */
          UpgradeAdapter.prototype.registerForNg1Tests = function (modules) {
              var _this = this;
              var windowNgMock = window['angular'].mock;
              if (!windowNgMock || !windowNgMock.module) {
                  throw new Error('Failed to find \'angular.mock.module\'.');
              }
              this.declareNg1Module(modules);
              windowNgMock.module(this.ng1Module.name);
              var upgrade = new UpgradeAdapterRef();
              this.ng2BootstrapDeferred.promise.then(function (ng1Injector) { upgrade._bootstrapDone(_this.moduleRef, ng1Injector); }, onError);
              return upgrade;
          };
          /**
           * Bootstrap a hybrid AngularJS / Angular application.
           *
           * This `bootstrap` method is a direct replacement (takes same arguments) for AngularJS
           * [`bootstrap`](https://docs.angularjs.org/api/ng/function/angular.bootstrap) method. Unlike
           * AngularJS, this bootstrap is asynchronous.
           *
           * @usageNotes
           * ### Example
           *
           * ```
           * const adapter = new UpgradeAdapter(MyNg2Module);
           * const module = angular.module('myExample', []);
           * module.directive('ng2', adapter.downgradeNg2Component(Ng2));
           *
           * module.directive('ng1', function() {
           *   return {
           *      scope: { title: '=' },
           *      template: 'ng1[Hello {{title}}!](<span ng-transclude></span>)'
           *   };
           * });
           *
           *
           * @Component({
           *   selector: 'ng2',
           *   inputs: ['name'],
           *   template: 'ng2[<ng1 [title]="name">transclude</ng1>](<ng-content></ng-content>)'
           * })
           * class Ng2 {
           * }
           *
           * @NgModule({
           *   declarations: [Ng2, adapter.upgradeNg1Component('ng1')],
           *   imports: [BrowserModule]
           * })
           * class MyNg2Module {}
           *
           * document.body.innerHTML = '<ng2 name="World">project</ng2>';
           *
           * adapter.bootstrap(document.body, ['myExample']).ready(function() {
           *   expect(document.body.textContent).toEqual(
           *       "ng2[ng1[Hello World!](transclude)](project)");
           * });
           * ```
           */
          UpgradeAdapter.prototype.bootstrap = function (element$$1, modules, config) {
              var _this = this;
              this.declareNg1Module(modules);
              var upgrade = new UpgradeAdapterRef();
              // Make sure resumeBootstrap() only exists if the current bootstrap is deferred
              var windowAngular = window /** TODO #???? */['angular'];
              windowAngular.resumeBootstrap = undefined;
              this.ngZone.run(function () { bootstrap(element$$1, [_this.ng1Module.name], config); });
              var ng1BootstrapPromise = new Promise(function (resolve) {
                  if (windowAngular.resumeBootstrap) {
                      var originalResumeBootstrap_1 = windowAngular.resumeBootstrap;
                      windowAngular.resumeBootstrap = function () {
                          windowAngular.resumeBootstrap = originalResumeBootstrap_1;
                          var r = windowAngular.resumeBootstrap.apply(this, arguments);
                          resolve();
                          return r;
                      };
                  }
                  else {
                      resolve();
                  }
              });
              Promise.all([this.ng2BootstrapDeferred.promise, ng1BootstrapPromise]).then(function (_a) {
                  var _b = __read(_a, 1), ng1Injector = _b[0];
                  element(element$$1).data(controllerKey(INJECTOR_KEY), _this.moduleRef.injector);
                  _this.moduleRef.injector.get(core.NgZone).run(function () { upgrade._bootstrapDone(_this.moduleRef, ng1Injector); });
              }, onError);
              return upgrade;
          };
          /**
           * Allows AngularJS service to be accessible from Angular.
           *
           * @usageNotes
           * ### Example
           *
           * ```
           * class Login { ... }
           * class Server { ... }
           *
           * @Injectable()
           * class Example {
           *   constructor(@Inject('server') server, login: Login) {
           *     ...
           *   }
           * }
           *
           * const module = angular.module('myExample', []);
           * module.service('server', Server);
           * module.service('login', Login);
           *
           * const adapter = new UpgradeAdapter(MyNg2Module);
           * adapter.upgradeNg1Provider('server');
           * adapter.upgradeNg1Provider('login', {asToken: Login});
           *
           * adapter.bootstrap(document.body, ['myExample']).ready((ref) => {
           *   const example: Example = ref.ng2Injector.get(Example);
           * });
           *
           * ```
           */
          UpgradeAdapter.prototype.upgradeNg1Provider = function (name, options) {
              var token = options && options.asToken || name;
              this.upgradedProviders.push({
                  provide: token,
                  useFactory: function ($injector) { return $injector.get(name); },
                  deps: [$INJECTOR]
              });
          };
          /**
           * Allows Angular service to be accessible from AngularJS.
           *
           * @usageNotes
           * ### Example
           *
           * ```
           * class Example {
           * }
           *
           * const adapter = new UpgradeAdapter(MyNg2Module);
           *
           * const module = angular.module('myExample', []);
           * module.factory('example', adapter.downgradeNg2Provider(Example));
           *
           * adapter.bootstrap(document.body, ['myExample']).ready((ref) => {
           *   const example: Example = ref.ng1Injector.get('example');
           * });
           *
           * ```
           */
          UpgradeAdapter.prototype.downgradeNg2Provider = function (token) { return downgradeInjectable(token); };
          /**
           * Declare the AngularJS upgrade module for this adapter without bootstrapping the whole
           * hybrid application.
           *
           * This method is automatically called by `bootstrap()` and `registerForNg1Tests()`.
           *
           * @param modules The AngularJS modules that this upgrade module should depend upon.
           * @returns The AngularJS upgrade module that is declared by this method
           *
           * @usageNotes
           * ### Example
           *
           * ```
           * const upgradeAdapter = new UpgradeAdapter(MyNg2Module);
           * upgradeAdapter.declareNg1Module(['heroApp']);
           * ```
           */
          UpgradeAdapter.prototype.declareNg1Module = function (modules) {
              var _this = this;
              if (modules === void 0) { modules = []; }
              var delayApplyExps = [];
              var original$applyFn;
              var rootScopePrototype;
              var rootScope;
              var upgradeAdapter = this;
              var ng1Module = this.ng1Module = module$1(this.idPrefix, modules);
              var platformRef = platformBrowserDynamic.platformBrowserDynamic();
              this.ngZone = new core.NgZone({ enableLongStackTrace: Zone.hasOwnProperty('longStackTraceZoneSpec') });
              this.ng2BootstrapDeferred = new Deferred();
              ng1Module.factory(INJECTOR_KEY, function () { return _this.moduleRef.injector.get(core.Injector); })
                  .factory(LAZY_MODULE_REF, [
                  INJECTOR_KEY,
                  function (injector) { return ({ injector: injector, needsNgZone: false }); }
              ])
                  .constant(NG_ZONE_KEY, this.ngZone)
                  .factory(COMPILER_KEY, function () { return _this.moduleRef.injector.get(core.Compiler); })
                  .config([
                  '$provide', '$injector',
                  function (provide, ng1Injector) {
                      provide.decorator($ROOT_SCOPE, [
                          '$delegate',
                          function (rootScopeDelegate) {
                              // Capture the root apply so that we can delay first call to $apply until we
                              // bootstrap Angular and then we replay and restore the $apply.
                              rootScopePrototype = rootScopeDelegate.constructor.prototype;
                              if (rootScopePrototype.hasOwnProperty('$apply')) {
                                  original$applyFn = rootScopePrototype.$apply;
                                  rootScopePrototype.$apply = function (exp) { return delayApplyExps.push(exp); };
                              }
                              else {
                                  throw new Error('Failed to find \'$apply\' on \'$rootScope\'!');
                              }
                              return rootScope = rootScopeDelegate;
                          }
                      ]);
                      if (ng1Injector.has($$TESTABILITY)) {
                          provide.decorator($$TESTABILITY, [
                              '$delegate',
                              function (testabilityDelegate) {
                                  var originalWhenStable = testabilityDelegate.whenStable;
                                  // Cannot use arrow function below because we need the context
                                  var newWhenStable = function (callback) {
                                      originalWhenStable.call(this, function () {
                                          var ng2Testability = upgradeAdapter.moduleRef.injector.get(core.Testability);
                                          if (ng2Testability.isStable()) {
                                              callback.apply(this, arguments);
                                          }
                                          else {
                                              ng2Testability.whenStable(newWhenStable.bind(this, callback));
                                          }
                                      });
                                  };
                                  testabilityDelegate.whenStable = newWhenStable;
                                  return testabilityDelegate;
                              }
                          ]);
                      }
                  }
              ]);
              ng1Module.run([
                  '$injector', '$rootScope',
                  function (ng1Injector, rootScope) {
                      UpgradeNg1ComponentAdapterBuilder.resolve(_this.ng1ComponentsToBeUpgraded, ng1Injector)
                          .then(function () {
                          // Note: There is a bug in TS 2.4 that prevents us from
                          // inlining this into @NgModule
                          // TODO(tbosch): find or file a bug against TypeScript for this.
                          var ngModule = {
                              providers: [
                                  { provide: $INJECTOR, useFactory: function () { return ng1Injector; } },
                                  { provide: $COMPILE, useFactory: function () { return ng1Injector.get($COMPILE); } },
                                  _this.upgradedProviders
                              ],
                              imports: [_this.ng2AppModule],
                              entryComponents: _this.downgradedComponents
                          };
                          // At this point we have ng1 injector and we have prepared
                          // ng1 components to be upgraded, we now can bootstrap ng2.
                          var DynamicNgUpgradeModule = /** @class */ (function () {
                              function DynamicNgUpgradeModule() {
                              }
                              DynamicNgUpgradeModule.prototype.ngDoBootstrap = function () { };
                              DynamicNgUpgradeModule = __decorate([
                                  core.NgModule(__assign({ jit: true }, ngModule)),
                                  __metadata("design:paramtypes", [])
                              ], DynamicNgUpgradeModule);
                              return DynamicNgUpgradeModule;
                          }());
                          platformRef
                              .bootstrapModule(DynamicNgUpgradeModule, [_this.compilerOptions, { ngZone: _this.ngZone }])
                              .then(function (ref) {
                              _this.moduleRef = ref;
                              _this.ngZone.run(function () {
                                  if (rootScopePrototype) {
                                      rootScopePrototype.$apply = original$applyFn; // restore original $apply
                                      while (delayApplyExps.length) {
                                          rootScope.$apply(delayApplyExps.shift());
                                      }
                                      rootScopePrototype = null;
                                  }
                              });
                          })
                              .then(function () { return _this.ng2BootstrapDeferred.resolve(ng1Injector); }, onError)
                              .then(function () {
                              var subscription = _this.ngZone.onMicrotaskEmpty.subscribe({ next: function () { return rootScope.$digest(); } });
                              rootScope.$on('$destroy', function () { subscription.unsubscribe(); });
                          });
                      })
                          .catch(function (e) { return _this.ng2BootstrapDeferred.reject(e); });
                  }
              ]);
              return ng1Module;
          };
          return UpgradeAdapter;
      }());
      /**
       * Use `UpgradeAdapterRef` to control a hybrid AngularJS / Angular application.
       *
       * @deprecated Deprecated since v5. Use `upgrade/static` instead, which also supports
       * [Ahead-of-Time compilation](guide/aot-compiler).
       */
      var UpgradeAdapterRef = /** @class */ (function () {
          function UpgradeAdapterRef() {
              /* @internal */
              this._readyFn = null;
              this.ng1RootScope = null;
              this.ng1Injector = null;
              this.ng2ModuleRef = null;
              this.ng2Injector = null;
          }
          /* @internal */
          UpgradeAdapterRef.prototype._bootstrapDone = function (ngModuleRef, ng1Injector) {
              this.ng2ModuleRef = ngModuleRef;
              this.ng2Injector = ngModuleRef.injector;
              this.ng1Injector = ng1Injector;
              this.ng1RootScope = ng1Injector.get($ROOT_SCOPE);
              this._readyFn && this._readyFn(this);
          };
          /**
           * Register a callback function which is notified upon successful hybrid AngularJS / Angular
           * application has been bootstrapped.
           *
           * The `ready` callback function is invoked inside the Angular zone, therefore it does not
           * require a call to `$apply()`.
           */
          UpgradeAdapterRef.prototype.ready = function (fn) { this._readyFn = fn; };
          /**
           * Dispose of running hybrid AngularJS / Angular application.
           */
          UpgradeAdapterRef.prototype.dispose = function () {
              this.ng1Injector.get($ROOT_SCOPE).$destroy();
              this.ng2ModuleRef.destroy();
          };
          return UpgradeAdapterRef;
      }());
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      // This file only re-exports content of the `src` folder. Keep it that way.
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
  
      /**
       * Generated bundle index. Do not edit.
       */
  
      exports.VERSION = VERSION;
      exports.UpgradeAdapter = UpgradeAdapter;
      exports.UpgradeAdapterRef = UpgradeAdapterRef;
  
      Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=upgrade.umd.js.map
  