text: /**
   * @license Angular v9.1.9
   * (c) 2010-2020 Google LLC. https://angular.io/
   * License: MIT
   */
  
  (function (global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/compiler')) :
      typeof define === 'function' && define.amd ? define('@angular/core/testing', ['exports', '@angular/core', '@angular/compiler'], factory) :
      (global = global || self, factory((global.ng = global.ng || {}, global.ng.core = global.ng.core || {}, global.ng.core.testing = {}), global.ng.core, global.ng.compiler));
  }(this, (function (exports, core, compiler) { '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 _global = (typeof window === 'undefined' ? global : window);
      /**
       * Wraps a test function in an asynchronous test zone. The test will automatically
       * complete when all asynchronous calls within this zone are done. Can be used
       * to wrap an {@link inject} call.
       *
       * Example:
       *
       * ```
       * it('...', async(inject([AClass], (object) => {
       *   object.doSomething.then(() => {
       *     expect(...);
       *   })
       * });
       * ```
       *
       *
       */
      function asyncFallback(fn) {
          // If we're running using the Jasmine test framework, adapt to call the 'done'
          // function when asynchronous activity is finished.
          if (_global.jasmine) {
              // Not using an arrow function to preserve context passed from call site
              return function (done) {
                  if (!done) {
                      // if we run beforeEach in @angular/core/testing/testing_internal then we get no done
                      // fake it here and assume sync.
                      done = function () { };
                      done.fail = function (e) {
                          throw e;
                      };
                  }
                  runInTestZone(fn, this, done, function (err) {
                      if (typeof err === 'string') {
                          return done.fail(new Error(err));
                      }
                      else {
                          done.fail(err);
                      }
                  });
              };
          }
          // Otherwise, return a promise which will resolve when asynchronous activity
          // is finished. This will be correctly consumed by the Mocha framework with
          // it('...', async(myFn)); or can be used in a custom framework.
          // Not using an arrow function to preserve context passed from call site
          return function () {
              var _this = this;
              return new Promise(function (finishCallback, failCallback) {
                  runInTestZone(fn, _this, finishCallback, failCallback);
              });
          };
      }
      function runInTestZone(fn, context, finishCallback, failCallback) {
          var currentZone = Zone.current;
          var AsyncTestZoneSpec = Zone['AsyncTestZoneSpec'];
          if (AsyncTestZoneSpec === undefined) {
              throw new Error('AsyncTestZoneSpec is needed for the async() test helper but could not be found. ' +
                  'Please make sure that your environment includes zone.js/dist/async-test.js');
          }
          var ProxyZoneSpec = Zone['ProxyZoneSpec'];
          if (ProxyZoneSpec === undefined) {
              throw new Error('ProxyZoneSpec is needed for the async() test helper but could not be found. ' +
                  'Please make sure that your environment includes zone.js/dist/proxy.js');
          }
          var proxyZoneSpec = ProxyZoneSpec.get();
          ProxyZoneSpec.assertPresent();
          // We need to create the AsyncTestZoneSpec outside the ProxyZone.
          // If we do it in ProxyZone then we will get to infinite recursion.
          var proxyZone = Zone.current.getZoneWith('ProxyZoneSpec');
          var previousDelegate = proxyZoneSpec.getDelegate();
          proxyZone.parent.run(function () {
              var testZoneSpec = new AsyncTestZoneSpec(function () {
                  // Need to restore the original zone.
                  currentZone.run(function () {
                      if (proxyZoneSpec.getDelegate() == testZoneSpec) {
                          // Only reset the zone spec if it's sill this one. Otherwise, assume it's OK.
                          proxyZoneSpec.setDelegate(previousDelegate);
                      }
                      finishCallback();
                  });
              }, function (error) {
                  // Need to restore the original zone.
                  currentZone.run(function () {
                      if (proxyZoneSpec.getDelegate() == testZoneSpec) {
                          // Only reset the zone spec if it's sill this one. Otherwise, assume it's OK.
                          proxyZoneSpec.setDelegate(previousDelegate);
                      }
                      failCallback(error);
                  });
              }, 'test');
              proxyZoneSpec.setDelegate(testZoneSpec);
          });
          return Zone.current.runGuarded(fn, context);
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * Wraps a test function in an asynchronous test zone. The test will automatically
       * complete when all asynchronous calls within this zone are done. Can be used
       * to wrap an {@link inject} call.
       *
       * Example:
       *
       * ```
       * it('...', async(inject([AClass], (object) => {
       *   object.doSomething.then(() => {
       *     expect(...);
       *   })
       * });
       * ```
       *
       * @publicApi
       */
      function async(fn) {
          var _Zone = typeof Zone !== 'undefined' ? Zone : null;
          if (!_Zone) {
              return function () {
                  return Promise.reject('Zone is needed for the async() test helper but could not be found. ' +
                      'Please make sure that your environment includes zone.js/dist/zone.js');
              };
          }
          var asyncTest = _Zone && _Zone[_Zone.__symbol__('asyncTest')];
          if (typeof asyncTest === 'function') {
              return asyncTest(fn);
          }
          // not using new version of zone.js
          // TODO @JiaLiPassion, remove this after all library updated to
          // newest version of zone.js(0.8.25)
          return asyncFallback(fn);
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * Fixture for debugging and testing a component.
       *
       * @publicApi
       */
      var ComponentFixture = /** @class */ (function () {
          function ComponentFixture(componentRef, ngZone, _autoDetect) {
              var _this = this;
              this.componentRef = componentRef;
              this.ngZone = ngZone;
              this._autoDetect = _autoDetect;
              this._isStable = true;
              this._isDestroyed = false;
              this._resolve = null;
              this._promise = null;
              this._onUnstableSubscription = null;
              this._onStableSubscription = null;
              this._onMicrotaskEmptySubscription = null;
              this._onErrorSubscription = null;
              this.changeDetectorRef = componentRef.changeDetectorRef;
              this.elementRef = componentRef.location;
              this.debugElement = core.getDebugNode(this.elementRef.nativeElement);
              this.componentInstance = componentRef.instance;
              this.nativeElement = this.elementRef.nativeElement;
              this.componentRef = componentRef;
              this.ngZone = ngZone;
              if (ngZone) {
                  // Create subscriptions outside the NgZone so that the callbacks run oustide
                  // of NgZone.
                  ngZone.runOutsideAngular(function () {
                      _this._onUnstableSubscription = ngZone.onUnstable.subscribe({
                          next: function () {
                              _this._isStable = false;
                          }
                      });
                      _this._onMicrotaskEmptySubscription = ngZone.onMicrotaskEmpty.subscribe({
                          next: function () {
                              if (_this._autoDetect) {
                                  // Do a change detection run with checkNoChanges set to true to check
                                  // there are no changes on the second run.
                                  _this.detectChanges(true);
                              }
                          }
                      });
                      _this._onStableSubscription = ngZone.onStable.subscribe({
                          next: function () {
                              _this._isStable = true;
                              // Check whether there is a pending whenStable() completer to resolve.
                              if (_this._promise !== null) {
                                  // If so check whether there are no pending macrotasks before resolving.
                                  // Do this check in the next tick so that ngZone gets a chance to update the state of
                                  // pending macrotasks.
                                  scheduleMicroTask(function () {
                                      if (!ngZone.hasPendingMacrotasks) {
                                          if (_this._promise !== null) {
                                              _this._resolve(true);
                                              _this._resolve = null;
                                              _this._promise = null;
                                          }
                                      }
                                  });
                              }
                          }
                      });
                      _this._onErrorSubscription = ngZone.onError.subscribe({
                          next: function (error) {
                              throw error;
                          }
                      });
                  });
              }
          }
          ComponentFixture.prototype._tick = function (checkNoChanges) {
              this.changeDetectorRef.detectChanges();
              if (checkNoChanges) {
                  this.checkNoChanges();
              }
          };
          /**
           * Trigger a change detection cycle for the component.
           */
          ComponentFixture.prototype.detectChanges = function (checkNoChanges) {
              var _this = this;
              if (checkNoChanges === void 0) { checkNoChanges = true; }
              if (this.ngZone != null) {
                  // Run the change detection inside the NgZone so that any async tasks as part of the change
                  // detection are captured by the zone and can be waited for in isStable.
                  this.ngZone.run(function () {
                      _this._tick(checkNoChanges);
                  });
              }
              else {
                  // Running without zone. Just do the change detection.
                  this._tick(checkNoChanges);
              }
          };
          /**
           * Do a change detection run to make sure there were no changes.
           */
          ComponentFixture.prototype.checkNoChanges = function () {
              this.changeDetectorRef.checkNoChanges();
          };
          /**
           * Set whether the fixture should autodetect changes.
           *
           * Also runs detectChanges once so that any existing change is detected.
           */
          ComponentFixture.prototype.autoDetectChanges = function (autoDetect) {
              if (autoDetect === void 0) { autoDetect = true; }
              if (this.ngZone == null) {
                  throw new Error('Cannot call autoDetectChanges when ComponentFixtureNoNgZone is set');
              }
              this._autoDetect = autoDetect;
              this.detectChanges();
          };
          /**
           * Return whether the fixture is currently stable or has async tasks that have not been completed
           * yet.
           */
          ComponentFixture.prototype.isStable = function () {
              return this._isStable && !this.ngZone.hasPendingMacrotasks;
          };
          /**
           * Get a promise that resolves when the fixture is stable.
           *
           * This can be used to resume testing after events have triggered asynchronous activity or
           * asynchronous change detection.
           */
          ComponentFixture.prototype.whenStable = function () {
              var _this = this;
              if (this.isStable()) {
                  return Promise.resolve(false);
              }
              else if (this._promise !== null) {
                  return this._promise;
              }
              else {
                  this._promise = new Promise(function (res) {
                      _this._resolve = res;
                  });
                  return this._promise;
              }
          };
          ComponentFixture.prototype._getRenderer = function () {
              if (this._renderer === undefined) {
                  this._renderer = this.componentRef.injector.get(core.RendererFactory2, null);
              }
              return this._renderer;
          };
          /**
           * Get a promise that resolves when the ui state is stable following animations.
           */
          ComponentFixture.prototype.whenRenderingDone = function () {
              var renderer = this._getRenderer();
              if (renderer && renderer.whenRenderingDone) {
                  return renderer.whenRenderingDone();
              }
              return this.whenStable();
          };
          /**
           * Trigger component destruction.
           */
          ComponentFixture.prototype.destroy = function () {
              if (!this._isDestroyed) {
                  this.componentRef.destroy();
                  if (this._onUnstableSubscription != null) {
                      this._onUnstableSubscription.unsubscribe();
                      this._onUnstableSubscription = null;
                  }
                  if (this._onStableSubscription != null) {
                      this._onStableSubscription.unsubscribe();
                      this._onStableSubscription = null;
                  }
                  if (this._onMicrotaskEmptySubscription != null) {
                      this._onMicrotaskEmptySubscription.unsubscribe();
                      this._onMicrotaskEmptySubscription = null;
                  }
                  if (this._onErrorSubscription != null) {
                      this._onErrorSubscription.unsubscribe();
                      this._onErrorSubscription = null;
                  }
                  this._isDestroyed = true;
              }
          };
          return ComponentFixture;
      }());
      function scheduleMicroTask(fn) {
          Zone.current.scheduleMicroTask('scheduleMicrotask', fn);
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * fakeAsync has been moved to zone.js
       * this file is for fallback in case old version of zone.js is used
       */
      var _Zone = typeof Zone !== 'undefined' ? Zone : null;
      var FakeAsyncTestZoneSpec = _Zone && _Zone['FakeAsyncTestZoneSpec'];
      var ProxyZoneSpec = _Zone && _Zone['ProxyZoneSpec'];
      var _fakeAsyncTestZoneSpec = null;
      /**
       * Clears out the shared fake async zone for a test.
       * To be called in a global `beforeEach`.
       *
       * @publicApi
       */
      function resetFakeAsyncZoneFallback() {
          _fakeAsyncTestZoneSpec = null;
          // in node.js testing we may not have ProxyZoneSpec in which case there is nothing to reset.
          ProxyZoneSpec && ProxyZoneSpec.assertPresent().resetDelegate();
      }
      var _inFakeAsyncCall = false;
      /**
       * Wraps a function to be executed in the fakeAsync zone:
       * - microtasks are manually executed by calling `flushMicrotasks()`,
       * - timers are synchronous, `tick()` simulates the asynchronous passage of time.
       *
       * If there are any pending timers at the end of the function, an exception will be thrown.
       *
       * Can be used to wrap inject() calls.
       *
       * @usageNotes
       * ### Example
       *
       * {@example core/testing/ts/fake_async.ts region='basic'}
       *
       * @param fn
       * @returns The function wrapped to be executed in the fakeAsync zone
       *
       * @publicApi
       */
      function fakeAsyncFallback(fn) {
          // Not using an arrow function to preserve context passed from call site
          return function () {
              var args = [];
              for (var _i = 0; _i < arguments.length; _i++) {
                  args[_i] = arguments[_i];
              }
              var proxyZoneSpec = ProxyZoneSpec.assertPresent();
              if (_inFakeAsyncCall) {
                  throw new Error('fakeAsync() calls can not be nested');
              }
              _inFakeAsyncCall = true;
              try {
                  if (!_fakeAsyncTestZoneSpec) {
                      if (proxyZoneSpec.getDelegate() instanceof FakeAsyncTestZoneSpec) {
                          throw new Error('fakeAsync() calls can not be nested');
                      }
                      _fakeAsyncTestZoneSpec = new FakeAsyncTestZoneSpec();
                  }
                  var res = void 0;
                  var lastProxyZoneSpec = proxyZoneSpec.getDelegate();
                  proxyZoneSpec.setDelegate(_fakeAsyncTestZoneSpec);
                  try {
                      res = fn.apply(this, args);
                      flushMicrotasksFallback();
                  }
                  finally {
                      proxyZoneSpec.setDelegate(lastProxyZoneSpec);
                  }
                  if (_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length > 0) {
                      throw new Error(_fakeAsyncTestZoneSpec.pendingPeriodicTimers.length + " " +
                          "periodic timer(s) still in the queue.");
                  }
                  if (_fakeAsyncTestZoneSpec.pendingTimers.length > 0) {
                      throw new Error(_fakeAsyncTestZoneSpec.pendingTimers.length + " timer(s) still in the queue.");
                  }
                  return res;
              }
              finally {
                  _inFakeAsyncCall = false;
                  resetFakeAsyncZoneFallback();
              }
          };
      }
      function _getFakeAsyncZoneSpec() {
          if (_fakeAsyncTestZoneSpec == null) {
              throw new Error('The code should be running in the fakeAsync zone to call this function');
          }
          return _fakeAsyncTestZoneSpec;
      }
      /**
       * Simulates the asynchronous passage of time for the timers in the fakeAsync zone.
       *
       * The microtasks queue is drained at the very start of this function and after any timer callback
       * has been executed.
       *
       * @usageNotes
       * ### Example
       *
       * {@example core/testing/ts/fake_async.ts region='basic'}
       *
       * @publicApi
       */
      function tickFallback(millis, tickOptions) {
          if (millis === void 0) { millis = 0; }
          if (tickOptions === void 0) { tickOptions = {
              processNewMacroTasksSynchronously: true
          }; }
          _getFakeAsyncZoneSpec().tick(millis, null, tickOptions);
      }
      /**
       * Simulates the asynchronous passage of time for the timers in the fakeAsync zone by
       * draining the macrotask queue until it is empty. The returned value is the milliseconds
       * of time that would have been elapsed.
       *
       * @param maxTurns
       * @returns The simulated time elapsed, in millis.
       *
       * @publicApi
       */
      function flushFallback(maxTurns) {
          return _getFakeAsyncZoneSpec().flush(maxTurns);
      }
      /**
       * Discard all remaining periodic tasks.
       *
       * @publicApi
       */
      function discardPeriodicTasksFallback() {
          var zoneSpec = _getFakeAsyncZoneSpec();
          zoneSpec.pendingPeriodicTimers.length = 0;
      }
      /**
       * Flush any pending microtasks.
       *
       * @publicApi
       */
      function flushMicrotasksFallback() {
          _getFakeAsyncZoneSpec().flushMicrotasks();
      }
  
      /**
       * @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 _Zone$1 = typeof Zone !== 'undefined' ? Zone : null;
      var fakeAsyncTestModule = _Zone$1 && _Zone$1[_Zone$1.__symbol__('fakeAsyncTest')];
      /**
       * Clears out the shared fake async zone for a test.
       * To be called in a global `beforeEach`.
       *
       * @publicApi
       */
      function resetFakeAsyncZone() {
          if (fakeAsyncTestModule) {
              return fakeAsyncTestModule.resetFakeAsyncZone();
          }
          else {
              return resetFakeAsyncZoneFallback();
          }
      }
      /**
       * Wraps a function to be executed in the fakeAsync zone:
       * - microtasks are manually executed by calling `flushMicrotasks()`,
       * - timers are synchronous, `tick()` simulates the asynchronous passage of time.
       *
       * If there are any pending timers at the end of the function, an exception will be thrown.
       *
       * Can be used to wrap inject() calls.
       *
       * @usageNotes
       * ### Example
       *
       * {@example core/testing/ts/fake_async.ts region='basic'}
       *
       * @param fn
       * @returns The function wrapped to be executed in the fakeAsync zone
       *
       * @publicApi
       */
      function fakeAsync(fn) {
          if (fakeAsyncTestModule) {
              return fakeAsyncTestModule.fakeAsync(fn);
          }
          else {
              return fakeAsyncFallback(fn);
          }
      }
      /**
       * Simulates the asynchronous passage of time for the timers in the fakeAsync zone.
       *
       * The microtasks queue is drained at the very start of this function and after any timer callback
       * has been executed.
       *
       * @usageNotes
       * ### Example
       *
       * {@example core/testing/ts/fake_async.ts region='basic'}
       *
       * @param millis, the number of millisecond to advance the virtual timer
       * @param tickOptions, the options of tick with a flag called
       * processNewMacroTasksSynchronously, whether to invoke the new macroTasks, by default is
       * false, means the new macroTasks will be invoked
       *
       * For example,
       *
       * it ('test with nested setTimeout', fakeAsync(() => {
       *   let nestedTimeoutInvoked = false;
       *   function funcWithNestedTimeout() {
       *     setTimeout(() => {
       *       nestedTimeoutInvoked = true;
       *     });
       *   };
       *   setTimeout(funcWithNestedTimeout);
       *   tick();
       *   expect(nestedTimeoutInvoked).toBe(true);
       * }));
       *
       * in this case, we have a nested timeout (new macroTask), when we tick, both the
       * funcWithNestedTimeout and the nested timeout both will be invoked.
       *
       * it ('test with nested setTimeout', fakeAsync(() => {
       *   let nestedTimeoutInvoked = false;
       *   function funcWithNestedTimeout() {
       *     setTimeout(() => {
       *       nestedTimeoutInvoked = true;
       *     });
       *   };
       *   setTimeout(funcWithNestedTimeout);
       *   tick(0, {processNewMacroTasksSynchronously: false});
       *   expect(nestedTimeoutInvoked).toBe(false);
       * }));
       *
       * if we pass the tickOptions with processNewMacroTasksSynchronously to be false, the nested timeout
       * will not be invoked.
       *
       *
       * @publicApi
       */
      function tick(millis, tickOptions) {
          if (millis === void 0) { millis = 0; }
          if (tickOptions === void 0) { tickOptions = {
              processNewMacroTasksSynchronously: true
          }; }
          if (fakeAsyncTestModule) {
              return fakeAsyncTestModule.tick(millis, tickOptions);
          }
          else {
              return tickFallback(millis, tickOptions);
          }
      }
      /**
       * Simulates the asynchronous passage of time for the timers in the fakeAsync zone by
       * draining the macrotask queue until it is empty. The returned value is the milliseconds
       * of time that would have been elapsed.
       *
       * @param maxTurns
       * @returns The simulated time elapsed, in millis.
       *
       * @publicApi
       */
      function flush(maxTurns) {
          if (fakeAsyncTestModule) {
              return fakeAsyncTestModule.flush(maxTurns);
          }
          else {
              return flushFallback(maxTurns);
          }
      }
      /**
       * Discard all remaining periodic tasks.
       *
       * @publicApi
       */
      function discardPeriodicTasks() {
          if (fakeAsyncTestModule) {
              return fakeAsyncTestModule.discardPeriodicTasks();
          }
          else {
              discardPeriodicTasksFallback();
          }
      }
      /**
       * Flush any pending microtasks.
       *
       * @publicApi
       */
      function flushMicrotasks() {
          if (fakeAsyncTestModule) {
              return fakeAsyncTestModule.flushMicrotasks();
          }
          else {
              return flushMicrotasksFallback();
          }
      }
  
      /*! *****************************************************************************
      Copyright (c) Microsoft Corporation. All rights reserved.
      Licensed under the Apache License, Version 2.0 (the "License"); you may not use
      this file except in compliance with the License. You may obtain a copy of the
      License at http://www.apache.org/licenses/LICENSE-2.0
  
      THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
      KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
      WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
      MERCHANTABLITY OR NON-INFRINGEMENT.
  
      See the Apache Version 2.0 License for specific language governing permissions
      and limitations under the License.
      ***************************************************************************** */
      /* global Reflect, Promise */
  
      var extendStatics = function(d, b) {
          extendStatics = Object.setPrototypeOf ||
              ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
              function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
          return extendStatics(d, b);
      };
  
      function __extends(d, b) {
          extendStatics(d, b);
          function __() { this.constructor = d; }
          d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
      }
  
      var __assign = function() {
          __assign = Object.assign || function __assign(t) {
              for (var s, i = 1, n = arguments.length; i < n; i++) {
                  s = arguments[i];
                  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
              }
              return t;
          };
          return __assign.apply(this, arguments);
      };
  
      function __rest(s, e) {
          var t = {};
          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
              t[p] = s[p];
          if (s != null && typeof Object.getOwnPropertySymbols === "function")
              for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
                  if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                      t[p[i]] = s[p[i]];
              }
          return t;
      }
  
      function __decorate(decorators, target, key, desc) {
          var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
          if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
          else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
          return c > 3 && r && Object.defineProperty(target, key, r), r;
      }
  
      function __param(paramIndex, decorator) {
          return function (target, key) { decorator(target, key, paramIndex); }
      }
  
      function __metadata(metadataKey, metadataValue) {
          if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
      }
  
      function __awaiter(thisArg, _arguments, P, generator) {
          function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
          return new (P || (P = Promise))(function (resolve, reject) {
              function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
              function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
              function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
              step((generator = generator.apply(thisArg, _arguments || [])).next());
          });
      }
  
      function __generator(thisArg, body) {
          var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
          return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
          function verb(n) { return function (v) { return step([n, v]); }; }
          function step(op) {
              if (f) throw new TypeError("Generator is already executing.");
              while (_) try {
                  if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
                  if (y = 0, t) op = [op[0] & 2, t.value];
                  switch (op[0]) {
                      case 0: case 1: t = op; break;
                      case 4: _.label++; return { value: op[1], done: false };
                      case 5: _.label++; y = op[1]; op = [0]; continue;
                      case 7: op = _.ops.pop(); _.trys.pop(); continue;
                      default:
                          if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                          if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                          if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                          if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                          if (t[2]) _.ops.pop();
                          _.trys.pop(); continue;
                  }
                  op = body.call(thisArg, _);
              } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
              if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
          }
      }
  
      function __exportStar(m, exports) {
          for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
      }
  
      function __values(o) {
          var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
          if (m) return m.call(o);
          if (o && typeof o.length === "number") return {
              next: function () {
                  if (o && i >= o.length) o = void 0;
                  return { value: o && o[i++], done: !o };
              }
          };
          throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
      }
  
      function __read(o, n) {
          var m = typeof Symbol === "function" && o[Symbol.iterator];
          if (!m) return o;
          var i = m.call(o), r, ar = [], e;
          try {
              while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
          }
          catch (error) { e = { error: error }; }
          finally {
              try {
                  if (r && !r.done && (m = i["return"])) m.call(i);
              }
              finally { if (e) throw e.error; }
          }
          return ar;
      }
  
      function __spread() {
          for (var ar = [], i = 0; i < arguments.length; i++)
              ar = ar.concat(__read(arguments[i]));
          return ar;
      }
  
      function __spreadArrays() {
          for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
          for (var r = Array(s), k = 0, i = 0; i < il; i++)
              for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                  r[k] = a[j];
          return r;
      };
  
      function __await(v) {
          return this instanceof __await ? (this.v = v, this) : new __await(v);
      }
  
      function __asyncGenerator(thisArg, _arguments, generator) {
          if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
          var g = generator.apply(thisArg, _arguments || []), i, q = [];
          return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
          function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
          function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
          function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
          function fulfill(value) { resume("next", value); }
          function reject(value) { resume("throw", value); }
          function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
      }
  
      function __asyncDelegator(o) {
          var i, p;
          return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
          function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
      }
  
      function __asyncValues(o) {
          if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
          var m = o[Symbol.asyncIterator], i;
          return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
          function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
          function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
      }
  
      function __makeTemplateObject(cooked, raw) {
          if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
          return cooked;
      };
  
      function __importStar(mod) {
          if (mod && mod.__esModule) return mod;
          var result = {};
          if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
          result.default = mod;
          return result;
      }
  
      function __importDefault(mod) {
          return (mod && mod.__esModule) ? mod : { default: mod };
      }
  
      function __classPrivateFieldGet(receiver, privateMap) {
          if (!privateMap.has(receiver)) {
              throw new TypeError("attempted to get private field on non-instance");
          }
          return privateMap.get(receiver);
      }
  
      function __classPrivateFieldSet(receiver, privateMap, value) {
          if (!privateMap.has(receiver)) {
              throw new TypeError("attempted to set private field on non-instance");
          }
          privateMap.set(receiver, value);
          return value;
      }
  
      /**
       * @license
       * Copyright Google 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
       */
      /**
       * Injectable completer that allows signaling completion of an asynchronous test. Used internally.
       */
      var AsyncTestCompleter = /** @class */ (function () {
          function AsyncTestCompleter() {
              var _this = this;
              this._promise = new Promise(function (res, rej) {
                  _this._resolve = res;
                  _this._reject = rej;
              });
          }
          AsyncTestCompleter.prototype.done = function (value) {
              this._resolve(value);
          };
          AsyncTestCompleter.prototype.fail = function (error, stackTrace) {
              this._reject(error);
          };
          Object.defineProperty(AsyncTestCompleter.prototype, "promise", {
              get: function () {
                  return this._promise;
              },
              enumerable: true,
              configurable: true
          });
          return AsyncTestCompleter;
      }());
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * Used to resolve resource URLs on `@Component` when used with JIT compilation.
       *
       * Example:
       * ```
       * @Component({
       *   selector: 'my-comp',
       *   templateUrl: 'my-comp.html', // This requires asynchronous resolution
       * })
       * class MyComponent{
       * }
       *
       * // Calling `renderComponent` will fail because `renderComponent` is a synchronous process
       * // and `MyComponent`'s `@Component.templateUrl` needs to be resolved asynchronously.
       *
       * // Calling `resolveComponentResources()` will resolve `@Component.templateUrl` into
       * // `@Component.template`, which allows `renderComponent` to proceed in a synchronous manner.
       *
       * // Use browser's `fetch()` function as the default resource resolution strategy.
       * resolveComponentResources(fetch).then(() => {
       *   // After resolution all URLs have been converted into `template` strings.
       *   renderComponent(MyComponent);
       * });
       *
       * ```
       *
       * NOTE: In AOT the resolution happens during compilation, and so there should be no need
       * to call this method outside JIT mode.
       *
       * @param resourceResolver a function which is responsible for returning a `Promise` to the
       * contents of the resolved URL. Browser's `fetch()` method is a good default implementation.
       */
      function resolveComponentResources(resourceResolver) {
          // Store all promises which are fetching the resources.
          var componentResolved = [];
          // Cache so that we don't fetch the same resource more than once.
          var urlMap = new Map();
          function cachedResourceResolve(url) {
              var promise = urlMap.get(url);
              if (!promise) {
                  var resp = resourceResolver(url);
                  urlMap.set(url, promise = resp.then(unwrapResponse));
              }
              return promise;
          }
          componentResourceResolutionQueue.forEach(function (component, type) {
              var promises = [];
              if (component.templateUrl) {
                  promises.push(cachedResourceResolve(component.templateUrl).then(function (template) {
                      component.template = template;
                  }));
              }
              var styleUrls = component.styleUrls;
              var styles = component.styles || (component.styles = []);
              var styleOffset = component.styles.length;
              styleUrls && styleUrls.forEach(function (styleUrl, index) {
                  styles.push(''); // pre-allocate array.
                  promises.push(cachedResourceResolve(styleUrl).then(function (style) {
                      styles[styleOffset + index] = style;
                      styleUrls.splice(styleUrls.indexOf(styleUrl), 1);
                      if (styleUrls.length == 0) {
                          component.styleUrls = undefined;
                      }
                  }));
              });
              var fullyResolved = Promise.all(promises).then(function () { return componentDefResolved(type); });
              componentResolved.push(fullyResolved);
          });
          clearResolutionOfComponentResourcesQueue();
          return Promise.all(componentResolved).then(function () { return undefined; });
      }
      var componentResourceResolutionQueue = new Map();
      // Track when existing ɵcmp for a Type is waiting on resources.
      var componentDefPendingResolution = new Set();
      function maybeQueueResolutionOfComponentResources(type, metadata) {
          if (componentNeedsResolution(metadata)) {
              componentResourceResolutionQueue.set(type, metadata);
              componentDefPendingResolution.add(type);
          }
      }
      function isComponentDefPendingResolution(type) {
          return componentDefPendingResolution.has(type);
      }
      function componentNeedsResolution(component) {
          return !!((component.templateUrl && !component.hasOwnProperty('template')) ||
              component.styleUrls && component.styleUrls.length);
      }
      function clearResolutionOfComponentResourcesQueue() {
          var old = componentResourceResolutionQueue;
          componentResourceResolutionQueue = new Map();
          return old;
      }
      function restoreComponentResolutionQueue(queue) {
          componentDefPendingResolution.clear();
          queue.forEach(function (_, type) { return componentDefPendingResolution.add(type); });
          componentResourceResolutionQueue = queue;
      }
      function isComponentResourceResolutionQueueEmpty() {
          return componentResourceResolutionQueue.size === 0;
      }
      function unwrapResponse(response) {
          return typeof response == 'string' ? response : response.text();
      }
      function componentDefResolved(type) {
          componentDefPendingResolution.delete(type);
      }
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      var _nextReferenceId = 0;
      var MetadataOverrider = /** @class */ (function () {
          function MetadataOverrider() {
              this._references = new Map();
          }
          /**
           * Creates a new instance for the given metadata class
           * based on an old instance and overrides.
           */
          MetadataOverrider.prototype.overrideMetadata = function (metadataClass, oldMetadata, override) {
              var props = {};
              if (oldMetadata) {
                  _valueProps(oldMetadata).forEach(function (prop) { return props[prop] = oldMetadata[prop]; });
              }
              if (override.set) {
                  if (override.remove || override.add) {
                      throw new Error("Cannot set and add/remove " + core.ɵstringify(metadataClass) + " at the same time!");
                  }
                  setMetadata(props, override.set);
              }
              if (override.remove) {
                  removeMetadata(props, override.remove, this._references);
              }
              if (override.add) {
                  addMetadata(props, override.add);
              }
              return new metadataClass(props);
          };
          return MetadataOverrider;
      }());
      function removeMetadata(metadata, remove, references) {
          var removeObjects = new Set();
          var _loop_1 = function (prop) {
              var removeValue = remove[prop];
              if (Array.isArray(removeValue)) {
                  removeValue.forEach(function (value) {
                      removeObjects.add(_propHashKey(prop, value, references));
                  });
              }
              else {
                  removeObjects.add(_propHashKey(prop, removeValue, references));
              }
          };
          for (var prop in remove) {
              _loop_1(prop);
          }
          var _loop_2 = function (prop) {
              var propValue = metadata[prop];
              if (Array.isArray(propValue)) {
                  metadata[prop] = propValue.filter(function (value) { return !removeObjects.has(_propHashKey(prop, value, references)); });
              }
              else {
                  if (removeObjects.has(_propHashKey(prop, propValue, references))) {
                      metadata[prop] = undefined;
                  }
              }
          };
          for (var prop in metadata) {
              _loop_2(prop);
          }
      }
      function addMetadata(metadata, add) {
          for (var prop in add) {
              var addValue = add[prop];
              var propValue = metadata[prop];
              if (propValue != null && Array.isArray(propValue)) {
                  metadata[prop] = propValue.concat(addValue);
              }
              else {
                  metadata[prop] = addValue;
              }
          }
      }
      function setMetadata(metadata, set) {
          for (var prop in set) {
              metadata[prop] = set[prop];
          }
      }
      function _propHashKey(propName, propValue, references) {
          var replacer = function (key, value) {
              if (typeof value === 'function') {
                  value = _serializeReference(value, references);
              }
              return value;
          };
          return propName + ":" + JSON.stringify(propValue, replacer);
      }
      function _serializeReference(ref, references) {
          var id = references.get(ref);
          if (!id) {
              id = "" + core.ɵstringify(ref) + _nextReferenceId++;
              references.set(ref, id);
          }
          return id;
      }
      function _valueProps(obj) {
          var props = [];
          // regular public props
          Object.keys(obj).forEach(function (prop) {
              if (!prop.startsWith('_')) {
                  props.push(prop);
              }
          });
          // getters
          var proto = obj;
          while (proto = Object.getPrototypeOf(proto)) {
              Object.keys(proto).forEach(function (protoProp) {
                  var desc = Object.getOwnPropertyDescriptor(proto, protoProp);
                  if (!protoProp.startsWith('_') && desc && 'get' in desc) {
                      props.push(protoProp);
                  }
              });
          }
          return props;
      }
  
      /**
       * @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 reflection = new core.ɵReflectionCapabilities();
      /**
       * Allows to override ivy metadata for tests (via the `TestBed`).
       */
      var OverrideResolver = /** @class */ (function () {
          function OverrideResolver() {
              this.overrides = new Map();
              this.resolved = new Map();
          }
          OverrideResolver.prototype.addOverride = function (type, override) {
              var overrides = this.overrides.get(type) || [];
              overrides.push(override);
              this.overrides.set(type, overrides);
              this.resolved.delete(type);
          };
          OverrideResolver.prototype.setOverrides = function (overrides) {
              var _this = this;
              this.overrides.clear();
              overrides.forEach(function (_a) {
                  var _b = __read(_a, 2), type = _b[0], override = _b[1];
                  _this.addOverride(type, override);
              });
          };
          OverrideResolver.prototype.getAnnotation = function (type) {
              var annotations = reflection.annotations(type);
              // Try to find the nearest known Type annotation and make sure that this annotation is an
              // instance of the type we are looking for, so we can use it for resolution. Note: there might
              // be multiple known annotations found due to the fact that Components can extend Directives (so
              // both Directive and Component annotations would be present), so we always check if the known
              // annotation has the right type.
              for (var i = annotations.length - 1; i >= 0; i--) {
                  var annotation = annotations[i];
                  var isKnownType = annotation instanceof core.Directive || annotation instanceof core.Component ||
                      annotation instanceof core.Pipe || annotation instanceof core.NgModule;
                  if (isKnownType) {
                      return annotation instanceof this.type ? annotation : null;
                  }
              }
              return null;
          };
          OverrideResolver.prototype.resolve = function (type) {
              var _this = this;
              var resolved = this.resolved.get(type) || null;
              if (!resolved) {
                  resolved = this.getAnnotation(type);
                  if (resolved) {
                      var overrides = this.overrides.get(type);
                      if (overrides) {
                          var overrider_1 = new MetadataOverrider();
                          overrides.forEach(function (override) {
                              resolved = overrider_1.overrideMetadata(_this.type, resolved, override);
                          });
                      }
                  }
                  this.resolved.set(type, resolved);
              }
              return resolved;
          };
          return OverrideResolver;
      }());
      var DirectiveResolver = /** @class */ (function (_super) {
          __extends(DirectiveResolver, _super);
          function DirectiveResolver() {
              return _super !== null && _super.apply(this, arguments) || this;
          }
          Object.defineProperty(DirectiveResolver.prototype, "type", {
              get: function () {
                  return core.Directive;
              },
              enumerable: true,
              configurable: true
          });
          return DirectiveResolver;
      }(OverrideResolver));
      var ComponentResolver = /** @class */ (function (_super) {
          __extends(ComponentResolver, _super);
          function ComponentResolver() {
              return _super !== null && _super.apply(this, arguments) || this;
          }
          Object.defineProperty(ComponentResolver.prototype, "type", {
              get: function () {
                  return core.Component;
              },
              enumerable: true,
              configurable: true
          });
          return ComponentResolver;
      }(OverrideResolver));
      var PipeResolver = /** @class */ (function (_super) {
          __extends(PipeResolver, _super);
          function PipeResolver() {
              return _super !== null && _super.apply(this, arguments) || this;
          }
          Object.defineProperty(PipeResolver.prototype, "type", {
              get: function () {
                  return core.Pipe;
              },
              enumerable: true,
              configurable: true
          });
          return PipeResolver;
      }(OverrideResolver));
      var NgModuleResolver = /** @class */ (function (_super) {
          __extends(NgModuleResolver, _super);
          function NgModuleResolver() {
              return _super !== null && _super.apply(this, arguments) || this;
          }
          Object.defineProperty(NgModuleResolver.prototype, "type", {
              get: function () {
                  return core.NgModule;
              },
              enumerable: true,
              configurable: true
          });
          return NgModuleResolver;
      }(OverrideResolver));
  
      /**
       * @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 TestingModuleOverride;
      (function (TestingModuleOverride) {
          TestingModuleOverride[TestingModuleOverride["DECLARATION"] = 0] = "DECLARATION";
          TestingModuleOverride[TestingModuleOverride["OVERRIDE_TEMPLATE"] = 1] = "OVERRIDE_TEMPLATE";
      })(TestingModuleOverride || (TestingModuleOverride = {}));
      function isTestingModuleOverride(value) {
          return value === TestingModuleOverride.DECLARATION ||
              value === TestingModuleOverride.OVERRIDE_TEMPLATE;
      }
      var R3TestBedCompiler = /** @class */ (function () {
          function R3TestBedCompiler(platform, additionalModuleTypes) {
              this.platform = platform;
              this.additionalModuleTypes = additionalModuleTypes;
              this.originalComponentResolutionQueue = null;
              // Testing module configuration
              this.declarations = [];
              this.imports = [];
              this.providers = [];
              this.schemas = [];
              // Queues of components/directives/pipes that should be recompiled.
              this.pendingComponents = new Set();
              this.pendingDirectives = new Set();
              this.pendingPipes = new Set();
              // Keep track of all components and directives, so we can patch Providers onto defs later.
              this.seenComponents = new Set();
              this.seenDirectives = new Set();
              // Keep track of overridden modules, so that we can collect all affected ones in the module tree.
              this.overriddenModules = new Set();
              // Store resolved styles for Components that have template overrides present and `styleUrls`
              // defined at the same time.
              this.existingComponentStyles = new Map();
              this.resolvers = initResolvers();
              this.componentToModuleScope = new Map();
              // Map that keeps initial version of component/directive/pipe defs in case
              // we compile a Type again, thus overriding respective static fields. This is
              // required to make sure we restore defs to their initial states between test runs
              // TODO: we should support the case with multiple defs on a type
              this.initialNgDefs = new Map();
              // Array that keeps cleanup operations for initial versions of component/directive/pipe/module
              // defs in case TestBed makes changes to the originals.
              this.defCleanupOps = [];
              this._injector = null;
              this.compilerProviders = null;
              this.providerOverrides = [];
              this.rootProviderOverrides = [];
              // Overrides for injectables with `{providedIn: SomeModule}` need to be tracked and added to that
              // module's provider list.
              this.providerOverridesByModule = new Map();
              this.providerOverridesByToken = new Map();
              this.moduleProvidersOverridden = new Set();
              this.testModuleRef = null;
              var DynamicTestModule = /** @class */ (function () {
                  function DynamicTestModule() {
                  }
                  return DynamicTestModule;
              }());
              this.testModuleType = DynamicTestModule;
          }
          R3TestBedCompiler.prototype.setCompilerProviders = function (providers) {
              this.compilerProviders = providers;
              this._injector = null;
          };
          R3TestBedCompiler.prototype.configureTestingModule = function (moduleDef) {
              var _a, _b, _c, _d;
              // Enqueue any compilation tasks for the directly declared component.
              if (moduleDef.declarations !== undefined) {
                  this.queueTypeArray(moduleDef.declarations, TestingModuleOverride.DECLARATION);
                  (_a = this.declarations).push.apply(_a, __spread(moduleDef.declarations));
              }
              // Enqueue any compilation tasks for imported modules.
              if (moduleDef.imports !== undefined) {
                  this.queueTypesFromModulesArray(moduleDef.imports);
                  (_b = this.imports).push.apply(_b, __spread(moduleDef.imports));
              }
              if (moduleDef.providers !== undefined) {
                  (_c = this.providers).push.apply(_c, __spread(moduleDef.providers));
              }
              if (moduleDef.schemas !== undefined) {
                  (_d = this.schemas).push.apply(_d, __spread(moduleDef.schemas));
              }
          };
          R3TestBedCompiler.prototype.overrideModule = function (ngModule, override) {
              this.overriddenModules.add(ngModule);
              // Compile the module right away.
              this.resolvers.module.addOverride(ngModule, override);
              var metadata = this.resolvers.module.resolve(ngModule);
              if (metadata === null) {
                  throw invalidTypeError(ngModule.name, 'NgModule');
              }
              this.recompileNgModule(ngModule, metadata);
              // At this point, the module has a valid module def (ɵmod), but the override may have introduced
              // new declarations or imported modules. Ingest any possible new types and add them to the
              // current queue.
              this.queueTypesFromModulesArray([ngModule]);
          };
          R3TestBedCompiler.prototype.overrideComponent = function (component, override) {
              this.resolvers.component.addOverride(component, override);
              this.pendingComponents.add(component);
          };
          R3TestBedCompiler.prototype.overrideDirective = function (directive, override) {
              this.resolvers.directive.addOverride(directive, override);
              this.pendingDirectives.add(directive);
          };
          R3TestBedCompiler.prototype.overridePipe = function (pipe, override) {
              this.resolvers.pipe.addOverride(pipe, override);
              this.pendingPipes.add(pipe);
          };
          R3TestBedCompiler.prototype.overrideProvider = function (token, provider) {
              var providerDef;
              if (provider.useFactory !== undefined) {
                  providerDef = {
                      provide: token,
                      useFactory: provider.useFactory,
                      deps: provider.deps || [],
                      multi: provider.multi
                  };
              }
              else if (provider.useValue !== undefined) {
                  providerDef = { provide: token, useValue: provider.useValue, multi: provider.multi };
              }
              else {
                  providerDef = { provide: token };
              }
              var injectableDef = typeof token !== 'string' ? core.ɵgetInjectableDef(token) : null;
              var isRoot = injectableDef !== null && injectableDef.providedIn === 'root';
              var overridesBucket = isRoot ? this.rootProviderOverrides : this.providerOverrides;
              overridesBucket.push(providerDef);
              // Keep overrides grouped by token as well for fast lookups using token
              this.providerOverridesByToken.set(token, providerDef);
              if (injectableDef !== null && injectableDef.providedIn !== null &&
                  typeof injectableDef.providedIn !== 'string') {
                  var existingOverrides = this.providerOverridesByModule.get(injectableDef.providedIn);
                  if (existingOverrides !== undefined) {
                      existingOverrides.push(providerDef);
                  }
                  else {
                      this.providerOverridesByModule.set(injectableDef.providedIn, [providerDef]);
                  }
              }
          };
          R3TestBedCompiler.prototype.overrideTemplateUsingTestingModule = function (type, template) {
              var _this = this;
              var def = type[core.ɵNG_COMP_DEF];
              var hasStyleUrls = function () {
                  var metadata = _this.resolvers.component.resolve(type);
                  return !!metadata.styleUrls && metadata.styleUrls.length > 0;
              };
              var overrideStyleUrls = !!def && !isComponentDefPendingResolution(type) && hasStyleUrls();
              // In Ivy, compiling a component does not require knowing the module providing the
              // component's scope, so overrideTemplateUsingTestingModule can be implemented purely via
              // overrideComponent. Important: overriding template requires full Component re-compilation,
              // which may fail in case styleUrls are also present (thus Component is considered as required
              // resolution). In order to avoid this, we preemptively set styleUrls to an empty array,
              // preserve current styles available on Component def and restore styles back once compilation
              // is complete.
              var override = overrideStyleUrls ? { template: template, styles: [], styleUrls: [] } : { template: template };
              this.overrideComponent(type, { set: override });
              if (overrideStyleUrls && def.styles && def.styles.length > 0) {
                  this.existingComponentStyles.set(type, def.styles);
              }
              // Set the component's scope to be the testing module.
              this.componentToModuleScope.set(type, TestingModuleOverride.OVERRIDE_TEMPLATE);
          };
          R3TestBedCompiler.prototype.compileComponents = function () {
              return __awaiter(this, void 0, void 0, function () {
                  var needsAsyncResources, resourceLoader_1, resolver;
                  var _this = this;
                  return __generator(this, function (_a) {
                      switch (_a.label) {
                          case 0:
                              this.clearComponentResolutionQueue();
                              needsAsyncResources = this.compileTypesSync();
                              if (!needsAsyncResources) return [3 /*break*/, 2];
                              resolver = function (url) {
                                  if (!resourceLoader_1) {
                                      resourceLoader_1 = _this.injector.get(compiler.ResourceLoader);
                                  }
                                  return Promise.resolve(resourceLoader_1.get(url));
                              };
                              return [4 /*yield*/, resolveComponentResources(resolver)];
                          case 1:
                              _a.sent();
                              _a.label = 2;
                          case 2: return [2 /*return*/];
                      }
                  });
              });
          };
          R3TestBedCompiler.prototype.finalize = function () {
              // One last compile
              this.compileTypesSync();
              // Create the testing module itself.
              this.compileTestModule();
              this.applyTransitiveScopes();
              this.applyProviderOverrides();
              // Patch previously stored `styles` Component values (taken from ɵcmp), in case these
              // Components have `styleUrls` fields defined and template override was requested.
              this.patchComponentsWithExistingStyles();
              // Clear the componentToModuleScope map, so that future compilations don't reset the scope of
              // every component.
              this.componentToModuleScope.clear();
              var parentInjector = this.platform.injector;
              this.testModuleRef = new core.ɵRender3NgModuleRef(this.testModuleType, parentInjector);
              // ApplicationInitStatus.runInitializers() is marked @internal to core.
              // Cast it to any before accessing it.
              this.testModuleRef.injector.get(core.ApplicationInitStatus).runInitializers();
              // Set locale ID after running app initializers, since locale information might be updated while
              // running initializers. This is also consistent with the execution order while bootstrapping an
              // app (see `packages/core/src/application_ref.ts` file).
              var localeId = this.testModuleRef.injector.get(core.LOCALE_ID, core.ɵDEFAULT_LOCALE_ID);
              core.ɵsetLocaleId(localeId);
              return this.testModuleRef;
          };
          /**
           * @internal
           */
          R3TestBedCompiler.prototype._compileNgModuleSync = function (moduleType) {
              this.queueTypesFromModulesArray([moduleType]);
              this.compileTypesSync();
              this.applyProviderOverrides();
              this.applyProviderOverridesToModule(moduleType);
              this.applyTransitiveScopes();
          };
          /**
           * @internal
           */
          R3TestBedCompiler.prototype._compileNgModuleAsync = function (moduleType) {
              return __awaiter(this, void 0, void 0, function () {
                  return __generator(this, function (_a) {
                      switch (_a.label) {
                          case 0:
                              this.queueTypesFromModulesArray([moduleType]);
                              return [4 /*yield*/, this.compileComponents()];
                          case 1:
                              _a.sent();
                              this.applyProviderOverrides();
                              this.applyProviderOverridesToModule(moduleType);
                              this.applyTransitiveScopes();
                              return [2 /*return*/];
                      }
                  });
              });
          };
          /**
           * @internal
           */
          R3TestBedCompiler.prototype._getModuleResolver = function () {
              return this.resolvers.module;
          };
          /**
           * @internal
           */
          R3TestBedCompiler.prototype._getComponentFactories = function (moduleType) {
              var _this = this;
              return maybeUnwrapFn(moduleType.ɵmod.declarations).reduce(function (factories, declaration) {
                  var componentDef = declaration.ɵcmp;
                  componentDef && factories.push(new core.ɵRender3ComponentFactory(componentDef, _this.testModuleRef));
                  return factories;
              }, []);
          };
          R3TestBedCompiler.prototype.compileTypesSync = function () {
              var _this = this;
              // Compile all queued components, directives, pipes.
              var needsAsyncResources = false;
              this.pendingComponents.forEach(function (declaration) {
                  needsAsyncResources = needsAsyncResources || isComponentDefPendingResolution(declaration);
                  var metadata = _this.resolvers.component.resolve(declaration);
                  if (metadata === null) {
                      throw invalidTypeError(declaration.name, 'Component');
                  }
                  _this.maybeStoreNgDef(core.ɵNG_COMP_DEF, declaration);
                  core.ɵcompileComponent(declaration, metadata);
              });
              this.pendingComponents.clear();
              this.pendingDirectives.forEach(function (declaration) {
                  var metadata = _this.resolvers.directive.resolve(declaration);
                  if (metadata === null) {
                      throw invalidTypeError(declaration.name, 'Directive');
                  }
                  _this.maybeStoreNgDef(core.ɵNG_DIR_DEF, declaration);
                  core.ɵcompileDirective(declaration, metadata);
              });
              this.pendingDirectives.clear();
              this.pendingPipes.forEach(function (declaration) {
                  var metadata = _this.resolvers.pipe.resolve(declaration);
                  if (metadata === null) {
                      throw invalidTypeError(declaration.name, 'Pipe');
                  }
                  _this.maybeStoreNgDef(core.ɵNG_PIPE_DEF, declaration);
                  core.ɵcompilePipe(declaration, metadata);
              });
              this.pendingPipes.clear();
              return needsAsyncResources;
          };
          R3TestBedCompiler.prototype.applyTransitiveScopes = function () {
              var _this = this;
              if (this.overriddenModules.size > 0) {
                  // Module overrides (via `TestBed.overrideModule`) might affect scopes that were previously
                  // calculated and stored in `transitiveCompileScopes`. If module overrides are present,
                  // collect all affected modules and reset scopes to force their re-calculatation.
                  var testingModuleDef = this.testModuleType[core.ɵNG_MOD_DEF];
                  var affectedModules = this.collectModulesAffectedByOverrides(testingModuleDef.imports);
                  if (affectedModules.size > 0) {
                      affectedModules.forEach(function (moduleType) {
                          _this.storeFieldOfDefOnType(moduleType, core.ɵNG_MOD_DEF, 'transitiveCompileScopes');
                          moduleType[core.ɵNG_MOD_DEF].transitiveCompileScopes = null;
                      });
                  }
              }
              var moduleToScope = new Map();
              var getScopeOfModule = function (moduleType) {
                  if (!moduleToScope.has(moduleType)) {
                      var isTestingModule = isTestingModuleOverride(moduleType);
                      var realType = isTestingModule ? _this.testModuleType : moduleType;
                      moduleToScope.set(moduleType, core.ɵtransitiveScopesFor(realType));
                  }
                  return moduleToScope.get(moduleType);
              };
              this.componentToModuleScope.forEach(function (moduleType, componentType) {
                  var moduleScope = getScopeOfModule(moduleType);
                  _this.storeFieldOfDefOnType(componentType, core.ɵNG_COMP_DEF, 'directiveDefs');
                  _this.storeFieldOfDefOnType(componentType, core.ɵNG_COMP_DEF, 'pipeDefs');
                  core.ɵpatchComponentDefWithScope(componentType.ɵcmp, moduleScope);
              });
              this.componentToModuleScope.clear();
          };
          R3TestBedCompiler.prototype.applyProviderOverrides = function () {
              var _this = this;
              var maybeApplyOverrides = function (field) { return function (type) {
                  var resolver = field === core.ɵNG_COMP_DEF ? _this.resolvers.component : _this.resolvers.directive;
                  var metadata = resolver.resolve(type);
                  if (_this.hasProviderOverrides(metadata.providers)) {
                      _this.patchDefWithProviderOverrides(type, field);
                  }
              }; };
              this.seenComponents.forEach(maybeApplyOverrides(core.ɵNG_COMP_DEF));
              this.seenDirectives.forEach(maybeApplyOverrides(core.ɵNG_DIR_DEF));
              this.seenComponents.clear();
              this.seenDirectives.clear();
          };
          R3TestBedCompiler.prototype.applyProviderOverridesToModule = function (moduleType) {
              var e_1, _a, e_2, _b;
              if (this.moduleProvidersOverridden.has(moduleType)) {
                  return;
              }
              this.moduleProvidersOverridden.add(moduleType);
              var injectorDef = moduleType[core.ɵNG_INJ_DEF];
              if (this.providerOverridesByToken.size > 0) {
                  var providers = __spread(injectorDef.providers, (this.providerOverridesByModule.get(moduleType) || []));
                  if (this.hasProviderOverrides(providers)) {
                      this.maybeStoreNgDef(core.ɵNG_INJ_DEF, moduleType);
                      this.storeFieldOfDefOnType(moduleType, core.ɵNG_INJ_DEF, 'providers');
                      injectorDef.providers = this.getOverriddenProviders(providers);
                  }
                  // Apply provider overrides to imported modules recursively
                  var moduleDef = moduleType[core.ɵNG_MOD_DEF];
                  var imports = maybeUnwrapFn(moduleDef.imports);
                  try {
                      for (var imports_1 = __values(imports), imports_1_1 = imports_1.next(); !imports_1_1.done; imports_1_1 = imports_1.next()) {
                          var importedModule = imports_1_1.value;
                          this.applyProviderOverridesToModule(importedModule);
                      }
                  }
                  catch (e_1_1) { e_1 = { error: e_1_1 }; }
                  finally {
                      try {
                          if (imports_1_1 && !imports_1_1.done && (_a = imports_1.return)) _a.call(imports_1);
                      }
                      finally { if (e_1) throw e_1.error; }
                  }
                  try {
                      // Also override the providers on any ModuleWithProviders imports since those don't appear in
                      // the moduleDef.
                      for (var _c = __values(flatten(injectorDef.imports)), _d = _c.next(); !_d.done; _d = _c.next()) {
                          var importedModule = _d.value;
                          if (isModuleWithProviders(importedModule)) {
                              this.defCleanupOps.push({
                                  object: importedModule,
                                  fieldName: 'providers',
                                  originalValue: importedModule.providers
                              });
                              importedModule.providers = this.getOverriddenProviders(importedModule.providers);
                          }
                      }
                  }
                  catch (e_2_1) { e_2 = { error: e_2_1 }; }
                  finally {
                      try {
                          if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
                      }
                      finally { if (e_2) throw e_2.error; }
                  }
              }
          };
          R3TestBedCompiler.prototype.patchComponentsWithExistingStyles = function () {
              this.existingComponentStyles.forEach(function (styles, type) { return type[core.ɵNG_COMP_DEF].styles = styles; });
              this.existingComponentStyles.clear();
          };
          R3TestBedCompiler.prototype.queueTypeArray = function (arr, moduleType) {
              var e_3, _a;
              try {
                  for (var arr_1 = __values(arr), arr_1_1 = arr_1.next(); !arr_1_1.done; arr_1_1 = arr_1.next()) {
                      var value = arr_1_1.value;
                      if (Array.isArray(value)) {
                          this.queueTypeArray(value, moduleType);
                      }
                      else {
                          this.queueType(value, moduleType);
                      }
                  }
              }
              catch (e_3_1) { e_3 = { error: e_3_1 }; }
              finally {
                  try {
                      if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) _a.call(arr_1);
                  }
                  finally { if (e_3) throw e_3.error; }
              }
          };
          R3TestBedCompiler.prototype.recompileNgModule = function (ngModule, metadata) {
              // Cache the initial ngModuleDef as it will be overwritten.
              this.maybeStoreNgDef(core.ɵNG_MOD_DEF, ngModule);
              this.maybeStoreNgDef(core.ɵNG_INJ_DEF, ngModule);
              core.ɵcompileNgModuleDefs(ngModule, metadata);
          };
          R3TestBedCompiler.prototype.queueType = function (type, moduleType) {
              var component = this.resolvers.component.resolve(type);
              if (component) {
                  // Check whether a give Type has respective NG def (ɵcmp) and compile if def is
                  // missing. That might happen in case a class without any Angular decorators extends another
                  // class where Component/Directive/Pipe decorator is defined.
                  if (isComponentDefPendingResolution(type) || !type.hasOwnProperty(core.ɵNG_COMP_DEF)) {
                      this.pendingComponents.add(type);
                  }
                  this.seenComponents.add(type);
                  // Keep track of the module which declares this component, so later the component's scope
                  // can be set correctly. If the component has already been recorded here, then one of several
                  // cases is true:
                  // * the module containing the component was imported multiple times (common).
                  // * the component is declared in multiple modules (which is an error).
                  // * the component was in 'declarations' of the testing module, and also in an imported module
                  //   in which case the module scope will be TestingModuleOverride.DECLARATION.
                  // * overrideTemplateUsingTestingModule was called for the component in which case the module
                  //   scope will be TestingModuleOverride.OVERRIDE_TEMPLATE.
                  //
                  // If the component was previously in the testing module's 'declarations' (meaning the
                  // current value is TestingModuleOverride.DECLARATION), then `moduleType` is the component's
                  // real module, which was imported. This pattern is understood to mean that the component
                  // should use its original scope, but that the testing module should also contain the
                  // component in its scope.
                  if (!this.componentToModuleScope.has(type) ||
                      this.componentToModuleScope.get(type) === TestingModuleOverride.DECLARATION) {
                      this.componentToModuleScope.set(type, moduleType);
                  }
                  return;
              }
              var directive = this.resolvers.directive.resolve(type);
              if (directive) {
                  if (!type.hasOwnProperty(core.ɵNG_DIR_DEF)) {
                      this.pendingDirectives.add(type);
                  }
                  this.seenDirectives.add(type);
                  return;
              }
              var pipe = this.resolvers.pipe.resolve(type);
              if (pipe && !type.hasOwnProperty(core.ɵNG_PIPE_DEF)) {
                  this.pendingPipes.add(type);
                  return;
              }
          };
          R3TestBedCompiler.prototype.queueTypesFromModulesArray = function (arr) {
              var _this = this;
              // Because we may encounter the same NgModule while processing the imports and exports of an
              // NgModule tree, we cache them in this set so we can skip ones that have already been seen
              // encountered. In some test setups, this caching resulted in 10X runtime improvement.
              var processedNgModuleDefs = new Set();
              var queueTypesFromModulesArrayRecur = function (arr) {
                  var e_4, _a;
                  try {
                      for (var arr_2 = __values(arr), arr_2_1 = arr_2.next(); !arr_2_1.done; arr_2_1 = arr_2.next()) {
                          var value = arr_2_1.value;
                          if (Array.isArray(value)) {
                              queueTypesFromModulesArrayRecur(value);
                          }
                          else if (hasNgModuleDef(value)) {
                              var def = value.ɵmod;
                              if (processedNgModuleDefs.has(def)) {
                                  continue;
                              }
                              processedNgModuleDefs.add(def);
                              // Look through declarations, imports, and exports, and queue
                              // everything found there.
                              _this.queueTypeArray(maybeUnwrapFn(def.declarations), value);
                              queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.imports));
                              queueTypesFromModulesArrayRecur(maybeUnwrapFn(def.exports));
                          }
                      }
                  }
                  catch (e_4_1) { e_4 = { error: e_4_1 }; }
                  finally {
                      try {
                          if (arr_2_1 && !arr_2_1.done && (_a = arr_2.return)) _a.call(arr_2);
                      }
                      finally { if (e_4) throw e_4.error; }
                  }
              };
              queueTypesFromModulesArrayRecur(arr);
          };
          // When module overrides (via `TestBed.overrideModule`) are present, it might affect all modules
          // that import (even transitively) an overridden one. For all affected modules we need to
          // recalculate their scopes for a given test run and restore original scopes at the end. The goal
          // of this function is to collect all affected modules in a set for further processing. Example:
          // if we have the following module hierarchy: A -> B -> C (where `->` means `imports`) and module
          // `C` is overridden, we consider `A` and `B` as affected, since their scopes might become
          // invalidated with the override.
          R3TestBedCompiler.prototype.collectModulesAffectedByOverrides = function (arr) {
              var _this = this;
              var seenModules = new Set();
              var affectedModules = new Set();
              var calcAffectedModulesRecur = function (arr, path) {
                  var e_5, _a;
                  try {
                      for (var arr_3 = __values(arr), arr_3_1 = arr_3.next(); !arr_3_1.done; arr_3_1 = arr_3.next()) {
                          var value = arr_3_1.value;
                          if (Array.isArray(value)) {
                              // If the value is an array, just flatten it (by invoking this function recursively),
                              // keeping "path" the same.
                              calcAffectedModulesRecur(value, path);
                          }
                          else if (hasNgModuleDef(value)) {
                              if (seenModules.has(value)) {
                                  // If we've seen this module before and it's included into "affected modules" list, mark
                                  // the whole path that leads to that module as affected, but do not descend into its
                                  // imports, since we already examined them before.
                                  if (affectedModules.has(value)) {
                                      path.forEach(function (item) { return affectedModules.add(item); });
                                  }
                                  continue;
                              }
                              seenModules.add(value);
                              if (_this.overriddenModules.has(value)) {
                                  path.forEach(function (item) { return affectedModules.add(item); });
                              }
                              // Examine module imports recursively to look for overridden modules.
                              var moduleDef = value[core.ɵNG_MOD_DEF];
                              calcAffectedModulesRecur(maybeUnwrapFn(moduleDef.imports), path.concat(value));
                          }
                      }
                  }
                  catch (e_5_1) { e_5 = { error: e_5_1 }; }
                  finally {
                      try {
                          if (arr_3_1 && !arr_3_1.done && (_a = arr_3.return)) _a.call(arr_3);
                      }
                      finally { if (e_5) throw e_5.error; }
                  }
              };
              calcAffectedModulesRecur(arr, []);
              return affectedModules;
          };
          R3TestBedCompiler.prototype.maybeStoreNgDef = function (prop, type) {
              if (!this.initialNgDefs.has(type)) {
                  var currentDef = Object.getOwnPropertyDescriptor(type, prop);
                  this.initialNgDefs.set(type, [prop, currentDef]);
              }
          };
          R3TestBedCompiler.prototype.storeFieldOfDefOnType = function (type, defField, fieldName) {
              var def = type[defField];
              var originalValue = def[fieldName];
              this.defCleanupOps.push({ object: def, fieldName: fieldName, originalValue: originalValue });
          };
          /**
           * Clears current components resolution queue, but stores the state of the queue, so we can
           * restore it later. Clearing the queue is required before we try to compile components (via
           * `TestBed.compileComponents`), so that component defs are in sync with the resolution queue.
           */
          R3TestBedCompiler.prototype.clearComponentResolutionQueue = function () {
              var _this = this;
              if (this.originalComponentResolutionQueue === null) {
                  this.originalComponentResolutionQueue = new Map();
              }
              clearResolutionOfComponentResourcesQueue().forEach(function (value, key) { return _this.originalComponentResolutionQueue.set(key, value); });
          };
          /*
           * Restores component resolution queue to the previously saved state. This operation is performed
           * as a part of restoring the state after completion of the current set of tests (that might
           * potentially mutate the state).
           */
          R3TestBedCompiler.prototype.restoreComponentResolutionQueue = function () {
              if (this.originalComponentResolutionQueue !== null) {
                  restoreComponentResolutionQueue(this.originalComponentResolutionQueue);
                  this.originalComponentResolutionQueue = null;
              }
          };
          R3TestBedCompiler.prototype.restoreOriginalState = function () {
              // Process cleanup ops in reverse order so the field's original value is restored correctly (in
              // case there were multiple overrides for the same field).
              forEachRight(this.defCleanupOps, function (op) {
                  op.object[op.fieldName] = op.originalValue;
              });
              // Restore initial component/directive/pipe defs
              this.initialNgDefs.forEach(function (value, type) {
                  var _a = __read(value, 2), prop = _a[0], descriptor = _a[1];
                  if (!descriptor) {
                      // Delete operations are generally undesirable since they have performance implications
                      // on objects they were applied to. In this particular case, situations where this code
                      // is invoked should be quite rare to cause any noticeable impact, since it's applied
                      // only to some test cases (for example when class with no annotations extends some
                      // @Component) when we need to clear 'ɵcmp' field on a given class to restore
                      // its original state (before applying overrides and running tests).
                      delete type[prop];
                  }
                  else {
                      Object.defineProperty(type, prop, descriptor);
                  }
              });
              this.initialNgDefs.clear();
              this.moduleProvidersOverridden.clear();
              this.restoreComponentResolutionQueue();
              // Restore the locale ID to the default value, this shouldn't be necessary but we never know
              core.ɵsetLocaleId(core.ɵDEFAULT_LOCALE_ID);
          };
          R3TestBedCompiler.prototype.compileTestModule = function () {
              var _this = this;
              var RootScopeModule = /** @class */ (function () {
                  function RootScopeModule() {
                  }
                  return RootScopeModule;
              }());
              core.ɵcompileNgModuleDefs(RootScopeModule, {
                  providers: __spread(this.rootProviderOverrides),
              });
              var ngZone = new core.NgZone({ enableLongStackTrace: true });
              var providers = __spread([
                  { provide: core.NgZone, useValue: ngZone },
                  { provide: core.Compiler, useFactory: function () { return new R3TestCompiler(_this); } }
              ], this.providers, this.providerOverrides);
              var imports = [RootScopeModule, this.additionalModuleTypes, this.imports || []];
              // clang-format off
              core.ɵcompileNgModuleDefs(this.testModuleType, {
                  declarations: this.declarations,
                  imports: imports,
                  schemas: this.schemas,
                  providers: providers,
              }, /* allowDuplicateDeclarationsInRoot */ true);
              // clang-format on
              this.applyProviderOverridesToModule(this.testModuleType);
          };
          Object.defineProperty(R3TestBedCompiler.prototype, "injector", {
              get: function () {
                  if (this._injector !== null) {
                      return this._injector;
                  }
                  var providers = [];
                  var compilerOptions = this.platform.injector.get(core.COMPILER_OPTIONS);
                  compilerOptions.forEach(function (opts) {
                      if (opts.providers) {
                          providers.push(opts.providers);
                      }
                  });
                  if (this.compilerProviders !== null) {
                      providers.push.apply(providers, __spread(this.compilerProviders));
                  }
                  // TODO(ocombe): make this work with an Injector directly instead of creating a module for it
                  var CompilerModule = /** @class */ (function () {
                      function CompilerModule() {
                      }
                      return CompilerModule;
                  }());
                  core.ɵcompileNgModuleDefs(CompilerModule, { providers: providers });
                  var CompilerModuleFactory = new core.ɵNgModuleFactory(CompilerModule);
                  this._injector = CompilerModuleFactory.create(this.platform.injector).injector;
                  return this._injector;
              },
              enumerable: true,
              configurable: true
          });
          // get overrides for a specific provider (if any)
          R3TestBedCompiler.prototype.getSingleProviderOverrides = function (provider) {
              var token = getProviderToken(provider);
              return this.providerOverridesByToken.get(token) || null;
          };
          R3TestBedCompiler.prototype.getProviderOverrides = function (providers) {
              var _this = this;
              if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
                  return [];
              // There are two flattening operations here. The inner flatten() operates on the metadata's
              // providers and applies a mapping function which retrieves overrides for each incoming
              // provider. The outer flatten() then flattens the produced overrides array. If this is not
              // done, the array can contain other empty arrays (e.g. `[[], []]`) which leak into the
              // providers array and contaminate any error messages that might be generated.
              return flatten(flatten(providers, function (provider) { return _this.getSingleProviderOverrides(provider) || []; }));
          };
          R3TestBedCompiler.prototype.getOverriddenProviders = function (providers) {
              var _this = this;
              if (!providers || !providers.length || this.providerOverridesByToken.size === 0)
                  return [];
              var flattenedProviders = flatten(providers);
              var overrides = this.getProviderOverrides(flattenedProviders);
              var overriddenProviders = __spread(flattenedProviders, overrides);
              var final = [];
              var seenOverriddenProviders = new Set();
              // We iterate through the list of providers in reverse order to make sure provider overrides
              // take precedence over the values defined in provider list. We also filter out all providers
              // that have overrides, keeping overridden values only. This is needed, since presence of a
              // provider with `ngOnDestroy` hook will cause this hook to be registered and invoked later.
              forEachRight(overriddenProviders, function (provider) {
                  var token = getProviderToken(provider);
                  if (_this.providerOverridesByToken.has(token)) {
                      if (!seenOverriddenProviders.has(token)) {
                          seenOverriddenProviders.add(token);
                          // Treat all overridden providers as `{multi: false}` (even if it's a multi-provider) to
                          // make sure that provided override takes highest precedence and is not combined with
                          // other instances of the same multi provider.
                          final.unshift(__assign(__assign({}, provider), { multi: false }));
                      }
                  }
                  else {
                      final.unshift(provider);
                  }
              });
              return final;
          };
          R3TestBedCompiler.prototype.hasProviderOverrides = function (providers) {
              return this.getProviderOverrides(providers).length > 0;
          };
          R3TestBedCompiler.prototype.patchDefWithProviderOverrides = function (declaration, field) {
              var _this = this;
              var def = declaration[field];
              if (def && def.providersResolver) {
                  this.maybeStoreNgDef(field, declaration);
                  var resolver_1 = def.providersResolver;
                  var processProvidersFn_1 = function (providers) { return _this.getOverriddenProviders(providers); };
                  this.storeFieldOfDefOnType(declaration, field, 'providersResolver');
                  def.providersResolver = function (ngDef) { return resolver_1(ngDef, processProvidersFn_1); };
              }
          };
          return R3TestBedCompiler;
      }());
      function initResolvers() {
          return {
              module: new NgModuleResolver(),
              component: new ComponentResolver(),
              directive: new DirectiveResolver(),
              pipe: new PipeResolver()
          };
      }
      function hasNgModuleDef(value) {
          return value.hasOwnProperty('ɵmod');
      }
      function maybeUnwrapFn(maybeFn) {
          return maybeFn instanceof Function ? maybeFn() : maybeFn;
      }
      function flatten(values, mapFn) {
          var out = [];
          values.forEach(function (value) {
              if (Array.isArray(value)) {
                  out.push.apply(out, __spread(flatten(value, mapFn)));
              }
              else {
                  out.push(mapFn ? mapFn(value) : value);
              }
          });
          return out;
      }
      function getProviderField(provider, field) {
          return provider && typeof provider === 'object' && provider[field];
      }
      function getProviderToken(provider) {
          return getProviderField(provider, 'provide') || provider;
      }
      function isModuleWithProviders(value) {
          return value.hasOwnProperty('ngModule');
      }
      function forEachRight(values, fn) {
          for (var idx = values.length - 1; idx >= 0; idx--) {
              fn(values[idx], idx);
          }
      }
      function invalidTypeError(name, expectedType) {
          return new Error(name + " class doesn't have @" + expectedType + " decorator or is missing metadata.");
      }
      var R3TestCompiler = /** @class */ (function () {
          function R3TestCompiler(testBed) {
              this.testBed = testBed;
          }
          R3TestCompiler.prototype.compileModuleSync = function (moduleType) {
              this.testBed._compileNgModuleSync(moduleType);
              return new core.ɵNgModuleFactory(moduleType);
          };
          R3TestCompiler.prototype.compileModuleAsync = function (moduleType) {
              return __awaiter(this, void 0, void 0, function () {
                  return __generator(this, function (_a) {
                      switch (_a.label) {
                          case 0: return [4 /*yield*/, this.testBed._compileNgModuleAsync(moduleType)];
                          case 1:
                              _a.sent();
                              return [2 /*return*/, new core.ɵNgModuleFactory(moduleType)];
                      }
                  });
              });
          };
          R3TestCompiler.prototype.compileModuleAndAllComponentsSync = function (moduleType) {
              var ngModuleFactory = this.compileModuleSync(moduleType);
              var componentFactories = this.testBed._getComponentFactories(moduleType);
              return new core.ModuleWithComponentFactories(ngModuleFactory, componentFactories);
          };
          R3TestCompiler.prototype.compileModuleAndAllComponentsAsync = function (moduleType) {
              return __awaiter(this, void 0, void 0, function () {
                  var ngModuleFactory, componentFactories;
                  return __generator(this, function (_a) {
                      switch (_a.label) {
                          case 0: return [4 /*yield*/, this.compileModuleAsync(moduleType)];
                          case 1:
                              ngModuleFactory = _a.sent();
                              componentFactories = this.testBed._getComponentFactories(moduleType);
                              return [2 /*return*/, new core.ModuleWithComponentFactories(ngModuleFactory, componentFactories)];
                      }
                  });
              });
          };
          R3TestCompiler.prototype.clearCache = function () { };
          R3TestCompiler.prototype.clearCacheFor = function (type) { };
          R3TestCompiler.prototype.getModuleId = function (moduleType) {
              var meta = this.testBed._getModuleResolver().resolve(moduleType);
              return meta && meta.id || undefined;
          };
          return R3TestCompiler;
      }());
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      /**
       * An abstract class for inserting the root test component element in a platform independent way.
       *
       * @publicApi
       */
      var TestComponentRenderer = /** @class */ (function () {
          function TestComponentRenderer() {
          }
          TestComponentRenderer.prototype.insertRootElement = function (rootElementId) { };
          return TestComponentRenderer;
      }());
      /**
       * @publicApi
       */
      var ComponentFixtureAutoDetect = new core.InjectionToken('ComponentFixtureAutoDetect');
      /**
       * @publicApi
       */
      var ComponentFixtureNoNgZone = new core.InjectionToken('ComponentFixtureNoNgZone');
  
      /**
       * @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 _nextRootElementId = 0;
      /**
       * @description
       * Configures and initializes environment for unit testing and provides methods for
       * creating components and services in unit tests.
       *
       * TestBed is the primary api for writing unit tests for Angular applications and libraries.
       *
       * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3`
       * according to the compiler used.
       */
      var TestBedRender3 = /** @class */ (function () {
          function TestBedRender3() {
              // Properties
              this.platform = null;
              this.ngModule = null;
              this._compiler = null;
              this._testModuleRef = null;
              this._activeFixtures = [];
              this._globalCompilationChecked = false;
          }
          /**
           * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
           * angular module. These are common to every test in the suite.
           *
           * This may only be called once, to set up the common providers for the current test
           * suite on the current platform. If you absolutely need to change the providers,
           * first use `resetTestEnvironment`.
           *
           * Test modules and platforms for individual platforms are available from
           * '@angular/<platform_name>/testing'.
           *
           * @publicApi
           */
          TestBedRender3.initTestEnvironment = function (ngModule, platform, aotSummaries) {
              var testBed = _getTestBedRender3();
              testBed.initTestEnvironment(ngModule, platform, aotSummaries);
              return testBed;
          };
          /**
           * Reset the providers for the test injector.
           *
           * @publicApi
           */
          TestBedRender3.resetTestEnvironment = function () {
              _getTestBedRender3().resetTestEnvironment();
          };
          TestBedRender3.configureCompiler = function (config) {
              _getTestBedRender3().configureCompiler(config);
              return TestBedRender3;
          };
          /**
           * Allows overriding default providers, directives, pipes, modules of the test injector,
           * which are defined in test_injector.js
           */
          TestBedRender3.configureTestingModule = function (moduleDef) {
              _getTestBedRender3().configureTestingModule(moduleDef);
              return TestBedRender3;
          };
          /**
           * Compile components with a `templateUrl` for the test's NgModule.
           * It is necessary to call this function
           * as fetching urls is asynchronous.
           */
          TestBedRender3.compileComponents = function () {
              return _getTestBedRender3().compileComponents();
          };
          TestBedRender3.overrideModule = function (ngModule, override) {
              _getTestBedRender3().overrideModule(ngModule, override);
              return TestBedRender3;
          };
          TestBedRender3.overrideComponent = function (component, override) {
              _getTestBedRender3().overrideComponent(component, override);
              return TestBedRender3;
          };
          TestBedRender3.overrideDirective = function (directive, override) {
              _getTestBedRender3().overrideDirective(directive, override);
              return TestBedRender3;
          };
          TestBedRender3.overridePipe = function (pipe, override) {
              _getTestBedRender3().overridePipe(pipe, override);
              return TestBedRender3;
          };
          TestBedRender3.overrideTemplate = function (component, template) {
              _getTestBedRender3().overrideComponent(component, { set: { template: template, templateUrl: null } });
              return TestBedRender3;
          };
          /**
           * Overrides the template of the given component, compiling the template
           * in the context of the TestingModule.
           *
           * Note: This works for JIT and AOTed components as well.
           */
          TestBedRender3.overrideTemplateUsingTestingModule = function (component, template) {
              _getTestBedRender3().overrideTemplateUsingTestingModule(component, template);
              return TestBedRender3;
          };
          TestBedRender3.overrideProvider = function (token, provider) {
              _getTestBedRender3().overrideProvider(token, provider);
              return TestBedRender3;
          };
          TestBedRender3.inject = function (token, notFoundValue, flags) {
              return _getTestBedRender3().inject(token, notFoundValue, flags);
          };
          /** @deprecated from v9.0.0 use TestBed.inject */
          TestBedRender3.get = function (token, notFoundValue, flags) {
              if (notFoundValue === void 0) { notFoundValue = core.Injector.THROW_IF_NOT_FOUND; }
              if (flags === void 0) { flags = core.InjectFlags.Default; }
              return _getTestBedRender3().inject(token, notFoundValue, flags);
          };
          TestBedRender3.createComponent = function (component) {
              return _getTestBedRender3().createComponent(component);
          };
          TestBedRender3.resetTestingModule = function () {
              _getTestBedRender3().resetTestingModule();
              return TestBedRender3;
          };
          /**
           * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
           * angular module. These are common to every test in the suite.
           *
           * This may only be called once, to set up the common providers for the current test
           * suite on the current platform. If you absolutely need to change the providers,
           * first use `resetTestEnvironment`.
           *
           * Test modules and platforms for individual platforms are available from
           * '@angular/<platform_name>/testing'.
           *
           * @publicApi
           */
          TestBedRender3.prototype.initTestEnvironment = function (ngModule, platform, aotSummaries) {
              if (this.platform || this.ngModule) {
                  throw new Error('Cannot set base providers because it has already been called');
              }
              this.platform = platform;
              this.ngModule = ngModule;
              this._compiler = new R3TestBedCompiler(this.platform, this.ngModule);
          };
          /**
           * Reset the providers for the test injector.
           *
           * @publicApi
           */
          TestBedRender3.prototype.resetTestEnvironment = function () {
              this.resetTestingModule();
              this._compiler = null;
              this.platform = null;
              this.ngModule = null;
          };
          TestBedRender3.prototype.resetTestingModule = function () {
              this.checkGlobalCompilationFinished();
              core.ɵresetCompiledComponents();
              if (this._compiler !== null) {
                  this.compiler.restoreOriginalState();
              }
              this._compiler = new R3TestBedCompiler(this.platform, this.ngModule);
              this._testModuleRef = null;
              this.destroyActiveFixtures();
          };
          TestBedRender3.prototype.configureCompiler = function (config) {
              if (config.useJit != null) {
                  throw new Error('the Render3 compiler JiT mode is not configurable !');
              }
              if (config.providers !== undefined) {
                  this.compiler.setCompilerProviders(config.providers);
              }
          };
          TestBedRender3.prototype.configureTestingModule = function (moduleDef) {
              this.assertNotInstantiated('R3TestBed.configureTestingModule', 'configure the test module');
              this.compiler.configureTestingModule(moduleDef);
          };
          TestBedRender3.prototype.compileComponents = function () {
              return this.compiler.compileComponents();
          };
          TestBedRender3.prototype.inject = function (token, notFoundValue, flags) {
              if (token === TestBedRender3) {
                  return this;
              }
              var UNDEFINED = {};
              var result = this.testModuleRef.injector.get(token, UNDEFINED, flags);
              return result === UNDEFINED ? this.compiler.injector.get(token, notFoundValue, flags) :
                  result;
          };
          /** @deprecated from v9.0.0 use TestBed.inject */
          TestBedRender3.prototype.get = function (token, notFoundValue, flags) {
              if (notFoundValue === void 0) { notFoundValue = core.Injector.THROW_IF_NOT_FOUND; }
              if (flags === void 0) { flags = core.InjectFlags.Default; }
              return this.inject(token, notFoundValue, flags);
          };
          TestBedRender3.prototype.execute = function (tokens, fn, context) {
              var _this = this;
              var params = tokens.map(function (t) { return _this.inject(t); });
              return fn.apply(context, params);
          };
          TestBedRender3.prototype.overrideModule = function (ngModule, override) {
              this.assertNotInstantiated('overrideModule', 'override module metadata');
              this.compiler.overrideModule(ngModule, override);
          };
          TestBedRender3.prototype.overrideComponent = function (component, override) {
              this.assertNotInstantiated('overrideComponent', 'override component metadata');
              this.compiler.overrideComponent(component, override);
          };
          TestBedRender3.prototype.overrideTemplateUsingTestingModule = function (component, template) {
              this.assertNotInstantiated('R3TestBed.overrideTemplateUsingTestingModule', 'Cannot override template when the test module has already been instantiated');
              this.compiler.overrideTemplateUsingTestingModule(component, template);
          };
          TestBedRender3.prototype.overrideDirective = function (directive, override) {
              this.assertNotInstantiated('overrideDirective', 'override directive metadata');
              this.compiler.overrideDirective(directive, override);
          };
          TestBedRender3.prototype.overridePipe = function (pipe, override) {
              this.assertNotInstantiated('overridePipe', 'override pipe metadata');
              this.compiler.overridePipe(pipe, override);
          };
          /**
           * Overwrites all providers for the given token with the given provider definition.
           */
          TestBedRender3.prototype.overrideProvider = function (token, provider) {
              this.compiler.overrideProvider(token, provider);
          };
          TestBedRender3.prototype.createComponent = function (type) {
              var _this = this;
              var testComponentRenderer = this.inject(TestComponentRenderer);
              var rootElId = "root-ng-internal-isolated-" + _nextRootElementId++;
              testComponentRenderer.insertRootElement(rootElId);
              var componentDef = type.ɵcmp;
              if (!componentDef) {
                  throw new Error("It looks like '" + core.ɵstringify(type) + "' has not been IVY compiled - it has no '\u0275cmp' field");
              }
              // TODO: Don't cast as `InjectionToken<boolean>`, proper type is boolean[]
              var noNgZone = this.inject(ComponentFixtureNoNgZone, false);
              // TODO: Don't cast as `InjectionToken<boolean>`, proper type is boolean[]
              var autoDetect = this.inject(ComponentFixtureAutoDetect, false);
              var ngZone = noNgZone ? null : this.inject(core.NgZone, null);
              var componentFactory = new core.ɵRender3ComponentFactory(componentDef);
              var initComponent = function () {
                  var componentRef = componentFactory.create(core.Injector.NULL, [], "#" + rootElId, _this.testModuleRef);
                  return new ComponentFixture(componentRef, ngZone, autoDetect);
              };
              var fixture = ngZone ? ngZone.run(initComponent) : initComponent();
              this._activeFixtures.push(fixture);
              return fixture;
          };
          Object.defineProperty(TestBedRender3.prototype, "compiler", {
              /**
               * @internal strip this from published d.ts files due to
               * https://github.com/microsoft/TypeScript/issues/36216
               */
              get: function () {
                  if (this._compiler === null) {
                      throw new Error("Need to call TestBed.initTestEnvironment() first");
                  }
                  return this._compiler;
              },
              enumerable: true,
              configurable: true
          });
          Object.defineProperty(TestBedRender3.prototype, "testModuleRef", {
              /**
               * @internal strip this from published d.ts files due to
               * https://github.com/microsoft/TypeScript/issues/36216
               */
              get: function () {
                  if (this._testModuleRef === null) {
                      this._testModuleRef = this.compiler.finalize();
                  }
                  return this._testModuleRef;
              },
              enumerable: true,
              configurable: true
          });
          TestBedRender3.prototype.assertNotInstantiated = function (methodName, methodDescription) {
              if (this._testModuleRef !== null) {
                  throw new Error("Cannot " + methodDescription + " when the test module has already been instantiated. " +
                      ("Make sure you are not using `inject` before `" + methodName + "`."));
              }
          };
          /**
           * Check whether the module scoping queue should be flushed, and flush it if needed.
           *
           * When the TestBed is reset, it clears the JIT module compilation queue, cancelling any
           * in-progress module compilation. This creates a potential hazard - the very first time the
           * TestBed is initialized (or if it's reset without being initialized), there may be pending
           * compilations of modules declared in global scope. These compilations should be finished.
           *
           * To ensure that globally declared modules have their components scoped properly, this function
           * is called whenever TestBed is initialized or reset. The _first_ time that this happens, prior
           * to any other operations, the scoping queue is flushed.
           */
          TestBedRender3.prototype.checkGlobalCompilationFinished = function () {
              // Checking _testNgModuleRef is null should not be necessary, but is left in as an additional
              // guard that compilations queued in tests (after instantiation) are never flushed accidentally.
              if (!this._globalCompilationChecked && this._testModuleRef === null) {
                  core.ɵflushModuleScopingQueueAsMuchAsPossible();
              }
              this._globalCompilationChecked = true;
          };
          TestBedRender3.prototype.destroyActiveFixtures = function () {
              this._activeFixtures.forEach(function (fixture) {
                  try {
                      fixture.destroy();
                  }
                  catch (e) {
                      console.error('Error during cleanup of component', {
                          component: fixture.componentInstance,
                          stacktrace: e,
                      });
                  }
              });
              this._activeFixtures = [];
          };
          return TestBedRender3;
      }());
      var testBed;
      function _getTestBedRender3() {
          return testBed = testBed || new TestBedRender3();
      }
  
      /**
       * @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 unimplemented() {
          throw Error('unimplemented');
      }
      /**
       * Special interface to the compiler only used by testing
       *
       * @publicApi
       */
      var TestingCompiler = /** @class */ (function (_super) {
          __extends(TestingCompiler, _super);
          function TestingCompiler() {
              return _super !== null && _super.apply(this, arguments) || this;
          }
          Object.defineProperty(TestingCompiler.prototype, "injector", {
              get: function () {
                  throw unimplemented();
              },
              enumerable: true,
              configurable: true
          });
          TestingCompiler.prototype.overrideModule = function (module, overrides) {
              throw unimplemented();
          };
          TestingCompiler.prototype.overrideDirective = function (directive, overrides) {
              throw unimplemented();
          };
          TestingCompiler.prototype.overrideComponent = function (component, overrides) {
              throw unimplemented();
          };
          TestingCompiler.prototype.overridePipe = function (directive, overrides) {
              throw unimplemented();
          };
          /**
           * Allows to pass the compile summary from AOT compilation to the JIT compiler,
           * so that it can use the code generated by AOT.
           */
          TestingCompiler.prototype.loadAotSummaries = function (summaries) {
              throw unimplemented();
          };
          /**
           * Gets the component factory for the given component.
           * This assumes that the component has been compiled before calling this call using
           * `compileModuleAndAllComponents*`.
           */
          TestingCompiler.prototype.getComponentFactory = function (component) {
              throw unimplemented();
          };
          /**
           * Returns the component type that is stored in the given error.
           * This can be used for errors created by compileModule...
           */
          TestingCompiler.prototype.getComponentFromError = function (error) {
              throw unimplemented();
          };
          TestingCompiler = __decorate([
              core.Injectable()
          ], TestingCompiler);
          return TestingCompiler;
      }(core.Compiler));
      /**
       * A factory for creating a Compiler
       *
       * @publicApi
       */
      var TestingCompilerFactory = /** @class */ (function () {
          function TestingCompilerFactory() {
          }
          return TestingCompilerFactory;
      }());
  
      /**
       * @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 _nextRootElementId$1 = 0;
      /**
       * @description
       * Configures and initializes environment for unit testing and provides methods for
       * creating components and services in unit tests.
       *
       * `TestBed` is the primary api for writing unit tests for Angular applications and libraries.
       *
       * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3`
       * according to the compiler used.
       */
      var TestBedViewEngine = /** @class */ (function () {
          function TestBedViewEngine() {
              this._instantiated = false;
              this._compiler = null;
              this._moduleRef = null;
              this._moduleFactory = null;
              this._compilerOptions = [];
              this._moduleOverrides = [];
              this._componentOverrides = [];
              this._directiveOverrides = [];
              this._pipeOverrides = [];
              this._providers = [];
              this._declarations = [];
              this._imports = [];
              this._schemas = [];
              this._activeFixtures = [];
              this._testEnvAotSummaries = function () { return []; };
              this._aotSummaries = [];
              this._templateOverrides = [];
              this._isRoot = true;
              this._rootProviderOverrides = [];
              this.platform = null;
              this.ngModule = null;
          }
          /**
           * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
           * angular module. These are common to every test in the suite.
           *
           * This may only be called once, to set up the common providers for the current test
           * suite on the current platform. If you absolutely need to change the providers,
           * first use `resetTestEnvironment`.
           *
           * Test modules and platforms for individual platforms are available from
           * '@angular/<platform_name>/testing'.
           */
          TestBedViewEngine.initTestEnvironment = function (ngModule, platform, aotSummaries) {
              var testBed = _getTestBedViewEngine();
              testBed.initTestEnvironment(ngModule, platform, aotSummaries);
              return testBed;
          };
          /**
           * Reset the providers for the test injector.
           */
          TestBedViewEngine.resetTestEnvironment = function () {
              _getTestBedViewEngine().resetTestEnvironment();
          };
          TestBedViewEngine.resetTestingModule = function () {
              _getTestBedViewEngine().resetTestingModule();
              return TestBedViewEngine;
          };
          /**
           * Allows overriding default compiler providers and settings
           * which are defined in test_injector.js
           */
          TestBedViewEngine.configureCompiler = function (config) {
              _getTestBedViewEngine().configureCompiler(config);
              return TestBedViewEngine;
          };
          /**
           * Allows overriding default providers, directives, pipes, modules of the test injector,
           * which are defined in test_injector.js
           */
          TestBedViewEngine.configureTestingModule = function (moduleDef) {
              _getTestBedViewEngine().configureTestingModule(moduleDef);
              return TestBedViewEngine;
          };
          /**
           * Compile components with a `templateUrl` for the test's NgModule.
           * It is necessary to call this function
           * as fetching urls is asynchronous.
           */
          TestBedViewEngine.compileComponents = function () {
              return getTestBed().compileComponents();
          };
          TestBedViewEngine.overrideModule = function (ngModule, override) {
              _getTestBedViewEngine().overrideModule(ngModule, override);
              return TestBedViewEngine;
          };
          TestBedViewEngine.overrideComponent = function (component, override) {
              _getTestBedViewEngine().overrideComponent(component, override);
              return TestBedViewEngine;
          };
          TestBedViewEngine.overrideDirective = function (directive, override) {
              _getTestBedViewEngine().overrideDirective(directive, override);
              return TestBedViewEngine;
          };
          TestBedViewEngine.overridePipe = function (pipe, override) {
              _getTestBedViewEngine().overridePipe(pipe, override);
              return TestBedViewEngine;
          };
          TestBedViewEngine.overrideTemplate = function (component, template) {
              _getTestBedViewEngine().overrideComponent(component, { set: { template: template, templateUrl: null } });
              return TestBedViewEngine;
          };
          /**
           * Overrides the template of the given component, compiling the template
           * in the context of the TestingModule.
           *
           * Note: This works for JIT and AOTed components as well.
           */
          TestBedViewEngine.overrideTemplateUsingTestingModule = function (component, template) {
              _getTestBedViewEngine().overrideTemplateUsingTestingModule(component, template);
              return TestBedViewEngine;
          };
          TestBedViewEngine.overrideProvider = function (token, provider) {
              _getTestBedViewEngine().overrideProvider(token, provider);
              return TestBedViewEngine;
          };
          TestBedViewEngine.inject = function (token, notFoundValue, flags) {
              return _getTestBedViewEngine().inject(token, notFoundValue, flags);
          };
          /** @deprecated from v9.0.0 use TestBed.inject */
          TestBedViewEngine.get = function (token, notFoundValue, flags) {
              if (notFoundValue === void 0) { notFoundValue = core.Injector.THROW_IF_NOT_FOUND; }
              if (flags === void 0) { flags = core.InjectFlags.Default; }
              return _getTestBedViewEngine().inject(token, notFoundValue, flags);
          };
          TestBedViewEngine.createComponent = function (component) {
              return _getTestBedViewEngine().createComponent(component);
          };
          /**
           * Initialize the environment for testing with a compiler factory, a PlatformRef, and an
           * angular module. These are common to every test in the suite.
           *
           * This may only be called once, to set up the common providers for the current test
           * suite on the current platform. If you absolutely need to change the providers,
           * first use `resetTestEnvironment`.
           *
           * Test modules and platforms for individual platforms are available from
           * '@angular/<platform_name>/testing'.
           */
          TestBedViewEngine.prototype.initTestEnvironment = function (ngModule, platform, aotSummaries) {
              if (this.platform || this.ngModule) {
                  throw new Error('Cannot set base providers because it has already been called');
              }
              this.platform = platform;
              this.ngModule = ngModule;
              if (aotSummaries) {
                  this._testEnvAotSummaries = aotSummaries;
              }
          };
          /**
           * Reset the providers for the test injector.
           */
          TestBedViewEngine.prototype.resetTestEnvironment = function () {
              this.resetTestingModule();
              this.platform = null;
              this.ngModule = null;
              this._testEnvAotSummaries = function () { return []; };
          };
          TestBedViewEngine.prototype.resetTestingModule = function () {
              core.ɵclearOverrides();
              this._aotSummaries = [];
              this._templateOverrides = [];
              this._compiler = null;
              this._moduleOverrides = [];
              this._componentOverrides = [];
              this._directiveOverrides = [];
              this._pipeOverrides = [];
              this._isRoot = true;
              this._rootProviderOverrides = [];
              this._moduleRef = null;
              this._moduleFactory = null;
              this._compilerOptions = [];
              this._providers = [];
              this._declarations = [];
              this._imports = [];
              this._schemas = [];
              this._instantiated = false;
              this._activeFixtures.forEach(function (fixture) {
                  try {
                      fixture.destroy();
                  }
                  catch (e) {
                      console.error('Error during cleanup of component', {
                          component: fixture.componentInstance,
                          stacktrace: e,
                      });
                  }
              });
              this._activeFixtures = [];
          };
          TestBedViewEngine.prototype.configureCompiler = function (config) {
              this._assertNotInstantiated('TestBed.configureCompiler', 'configure the compiler');
              this._compilerOptions.push(config);
          };
          TestBedViewEngine.prototype.configureTestingModule = function (moduleDef) {
              var _a, _b, _c, _d;
              this._assertNotInstantiated('TestBed.configureTestingModule', 'configure the test module');
              if (moduleDef.providers) {
                  (_a = this._providers).push.apply(_a, __spread(moduleDef.providers));
              }
              if (moduleDef.declarations) {
                  (_b = this._declarations).push.apply(_b, __spread(moduleDef.declarations));
              }
              if (moduleDef.imports) {
                  (_c = this._imports).push.apply(_c, __spread(moduleDef.imports));
              }
              if (moduleDef.schemas) {
                  (_d = this._schemas).push.apply(_d, __spread(moduleDef.schemas));
              }
              if (moduleDef.aotSummaries) {
                  this._aotSummaries.push(moduleDef.aotSummaries);
              }
          };
          TestBedViewEngine.prototype.compileComponents = function () {
              var _this = this;
              if (this._moduleFactory || this._instantiated) {
                  return Promise.resolve(null);
              }
              var moduleType = this._createCompilerAndModule();
              return this._compiler.compileModuleAndAllComponentsAsync(moduleType)
                  .then(function (moduleAndComponentFactories) {
                  _this._moduleFactory = moduleAndComponentFactories.ngModuleFactory;
              });
          };
          TestBedViewEngine.prototype._initIfNeeded = function () {
              var e_1, _a;
              if (this._instantiated) {
                  return;
              }
              if (!this._moduleFactory) {
                  try {
                      var moduleType = this._createCompilerAndModule();
                      this._moduleFactory =
                          this._compiler.compileModuleAndAllComponentsSync(moduleType).ngModuleFactory;
                  }
                  catch (e) {
                      var errorCompType = this._compiler.getComponentFromError(e);
                      if (errorCompType) {
                          throw new Error("This test module uses the component " + core.ɵstringify(errorCompType) + " which is using a \"templateUrl\" or \"styleUrls\", but they were never compiled. " +
                              "Please call \"TestBed.compileComponents\" before your test.");
                      }
                      else {
                          throw e;
                      }
                  }
              }
              try {
                  for (var _b = __values(this._templateOverrides), _c = _b.next(); !_c.done; _c = _b.next()) {
                      var _d = _c.value, component = _d.component, templateOf = _d.templateOf;
                      var compFactory = this._compiler.getComponentFactory(templateOf);
                      core.ɵoverrideComponentView(component, compFactory);
                  }
              }
              catch (e_1_1) { e_1 = { error: e_1_1 }; }
              finally {
                  try {
                      if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                  }
                  finally { if (e_1) throw e_1.error; }
              }
              var ngZone = new core.NgZone({ enableLongStackTrace: true, shouldCoalesceEventChangeDetection: false });
              var providers = [{ provide: core.NgZone, useValue: ngZone }];
              var ngZoneInjector = core.Injector.create({
                  providers: providers,
                  parent: this.platform.injector,
                  name: this._moduleFactory.moduleType.name
              });
              this._moduleRef = this._moduleFactory.create(ngZoneInjector);
              // ApplicationInitStatus.runInitializers() is marked @internal to core. So casting to any
              // before accessing it.
              this._moduleRef.injector.get(core.ApplicationInitStatus).runInitializers();
              this._instantiated = true;
          };
          TestBedViewEngine.prototype._createCompilerAndModule = function () {
              var e_2, _a;
              var _this = this;
              var providers = this._providers.concat([{ provide: TestBed, useValue: this }]);
              var declarations = __spread(this._declarations, this._templateOverrides.map(function (entry) { return entry.templateOf; }));
              var rootScopeImports = [];
              var rootProviderOverrides = this._rootProviderOverrides;
              if (this._isRoot) {
                  var RootScopeModule = /** @class */ (function () {
                      function RootScopeModule() {
                      }
                      RootScopeModule = __decorate([
                          core.NgModule({
                              providers: __spread(rootProviderOverrides),
                              jit: true,
                          })
                      ], RootScopeModule);
                      return RootScopeModule;
                  }());
                  rootScopeImports.push(RootScopeModule);
              }
              providers.push({ provide: core.ɵINJECTOR_SCOPE, useValue: this._isRoot ? 'root' : null });
              var imports = [rootScopeImports, this.ngModule, this._imports];
              var schemas = this._schemas;
              var DynamicTestModule = /** @class */ (function () {
                  function DynamicTestModule() {
                  }
                  DynamicTestModule = __decorate([
                      core.NgModule({ providers: providers, declarations: declarations, imports: imports, schemas: schemas, jit: true })
                  ], DynamicTestModule);
                  return DynamicTestModule;
              }());
              var compilerFactory = this.platform.injector.get(TestingCompilerFactory);
              this._compiler = compilerFactory.createTestingCompiler(this._compilerOptions);
              try {
                  for (var _b = __values(__spread([this._testEnvAotSummaries], this._aotSummaries)), _c = _b.next(); !_c.done; _c = _b.next()) {
                      var summary = _c.value;
                      this._compiler.loadAotSummaries(summary);
                  }
              }
              catch (e_2_1) { e_2 = { error: e_2_1 }; }
              finally {
                  try {
                      if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
                  }
                  finally { if (e_2) throw e_2.error; }
              }
              this._moduleOverrides.forEach(function (entry) { return _this._compiler.overrideModule(entry[0], entry[1]); });
              this._componentOverrides.forEach(function (entry) { return _this._compiler.overrideComponent(entry[0], entry[1]); });
              this._directiveOverrides.forEach(function (entry) { return _this._compiler.overrideDirective(entry[0], entry[1]); });
              this._pipeOverrides.forEach(function (entry) { return _this._compiler.overridePipe(entry[0], entry[1]); });
              return DynamicTestModule;
          };
          TestBedViewEngine.prototype._assertNotInstantiated = function (methodName, methodDescription) {
              if (this._instantiated) {
                  throw new Error("Cannot " + methodDescription + " when the test module has already been instantiated. " +
                      ("Make sure you are not using `inject` before `" + methodName + "`."));
              }
          };
          TestBedViewEngine.prototype.inject = function (token, notFoundValue, flags) {
              this._initIfNeeded();
              if (token === TestBed) {
                  return this;
              }
              // Tests can inject things from the ng module and from the compiler,
              // but the ng module can't inject things from the compiler and vice versa.
              var UNDEFINED = {};
              var result = this._moduleRef.injector.get(token, UNDEFINED, flags);
              return result === UNDEFINED ? this._compiler.injector.get(token, notFoundValue, flags) :
                  result;
          };
          /** @deprecated from v9.0.0 use TestBed.inject */
          TestBedViewEngine.prototype.get = function (token, notFoundValue, flags) {
              if (notFoundValue === void 0) { notFoundValue = core.Injector.THROW_IF_NOT_FOUND; }
              if (flags === void 0) { flags = core.InjectFlags.Default; }
              return this.inject(token, notFoundValue, flags);
          };
          TestBedViewEngine.prototype.execute = function (tokens, fn, context) {
              var _this = this;
              this._initIfNeeded();
              var params = tokens.map(function (t) { return _this.inject(t); });
              return fn.apply(context, params);
          };
          TestBedViewEngine.prototype.overrideModule = function (ngModule, override) {
              this._assertNotInstantiated('overrideModule', 'override module metadata');
              this._moduleOverrides.push([ngModule, override]);
          };
          TestBedViewEngine.prototype.overrideComponent = function (component, override) {
              this._assertNotInstantiated('overrideComponent', 'override component metadata');
              this._componentOverrides.push([component, override]);
          };
          TestBedViewEngine.prototype.overrideDirective = function (directive, override) {
              this._assertNotInstantiated('overrideDirective', 'override directive metadata');
              this._directiveOverrides.push([directive, override]);
          };
          TestBedViewEngine.prototype.overridePipe = function (pipe, override) {
              this._assertNotInstantiated('overridePipe', 'override pipe metadata');
              this._pipeOverrides.push([pipe, override]);
          };
          TestBedViewEngine.prototype.overrideProvider = function (token, provider) {
              this.overrideProviderImpl(token, provider);
          };
          TestBedViewEngine.prototype.overrideProviderImpl = function (token, provider, deprecated) {
              if (deprecated === void 0) { deprecated = false; }
              var def = null;
              if (typeof token !== 'string' && (def = core.ɵgetInjectableDef(token)) && def.providedIn === 'root') {
                  if (provider.useFactory) {
                      this._rootProviderOverrides.push({ provide: token, useFactory: provider.useFactory, deps: provider.deps || [] });
                  }
                  else {
                      this._rootProviderOverrides.push({ provide: token, useValue: provider.useValue });
                  }
              }
              var flags = 0;
              var value;
              if (provider.useFactory) {
                  flags |= 1024 /* TypeFactoryProvider */;
                  value = provider.useFactory;
              }
              else {
                  flags |= 256 /* TypeValueProvider */;
                  value = provider.useValue;
              }
              var deps = (provider.deps || []).map(function (dep) {
                  var depFlags = 0 /* None */;
                  var depToken;
                  if (Array.isArray(dep)) {
                      dep.forEach(function (entry) {
                          if (entry instanceof core.Optional) {
                              depFlags |= 2 /* Optional */;
                          }
                          else if (entry instanceof core.SkipSelf) {
                              depFlags |= 1 /* SkipSelf */;
                          }
                          else {
                              depToken = entry;
                          }
                      });
                  }
                  else {
                      depToken = dep;
                  }
                  return [depFlags, depToken];
              });
              core.ɵoverrideProvider({ token: token, flags: flags, deps: deps, value: value, deprecatedBehavior: deprecated });
          };
          TestBedViewEngine.prototype.overrideTemplateUsingTestingModule = function (component, template) {
              this._assertNotInstantiated('overrideTemplateUsingTestingModule', 'override template');
              var OverrideComponent = /** @class */ (function () {
                  function OverrideComponent() {
                  }
                  OverrideComponent = __decorate([
                      core.Component({ selector: 'empty', template: template, jit: true })
                  ], OverrideComponent);
                  return OverrideComponent;
              }());
              this._templateOverrides.push({ component: component, templateOf: OverrideComponent });
          };
          TestBedViewEngine.prototype.createComponent = function (component) {
              var _this = this;
              this._initIfNeeded();
              var componentFactory = this._compiler.getComponentFactory(component);
              if (!componentFactory) {
                  throw new Error("Cannot create the component " + core.ɵstringify(component) + " as it was not imported into the testing module!");
              }
              // TODO: Don't cast as `InjectionToken<boolean>`, declared type is boolean[]
              var noNgZone = this.inject(ComponentFixtureNoNgZone, false);
              // TODO: Don't cast as `InjectionToken<boolean>`, declared type is boolean[]
              var autoDetect = this.inject(ComponentFixtureAutoDetect, false);
              var ngZone = noNgZone ? null : this.inject(core.NgZone, null);
              var testComponentRenderer = this.inject(TestComponentRenderer);
              var rootElId = "root" + _nextRootElementId$1++;
              testComponentRenderer.insertRootElement(rootElId);
              var initComponent = function () {
                  var componentRef = componentFactory.create(core.Injector.NULL, [], "#" + rootElId, _this._moduleRef);
                  return new ComponentFixture(componentRef, ngZone, autoDetect);
              };
              var fixture = !ngZone ? initComponent() : ngZone.run(initComponent);
              this._activeFixtures.push(fixture);
              return fixture;
          };
          return TestBedViewEngine;
      }());
      /**
       * @description
       * Configures and initializes environment for unit testing and provides methods for
       * creating components and services in unit tests.
       *
       * `TestBed` is the primary api for writing unit tests for Angular applications and libraries.
       *
       * Note: Use `TestBed` in tests. It will be set to either `TestBedViewEngine` or `TestBedRender3`
       * according to the compiler used.
       *
       * @publicApi
       */
      var TestBed = core.ɵivyEnabled ? TestBedRender3 : TestBedViewEngine;
      /**
       * Returns a singleton of the applicable `TestBed`.
       *
       * It will be either an instance of `TestBedViewEngine` or `TestBedRender3`.
       *
       * @publicApi
       */
      var getTestBed = core.ɵivyEnabled ? _getTestBedRender3 : _getTestBedViewEngine;
      var testBed$1;
      function _getTestBedViewEngine() {
          return testBed$1 = testBed$1 || new TestBedViewEngine();
      }
      /**
       * Allows injecting dependencies in `beforeEach()` and `it()`.
       *
       * Example:
       *
       * ```
       * beforeEach(inject([Dependency, AClass], (dep, object) => {
       *   // some code that uses `dep` and `object`
       *   // ...
       * }));
       *
       * it('...', inject([AClass], (object) => {
       *   object.doSomething();
       *   expect(...);
       * })
       * ```
       *
       * Notes:
       * - inject is currently a function because of some Traceur limitation the syntax should
       * eventually
       *   becomes `it('...', @Inject (object: AClass, async: AsyncTestCompleter) => { ... });`
       *
       * @publicApi
       */
      function inject(tokens, fn) {
          var testBed = getTestBed();
          if (tokens.indexOf(AsyncTestCompleter) >= 0) {
              // Not using an arrow function to preserve context passed from call site
              return function () {
                  var _this = this;
                  // Return an async test method that returns a Promise if AsyncTestCompleter is one of
                  // the injected tokens.
                  return testBed.compileComponents().then(function () {
                      var completer = testBed.inject(AsyncTestCompleter);
                      testBed.execute(tokens, fn, _this);
                      return completer.promise;
                  });
              };
          }
          else {
              // Not using an arrow function to preserve context passed from call site
              return function () {
                  return testBed.execute(tokens, fn, this);
              };
          }
      }
      /**
       * @publicApi
       */
      var InjectSetupWrapper = /** @class */ (function () {
          function InjectSetupWrapper(_moduleDef) {
              this._moduleDef = _moduleDef;
          }
          InjectSetupWrapper.prototype._addModule = function () {
              var moduleDef = this._moduleDef();
              if (moduleDef) {
                  getTestBed().configureTestingModule(moduleDef);
              }
          };
          InjectSetupWrapper.prototype.inject = function (tokens, fn) {
              var self = this;
              // Not using an arrow function to preserve context passed from call site
              return function () {
                  self._addModule();
                  return inject(tokens, fn).call(this);
              };
          };
          return InjectSetupWrapper;
      }());
      function withModule(moduleDef, fn) {
          if (fn) {
              // Not using an arrow function to preserve context passed from call site
              return function () {
                  var testBed = getTestBed();
                  if (moduleDef) {
                      testBed.configureTestingModule(moduleDef);
                  }
                  return fn.apply(this);
              };
          }
          return new InjectSetupWrapper(function () { return moduleDef; });
      }
  
      /**
       * @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 _global$1 = (typeof window === 'undefined' ? global : window);
      // Reset the test providers and the fake async zone before each test.
      if (_global$1.beforeEach) {
          _global$1.beforeEach(function () {
              TestBed.resetTestingModule();
              resetFakeAsyncZone();
          });
      }
      // TODO(juliemr): remove this, only used because we need to export something to have compilation
      // work.
      var __core_private_testing_placeholder__ = '';
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
      // This file only reexports content of the `src` folder. Keep it that way.
  
      /**
       * @license
       * Copyright Google Inc. All Rights Reserved.
       *
       * Use of this source code is governed by an MIT-style license that can be
       * found in the LICENSE file at https://angular.io/license
       */
  
      /**
       * Generated bundle index. Do not edit.
       */
  
      exports.ComponentFixture = ComponentFixture;
      exports.ComponentFixtureAutoDetect = ComponentFixtureAutoDetect;
      exports.ComponentFixtureNoNgZone = ComponentFixtureNoNgZone;
      exports.InjectSetupWrapper = InjectSetupWrapper;
      exports.TestBed = TestBed;
      exports.TestComponentRenderer = TestComponentRenderer;
      exports.__core_private_testing_placeholder__ = __core_private_testing_placeholder__;
      exports.async = async;
      exports.discardPeriodicTasks = discardPeriodicTasks;
      exports.fakeAsync = fakeAsync;
      exports.flush = flush;
      exports.flushMicrotasks = flushMicrotasks;
      exports.getTestBed = getTestBed;
      exports.inject = inject;
      exports.resetFakeAsyncZone = resetFakeAsyncZone;
      exports.tick = tick;
      exports.withModule = withModule;
      exports.ɵMetadataOverrider = MetadataOverrider;
      exports.ɵTestingCompiler = TestingCompiler;
      exports.ɵTestingCompilerFactory = TestingCompilerFactory;
      exports.ɵangular_packages_core_testing_testing_a = TestBedViewEngine;
      exports.ɵangular_packages_core_testing_testing_b = TestBedRender3;
      exports.ɵangular_packages_core_testing_testing_c = _getTestBedRender3;
  
      Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  //# sourceMappingURL=core-testing.umd.js.map
  