text: /**
   * @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 __extends = (this && this.__extends) || function (d, b) {
      for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
      function __() { this.constructor = d; }
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  };
  import { ErrorHandler } from '../src/error_handler';
  import { ListWrapper } from '../src/facade/collection';
  import { unimplemented } from '../src/facade/errors';
  import { stringify } from '../src/facade/lang';
  import { isPromise } from '../src/util/lang';
  import { ApplicationInitStatus } from './application_init';
  import { APP_BOOTSTRAP_LISTENER, PLATFORM_INITIALIZER } from './application_tokens';
  import { Console } from './console';
  import { Injectable, Injector, OpaqueToken, Optional, ReflectiveInjector } from './di';
  import { CompilerFactory } from './linker/compiler';
  import { ComponentFactory } from './linker/component_factory';
  import { ComponentFactoryResolver } from './linker/component_factory_resolver';
  import { wtfCreateScope, wtfLeave } from './profile/profile';
  import { Testability, TestabilityRegistry } from './testability/testability';
  import { NgZone } from './zone/ng_zone';
  var _devMode = true;
  var _runModeLocked = false;
  var _platform;
  /**
   * Disable Angular's development mode, which turns off assertions and other
   * checks within the framework.
   *
   * One important assertion this disables verifies that a change detection pass
   * does not result in additional changes to any bindings (also known as
   * unidirectional data flow).
   *
   * @stable
   */
  export function enableProdMode() {
      if (_runModeLocked) {
          throw new Error('Cannot enable prod mode after platform setup.');
      }
      _devMode = false;
  }
  /**
   * Returns whether Angular is in development mode. After called once,
   * the value is locked and won't change any more.
   *
   * By default, this is true, unless a user calls `enableProdMode` before calling this.
   *
   * @experimental APIs related to application bootstrap are currently under review.
   */
  export function isDevMode() {
      _runModeLocked = true;
      return _devMode;
  }
  /**
   * Creates a platform.
   * Platforms have to be eagerly created via this function.
   *
   * @experimental APIs related to application bootstrap are currently under review.
   */
  export function createPlatform(injector) {
      if (_platform && !_platform.destroyed) {
          throw new Error('There can be only one platform. Destroy the previous one to create a new one.');
      }
      _platform = injector.get(PlatformRef);
      var inits = injector.get(PLATFORM_INITIALIZER, null);
      if (inits)
          inits.forEach(function (init) { return init(); });
      return _platform;
  }
  /**
   * Creates a factory for a platform
   *
   * @experimental APIs related to application bootstrap are currently under review.
   */
  export function createPlatformFactory(parentPlaformFactory, name, providers) {
      if (providers === void 0) { providers = []; }
      var marker = new OpaqueToken("Platform: " + name);
      return function (extraProviders) {
          if (extraProviders === void 0) { extraProviders = []; }
          if (!getPlatform()) {
              if (parentPlaformFactory) {
                  parentPlaformFactory(providers.concat(extraProviders).concat({ provide: marker, useValue: true }));
              }
              else {
                  createPlatform(ReflectiveInjector.resolveAndCreate(providers.concat(extraProviders).concat({ provide: marker, useValue: true })));
              }
          }
          return assertPlatform(marker);
      };
  }
  /**
   * Checks that there currently is a platform
   * which contains the given token as a provider.
   *
   * @experimental APIs related to application bootstrap are currently under review.
   */
  export function assertPlatform(requiredToken) {
      var platform = getPlatform();
      if (!platform) {
          throw new Error('No platform exists!');
      }
      if (!platform.injector.get(requiredToken, null)) {
          throw new Error('A platform with a different configuration has been created. Please destroy it first.');
      }
      return platform;
  }
  /**
   * Destroy the existing platform.
   *
   * @experimental APIs related to application bootstrap are currently under review.
   */
  export function destroyPlatform() {
      if (_platform && !_platform.destroyed) {
          _platform.destroy();
      }
  }
  /**
   * Returns the current platform.
   *
   * @experimental APIs related to application bootstrap are currently under review.
   */
  export function getPlatform() {
      return _platform && !_platform.destroyed ? _platform : null;
  }
  /**
   * The Angular platform is the entry point for Angular on a web page. Each page
   * has exactly one platform, and services (such as reflection) which are common
   * to every Angular application running on the page are bound in its scope.
   *
   * A page's platform is initialized implicitly when {@link bootstrap}() is called, or
   * explicitly by calling {@link createPlatform}().
   *
   * @stable
   */
  export var PlatformRef = (function () {
      function PlatformRef() {
      }
      /**
       * Creates an instance of an `@NgModule` for the given platform
       * for offline compilation.
       *
       * ## Simple Example
       *
       * ```typescript
       * my_module.ts:
       *
       * @NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * main.ts:
       * import {MyModuleNgFactory} from './my_module.ngfactory';
       * import {platformBrowser} from '@angular/platform-browser';
       *
       * let moduleRef = platformBrowser().bootstrapModuleFactory(MyModuleNgFactory);
       * ```
       *
       * @experimental APIs related to application bootstrap are currently under review.
       */
      PlatformRef.prototype.bootstrapModuleFactory = function (moduleFactory) {
          throw unimplemented();
      };
      /**
       * Creates an instance of an `@NgModule` for a given platform using the given runtime compiler.
       *
       * ## Simple Example
       *
       * ```typescript
       * @NgModule({
       *   imports: [BrowserModule]
       * })
       * class MyModule {}
       *
       * let moduleRef = platformBrowser().bootstrapModule(MyModule);
       * ```
       * @stable
       */
      PlatformRef.prototype.bootstrapModule = function (moduleType, compilerOptions) {
          if (compilerOptions === void 0) { compilerOptions = []; }
          throw unimplemented();
      };
      Object.defineProperty(PlatformRef.prototype, "injector", {
          /**
           * Retrieve the platform {@link Injector}, which is the parent injector for
           * every Angular application on the page and provides singleton providers.
           */
          get: function () { throw unimplemented(); },
          enumerable: true,
          configurable: true
      });
      ;
      Object.defineProperty(PlatformRef.prototype, "destroyed", {
          get: function () { throw unimplemented(); },
          enumerable: true,
          configurable: true
      });
      return PlatformRef;
  }());
  function _callAndReportToErrorHandler(errorHandler, callback) {
      try {
          var result = callback();
          if (isPromise(result)) {
              return result.catch(function (e) {
                  errorHandler.handleError(e);
                  // rethrow as the exception handler might not do it
                  throw e;
              });
          }
          return result;
      }
      catch (e) {
          errorHandler.handleError(e);
          // rethrow as the exception handler might not do it
          throw e;
      }
  }
  export var PlatformRef_ = (function (_super) {
      __extends(PlatformRef_, _super);
      function PlatformRef_(_injector) {
          _super.call(this);
          this._injector = _injector;
          this._modules = [];
          this._destroyListeners = [];
          this._destroyed = false;
      }
      PlatformRef_.prototype.onDestroy = function (callback) { this._destroyListeners.push(callback); };
      Object.defineProperty(PlatformRef_.prototype, "injector", {
          get: function () { return this._injector; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(PlatformRef_.prototype, "destroyed", {
          get: function () { return this._destroyed; },
          enumerable: true,
          configurable: true
      });
      PlatformRef_.prototype.destroy = function () {
          if (this._destroyed) {
              throw new Error('The platform has already been destroyed!');
          }
          this._modules.slice().forEach(function (module) { return module.destroy(); });
          this._destroyListeners.forEach(function (listener) { return listener(); });
          this._destroyed = true;
      };
      PlatformRef_.prototype.bootstrapModuleFactory = function (moduleFactory) {
          return this._bootstrapModuleFactoryWithZone(moduleFactory, null);
      };
      PlatformRef_.prototype._bootstrapModuleFactoryWithZone = function (moduleFactory, ngZone) {
          var _this = this;
          // Note: We need to create the NgZone _before_ we instantiate the module,
          // as instantiating the module creates some providers eagerly.
          // So we create a mini parent injector that just contains the new NgZone and
          // pass that as parent to the NgModuleFactory.
          if (!ngZone)
              ngZone = new NgZone({ enableLongStackTrace: isDevMode() });
          // Attention: Don't use ApplicationRef.run here,
          // as we want to be sure that all possible constructor calls are inside `ngZone.run`!
          return ngZone.run(function () {
              var ngZoneInjector = ReflectiveInjector.resolveAndCreate([{ provide: NgZone, useValue: ngZone }], _this.injector);
              var moduleRef = moduleFactory.create(ngZoneInjector);
              var exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
              if (!exceptionHandler) {
                  throw new Error('No ErrorHandler. Is platform module (BrowserModule) included?');
              }
              moduleRef.onDestroy(function () { return ListWrapper.remove(_this._modules, moduleRef); });
              ngZone.onError.subscribe({ next: function (error) { exceptionHandler.handleError(error); } });
              return _callAndReportToErrorHandler(exceptionHandler, function () {
                  var initStatus = moduleRef.injector.get(ApplicationInitStatus);
                  return initStatus.donePromise.then(function () {
                      _this._moduleDoBootstrap(moduleRef);
                      return moduleRef;
                  });
              });
          });
      };
      PlatformRef_.prototype.bootstrapModule = function (moduleType, compilerOptions) {
          if (compilerOptions === void 0) { compilerOptions = []; }
          return this._bootstrapModuleWithZone(moduleType, compilerOptions, null);
      };
      PlatformRef_.prototype._bootstrapModuleWithZone = function (moduleType, compilerOptions, ngZone, componentFactoryCallback) {
          var _this = this;
          if (compilerOptions === void 0) { compilerOptions = []; }
          var compilerFactory = this.injector.get(CompilerFactory);
          var compiler = compilerFactory.createCompiler(Array.isArray(compilerOptions) ? compilerOptions : [compilerOptions]);
          // ugly internal api hack: generate host component factories for all declared components and
          // pass the factories into the callback - this is used by UpdateAdapter to get hold of all
          // factories.
          if (componentFactoryCallback) {
              return compiler.compileModuleAndAllComponentsAsync(moduleType)
                  .then(function (_a) {
                  var ngModuleFactory = _a.ngModuleFactory, componentFactories = _a.componentFactories;
                  componentFactoryCallback(componentFactories);
                  return _this._bootstrapModuleFactoryWithZone(ngModuleFactory, ngZone);
              });
          }
          return compiler.compileModuleAsync(moduleType)
              .then(function (moduleFactory) { return _this._bootstrapModuleFactoryWithZone(moduleFactory, ngZone); });
      };
      PlatformRef_.prototype._moduleDoBootstrap = function (moduleRef) {
          var appRef = moduleRef.injector.get(ApplicationRef);
          if (moduleRef.bootstrapFactories.length > 0) {
              moduleRef.bootstrapFactories.forEach(function (compFactory) { return appRef.bootstrap(compFactory); });
          }
          else if (moduleRef.instance.ngDoBootstrap) {
              moduleRef.instance.ngDoBootstrap(appRef);
          }
          else {
              throw new Error(("The module " + stringify(moduleRef.instance.constructor) + " was bootstrapped, but it does not declare \"@NgModule.bootstrap\" components nor a \"ngDoBootstrap\" method. ") +
                  "Please define one of these.");
          }
      };
      PlatformRef_.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      PlatformRef_.ctorParameters = [
          { type: Injector, },
      ];
      return PlatformRef_;
  }(PlatformRef));
  /**
   * A reference to an Angular application running on a page.
   *
   * For more about Angular applications, see the documentation for {@link bootstrap}.
   *
   * @stable
   */
  export var ApplicationRef = (function () {
      function ApplicationRef() {
      }
      Object.defineProperty(ApplicationRef.prototype, "componentTypes", {
          /**
           * Get a list of component types registered to this application.
           * This list is populated even before the component is created.
           */
          get: function () { return unimplemented(); },
          enumerable: true,
          configurable: true
      });
      ;
      Object.defineProperty(ApplicationRef.prototype, "components", {
          /**
           * Get a list of components registered to this application.
           */
          get: function () { return unimplemented(); },
          enumerable: true,
          configurable: true
      });
      ;
      return ApplicationRef;
  }());
  export var ApplicationRef_ = (function (_super) {
      __extends(ApplicationRef_, _super);
      function ApplicationRef_(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus, _testabilityRegistry, _testability) {
          var _this = this;
          _super.call(this);
          this._zone = _zone;
          this._console = _console;
          this._injector = _injector;
          this._exceptionHandler = _exceptionHandler;
          this._componentFactoryResolver = _componentFactoryResolver;
          this._initStatus = _initStatus;
          this._testabilityRegistry = _testabilityRegistry;
          this._testability = _testability;
          this._bootstrapListeners = [];
          this._rootComponents = [];
          this._rootComponentTypes = [];
          this._changeDetectorRefs = [];
          this._runningTick = false;
          this._enforceNoNewChanges = false;
          this._enforceNoNewChanges = isDevMode();
          this._zone.onMicrotaskEmpty.subscribe({ next: function () { _this._zone.run(function () { _this.tick(); }); } });
      }
      ApplicationRef_.prototype.registerChangeDetector = function (changeDetector) {
          this._changeDetectorRefs.push(changeDetector);
      };
      ApplicationRef_.prototype.unregisterChangeDetector = function (changeDetector) {
          ListWrapper.remove(this._changeDetectorRefs, changeDetector);
      };
      ApplicationRef_.prototype.bootstrap = function (componentOrFactory) {
          var _this = this;
          if (!this._initStatus.done) {
              throw new Error('Cannot bootstrap as there are still asynchronous initializers running. Bootstrap components in the `ngDoBootstrap` method of the root module.');
          }
          var componentFactory;
          if (componentOrFactory instanceof ComponentFactory) {
              componentFactory = componentOrFactory;
          }
          else {
              componentFactory = this._componentFactoryResolver.resolveComponentFactory(componentOrFactory);
          }
          this._rootComponentTypes.push(componentFactory.componentType);
          var compRef = componentFactory.create(this._injector, [], componentFactory.selector);
          compRef.onDestroy(function () { _this._unloadComponent(compRef); });
          var testability = compRef.injector.get(Testability, null);
          if (testability) {
              compRef.injector.get(TestabilityRegistry)
                  .registerApplication(compRef.location.nativeElement, testability);
          }
          this._loadComponent(compRef);
          if (isDevMode()) {
              this._console.log("Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.");
          }
          return compRef;
      };
      /** @internal */
      ApplicationRef_.prototype._loadComponent = function (componentRef) {
          this._changeDetectorRefs.push(componentRef.changeDetectorRef);
          this.tick();
          this._rootComponents.push(componentRef);
          // Get the listeners lazily to prevent DI cycles.
          var listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, [])
              .concat(this._bootstrapListeners);
          listeners.forEach(function (listener) { return listener(componentRef); });
      };
      /** @internal */
      ApplicationRef_.prototype._unloadComponent = function (componentRef) {
          if (this._rootComponents.indexOf(componentRef) == -1) {
              return;
          }
          this.unregisterChangeDetector(componentRef.changeDetectorRef);
          ListWrapper.remove(this._rootComponents, componentRef);
      };
      ApplicationRef_.prototype.tick = function () {
          if (this._runningTick) {
              throw new Error('ApplicationRef.tick is called recursively');
          }
          var scope = ApplicationRef_._tickScope();
          try {
              this._runningTick = true;
              this._changeDetectorRefs.forEach(function (detector) { return detector.detectChanges(); });
              if (this._enforceNoNewChanges) {
                  this._changeDetectorRefs.forEach(function (detector) { return detector.checkNoChanges(); });
              }
          }
          finally {
              this._runningTick = false;
              wtfLeave(scope);
          }
      };
      ApplicationRef_.prototype.ngOnDestroy = function () {
          // TODO(alxhub): Dispose of the NgZone.
          this._rootComponents.slice().forEach(function (component) { return component.destroy(); });
      };
      Object.defineProperty(ApplicationRef_.prototype, "componentTypes", {
          get: function () { return this._rootComponentTypes; },
          enumerable: true,
          configurable: true
      });
      Object.defineProperty(ApplicationRef_.prototype, "components", {
          get: function () { return this._rootComponents; },
          enumerable: true,
          configurable: true
      });
      /** @internal */
      ApplicationRef_._tickScope = wtfCreateScope('ApplicationRef#tick()');
      ApplicationRef_.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      ApplicationRef_.ctorParameters = [
          { type: NgZone, },
          { type: Console, },
          { type: Injector, },
          { type: ErrorHandler, },
          { type: ComponentFactoryResolver, },
          { type: ApplicationInitStatus, },
          { type: TestabilityRegistry, decorators: [{ type: Optional },] },
          { type: Testability, decorators: [{ type: Optional },] },
      ];
      return ApplicationRef_;
  }(ApplicationRef));
  //# sourceMappingURL=application_ref.js.map