/**
 * @license Angular v11.2.14
 * (c) 2010-2021 Google LLC. https://angular.io/
 * License: MIT
 */
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@angular/common"),require("@angular/common/testing"),require("@angular/core"),require("@angular/router")):"function"==typeof define&&define.amd?define("@angular/router/testing",["exports","@angular/common","@angular/common/testing","@angular/core","@angular/router"],r):r(((e=e||self).ng=e.ng||{},e.ng.router=e.ng.router||{},e.ng.router.testing={}),e.ng.common,e.ng.common.testing,e.ng.core,e.ng.router)}(this,(function(e,r,t,o,n){"use strict";
/*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

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

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */var u=function(){function e(e){this.compiler=e,this._stubbedModules={}}return Object.defineProperty(e.prototype,"stubbedModules",{get:function(){return this._stubbedModules},set:function(e){var r,t,o={};try{for(var n=function u(e){var r="function"==typeof Symbol&&Symbol.iterator,t=r&&e[r],o=0;if(t)return t.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&o>=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(r?"Object is not iterable.":"Symbol.iterator is not defined.")}(Object.keys(e)),i=n.next();!i.done;i=n.next()){var a=i.value;o[a]=this.compiler.compileModuleAsync(e[a])}}catch(e){r={error:e}}finally{try{i&&!i.done&&(t=n.return)&&t.call(n)}finally{if(r)throw r.error}}this._stubbedModules=o},enumerable:!1,configurable:!0}),e.prototype.load=function(e){return this._stubbedModules[e]?this._stubbedModules[e]:Promise.reject(new Error("Cannot find module "+e))},e}();function i(e,r,t,o,u,i,a,l,s){var d=new n.Router(null,e,r,t,i,o,u,n.ɵflatten(a));return l&&(function c(e){return"shouldProcessUrl"in e}(l)?d.urlHandlingStrategy=l:n.ɵassignExtraOptionsToRouter(l,d)),s&&(d.urlHandlingStrategy=s),d}u.decorators=[{type:o.Injectable}],u.ctorParameters=function(){return[{type:o.Compiler}]};var a=function(){function e(){}return e.withRoutes=function(r,t){return{ngModule:e,providers:[n.provideRoutes(r),{provide:n.ROUTER_CONFIGURATION,useValue:t||{}}]}},e}();a.decorators=[{type:o.NgModule,args:[{exports:[n.RouterModule],providers:[n.ɵROUTER_PROVIDERS,{provide:r.Location,useClass:t.SpyLocation},{provide:r.LocationStrategy,useClass:t.MockLocationStrategy},{provide:o.NgModuleFactoryLoader,useClass:u},{provide:n.Router,useFactory:i,deps:[n.UrlSerializer,n.ChildrenOutletContexts,r.Location,o.NgModuleFactoryLoader,o.Compiler,o.Injector,n.ROUTES,n.ROUTER_CONFIGURATION,[n.UrlHandlingStrategy,new o.Optional]]},{provide:n.PreloadingStrategy,useExisting:n.NoPreloading},n.provideRoutes([])]}]}],
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
/**
     * @license
     * Copyright Google LLC All Rights Reserved.
     *
     * Use of this source code is governed by an MIT-style license that can be
     * found in the LICENSE file at https://angular.io/license
     */
e.RouterTestingModule=a,e.SpyNgModuleFactoryLoader=u,e.setupTestingRouter=i,Object.defineProperty(e,"__esModule",{value:!0})}));