UNPKG

231 kBJavaScriptView Raw
1/**
2 * @license Angular v8.2.0
3 * (c) 2010-2019 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { __extends, __decorate, __assign, __values, __spread, __metadata, __param } from 'tslib';
8import { LocationStrategy, Location, PlatformLocation, APP_BASE_HREF, ViewportScroller, HashLocationStrategy, PathLocationStrategy, LOCATION_INITIALIZED } from '@angular/common';
9import { Component, ɵisObservable, ɵisPromise, NgModuleRef, InjectionToken, NgModuleFactory, isDevMode, NgZone, ɵConsole, Input, HostListener, Directive, Attribute, Renderer2, ElementRef, HostBinding, ContentChildren, QueryList, Optional, Output, ViewContainerRef, ComponentFactoryResolver, ChangeDetectorRef, EventEmitter, Injectable, NgModuleFactoryLoader, Compiler, Injector, ApplicationRef, SystemJsNgModuleLoader, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, Inject, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, Version } from '@angular/core';
10import { from, of, BehaviorSubject, EmptyError, Observable, combineLatest, defer, EMPTY, Subject } from 'rxjs';
11import { map, concatAll, last as last$1, catchError, first, mergeMap, every, switchMap, take, startWith, scan, filter, concatMap, reduce, tap, finalize, mergeAll } from 'rxjs/operators';
12import { ɵgetDOM } from '@angular/platform-browser';
13
14/**
15 * @license
16 * Copyright Google Inc. All Rights Reserved.
17 *
18 * Use of this source code is governed by an MIT-style license that can be
19 * found in the LICENSE file at https://angular.io/license
20 */
21/**
22 * Base for events the router goes through, as opposed to events tied to a specific
23 * route. Fired one time for any given navigation.
24 *
25 * @usageNotes
26 *
27 * ```ts
28 * class MyService {
29 * constructor(public router: Router, logger: Logger) {
30 * router.events.pipe(
31 * filter(e => e instanceof RouterEvent)
32 * ).subscribe(e => {
33 * logger.log(e.id, e.url);
34 * });
35 * }
36 * }
37 * ```
38 *
39 * @see `Event`
40 * @publicApi
41 */
42var RouterEvent = /** @class */ (function () {
43 function RouterEvent(
44 /** A unique ID that the router assigns to every router navigation. */
45 id,
46 /** The URL that is the destination for this navigation. */
47 url) {
48 this.id = id;
49 this.url = url;
50 }
51 return RouterEvent;
52}());
53/**
54 * An event triggered when a navigation starts.
55 *
56 * @publicApi
57 */
58var NavigationStart = /** @class */ (function (_super) {
59 __extends(NavigationStart, _super);
60 function NavigationStart(
61 /** @docsNotRequired */
62 id,
63 /** @docsNotRequired */
64 url,
65 /** @docsNotRequired */
66 navigationTrigger,
67 /** @docsNotRequired */
68 restoredState) {
69 if (navigationTrigger === void 0) { navigationTrigger = 'imperative'; }
70 if (restoredState === void 0) { restoredState = null; }
71 var _this = _super.call(this, id, url) || this;
72 _this.navigationTrigger = navigationTrigger;
73 _this.restoredState = restoredState;
74 return _this;
75 }
76 /** @docsNotRequired */
77 NavigationStart.prototype.toString = function () { return "NavigationStart(id: " + this.id + ", url: '" + this.url + "')"; };
78 return NavigationStart;
79}(RouterEvent));
80/**
81 * An event triggered when a navigation ends successfully.
82 *
83 * @publicApi
84 */
85var NavigationEnd = /** @class */ (function (_super) {
86 __extends(NavigationEnd, _super);
87 function NavigationEnd(
88 /** @docsNotRequired */
89 id,
90 /** @docsNotRequired */
91 url,
92 /** @docsNotRequired */
93 urlAfterRedirects) {
94 var _this = _super.call(this, id, url) || this;
95 _this.urlAfterRedirects = urlAfterRedirects;
96 return _this;
97 }
98 /** @docsNotRequired */
99 NavigationEnd.prototype.toString = function () {
100 return "NavigationEnd(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "')";
101 };
102 return NavigationEnd;
103}(RouterEvent));
104/**
105 * An event triggered when a navigation is canceled.
106 *
107 * @publicApi
108 */
109var NavigationCancel = /** @class */ (function (_super) {
110 __extends(NavigationCancel, _super);
111 function NavigationCancel(
112 /** @docsNotRequired */
113 id,
114 /** @docsNotRequired */
115 url,
116 /** @docsNotRequired */
117 reason) {
118 var _this = _super.call(this, id, url) || this;
119 _this.reason = reason;
120 return _this;
121 }
122 /** @docsNotRequired */
123 NavigationCancel.prototype.toString = function () { return "NavigationCancel(id: " + this.id + ", url: '" + this.url + "')"; };
124 return NavigationCancel;
125}(RouterEvent));
126/**
127 * An event triggered when a navigation fails due to an unexpected error.
128 *
129 * @publicApi
130 */
131var NavigationError = /** @class */ (function (_super) {
132 __extends(NavigationError, _super);
133 function NavigationError(
134 /** @docsNotRequired */
135 id,
136 /** @docsNotRequired */
137 url,
138 /** @docsNotRequired */
139 error) {
140 var _this = _super.call(this, id, url) || this;
141 _this.error = error;
142 return _this;
143 }
144 /** @docsNotRequired */
145 NavigationError.prototype.toString = function () {
146 return "NavigationError(id: " + this.id + ", url: '" + this.url + "', error: " + this.error + ")";
147 };
148 return NavigationError;
149}(RouterEvent));
150/**
151 *An event triggered when routes are recognized.
152 *
153 * @publicApi
154 */
155var RoutesRecognized = /** @class */ (function (_super) {
156 __extends(RoutesRecognized, _super);
157 function RoutesRecognized(
158 /** @docsNotRequired */
159 id,
160 /** @docsNotRequired */
161 url,
162 /** @docsNotRequired */
163 urlAfterRedirects,
164 /** @docsNotRequired */
165 state) {
166 var _this = _super.call(this, id, url) || this;
167 _this.urlAfterRedirects = urlAfterRedirects;
168 _this.state = state;
169 return _this;
170 }
171 /** @docsNotRequired */
172 RoutesRecognized.prototype.toString = function () {
173 return "RoutesRecognized(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")";
174 };
175 return RoutesRecognized;
176}(RouterEvent));
177/**
178 * An event triggered at the start of the Guard phase of routing.
179 *
180 * @publicApi
181 */
182var GuardsCheckStart = /** @class */ (function (_super) {
183 __extends(GuardsCheckStart, _super);
184 function GuardsCheckStart(
185 /** @docsNotRequired */
186 id,
187 /** @docsNotRequired */
188 url,
189 /** @docsNotRequired */
190 urlAfterRedirects,
191 /** @docsNotRequired */
192 state) {
193 var _this = _super.call(this, id, url) || this;
194 _this.urlAfterRedirects = urlAfterRedirects;
195 _this.state = state;
196 return _this;
197 }
198 GuardsCheckStart.prototype.toString = function () {
199 return "GuardsCheckStart(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")";
200 };
201 return GuardsCheckStart;
202}(RouterEvent));
203/**
204 * An event triggered at the end of the Guard phase of routing.
205 *
206 * @publicApi
207 */
208var GuardsCheckEnd = /** @class */ (function (_super) {
209 __extends(GuardsCheckEnd, _super);
210 function GuardsCheckEnd(
211 /** @docsNotRequired */
212 id,
213 /** @docsNotRequired */
214 url,
215 /** @docsNotRequired */
216 urlAfterRedirects,
217 /** @docsNotRequired */
218 state,
219 /** @docsNotRequired */
220 shouldActivate) {
221 var _this = _super.call(this, id, url) || this;
222 _this.urlAfterRedirects = urlAfterRedirects;
223 _this.state = state;
224 _this.shouldActivate = shouldActivate;
225 return _this;
226 }
227 GuardsCheckEnd.prototype.toString = function () {
228 return "GuardsCheckEnd(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ", shouldActivate: " + this.shouldActivate + ")";
229 };
230 return GuardsCheckEnd;
231}(RouterEvent));
232/**
233 * An event triggered at the the start of the Resolve phase of routing.
234 *
235 * Runs in the "resolve" phase whether or not there is anything to resolve.
236 * In future, may change to only run when there are things to be resolved.
237 *
238 * @publicApi
239 */
240var ResolveStart = /** @class */ (function (_super) {
241 __extends(ResolveStart, _super);
242 function ResolveStart(
243 /** @docsNotRequired */
244 id,
245 /** @docsNotRequired */
246 url,
247 /** @docsNotRequired */
248 urlAfterRedirects,
249 /** @docsNotRequired */
250 state) {
251 var _this = _super.call(this, id, url) || this;
252 _this.urlAfterRedirects = urlAfterRedirects;
253 _this.state = state;
254 return _this;
255 }
256 ResolveStart.prototype.toString = function () {
257 return "ResolveStart(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")";
258 };
259 return ResolveStart;
260}(RouterEvent));
261/**
262 * An event triggered at the end of the Resolve phase of routing.
263 * @see `ResolveStart`.
264 *
265 * @publicApi
266 */
267var ResolveEnd = /** @class */ (function (_super) {
268 __extends(ResolveEnd, _super);
269 function ResolveEnd(
270 /** @docsNotRequired */
271 id,
272 /** @docsNotRequired */
273 url,
274 /** @docsNotRequired */
275 urlAfterRedirects,
276 /** @docsNotRequired */
277 state) {
278 var _this = _super.call(this, id, url) || this;
279 _this.urlAfterRedirects = urlAfterRedirects;
280 _this.state = state;
281 return _this;
282 }
283 ResolveEnd.prototype.toString = function () {
284 return "ResolveEnd(id: " + this.id + ", url: '" + this.url + "', urlAfterRedirects: '" + this.urlAfterRedirects + "', state: " + this.state + ")";
285 };
286 return ResolveEnd;
287}(RouterEvent));
288/**
289 * An event triggered before lazy loading a route configuration.
290 *
291 * @publicApi
292 */
293var RouteConfigLoadStart = /** @class */ (function () {
294 function RouteConfigLoadStart(
295 /** @docsNotRequired */
296 route) {
297 this.route = route;
298 }
299 RouteConfigLoadStart.prototype.toString = function () { return "RouteConfigLoadStart(path: " + this.route.path + ")"; };
300 return RouteConfigLoadStart;
301}());
302/**
303 * An event triggered when a route has been lazy loaded.
304 *
305 * @publicApi
306 */
307var RouteConfigLoadEnd = /** @class */ (function () {
308 function RouteConfigLoadEnd(
309 /** @docsNotRequired */
310 route) {
311 this.route = route;
312 }
313 RouteConfigLoadEnd.prototype.toString = function () { return "RouteConfigLoadEnd(path: " + this.route.path + ")"; };
314 return RouteConfigLoadEnd;
315}());
316/**
317 * An event triggered at the start of the child-activation
318 * part of the Resolve phase of routing.
319 * @see `ChildActivationEnd`
320 * @see `ResolveStart`
321 *
322 * @publicApi
323 */
324var ChildActivationStart = /** @class */ (function () {
325 function ChildActivationStart(
326 /** @docsNotRequired */
327 snapshot) {
328 this.snapshot = snapshot;
329 }
330 ChildActivationStart.prototype.toString = function () {
331 var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
332 return "ChildActivationStart(path: '" + path + "')";
333 };
334 return ChildActivationStart;
335}());
336/**
337 * An event triggered at the end of the child-activation part
338 * of the Resolve phase of routing.
339 * @see `ChildActivationStart`
340 * @see `ResolveStart` *
341 * @publicApi
342 */
343var ChildActivationEnd = /** @class */ (function () {
344 function ChildActivationEnd(
345 /** @docsNotRequired */
346 snapshot) {
347 this.snapshot = snapshot;
348 }
349 ChildActivationEnd.prototype.toString = function () {
350 var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
351 return "ChildActivationEnd(path: '" + path + "')";
352 };
353 return ChildActivationEnd;
354}());
355/**
356 * An event triggered at the start of the activation part
357 * of the Resolve phase of routing.
358 * @see ActivationEnd`
359 * @see `ResolveStart`
360 *
361 * @publicApi
362 */
363var ActivationStart = /** @class */ (function () {
364 function ActivationStart(
365 /** @docsNotRequired */
366 snapshot) {
367 this.snapshot = snapshot;
368 }
369 ActivationStart.prototype.toString = function () {
370 var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
371 return "ActivationStart(path: '" + path + "')";
372 };
373 return ActivationStart;
374}());
375/**
376 * An event triggered at the end of the activation part
377 * of the Resolve phase of routing.
378 * @see `ActivationStart`
379 * @see `ResolveStart`
380 *
381 * @publicApi
382 */
383var ActivationEnd = /** @class */ (function () {
384 function ActivationEnd(
385 /** @docsNotRequired */
386 snapshot) {
387 this.snapshot = snapshot;
388 }
389 ActivationEnd.prototype.toString = function () {
390 var path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
391 return "ActivationEnd(path: '" + path + "')";
392 };
393 return ActivationEnd;
394}());
395/**
396 * An event triggered by scrolling.
397 *
398 * @publicApi
399 */
400var Scroll = /** @class */ (function () {
401 function Scroll(
402 /** @docsNotRequired */
403 routerEvent,
404 /** @docsNotRequired */
405 position,
406 /** @docsNotRequired */
407 anchor) {
408 this.routerEvent = routerEvent;
409 this.position = position;
410 this.anchor = anchor;
411 }
412 Scroll.prototype.toString = function () {
413 var pos = this.position ? this.position[0] + ", " + this.position[1] : null;
414 return "Scroll(anchor: '" + this.anchor + "', position: '" + pos + "')";
415 };
416 return Scroll;
417}());
418
419/**
420 * @license
421 * Copyright Google Inc. All Rights Reserved.
422 *
423 * Use of this source code is governed by an MIT-style license that can be
424 * found in the LICENSE file at https://angular.io/license
425 */
426/**
427 * This component is used internally within the router to be a placeholder when an empty
428 * router-outlet is needed. For example, with a config such as:
429 *
430 * `{path: 'parent', outlet: 'nav', children: [...]}`
431 *
432 * In order to render, there needs to be a component on this config, which will default
433 * to this `EmptyOutletComponent`.
434 */
435var ɵEmptyOutletComponent = /** @class */ (function () {
436 function ɵEmptyOutletComponent() {
437 }
438 ɵEmptyOutletComponent = __decorate([
439 Component({ template: "<router-outlet></router-outlet>" })
440 ], ɵEmptyOutletComponent);
441 return ɵEmptyOutletComponent;
442}());
443
444/**
445 * @license
446 * Copyright Google Inc. All Rights Reserved.
447 *
448 * Use of this source code is governed by an MIT-style license that can be
449 * found in the LICENSE file at https://angular.io/license
450 */
451/**
452 * The primary routing outlet.
453 *
454 * @publicApi
455 */
456var PRIMARY_OUTLET = 'primary';
457var ParamsAsMap = /** @class */ (function () {
458 function ParamsAsMap(params) {
459 this.params = params || {};
460 }
461 ParamsAsMap.prototype.has = function (name) { return this.params.hasOwnProperty(name); };
462 ParamsAsMap.prototype.get = function (name) {
463 if (this.has(name)) {
464 var v = this.params[name];
465 return Array.isArray(v) ? v[0] : v;
466 }
467 return null;
468 };
469 ParamsAsMap.prototype.getAll = function (name) {
470 if (this.has(name)) {
471 var v = this.params[name];
472 return Array.isArray(v) ? v : [v];
473 }
474 return [];
475 };
476 Object.defineProperty(ParamsAsMap.prototype, "keys", {
477 get: function () { return Object.keys(this.params); },
478 enumerable: true,
479 configurable: true
480 });
481 return ParamsAsMap;
482}());
483/**
484 * Converts a `Params` instance to a `ParamMap`.
485 * @param params The instance to convert.
486 * @returns The new map instance.
487 *
488 * @publicApi
489 */
490function convertToParamMap(params) {
491 return new ParamsAsMap(params);
492}
493var NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
494function navigationCancelingError(message) {
495 var error = Error('NavigationCancelingError: ' + message);
496 error[NAVIGATION_CANCELING_ERROR] = true;
497 return error;
498}
499function isNavigationCancelingError(error) {
500 return error && error[NAVIGATION_CANCELING_ERROR];
501}
502// Matches the route configuration (`route`) against the actual URL (`segments`).
503function defaultUrlMatcher(segments, segmentGroup, route) {
504 var parts = route.path.split('/');
505 if (parts.length > segments.length) {
506 // The actual URL is shorter than the config, no match
507 return null;
508 }
509 if (route.pathMatch === 'full' &&
510 (segmentGroup.hasChildren() || parts.length < segments.length)) {
511 // The config is longer than the actual URL but we are looking for a full match, return null
512 return null;
513 }
514 var posParams = {};
515 // Check each config part against the actual URL
516 for (var index = 0; index < parts.length; index++) {
517 var part = parts[index];
518 var segment = segments[index];
519 var isParameter = part.startsWith(':');
520 if (isParameter) {
521 posParams[part.substring(1)] = segment;
522 }
523 else if (part !== segment.path) {
524 // The actual URL part does not match the config, no match
525 return null;
526 }
527 }
528 return { consumed: segments.slice(0, parts.length), posParams: posParams };
529}
530
531/**
532 * @license
533 * Copyright Google Inc. All Rights Reserved.
534 *
535 * Use of this source code is governed by an MIT-style license that can be
536 * found in the LICENSE file at https://angular.io/license
537 */
538var LoadedRouterConfig = /** @class */ (function () {
539 function LoadedRouterConfig(routes, module) {
540 this.routes = routes;
541 this.module = module;
542 }
543 return LoadedRouterConfig;
544}());
545function validateConfig(config, parentPath) {
546 if (parentPath === void 0) { parentPath = ''; }
547 // forEach doesn't iterate undefined values
548 for (var i = 0; i < config.length; i++) {
549 var route = config[i];
550 var fullPath = getFullPath(parentPath, route);
551 validateNode(route, fullPath);
552 }
553}
554function validateNode(route, fullPath) {
555 if (!route) {
556 throw new Error("\n Invalid configuration of route '" + fullPath + "': Encountered undefined route.\n The reason might be an extra comma.\n\n Example:\n const routes: Routes = [\n { path: '', redirectTo: '/dashboard', pathMatch: 'full' },\n { path: 'dashboard', component: DashboardComponent },, << two commas\n { path: 'detail/:id', component: HeroDetailComponent }\n ];\n ");
557 }
558 if (Array.isArray(route)) {
559 throw new Error("Invalid configuration of route '" + fullPath + "': Array cannot be specified");
560 }
561 if (!route.component && !route.children && !route.loadChildren &&
562 (route.outlet && route.outlet !== PRIMARY_OUTLET)) {
563 throw new Error("Invalid configuration of route '" + fullPath + "': a componentless route without children or loadChildren cannot have a named outlet set");
564 }
565 if (route.redirectTo && route.children) {
566 throw new Error("Invalid configuration of route '" + fullPath + "': redirectTo and children cannot be used together");
567 }
568 if (route.redirectTo && route.loadChildren) {
569 throw new Error("Invalid configuration of route '" + fullPath + "': redirectTo and loadChildren cannot be used together");
570 }
571 if (route.children && route.loadChildren) {
572 throw new Error("Invalid configuration of route '" + fullPath + "': children and loadChildren cannot be used together");
573 }
574 if (route.redirectTo && route.component) {
575 throw new Error("Invalid configuration of route '" + fullPath + "': redirectTo and component cannot be used together");
576 }
577 if (route.path && route.matcher) {
578 throw new Error("Invalid configuration of route '" + fullPath + "': path and matcher cannot be used together");
579 }
580 if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
581 throw new Error("Invalid configuration of route '" + fullPath + "'. One of the following must be provided: component, redirectTo, children or loadChildren");
582 }
583 if (route.path === void 0 && route.matcher === void 0) {
584 throw new Error("Invalid configuration of route '" + fullPath + "': routes must have either a path or a matcher specified");
585 }
586 if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
587 throw new Error("Invalid configuration of route '" + fullPath + "': path cannot start with a slash");
588 }
589 if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
590 var exp = "The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.";
591 throw new Error("Invalid configuration of route '{path: \"" + fullPath + "\", redirectTo: \"" + route.redirectTo + "\"}': please provide 'pathMatch'. " + exp);
592 }
593 if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
594 throw new Error("Invalid configuration of route '" + fullPath + "': pathMatch can only be set to 'prefix' or 'full'");
595 }
596 if (route.children) {
597 validateConfig(route.children, fullPath);
598 }
599}
600function getFullPath(parentPath, currentRoute) {
601 if (!currentRoute) {
602 return parentPath;
603 }
604 if (!parentPath && !currentRoute.path) {
605 return '';
606 }
607 else if (parentPath && !currentRoute.path) {
608 return parentPath + "/";
609 }
610 else if (!parentPath && currentRoute.path) {
611 return currentRoute.path;
612 }
613 else {
614 return parentPath + "/" + currentRoute.path;
615 }
616}
617/**
618 * Makes a copy of the config and adds any default required properties.
619 */
620function standardizeConfig(r) {
621 var children = r.children && r.children.map(standardizeConfig);
622 var c = children ? __assign({}, r, { children: children }) : __assign({}, r);
623 if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
624 c.component = ɵEmptyOutletComponent;
625 }
626 return c;
627}
628
629/**
630 * @license
631 * Copyright Google Inc. All Rights Reserved.
632 *
633 * Use of this source code is governed by an MIT-style license that can be
634 * found in the LICENSE file at https://angular.io/license
635 */
636function shallowEqualArrays(a, b) {
637 if (a.length !== b.length)
638 return false;
639 for (var i = 0; i < a.length; ++i) {
640 if (!shallowEqual(a[i], b[i]))
641 return false;
642 }
643 return true;
644}
645function shallowEqual(a, b) {
646 // Casting Object.keys return values to include `undefined` as there are some cases
647 // in IE 11 where this can happen. Cannot provide a test because the behavior only
648 // exists in certain circumstances in IE 11, therefore doing this cast ensures the
649 // logic is correct for when this edge case is hit.
650 var k1 = Object.keys(a);
651 var k2 = Object.keys(b);
652 if (!k1 || !k2 || k1.length != k2.length) {
653 return false;
654 }
655 var key;
656 for (var i = 0; i < k1.length; i++) {
657 key = k1[i];
658 if (a[key] !== b[key]) {
659 return false;
660 }
661 }
662 return true;
663}
664/**
665 * Flattens single-level nested arrays.
666 */
667function flatten(arr) {
668 return Array.prototype.concat.apply([], arr);
669}
670/**
671 * Return the last element of an array.
672 */
673function last(a) {
674 return a.length > 0 ? a[a.length - 1] : null;
675}
676function forEach(map, callback) {
677 for (var prop in map) {
678 if (map.hasOwnProperty(prop)) {
679 callback(map[prop], prop);
680 }
681 }
682}
683function waitForMap(obj, fn) {
684 if (Object.keys(obj).length === 0) {
685 return of({});
686 }
687 var waitHead = [];
688 var waitTail = [];
689 var res = {};
690 forEach(obj, function (a, k) {
691 var mapped = fn(k, a).pipe(map(function (r) { return res[k] = r; }));
692 if (k === PRIMARY_OUTLET) {
693 waitHead.push(mapped);
694 }
695 else {
696 waitTail.push(mapped);
697 }
698 });
699 // Closure compiler has problem with using spread operator here. So we use "Array.concat".
700 // Note that we also need to cast the new promise because TypeScript cannot infer the type
701 // when calling the "of" function through "Function.apply"
702 return of.apply(null, waitHead.concat(waitTail))
703 .pipe(concatAll(), last$1(), map(function () { return res; }));
704}
705function wrapIntoObservable(value) {
706 if (ɵisObservable(value)) {
707 return value;
708 }
709 if (ɵisPromise(value)) {
710 // Use `Promise.resolve()` to wrap promise-like instances.
711 // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the
712 // change detection.
713 return from(Promise.resolve(value));
714 }
715 return of(value);
716}
717
718/**
719 * @license
720 * Copyright Google Inc. All Rights Reserved.
721 *
722 * Use of this source code is governed by an MIT-style license that can be
723 * found in the LICENSE file at https://angular.io/license
724 */
725function createEmptyUrlTree() {
726 return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
727}
728function containsTree(container, containee, exact) {
729 if (exact) {
730 return equalQueryParams(container.queryParams, containee.queryParams) &&
731 equalSegmentGroups(container.root, containee.root);
732 }
733 return containsQueryParams(container.queryParams, containee.queryParams) &&
734 containsSegmentGroup(container.root, containee.root);
735}
736function equalQueryParams(container, containee) {
737 // TODO: This does not handle array params correctly.
738 return shallowEqual(container, containee);
739}
740function equalSegmentGroups(container, containee) {
741 if (!equalPath(container.segments, containee.segments))
742 return false;
743 if (container.numberOfChildren !== containee.numberOfChildren)
744 return false;
745 for (var c in containee.children) {
746 if (!container.children[c])
747 return false;
748 if (!equalSegmentGroups(container.children[c], containee.children[c]))
749 return false;
750 }
751 return true;
752}
753function containsQueryParams(container, containee) {
754 // TODO: This does not handle array params correctly.
755 return Object.keys(containee).length <= Object.keys(container).length &&
756 Object.keys(containee).every(function (key) { return containee[key] === container[key]; });
757}
758function containsSegmentGroup(container, containee) {
759 return containsSegmentGroupHelper(container, containee, containee.segments);
760}
761function containsSegmentGroupHelper(container, containee, containeePaths) {
762 if (container.segments.length > containeePaths.length) {
763 var current = container.segments.slice(0, containeePaths.length);
764 if (!equalPath(current, containeePaths))
765 return false;
766 if (containee.hasChildren())
767 return false;
768 return true;
769 }
770 else if (container.segments.length === containeePaths.length) {
771 if (!equalPath(container.segments, containeePaths))
772 return false;
773 for (var c in containee.children) {
774 if (!container.children[c])
775 return false;
776 if (!containsSegmentGroup(container.children[c], containee.children[c]))
777 return false;
778 }
779 return true;
780 }
781 else {
782 var current = containeePaths.slice(0, container.segments.length);
783 var next = containeePaths.slice(container.segments.length);
784 if (!equalPath(container.segments, current))
785 return false;
786 if (!container.children[PRIMARY_OUTLET])
787 return false;
788 return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next);
789 }
790}
791/**
792 * @description
793 *
794 * Represents the parsed URL.
795 *
796 * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
797 * serialized tree.
798 * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
799 *
800 * @usageNotes
801 * ### Example
802 *
803 * ```
804 * @Component({templateUrl:'template.html'})
805 * class MyComponent {
806 * constructor(router: Router) {
807 * const tree: UrlTree =
808 * router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
809 * const f = tree.fragment; // return 'fragment'
810 * const q = tree.queryParams; // returns {debug: 'true'}
811 * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
812 * const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
813 * g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
814 * g.children['support'].segments; // return 1 segment 'help'
815 * }
816 * }
817 * ```
818 *
819 * @publicApi
820 */
821var UrlTree = /** @class */ (function () {
822 /** @internal */
823 function UrlTree(
824 /** The root segment group of the URL tree */
825 root,
826 /** The query params of the URL */
827 queryParams,
828 /** The fragment of the URL */
829 fragment) {
830 this.root = root;
831 this.queryParams = queryParams;
832 this.fragment = fragment;
833 }
834 Object.defineProperty(UrlTree.prototype, "queryParamMap", {
835 get: function () {
836 if (!this._queryParamMap) {
837 this._queryParamMap = convertToParamMap(this.queryParams);
838 }
839 return this._queryParamMap;
840 },
841 enumerable: true,
842 configurable: true
843 });
844 /** @docsNotRequired */
845 UrlTree.prototype.toString = function () { return DEFAULT_SERIALIZER.serialize(this); };
846 return UrlTree;
847}());
848/**
849 * @description
850 *
851 * Represents the parsed URL segment group.
852 *
853 * See `UrlTree` for more information.
854 *
855 * @publicApi
856 */
857var UrlSegmentGroup = /** @class */ (function () {
858 function UrlSegmentGroup(
859 /** The URL segments of this group. See `UrlSegment` for more information */
860 segments,
861 /** The list of children of this group */
862 children) {
863 var _this = this;
864 this.segments = segments;
865 this.children = children;
866 /** The parent node in the url tree */
867 this.parent = null;
868 forEach(children, function (v, k) { return v.parent = _this; });
869 }
870 /** Whether the segment has child segments */
871 UrlSegmentGroup.prototype.hasChildren = function () { return this.numberOfChildren > 0; };
872 Object.defineProperty(UrlSegmentGroup.prototype, "numberOfChildren", {
873 /** Number of child segments */
874 get: function () { return Object.keys(this.children).length; },
875 enumerable: true,
876 configurable: true
877 });
878 /** @docsNotRequired */
879 UrlSegmentGroup.prototype.toString = function () { return serializePaths(this); };
880 return UrlSegmentGroup;
881}());
882/**
883 * @description
884 *
885 * Represents a single URL segment.
886 *
887 * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
888 * parameters associated with the segment.
889 *
890 * @usageNotes
891 * ### Example
892 *
893 * ```
894 * @Component({templateUrl:'template.html'})
895 * class MyComponent {
896 * constructor(router: Router) {
897 * const tree: UrlTree = router.parseUrl('/team;id=33');
898 * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
899 * const s: UrlSegment[] = g.segments;
900 * s[0].path; // returns 'team'
901 * s[0].parameters; // returns {id: 33}
902 * }
903 * }
904 * ```
905 *
906 * @publicApi
907 */
908var UrlSegment = /** @class */ (function () {
909 function UrlSegment(
910 /** The path part of a URL segment */
911 path,
912 /** The matrix parameters associated with a segment */
913 parameters) {
914 this.path = path;
915 this.parameters = parameters;
916 }
917 Object.defineProperty(UrlSegment.prototype, "parameterMap", {
918 get: function () {
919 if (!this._parameterMap) {
920 this._parameterMap = convertToParamMap(this.parameters);
921 }
922 return this._parameterMap;
923 },
924 enumerable: true,
925 configurable: true
926 });
927 /** @docsNotRequired */
928 UrlSegment.prototype.toString = function () { return serializePath(this); };
929 return UrlSegment;
930}());
931function equalSegments(as, bs) {
932 return equalPath(as, bs) && as.every(function (a, i) { return shallowEqual(a.parameters, bs[i].parameters); });
933}
934function equalPath(as, bs) {
935 if (as.length !== bs.length)
936 return false;
937 return as.every(function (a, i) { return a.path === bs[i].path; });
938}
939function mapChildrenIntoArray(segment, fn) {
940 var res = [];
941 forEach(segment.children, function (child, childOutlet) {
942 if (childOutlet === PRIMARY_OUTLET) {
943 res = res.concat(fn(child, childOutlet));
944 }
945 });
946 forEach(segment.children, function (child, childOutlet) {
947 if (childOutlet !== PRIMARY_OUTLET) {
948 res = res.concat(fn(child, childOutlet));
949 }
950 });
951 return res;
952}
953/**
954 * @description
955 *
956 * Serializes and deserializes a URL string into a URL tree.
957 *
958 * The url serialization strategy is customizable. You can
959 * make all URLs case insensitive by providing a custom UrlSerializer.
960 *
961 * See `DefaultUrlSerializer` for an example of a URL serializer.
962 *
963 * @publicApi
964 */
965var UrlSerializer = /** @class */ (function () {
966 function UrlSerializer() {
967 }
968 return UrlSerializer;
969}());
970/**
971 * @description
972 *
973 * A default implementation of the `UrlSerializer`.
974 *
975 * Example URLs:
976 *
977 * ```
978 * /inbox/33(popup:compose)
979 * /inbox/33;open=true/messages/44
980 * ```
981 *
982 * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
983 * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
984 * specify route specific parameters.
985 *
986 * @publicApi
987 */
988var DefaultUrlSerializer = /** @class */ (function () {
989 function DefaultUrlSerializer() {
990 }
991 /** Parses a url into a `UrlTree` */
992 DefaultUrlSerializer.prototype.parse = function (url) {
993 var p = new UrlParser(url);
994 return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
995 };
996 /** Converts a `UrlTree` into a url */
997 DefaultUrlSerializer.prototype.serialize = function (tree) {
998 var segment = "/" + serializeSegment(tree.root, true);
999 var query = serializeQueryParams(tree.queryParams);
1000 var fragment = typeof tree.fragment === "string" ? "#" + encodeUriFragment(tree.fragment) : '';
1001 return "" + segment + query + fragment;
1002 };
1003 return DefaultUrlSerializer;
1004}());
1005var DEFAULT_SERIALIZER = new DefaultUrlSerializer();
1006function serializePaths(segment) {
1007 return segment.segments.map(function (p) { return serializePath(p); }).join('/');
1008}
1009function serializeSegment(segment, root) {
1010 if (!segment.hasChildren()) {
1011 return serializePaths(segment);
1012 }
1013 if (root) {
1014 var primary = segment.children[PRIMARY_OUTLET] ?
1015 serializeSegment(segment.children[PRIMARY_OUTLET], false) :
1016 '';
1017 var children_1 = [];
1018 forEach(segment.children, function (v, k) {
1019 if (k !== PRIMARY_OUTLET) {
1020 children_1.push(k + ":" + serializeSegment(v, false));
1021 }
1022 });
1023 return children_1.length > 0 ? primary + "(" + children_1.join('//') + ")" : primary;
1024 }
1025 else {
1026 var children = mapChildrenIntoArray(segment, function (v, k) {
1027 if (k === PRIMARY_OUTLET) {
1028 return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
1029 }
1030 return [k + ":" + serializeSegment(v, false)];
1031 });
1032 return serializePaths(segment) + "/(" + children.join('//') + ")";
1033 }
1034}
1035/**
1036 * Encodes a URI string with the default encoding. This function will only ever be called from
1037 * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
1038 * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
1039 * have to be encoded per https://url.spec.whatwg.org.
1040 */
1041function encodeUriString(s) {
1042 return encodeURIComponent(s)
1043 .replace(/%40/g, '@')
1044 .replace(/%3A/gi, ':')
1045 .replace(/%24/g, '$')
1046 .replace(/%2C/gi, ',');
1047}
1048/**
1049 * This function should be used to encode both keys and values in a query string key/value. In
1050 * the following URL, you need to call encodeUriQuery on "k" and "v":
1051 *
1052 * http://www.site.org/html;mk=mv?k=v#f
1053 */
1054function encodeUriQuery(s) {
1055 return encodeUriString(s).replace(/%3B/gi, ';');
1056}
1057/**
1058 * This function should be used to encode a URL fragment. In the following URL, you need to call
1059 * encodeUriFragment on "f":
1060 *
1061 * http://www.site.org/html;mk=mv?k=v#f
1062 */
1063function encodeUriFragment(s) {
1064 return encodeURI(s);
1065}
1066/**
1067 * This function should be run on any URI segment as well as the key and value in a key/value
1068 * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
1069 * "mk", and "mv":
1070 *
1071 * http://www.site.org/html;mk=mv?k=v#f
1072 */
1073function encodeUriSegment(s) {
1074 return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
1075}
1076function decode(s) {
1077 return decodeURIComponent(s);
1078}
1079// Query keys/values should have the "+" replaced first, as "+" in a query string is " ".
1080// decodeURIComponent function will not decode "+" as a space.
1081function decodeQuery(s) {
1082 return decode(s.replace(/\+/g, '%20'));
1083}
1084function serializePath(path) {
1085 return "" + encodeUriSegment(path.path) + serializeMatrixParams(path.parameters);
1086}
1087function serializeMatrixParams(params) {
1088 return Object.keys(params)
1089 .map(function (key) { return ";" + encodeUriSegment(key) + "=" + encodeUriSegment(params[key]); })
1090 .join('');
1091}
1092function serializeQueryParams(params) {
1093 var strParams = Object.keys(params).map(function (name) {
1094 var value = params[name];
1095 return Array.isArray(value) ?
1096 value.map(function (v) { return encodeUriQuery(name) + "=" + encodeUriQuery(v); }).join('&') :
1097 encodeUriQuery(name) + "=" + encodeUriQuery(value);
1098 });
1099 return strParams.length ? "?" + strParams.join("&") : '';
1100}
1101var SEGMENT_RE = /^[^\/()?;=#]+/;
1102function matchSegments(str) {
1103 var match = str.match(SEGMENT_RE);
1104 return match ? match[0] : '';
1105}
1106var QUERY_PARAM_RE = /^[^=?&#]+/;
1107// Return the name of the query param at the start of the string or an empty string
1108function matchQueryParams(str) {
1109 var match = str.match(QUERY_PARAM_RE);
1110 return match ? match[0] : '';
1111}
1112var QUERY_PARAM_VALUE_RE = /^[^?&#]+/;
1113// Return the value of the query param at the start of the string or an empty string
1114function matchUrlQueryParamValue(str) {
1115 var match = str.match(QUERY_PARAM_VALUE_RE);
1116 return match ? match[0] : '';
1117}
1118var UrlParser = /** @class */ (function () {
1119 function UrlParser(url) {
1120 this.url = url;
1121 this.remaining = url;
1122 }
1123 UrlParser.prototype.parseRootSegment = function () {
1124 this.consumeOptional('/');
1125 if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
1126 return new UrlSegmentGroup([], {});
1127 }
1128 // The root segment group never has segments
1129 return new UrlSegmentGroup([], this.parseChildren());
1130 };
1131 UrlParser.prototype.parseQueryParams = function () {
1132 var params = {};
1133 if (this.consumeOptional('?')) {
1134 do {
1135 this.parseQueryParam(params);
1136 } while (this.consumeOptional('&'));
1137 }
1138 return params;
1139 };
1140 UrlParser.prototype.parseFragment = function () {
1141 return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
1142 };
1143 UrlParser.prototype.parseChildren = function () {
1144 if (this.remaining === '') {
1145 return {};
1146 }
1147 this.consumeOptional('/');
1148 var segments = [];
1149 if (!this.peekStartsWith('(')) {
1150 segments.push(this.parseSegment());
1151 }
1152 while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
1153 this.capture('/');
1154 segments.push(this.parseSegment());
1155 }
1156 var children = {};
1157 if (this.peekStartsWith('/(')) {
1158 this.capture('/');
1159 children = this.parseParens(true);
1160 }
1161 var res = {};
1162 if (this.peekStartsWith('(')) {
1163 res = this.parseParens(false);
1164 }
1165 if (segments.length > 0 || Object.keys(children).length > 0) {
1166 res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
1167 }
1168 return res;
1169 };
1170 // parse a segment with its matrix parameters
1171 // ie `name;k1=v1;k2`
1172 UrlParser.prototype.parseSegment = function () {
1173 var path = matchSegments(this.remaining);
1174 if (path === '' && this.peekStartsWith(';')) {
1175 throw new Error("Empty path url segment cannot have parameters: '" + this.remaining + "'.");
1176 }
1177 this.capture(path);
1178 return new UrlSegment(decode(path), this.parseMatrixParams());
1179 };
1180 UrlParser.prototype.parseMatrixParams = function () {
1181 var params = {};
1182 while (this.consumeOptional(';')) {
1183 this.parseParam(params);
1184 }
1185 return params;
1186 };
1187 UrlParser.prototype.parseParam = function (params) {
1188 var key = matchSegments(this.remaining);
1189 if (!key) {
1190 return;
1191 }
1192 this.capture(key);
1193 var value = '';
1194 if (this.consumeOptional('=')) {
1195 var valueMatch = matchSegments(this.remaining);
1196 if (valueMatch) {
1197 value = valueMatch;
1198 this.capture(value);
1199 }
1200 }
1201 params[decode(key)] = decode(value);
1202 };
1203 // Parse a single query parameter `name[=value]`
1204 UrlParser.prototype.parseQueryParam = function (params) {
1205 var key = matchQueryParams(this.remaining);
1206 if (!key) {
1207 return;
1208 }
1209 this.capture(key);
1210 var value = '';
1211 if (this.consumeOptional('=')) {
1212 var valueMatch = matchUrlQueryParamValue(this.remaining);
1213 if (valueMatch) {
1214 value = valueMatch;
1215 this.capture(value);
1216 }
1217 }
1218 var decodedKey = decodeQuery(key);
1219 var decodedVal = decodeQuery(value);
1220 if (params.hasOwnProperty(decodedKey)) {
1221 // Append to existing values
1222 var currentVal = params[decodedKey];
1223 if (!Array.isArray(currentVal)) {
1224 currentVal = [currentVal];
1225 params[decodedKey] = currentVal;
1226 }
1227 currentVal.push(decodedVal);
1228 }
1229 else {
1230 // Create a new value
1231 params[decodedKey] = decodedVal;
1232 }
1233 };
1234 // parse `(a/b//outlet_name:c/d)`
1235 UrlParser.prototype.parseParens = function (allowPrimary) {
1236 var segments = {};
1237 this.capture('(');
1238 while (!this.consumeOptional(')') && this.remaining.length > 0) {
1239 var path = matchSegments(this.remaining);
1240 var next = this.remaining[path.length];
1241 // if is is not one of these characters, then the segment was unescaped
1242 // or the group was not closed
1243 if (next !== '/' && next !== ')' && next !== ';') {
1244 throw new Error("Cannot parse url '" + this.url + "'");
1245 }
1246 var outletName = undefined;
1247 if (path.indexOf(':') > -1) {
1248 outletName = path.substr(0, path.indexOf(':'));
1249 this.capture(outletName);
1250 this.capture(':');
1251 }
1252 else if (allowPrimary) {
1253 outletName = PRIMARY_OUTLET;
1254 }
1255 var children = this.parseChildren();
1256 segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] :
1257 new UrlSegmentGroup([], children);
1258 this.consumeOptional('//');
1259 }
1260 return segments;
1261 };
1262 UrlParser.prototype.peekStartsWith = function (str) { return this.remaining.startsWith(str); };
1263 // Consumes the prefix when it is present and returns whether it has been consumed
1264 UrlParser.prototype.consumeOptional = function (str) {
1265 if (this.peekStartsWith(str)) {
1266 this.remaining = this.remaining.substring(str.length);
1267 return true;
1268 }
1269 return false;
1270 };
1271 UrlParser.prototype.capture = function (str) {
1272 if (!this.consumeOptional(str)) {
1273 throw new Error("Expected \"" + str + "\".");
1274 }
1275 };
1276 return UrlParser;
1277}());
1278
1279/**
1280 * @license
1281 * Copyright Google Inc. All Rights Reserved.
1282 *
1283 * Use of this source code is governed by an MIT-style license that can be
1284 * found in the LICENSE file at https://angular.io/license
1285 */
1286var Tree = /** @class */ (function () {
1287 function Tree(root) {
1288 this._root = root;
1289 }
1290 Object.defineProperty(Tree.prototype, "root", {
1291 get: function () { return this._root.value; },
1292 enumerable: true,
1293 configurable: true
1294 });
1295 /**
1296 * @internal
1297 */
1298 Tree.prototype.parent = function (t) {
1299 var p = this.pathFromRoot(t);
1300 return p.length > 1 ? p[p.length - 2] : null;
1301 };
1302 /**
1303 * @internal
1304 */
1305 Tree.prototype.children = function (t) {
1306 var n = findNode(t, this._root);
1307 return n ? n.children.map(function (t) { return t.value; }) : [];
1308 };
1309 /**
1310 * @internal
1311 */
1312 Tree.prototype.firstChild = function (t) {
1313 var n = findNode(t, this._root);
1314 return n && n.children.length > 0 ? n.children[0].value : null;
1315 };
1316 /**
1317 * @internal
1318 */
1319 Tree.prototype.siblings = function (t) {
1320 var p = findPath(t, this._root);
1321 if (p.length < 2)
1322 return [];
1323 var c = p[p.length - 2].children.map(function (c) { return c.value; });
1324 return c.filter(function (cc) { return cc !== t; });
1325 };
1326 /**
1327 * @internal
1328 */
1329 Tree.prototype.pathFromRoot = function (t) { return findPath(t, this._root).map(function (s) { return s.value; }); };
1330 return Tree;
1331}());
1332// DFS for the node matching the value
1333function findNode(value, node) {
1334 var e_1, _a;
1335 if (value === node.value)
1336 return node;
1337 try {
1338 for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) {
1339 var child = _c.value;
1340 var node_1 = findNode(value, child);
1341 if (node_1)
1342 return node_1;
1343 }
1344 }
1345 catch (e_1_1) { e_1 = { error: e_1_1 }; }
1346 finally {
1347 try {
1348 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1349 }
1350 finally { if (e_1) throw e_1.error; }
1351 }
1352 return null;
1353}
1354// Return the path to the node with the given value using DFS
1355function findPath(value, node) {
1356 var e_2, _a;
1357 if (value === node.value)
1358 return [node];
1359 try {
1360 for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) {
1361 var child = _c.value;
1362 var path = findPath(value, child);
1363 if (path.length) {
1364 path.unshift(node);
1365 return path;
1366 }
1367 }
1368 }
1369 catch (e_2_1) { e_2 = { error: e_2_1 }; }
1370 finally {
1371 try {
1372 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1373 }
1374 finally { if (e_2) throw e_2.error; }
1375 }
1376 return [];
1377}
1378var TreeNode = /** @class */ (function () {
1379 function TreeNode(value, children) {
1380 this.value = value;
1381 this.children = children;
1382 }
1383 TreeNode.prototype.toString = function () { return "TreeNode(" + this.value + ")"; };
1384 return TreeNode;
1385}());
1386// Return the list of T indexed by outlet name
1387function nodeChildrenAsMap(node) {
1388 var map = {};
1389 if (node) {
1390 node.children.forEach(function (child) { return map[child.value.outlet] = child; });
1391 }
1392 return map;
1393}
1394
1395/**
1396 * @license
1397 * Copyright Google Inc. All Rights Reserved.
1398 *
1399 * Use of this source code is governed by an MIT-style license that can be
1400 * found in the LICENSE file at https://angular.io/license
1401 */
1402/**
1403 * Represents the state of the router as a tree of activated routes.
1404 *
1405 * @usageNotes
1406 *
1407 * Every node in the route tree is an `ActivatedRoute` instance
1408 * that knows about the "consumed" URL segments, the extracted parameters,
1409 * and the resolved data.
1410 * Use the `ActivatedRoute` properties to traverse the tree from any node.
1411 *
1412 * ### Example
1413 *
1414 * ```
1415 * @Component({templateUrl:'template.html'})
1416 * class MyComponent {
1417 * constructor(router: Router) {
1418 * const state: RouterState = router.routerState;
1419 * const root: ActivatedRoute = state.root;
1420 * const child = root.firstChild;
1421 * const id: Observable<string> = child.params.map(p => p.id);
1422 * //...
1423 * }
1424 * }
1425 * ```
1426 *
1427 * @see `ActivatedRoute`
1428 *
1429 * @publicApi
1430 */
1431var RouterState = /** @class */ (function (_super) {
1432 __extends(RouterState, _super);
1433 /** @internal */
1434 function RouterState(root,
1435 /** The current snapshot of the router state */
1436 snapshot) {
1437 var _this = _super.call(this, root) || this;
1438 _this.snapshot = snapshot;
1439 setRouterState(_this, root);
1440 return _this;
1441 }
1442 RouterState.prototype.toString = function () { return this.snapshot.toString(); };
1443 return RouterState;
1444}(Tree));
1445function createEmptyState(urlTree, rootComponent) {
1446 var snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
1447 var emptyUrl = new BehaviorSubject([new UrlSegment('', {})]);
1448 var emptyParams = new BehaviorSubject({});
1449 var emptyData = new BehaviorSubject({});
1450 var emptyQueryParams = new BehaviorSubject({});
1451 var fragment = new BehaviorSubject('');
1452 var activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
1453 activated.snapshot = snapshot.root;
1454 return new RouterState(new TreeNode(activated, []), snapshot);
1455}
1456function createEmptyStateSnapshot(urlTree, rootComponent) {
1457 var emptyParams = {};
1458 var emptyData = {};
1459 var emptyQueryParams = {};
1460 var fragment = '';
1461 var activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, urlTree.root, -1, {});
1462 return new RouterStateSnapshot('', new TreeNode(activated, []));
1463}
1464/**
1465 * Provides access to information about a route associated with a component
1466 * that is loaded in an outlet.
1467 * Use to traverse the `RouterState` tree and extract information from nodes.
1468 *
1469 * {@example router/activated-route/module.ts region="activated-route"
1470 * header="activated-route.component.ts"}
1471 *
1472 * @publicApi
1473 */
1474var ActivatedRoute = /** @class */ (function () {
1475 /** @internal */
1476 function ActivatedRoute(
1477 /** An observable of the URL segments matched by this route. */
1478 url,
1479 /** An observable of the matrix parameters scoped to this route. */
1480 params,
1481 /** An observable of the query parameters shared by all the routes. */
1482 queryParams,
1483 /** An observable of the URL fragment shared by all the routes. */
1484 fragment,
1485 /** An observable of the static and resolved data of this route. */
1486 data,
1487 /** The outlet name of the route, a constant. */
1488 outlet,
1489 /** The component of the route, a constant. */
1490 // TODO(vsavkin): remove |string
1491 component, futureSnapshot) {
1492 this.url = url;
1493 this.params = params;
1494 this.queryParams = queryParams;
1495 this.fragment = fragment;
1496 this.data = data;
1497 this.outlet = outlet;
1498 this.component = component;
1499 this._futureSnapshot = futureSnapshot;
1500 }
1501 Object.defineProperty(ActivatedRoute.prototype, "routeConfig", {
1502 /** The configuration used to match this route. */
1503 get: function () { return this._futureSnapshot.routeConfig; },
1504 enumerable: true,
1505 configurable: true
1506 });
1507 Object.defineProperty(ActivatedRoute.prototype, "root", {
1508 /** The root of the router state. */
1509 get: function () { return this._routerState.root; },
1510 enumerable: true,
1511 configurable: true
1512 });
1513 Object.defineProperty(ActivatedRoute.prototype, "parent", {
1514 /** The parent of this route in the router state tree. */
1515 get: function () { return this._routerState.parent(this); },
1516 enumerable: true,
1517 configurable: true
1518 });
1519 Object.defineProperty(ActivatedRoute.prototype, "firstChild", {
1520 /** The first child of this route in the router state tree. */
1521 get: function () { return this._routerState.firstChild(this); },
1522 enumerable: true,
1523 configurable: true
1524 });
1525 Object.defineProperty(ActivatedRoute.prototype, "children", {
1526 /** The children of this route in the router state tree. */
1527 get: function () { return this._routerState.children(this); },
1528 enumerable: true,
1529 configurable: true
1530 });
1531 Object.defineProperty(ActivatedRoute.prototype, "pathFromRoot", {
1532 /** The path from the root of the router state tree to this route. */
1533 get: function () { return this._routerState.pathFromRoot(this); },
1534 enumerable: true,
1535 configurable: true
1536 });
1537 Object.defineProperty(ActivatedRoute.prototype, "paramMap", {
1538 /** An Observable that contains a map of the required and optional parameters
1539 * specific to the route.
1540 * The map supports retrieving single and multiple values from the same parameter. */
1541 get: function () {
1542 if (!this._paramMap) {
1543 this._paramMap = this.params.pipe(map(function (p) { return convertToParamMap(p); }));
1544 }
1545 return this._paramMap;
1546 },
1547 enumerable: true,
1548 configurable: true
1549 });
1550 Object.defineProperty(ActivatedRoute.prototype, "queryParamMap", {
1551 /**
1552 * An Observable that contains a map of the query parameters available to all routes.
1553 * The map supports retrieving single and multiple values from the query parameter.
1554 */
1555 get: function () {
1556 if (!this._queryParamMap) {
1557 this._queryParamMap =
1558 this.queryParams.pipe(map(function (p) { return convertToParamMap(p); }));
1559 }
1560 return this._queryParamMap;
1561 },
1562 enumerable: true,
1563 configurable: true
1564 });
1565 ActivatedRoute.prototype.toString = function () {
1566 return this.snapshot ? this.snapshot.toString() : "Future(" + this._futureSnapshot + ")";
1567 };
1568 return ActivatedRoute;
1569}());
1570/**
1571 * Returns the inherited params, data, and resolve for a given route.
1572 * By default, this only inherits values up to the nearest path-less or component-less route.
1573 * @internal
1574 */
1575function inheritedParamsDataResolve(route, paramsInheritanceStrategy) {
1576 if (paramsInheritanceStrategy === void 0) { paramsInheritanceStrategy = 'emptyOnly'; }
1577 var pathFromRoot = route.pathFromRoot;
1578 var inheritingStartingFrom = 0;
1579 if (paramsInheritanceStrategy !== 'always') {
1580 inheritingStartingFrom = pathFromRoot.length - 1;
1581 while (inheritingStartingFrom >= 1) {
1582 var current = pathFromRoot[inheritingStartingFrom];
1583 var parent_1 = pathFromRoot[inheritingStartingFrom - 1];
1584 // current route is an empty path => inherits its parent's params and data
1585 if (current.routeConfig && current.routeConfig.path === '') {
1586 inheritingStartingFrom--;
1587 // parent is componentless => current route should inherit its params and data
1588 }
1589 else if (!parent_1.component) {
1590 inheritingStartingFrom--;
1591 }
1592 else {
1593 break;
1594 }
1595 }
1596 }
1597 return flattenInherited(pathFromRoot.slice(inheritingStartingFrom));
1598}
1599/** @internal */
1600function flattenInherited(pathFromRoot) {
1601 return pathFromRoot.reduce(function (res, curr) {
1602 var params = __assign({}, res.params, curr.params);
1603 var data = __assign({}, res.data, curr.data);
1604 var resolve = __assign({}, res.resolve, curr._resolvedData);
1605 return { params: params, data: data, resolve: resolve };
1606 }, { params: {}, data: {}, resolve: {} });
1607}
1608/**
1609 * @description
1610 *
1611 * Contains the information about a route associated with a component loaded in an
1612 * outlet at a particular moment in time. ActivatedRouteSnapshot can also be used to
1613 * traverse the router state tree.
1614 *
1615 * ```
1616 * @Component({templateUrl:'./my-component.html'})
1617 * class MyComponent {
1618 * constructor(route: ActivatedRoute) {
1619 * const id: string = route.snapshot.params.id;
1620 * const url: string = route.snapshot.url.join('');
1621 * const user = route.snapshot.data.user;
1622 * }
1623 * }
1624 * ```
1625 *
1626 * @publicApi
1627 */
1628var ActivatedRouteSnapshot = /** @class */ (function () {
1629 /** @internal */
1630 function ActivatedRouteSnapshot(
1631 /** The URL segments matched by this route */
1632 url,
1633 /** The matrix parameters scoped to this route */
1634 params,
1635 /** The query parameters shared by all the routes */
1636 queryParams,
1637 /** The URL fragment shared by all the routes */
1638 fragment,
1639 /** The static and resolved data of this route */
1640 data,
1641 /** The outlet name of the route */
1642 outlet,
1643 /** The component of the route */
1644 component, routeConfig, urlSegment, lastPathIndex, resolve) {
1645 this.url = url;
1646 this.params = params;
1647 this.queryParams = queryParams;
1648 this.fragment = fragment;
1649 this.data = data;
1650 this.outlet = outlet;
1651 this.component = component;
1652 this.routeConfig = routeConfig;
1653 this._urlSegment = urlSegment;
1654 this._lastPathIndex = lastPathIndex;
1655 this._resolve = resolve;
1656 }
1657 Object.defineProperty(ActivatedRouteSnapshot.prototype, "root", {
1658 /** The root of the router state */
1659 get: function () { return this._routerState.root; },
1660 enumerable: true,
1661 configurable: true
1662 });
1663 Object.defineProperty(ActivatedRouteSnapshot.prototype, "parent", {
1664 /** The parent of this route in the router state tree */
1665 get: function () { return this._routerState.parent(this); },
1666 enumerable: true,
1667 configurable: true
1668 });
1669 Object.defineProperty(ActivatedRouteSnapshot.prototype, "firstChild", {
1670 /** The first child of this route in the router state tree */
1671 get: function () { return this._routerState.firstChild(this); },
1672 enumerable: true,
1673 configurable: true
1674 });
1675 Object.defineProperty(ActivatedRouteSnapshot.prototype, "children", {
1676 /** The children of this route in the router state tree */
1677 get: function () { return this._routerState.children(this); },
1678 enumerable: true,
1679 configurable: true
1680 });
1681 Object.defineProperty(ActivatedRouteSnapshot.prototype, "pathFromRoot", {
1682 /** The path from the root of the router state tree to this route */
1683 get: function () { return this._routerState.pathFromRoot(this); },
1684 enumerable: true,
1685 configurable: true
1686 });
1687 Object.defineProperty(ActivatedRouteSnapshot.prototype, "paramMap", {
1688 get: function () {
1689 if (!this._paramMap) {
1690 this._paramMap = convertToParamMap(this.params);
1691 }
1692 return this._paramMap;
1693 },
1694 enumerable: true,
1695 configurable: true
1696 });
1697 Object.defineProperty(ActivatedRouteSnapshot.prototype, "queryParamMap", {
1698 get: function () {
1699 if (!this._queryParamMap) {
1700 this._queryParamMap = convertToParamMap(this.queryParams);
1701 }
1702 return this._queryParamMap;
1703 },
1704 enumerable: true,
1705 configurable: true
1706 });
1707 ActivatedRouteSnapshot.prototype.toString = function () {
1708 var url = this.url.map(function (segment) { return segment.toString(); }).join('/');
1709 var matched = this.routeConfig ? this.routeConfig.path : '';
1710 return "Route(url:'" + url + "', path:'" + matched + "')";
1711 };
1712 return ActivatedRouteSnapshot;
1713}());
1714/**
1715 * @description
1716 *
1717 * Represents the state of the router at a moment in time.
1718 *
1719 * This is a tree of activated route snapshots. Every node in this tree knows about
1720 * the "consumed" URL segments, the extracted parameters, and the resolved data.
1721 *
1722 * @usageNotes
1723 * ### Example
1724 *
1725 * ```
1726 * @Component({templateUrl:'template.html'})
1727 * class MyComponent {
1728 * constructor(router: Router) {
1729 * const state: RouterState = router.routerState;
1730 * const snapshot: RouterStateSnapshot = state.snapshot;
1731 * const root: ActivatedRouteSnapshot = snapshot.root;
1732 * const child = root.firstChild;
1733 * const id: Observable<string> = child.params.map(p => p.id);
1734 * //...
1735 * }
1736 * }
1737 * ```
1738 *
1739 * @publicApi
1740 */
1741var RouterStateSnapshot = /** @class */ (function (_super) {
1742 __extends(RouterStateSnapshot, _super);
1743 /** @internal */
1744 function RouterStateSnapshot(
1745 /** The url from which this snapshot was created */
1746 url, root) {
1747 var _this = _super.call(this, root) || this;
1748 _this.url = url;
1749 setRouterState(_this, root);
1750 return _this;
1751 }
1752 RouterStateSnapshot.prototype.toString = function () { return serializeNode(this._root); };
1753 return RouterStateSnapshot;
1754}(Tree));
1755function setRouterState(state, node) {
1756 node.value._routerState = state;
1757 node.children.forEach(function (c) { return setRouterState(state, c); });
1758}
1759function serializeNode(node) {
1760 var c = node.children.length > 0 ? " { " + node.children.map(serializeNode).join(', ') + " } " : '';
1761 return "" + node.value + c;
1762}
1763/**
1764 * The expectation is that the activate route is created with the right set of parameters.
1765 * So we push new values into the observables only when they are not the initial values.
1766 * And we detect that by checking if the snapshot field is set.
1767 */
1768function advanceActivatedRoute(route) {
1769 if (route.snapshot) {
1770 var currentSnapshot = route.snapshot;
1771 var nextSnapshot = route._futureSnapshot;
1772 route.snapshot = nextSnapshot;
1773 if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
1774 route.queryParams.next(nextSnapshot.queryParams);
1775 }
1776 if (currentSnapshot.fragment !== nextSnapshot.fragment) {
1777 route.fragment.next(nextSnapshot.fragment);
1778 }
1779 if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
1780 route.params.next(nextSnapshot.params);
1781 }
1782 if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
1783 route.url.next(nextSnapshot.url);
1784 }
1785 if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
1786 route.data.next(nextSnapshot.data);
1787 }
1788 }
1789 else {
1790 route.snapshot = route._futureSnapshot;
1791 // this is for resolved data
1792 route.data.next(route._futureSnapshot.data);
1793 }
1794}
1795function equalParamsAndUrlSegments(a, b) {
1796 var equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
1797 var parentsMismatch = !a.parent !== !b.parent;
1798 return equalUrlParams && !parentsMismatch &&
1799 (!a.parent || equalParamsAndUrlSegments(a.parent, b.parent));
1800}
1801
1802/**
1803 * @license
1804 * Copyright Google Inc. All Rights Reserved.
1805 *
1806 * Use of this source code is governed by an MIT-style license that can be
1807 * found in the LICENSE file at https://angular.io/license
1808 */
1809function createRouterState(routeReuseStrategy, curr, prevState) {
1810 var root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
1811 return new RouterState(root, curr);
1812}
1813function createNode(routeReuseStrategy, curr, prevState) {
1814 // reuse an activated route that is currently displayed on the screen
1815 if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
1816 var value = prevState.value;
1817 value._futureSnapshot = curr.value;
1818 var children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
1819 return new TreeNode(value, children);
1820 // retrieve an activated route that is used to be displayed, but is not currently displayed
1821 }
1822 else {
1823 var detachedRouteHandle = routeReuseStrategy.retrieve(curr.value);
1824 if (detachedRouteHandle) {
1825 var tree = detachedRouteHandle.route;
1826 setFutureSnapshotsOfActivatedRoutes(curr, tree);
1827 return tree;
1828 }
1829 else {
1830 var value = createActivatedRoute(curr.value);
1831 var children = curr.children.map(function (c) { return createNode(routeReuseStrategy, c); });
1832 return new TreeNode(value, children);
1833 }
1834 }
1835}
1836function setFutureSnapshotsOfActivatedRoutes(curr, result) {
1837 if (curr.value.routeConfig !== result.value.routeConfig) {
1838 throw new Error('Cannot reattach ActivatedRouteSnapshot created from a different route');
1839 }
1840 if (curr.children.length !== result.children.length) {
1841 throw new Error('Cannot reattach ActivatedRouteSnapshot with a different number of children');
1842 }
1843 result.value._futureSnapshot = curr.value;
1844 for (var i = 0; i < curr.children.length; ++i) {
1845 setFutureSnapshotsOfActivatedRoutes(curr.children[i], result.children[i]);
1846 }
1847}
1848function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
1849 return curr.children.map(function (child) {
1850 var e_1, _a;
1851 try {
1852 for (var _b = __values(prevState.children), _c = _b.next(); !_c.done; _c = _b.next()) {
1853 var p = _c.value;
1854 if (routeReuseStrategy.shouldReuseRoute(p.value.snapshot, child.value)) {
1855 return createNode(routeReuseStrategy, child, p);
1856 }
1857 }
1858 }
1859 catch (e_1_1) { e_1 = { error: e_1_1 }; }
1860 finally {
1861 try {
1862 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1863 }
1864 finally { if (e_1) throw e_1.error; }
1865 }
1866 return createNode(routeReuseStrategy, child);
1867 });
1868}
1869function createActivatedRoute(c) {
1870 return new ActivatedRoute(new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams), new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
1871}
1872
1873/**
1874 * @license
1875 * Copyright Google Inc. All Rights Reserved.
1876 *
1877 * Use of this source code is governed by an MIT-style license that can be
1878 * found in the LICENSE file at https://angular.io/license
1879 */
1880function createUrlTree(route, urlTree, commands, queryParams, fragment) {
1881 if (commands.length === 0) {
1882 return tree(urlTree.root, urlTree.root, urlTree, queryParams, fragment);
1883 }
1884 var nav = computeNavigation(commands);
1885 if (nav.toRoot()) {
1886 return tree(urlTree.root, new UrlSegmentGroup([], {}), urlTree, queryParams, fragment);
1887 }
1888 var startingPosition = findStartingPosition(nav, urlTree, route);
1889 var segmentGroup = startingPosition.processChildren ?
1890 updateSegmentGroupChildren(startingPosition.segmentGroup, startingPosition.index, nav.commands) :
1891 updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
1892 return tree(startingPosition.segmentGroup, segmentGroup, urlTree, queryParams, fragment);
1893}
1894function isMatrixParams(command) {
1895 return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
1896}
1897function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
1898 var qp = {};
1899 if (queryParams) {
1900 forEach(queryParams, function (value, name) {
1901 qp[name] = Array.isArray(value) ? value.map(function (v) { return "" + v; }) : "" + value;
1902 });
1903 }
1904 if (urlTree.root === oldSegmentGroup) {
1905 return new UrlTree(newSegmentGroup, qp, fragment);
1906 }
1907 return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment);
1908}
1909function replaceSegment(current, oldSegment, newSegment) {
1910 var children = {};
1911 forEach(current.children, function (c, outletName) {
1912 if (c === oldSegment) {
1913 children[outletName] = newSegment;
1914 }
1915 else {
1916 children[outletName] = replaceSegment(c, oldSegment, newSegment);
1917 }
1918 });
1919 return new UrlSegmentGroup(current.segments, children);
1920}
1921var Navigation = /** @class */ (function () {
1922 function Navigation(isAbsolute, numberOfDoubleDots, commands) {
1923 this.isAbsolute = isAbsolute;
1924 this.numberOfDoubleDots = numberOfDoubleDots;
1925 this.commands = commands;
1926 if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
1927 throw new Error('Root segment cannot have matrix parameters');
1928 }
1929 var cmdWithOutlet = commands.find(function (c) { return typeof c === 'object' && c != null && c.outlets; });
1930 if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
1931 throw new Error('{outlets:{}} has to be the last command');
1932 }
1933 }
1934 Navigation.prototype.toRoot = function () {
1935 return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/';
1936 };
1937 return Navigation;
1938}());
1939/** Transforms commands to a normalized `Navigation` */
1940function computeNavigation(commands) {
1941 if ((typeof commands[0] === 'string') && commands.length === 1 && commands[0] === '/') {
1942 return new Navigation(true, 0, commands);
1943 }
1944 var numberOfDoubleDots = 0;
1945 var isAbsolute = false;
1946 var res = commands.reduce(function (res, cmd, cmdIdx) {
1947 if (typeof cmd === 'object' && cmd != null) {
1948 if (cmd.outlets) {
1949 var outlets_1 = {};
1950 forEach(cmd.outlets, function (commands, name) {
1951 outlets_1[name] = typeof commands === 'string' ? commands.split('/') : commands;
1952 });
1953 return __spread(res, [{ outlets: outlets_1 }]);
1954 }
1955 if (cmd.segmentPath) {
1956 return __spread(res, [cmd.segmentPath]);
1957 }
1958 }
1959 if (!(typeof cmd === 'string')) {
1960 return __spread(res, [cmd]);
1961 }
1962 if (cmdIdx === 0) {
1963 cmd.split('/').forEach(function (urlPart, partIndex) {
1964 if (partIndex == 0 && urlPart === '.') ;
1965 else if (partIndex == 0 && urlPart === '') { // '/a'
1966 isAbsolute = true;
1967 }
1968 else if (urlPart === '..') { // '../a'
1969 numberOfDoubleDots++;
1970 }
1971 else if (urlPart != '') {
1972 res.push(urlPart);
1973 }
1974 });
1975 return res;
1976 }
1977 return __spread(res, [cmd]);
1978 }, []);
1979 return new Navigation(isAbsolute, numberOfDoubleDots, res);
1980}
1981var Position = /** @class */ (function () {
1982 function Position(segmentGroup, processChildren, index) {
1983 this.segmentGroup = segmentGroup;
1984 this.processChildren = processChildren;
1985 this.index = index;
1986 }
1987 return Position;
1988}());
1989function findStartingPosition(nav, tree, route) {
1990 if (nav.isAbsolute) {
1991 return new Position(tree.root, true, 0);
1992 }
1993 if (route.snapshot._lastPathIndex === -1) {
1994 return new Position(route.snapshot._urlSegment, true, 0);
1995 }
1996 var modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
1997 var index = route.snapshot._lastPathIndex + modifier;
1998 return createPositionApplyingDoubleDots(route.snapshot._urlSegment, index, nav.numberOfDoubleDots);
1999}
2000function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
2001 var g = group;
2002 var ci = index;
2003 var dd = numberOfDoubleDots;
2004 while (dd > ci) {
2005 dd -= ci;
2006 g = g.parent;
2007 if (!g) {
2008 throw new Error('Invalid number of \'../\'');
2009 }
2010 ci = g.segments.length;
2011 }
2012 return new Position(g, false, ci - dd);
2013}
2014function getPath(command) {
2015 if (typeof command === 'object' && command != null && command.outlets) {
2016 return command.outlets[PRIMARY_OUTLET];
2017 }
2018 return "" + command;
2019}
2020function getOutlets(commands) {
2021 var _a, _b;
2022 if (!(typeof commands[0] === 'object'))
2023 return _a = {}, _a[PRIMARY_OUTLET] = commands, _a;
2024 if (commands[0].outlets === undefined)
2025 return _b = {}, _b[PRIMARY_OUTLET] = commands, _b;
2026 return commands[0].outlets;
2027}
2028function updateSegmentGroup(segmentGroup, startIndex, commands) {
2029 if (!segmentGroup) {
2030 segmentGroup = new UrlSegmentGroup([], {});
2031 }
2032 if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
2033 return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
2034 }
2035 var m = prefixedWith(segmentGroup, startIndex, commands);
2036 var slicedCommands = commands.slice(m.commandIndex);
2037 if (m.match && m.pathIndex < segmentGroup.segments.length) {
2038 var g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
2039 g.children[PRIMARY_OUTLET] =
2040 new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
2041 return updateSegmentGroupChildren(g, 0, slicedCommands);
2042 }
2043 else if (m.match && slicedCommands.length === 0) {
2044 return new UrlSegmentGroup(segmentGroup.segments, {});
2045 }
2046 else if (m.match && !segmentGroup.hasChildren()) {
2047 return createNewSegmentGroup(segmentGroup, startIndex, commands);
2048 }
2049 else if (m.match) {
2050 return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
2051 }
2052 else {
2053 return createNewSegmentGroup(segmentGroup, startIndex, commands);
2054 }
2055}
2056function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
2057 if (commands.length === 0) {
2058 return new UrlSegmentGroup(segmentGroup.segments, {});
2059 }
2060 else {
2061 var outlets_2 = getOutlets(commands);
2062 var children_1 = {};
2063 forEach(outlets_2, function (commands, outlet) {
2064 if (commands !== null) {
2065 children_1[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
2066 }
2067 });
2068 forEach(segmentGroup.children, function (child, childOutlet) {
2069 if (outlets_2[childOutlet] === undefined) {
2070 children_1[childOutlet] = child;
2071 }
2072 });
2073 return new UrlSegmentGroup(segmentGroup.segments, children_1);
2074 }
2075}
2076function prefixedWith(segmentGroup, startIndex, commands) {
2077 var currentCommandIndex = 0;
2078 var currentPathIndex = startIndex;
2079 var noMatch = { match: false, pathIndex: 0, commandIndex: 0 };
2080 while (currentPathIndex < segmentGroup.segments.length) {
2081 if (currentCommandIndex >= commands.length)
2082 return noMatch;
2083 var path = segmentGroup.segments[currentPathIndex];
2084 var curr = getPath(commands[currentCommandIndex]);
2085 var next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
2086 if (currentPathIndex > 0 && curr === undefined)
2087 break;
2088 if (curr && next && (typeof next === 'object') && next.outlets === undefined) {
2089 if (!compare(curr, next, path))
2090 return noMatch;
2091 currentCommandIndex += 2;
2092 }
2093 else {
2094 if (!compare(curr, {}, path))
2095 return noMatch;
2096 currentCommandIndex++;
2097 }
2098 currentPathIndex++;
2099 }
2100 return { match: true, pathIndex: currentPathIndex, commandIndex: currentCommandIndex };
2101}
2102function createNewSegmentGroup(segmentGroup, startIndex, commands) {
2103 var paths = segmentGroup.segments.slice(0, startIndex);
2104 var i = 0;
2105 while (i < commands.length) {
2106 if (typeof commands[i] === 'object' && commands[i].outlets !== undefined) {
2107 var children = createNewSegmentChildren(commands[i].outlets);
2108 return new UrlSegmentGroup(paths, children);
2109 }
2110 // if we start with an object literal, we need to reuse the path part from the segment
2111 if (i === 0 && isMatrixParams(commands[0])) {
2112 var p = segmentGroup.segments[startIndex];
2113 paths.push(new UrlSegment(p.path, commands[0]));
2114 i++;
2115 continue;
2116 }
2117 var curr = getPath(commands[i]);
2118 var next = (i < commands.length - 1) ? commands[i + 1] : null;
2119 if (curr && next && isMatrixParams(next)) {
2120 paths.push(new UrlSegment(curr, stringify(next)));
2121 i += 2;
2122 }
2123 else {
2124 paths.push(new UrlSegment(curr, {}));
2125 i++;
2126 }
2127 }
2128 return new UrlSegmentGroup(paths, {});
2129}
2130function createNewSegmentChildren(outlets) {
2131 var children = {};
2132 forEach(outlets, function (commands, outlet) {
2133 if (commands !== null) {
2134 children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
2135 }
2136 });
2137 return children;
2138}
2139function stringify(params) {
2140 var res = {};
2141 forEach(params, function (v, k) { return res[k] = "" + v; });
2142 return res;
2143}
2144function compare(path, params, segment) {
2145 return path == segment.path && shallowEqual(params, segment.parameters);
2146}
2147
2148/**
2149 * @license
2150 * Copyright Google Inc. All Rights Reserved.
2151 *
2152 * Use of this source code is governed by an MIT-style license that can be
2153 * found in the LICENSE file at https://angular.io/license
2154 */
2155var activateRoutes = function (rootContexts, routeReuseStrategy, forwardEvent) {
2156 return map(function (t) {
2157 new ActivateRoutes(routeReuseStrategy, t.targetRouterState, t.currentRouterState, forwardEvent)
2158 .activate(rootContexts);
2159 return t;
2160 });
2161};
2162var ActivateRoutes = /** @class */ (function () {
2163 function ActivateRoutes(routeReuseStrategy, futureState, currState, forwardEvent) {
2164 this.routeReuseStrategy = routeReuseStrategy;
2165 this.futureState = futureState;
2166 this.currState = currState;
2167 this.forwardEvent = forwardEvent;
2168 }
2169 ActivateRoutes.prototype.activate = function (parentContexts) {
2170 var futureRoot = this.futureState._root;
2171 var currRoot = this.currState ? this.currState._root : null;
2172 this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
2173 advanceActivatedRoute(this.futureState.root);
2174 this.activateChildRoutes(futureRoot, currRoot, parentContexts);
2175 };
2176 // De-activate the child route that are not re-used for the future state
2177 ActivateRoutes.prototype.deactivateChildRoutes = function (futureNode, currNode, contexts) {
2178 var _this = this;
2179 var children = nodeChildrenAsMap(currNode);
2180 // Recurse on the routes active in the future state to de-activate deeper children
2181 futureNode.children.forEach(function (futureChild) {
2182 var childOutletName = futureChild.value.outlet;
2183 _this.deactivateRoutes(futureChild, children[childOutletName], contexts);
2184 delete children[childOutletName];
2185 });
2186 // De-activate the routes that will not be re-used
2187 forEach(children, function (v, childName) {
2188 _this.deactivateRouteAndItsChildren(v, contexts);
2189 });
2190 };
2191 ActivateRoutes.prototype.deactivateRoutes = function (futureNode, currNode, parentContext) {
2192 var future = futureNode.value;
2193 var curr = currNode ? currNode.value : null;
2194 if (future === curr) {
2195 // Reusing the node, check to see if the children need to be de-activated
2196 if (future.component) {
2197 // If we have a normal route, we need to go through an outlet.
2198 var context = parentContext.getContext(future.outlet);
2199 if (context) {
2200 this.deactivateChildRoutes(futureNode, currNode, context.children);
2201 }
2202 }
2203 else {
2204 // if we have a componentless route, we recurse but keep the same outlet map.
2205 this.deactivateChildRoutes(futureNode, currNode, parentContext);
2206 }
2207 }
2208 else {
2209 if (curr) {
2210 // Deactivate the current route which will not be re-used
2211 this.deactivateRouteAndItsChildren(currNode, parentContext);
2212 }
2213 }
2214 };
2215 ActivateRoutes.prototype.deactivateRouteAndItsChildren = function (route, parentContexts) {
2216 if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
2217 this.detachAndStoreRouteSubtree(route, parentContexts);
2218 }
2219 else {
2220 this.deactivateRouteAndOutlet(route, parentContexts);
2221 }
2222 };
2223 ActivateRoutes.prototype.detachAndStoreRouteSubtree = function (route, parentContexts) {
2224 var context = parentContexts.getContext(route.value.outlet);
2225 if (context && context.outlet) {
2226 var componentRef = context.outlet.detach();
2227 var contexts = context.children.onOutletDeactivated();
2228 this.routeReuseStrategy.store(route.value.snapshot, { componentRef: componentRef, route: route, contexts: contexts });
2229 }
2230 };
2231 ActivateRoutes.prototype.deactivateRouteAndOutlet = function (route, parentContexts) {
2232 var _this = this;
2233 var context = parentContexts.getContext(route.value.outlet);
2234 if (context) {
2235 var children = nodeChildrenAsMap(route);
2236 var contexts_1 = route.value.component ? context.children : parentContexts;
2237 forEach(children, function (v, k) { return _this.deactivateRouteAndItsChildren(v, contexts_1); });
2238 if (context.outlet) {
2239 // Destroy the component
2240 context.outlet.deactivate();
2241 // Destroy the contexts for all the outlets that were in the component
2242 context.children.onOutletDeactivated();
2243 }
2244 }
2245 };
2246 ActivateRoutes.prototype.activateChildRoutes = function (futureNode, currNode, contexts) {
2247 var _this = this;
2248 var children = nodeChildrenAsMap(currNode);
2249 futureNode.children.forEach(function (c) {
2250 _this.activateRoutes(c, children[c.value.outlet], contexts);
2251 _this.forwardEvent(new ActivationEnd(c.value.snapshot));
2252 });
2253 if (futureNode.children.length) {
2254 this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
2255 }
2256 };
2257 ActivateRoutes.prototype.activateRoutes = function (futureNode, currNode, parentContexts) {
2258 var future = futureNode.value;
2259 var curr = currNode ? currNode.value : null;
2260 advanceActivatedRoute(future);
2261 // reusing the node
2262 if (future === curr) {
2263 if (future.component) {
2264 // If we have a normal route, we need to go through an outlet.
2265 var context = parentContexts.getOrCreateContext(future.outlet);
2266 this.activateChildRoutes(futureNode, currNode, context.children);
2267 }
2268 else {
2269 // if we have a componentless route, we recurse but keep the same outlet map.
2270 this.activateChildRoutes(futureNode, currNode, parentContexts);
2271 }
2272 }
2273 else {
2274 if (future.component) {
2275 // if we have a normal route, we need to place the component into the outlet and recurse.
2276 var context = parentContexts.getOrCreateContext(future.outlet);
2277 if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
2278 var stored = this.routeReuseStrategy.retrieve(future.snapshot);
2279 this.routeReuseStrategy.store(future.snapshot, null);
2280 context.children.onOutletReAttached(stored.contexts);
2281 context.attachRef = stored.componentRef;
2282 context.route = stored.route.value;
2283 if (context.outlet) {
2284 // Attach right away when the outlet has already been instantiated
2285 // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
2286 context.outlet.attach(stored.componentRef, stored.route.value);
2287 }
2288 advanceActivatedRouteNodeAndItsChildren(stored.route);
2289 }
2290 else {
2291 var config = parentLoadedConfig(future.snapshot);
2292 var cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
2293 context.attachRef = null;
2294 context.route = future;
2295 context.resolver = cmpFactoryResolver;
2296 if (context.outlet) {
2297 // Activate the outlet when it has already been instantiated
2298 // Otherwise it will get activated from its `ngOnInit` when instantiated
2299 context.outlet.activateWith(future, cmpFactoryResolver);
2300 }
2301 this.activateChildRoutes(futureNode, null, context.children);
2302 }
2303 }
2304 else {
2305 // if we have a componentless route, we recurse but keep the same outlet map.
2306 this.activateChildRoutes(futureNode, null, parentContexts);
2307 }
2308 }
2309 };
2310 return ActivateRoutes;
2311}());
2312function advanceActivatedRouteNodeAndItsChildren(node) {
2313 advanceActivatedRoute(node.value);
2314 node.children.forEach(advanceActivatedRouteNodeAndItsChildren);
2315}
2316function parentLoadedConfig(snapshot) {
2317 for (var s = snapshot.parent; s; s = s.parent) {
2318 var route = s.routeConfig;
2319 if (route && route._loadedConfig)
2320 return route._loadedConfig;
2321 if (route && route.component)
2322 return null;
2323 }
2324 return null;
2325}
2326
2327/**
2328 * @license
2329 * Copyright Google Inc. All Rights Reserved.
2330 *
2331 * Use of this source code is governed by an MIT-style license that can be
2332 * found in the LICENSE file at https://angular.io/license
2333 */
2334/**
2335 * Simple function check, but generic so type inference will flow. Example:
2336 *
2337 * function product(a: number, b: number) {
2338 * return a * b;
2339 * }
2340 *
2341 * if (isFunction<product>(fn)) {
2342 * return fn(1, 2);
2343 * } else {
2344 * throw "Must provide the `product` function";
2345 * }
2346 */
2347function isFunction(v) {
2348 return typeof v === 'function';
2349}
2350function isBoolean(v) {
2351 return typeof v === 'boolean';
2352}
2353function isUrlTree(v) {
2354 return v instanceof UrlTree;
2355}
2356function isCanLoad(guard) {
2357 return guard && isFunction(guard.canLoad);
2358}
2359function isCanActivate(guard) {
2360 return guard && isFunction(guard.canActivate);
2361}
2362function isCanActivateChild(guard) {
2363 return guard && isFunction(guard.canActivateChild);
2364}
2365function isCanDeactivate(guard) {
2366 return guard && isFunction(guard.canDeactivate);
2367}
2368
2369/**
2370 * @license
2371 * Copyright Google Inc. All Rights Reserved.
2372 *
2373 * Use of this source code is governed by an MIT-style license that can be
2374 * found in the LICENSE file at https://angular.io/license
2375 */
2376var NoMatch = /** @class */ (function () {
2377 function NoMatch(segmentGroup) {
2378 this.segmentGroup = segmentGroup || null;
2379 }
2380 return NoMatch;
2381}());
2382var AbsoluteRedirect = /** @class */ (function () {
2383 function AbsoluteRedirect(urlTree) {
2384 this.urlTree = urlTree;
2385 }
2386 return AbsoluteRedirect;
2387}());
2388function noMatch(segmentGroup) {
2389 return new Observable(function (obs) { return obs.error(new NoMatch(segmentGroup)); });
2390}
2391function absoluteRedirect(newTree) {
2392 return new Observable(function (obs) { return obs.error(new AbsoluteRedirect(newTree)); });
2393}
2394function namedOutletsRedirect(redirectTo) {
2395 return new Observable(function (obs) { return obs.error(new Error("Only absolute redirects can have named outlets. redirectTo: '" + redirectTo + "'")); });
2396}
2397function canLoadFails(route) {
2398 return new Observable(function (obs) { return obs.error(navigationCancelingError("Cannot load children because the guard of the route \"path: '" + route.path + "'\" returned false")); });
2399}
2400/**
2401 * Returns the `UrlTree` with the redirection applied.
2402 *
2403 * Lazy modules are loaded along the way.
2404 */
2405function applyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config) {
2406 return new ApplyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config).apply();
2407}
2408var ApplyRedirects = /** @class */ (function () {
2409 function ApplyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config) {
2410 this.configLoader = configLoader;
2411 this.urlSerializer = urlSerializer;
2412 this.urlTree = urlTree;
2413 this.config = config;
2414 this.allowRedirects = true;
2415 this.ngModule = moduleInjector.get(NgModuleRef);
2416 }
2417 ApplyRedirects.prototype.apply = function () {
2418 var _this = this;
2419 var expanded$ = this.expandSegmentGroup(this.ngModule, this.config, this.urlTree.root, PRIMARY_OUTLET);
2420 var urlTrees$ = expanded$.pipe(map(function (rootSegmentGroup) { return _this.createUrlTree(rootSegmentGroup, _this.urlTree.queryParams, _this.urlTree.fragment); }));
2421 return urlTrees$.pipe(catchError(function (e) {
2422 if (e instanceof AbsoluteRedirect) {
2423 // after an absolute redirect we do not apply any more redirects!
2424 _this.allowRedirects = false;
2425 // we need to run matching, so we can fetch all lazy-loaded modules
2426 return _this.match(e.urlTree);
2427 }
2428 if (e instanceof NoMatch) {
2429 throw _this.noMatchError(e);
2430 }
2431 throw e;
2432 }));
2433 };
2434 ApplyRedirects.prototype.match = function (tree) {
2435 var _this = this;
2436 var expanded$ = this.expandSegmentGroup(this.ngModule, this.config, tree.root, PRIMARY_OUTLET);
2437 var mapped$ = expanded$.pipe(map(function (rootSegmentGroup) {
2438 return _this.createUrlTree(rootSegmentGroup, tree.queryParams, tree.fragment);
2439 }));
2440 return mapped$.pipe(catchError(function (e) {
2441 if (e instanceof NoMatch) {
2442 throw _this.noMatchError(e);
2443 }
2444 throw e;
2445 }));
2446 };
2447 ApplyRedirects.prototype.noMatchError = function (e) {
2448 return new Error("Cannot match any routes. URL Segment: '" + e.segmentGroup + "'");
2449 };
2450 ApplyRedirects.prototype.createUrlTree = function (rootCandidate, queryParams, fragment) {
2451 var _a;
2452 var root = rootCandidate.segments.length > 0 ?
2453 new UrlSegmentGroup([], (_a = {}, _a[PRIMARY_OUTLET] = rootCandidate, _a)) :
2454 rootCandidate;
2455 return new UrlTree(root, queryParams, fragment);
2456 };
2457 ApplyRedirects.prototype.expandSegmentGroup = function (ngModule, routes, segmentGroup, outlet) {
2458 if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
2459 return this.expandChildren(ngModule, routes, segmentGroup)
2460 .pipe(map(function (children) { return new UrlSegmentGroup([], children); }));
2461 }
2462 return this.expandSegment(ngModule, segmentGroup, routes, segmentGroup.segments, outlet, true);
2463 };
2464 // Recursively expand segment groups for all the child outlets
2465 ApplyRedirects.prototype.expandChildren = function (ngModule, routes, segmentGroup) {
2466 var _this = this;
2467 return waitForMap(segmentGroup.children, function (childOutlet, child) { return _this.expandSegmentGroup(ngModule, routes, child, childOutlet); });
2468 };
2469 ApplyRedirects.prototype.expandSegment = function (ngModule, segmentGroup, routes, segments, outlet, allowRedirects) {
2470 var _this = this;
2471 return of.apply(void 0, __spread(routes)).pipe(map(function (r) {
2472 var expanded$ = _this.expandSegmentAgainstRoute(ngModule, segmentGroup, routes, r, segments, outlet, allowRedirects);
2473 return expanded$.pipe(catchError(function (e) {
2474 if (e instanceof NoMatch) {
2475 // TODO(i): this return type doesn't match the declared Observable<UrlSegmentGroup> -
2476 // talk to Jason
2477 return of(null);
2478 }
2479 throw e;
2480 }));
2481 }), concatAll(), first(function (s) { return !!s; }), catchError(function (e, _) {
2482 if (e instanceof EmptyError || e.name === 'EmptyError') {
2483 if (_this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
2484 return of(new UrlSegmentGroup([], {}));
2485 }
2486 throw new NoMatch(segmentGroup);
2487 }
2488 throw e;
2489 }));
2490 };
2491 ApplyRedirects.prototype.noLeftoversInUrl = function (segmentGroup, segments, outlet) {
2492 return segments.length === 0 && !segmentGroup.children[outlet];
2493 };
2494 ApplyRedirects.prototype.expandSegmentAgainstRoute = function (ngModule, segmentGroup, routes, route, paths, outlet, allowRedirects) {
2495 if (getOutlet(route) !== outlet) {
2496 return noMatch(segmentGroup);
2497 }
2498 if (route.redirectTo === undefined) {
2499 return this.matchSegmentAgainstRoute(ngModule, segmentGroup, route, paths);
2500 }
2501 if (allowRedirects && this.allowRedirects) {
2502 return this.expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, paths, outlet);
2503 }
2504 return noMatch(segmentGroup);
2505 };
2506 ApplyRedirects.prototype.expandSegmentAgainstRouteUsingRedirect = function (ngModule, segmentGroup, routes, route, segments, outlet) {
2507 if (route.path === '**') {
2508 return this.expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet);
2509 }
2510 return this.expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet);
2511 };
2512 ApplyRedirects.prototype.expandWildCardWithParamsAgainstRouteUsingRedirect = function (ngModule, routes, route, outlet) {
2513 var _this = this;
2514 var newTree = this.applyRedirectCommands([], route.redirectTo, {});
2515 if (route.redirectTo.startsWith('/')) {
2516 return absoluteRedirect(newTree);
2517 }
2518 return this.lineralizeSegments(route, newTree).pipe(mergeMap(function (newSegments) {
2519 var group = new UrlSegmentGroup(newSegments, {});
2520 return _this.expandSegment(ngModule, group, routes, newSegments, outlet, false);
2521 }));
2522 };
2523 ApplyRedirects.prototype.expandRegularSegmentAgainstRouteUsingRedirect = function (ngModule, segmentGroup, routes, route, segments, outlet) {
2524 var _this = this;
2525 var _a = match(segmentGroup, route, segments), matched = _a.matched, consumedSegments = _a.consumedSegments, lastChild = _a.lastChild, positionalParamSegments = _a.positionalParamSegments;
2526 if (!matched)
2527 return noMatch(segmentGroup);
2528 var newTree = this.applyRedirectCommands(consumedSegments, route.redirectTo, positionalParamSegments);
2529 if (route.redirectTo.startsWith('/')) {
2530 return absoluteRedirect(newTree);
2531 }
2532 return this.lineralizeSegments(route, newTree).pipe(mergeMap(function (newSegments) {
2533 return _this.expandSegment(ngModule, segmentGroup, routes, newSegments.concat(segments.slice(lastChild)), outlet, false);
2534 }));
2535 };
2536 ApplyRedirects.prototype.matchSegmentAgainstRoute = function (ngModule, rawSegmentGroup, route, segments) {
2537 var _this = this;
2538 if (route.path === '**') {
2539 if (route.loadChildren) {
2540 return this.configLoader.load(ngModule.injector, route)
2541 .pipe(map(function (cfg) {
2542 route._loadedConfig = cfg;
2543 return new UrlSegmentGroup(segments, {});
2544 }));
2545 }
2546 return of(new UrlSegmentGroup(segments, {}));
2547 }
2548 var _a = match(rawSegmentGroup, route, segments), matched = _a.matched, consumedSegments = _a.consumedSegments, lastChild = _a.lastChild;
2549 if (!matched)
2550 return noMatch(rawSegmentGroup);
2551 var rawSlicedSegments = segments.slice(lastChild);
2552 var childConfig$ = this.getChildConfig(ngModule, route, segments);
2553 return childConfig$.pipe(mergeMap(function (routerConfig) {
2554 var childModule = routerConfig.module;
2555 var childConfig = routerConfig.routes;
2556 var _a = split(rawSegmentGroup, consumedSegments, rawSlicedSegments, childConfig), segmentGroup = _a.segmentGroup, slicedSegments = _a.slicedSegments;
2557 if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
2558 var expanded$_1 = _this.expandChildren(childModule, childConfig, segmentGroup);
2559 return expanded$_1.pipe(map(function (children) { return new UrlSegmentGroup(consumedSegments, children); }));
2560 }
2561 if (childConfig.length === 0 && slicedSegments.length === 0) {
2562 return of(new UrlSegmentGroup(consumedSegments, {}));
2563 }
2564 var expanded$ = _this.expandSegment(childModule, segmentGroup, childConfig, slicedSegments, PRIMARY_OUTLET, true);
2565 return expanded$.pipe(map(function (cs) {
2566 return new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children);
2567 }));
2568 }));
2569 };
2570 ApplyRedirects.prototype.getChildConfig = function (ngModule, route, segments) {
2571 var _this = this;
2572 if (route.children) {
2573 // The children belong to the same module
2574 return of(new LoadedRouterConfig(route.children, ngModule));
2575 }
2576 if (route.loadChildren) {
2577 // lazy children belong to the loaded module
2578 if (route._loadedConfig !== undefined) {
2579 return of(route._loadedConfig);
2580 }
2581 return runCanLoadGuard(ngModule.injector, route, segments)
2582 .pipe(mergeMap(function (shouldLoad) {
2583 if (shouldLoad) {
2584 return _this.configLoader.load(ngModule.injector, route)
2585 .pipe(map(function (cfg) {
2586 route._loadedConfig = cfg;
2587 return cfg;
2588 }));
2589 }
2590 return canLoadFails(route);
2591 }));
2592 }
2593 return of(new LoadedRouterConfig([], ngModule));
2594 };
2595 ApplyRedirects.prototype.lineralizeSegments = function (route, urlTree) {
2596 var res = [];
2597 var c = urlTree.root;
2598 while (true) {
2599 res = res.concat(c.segments);
2600 if (c.numberOfChildren === 0) {
2601 return of(res);
2602 }
2603 if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
2604 return namedOutletsRedirect(route.redirectTo);
2605 }
2606 c = c.children[PRIMARY_OUTLET];
2607 }
2608 };
2609 ApplyRedirects.prototype.applyRedirectCommands = function (segments, redirectTo, posParams) {
2610 return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
2611 };
2612 ApplyRedirects.prototype.applyRedirectCreatreUrlTree = function (redirectTo, urlTree, segments, posParams) {
2613 var newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
2614 return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
2615 };
2616 ApplyRedirects.prototype.createQueryParams = function (redirectToParams, actualParams) {
2617 var res = {};
2618 forEach(redirectToParams, function (v, k) {
2619 var copySourceValue = typeof v === 'string' && v.startsWith(':');
2620 if (copySourceValue) {
2621 var sourceName = v.substring(1);
2622 res[k] = actualParams[sourceName];
2623 }
2624 else {
2625 res[k] = v;
2626 }
2627 });
2628 return res;
2629 };
2630 ApplyRedirects.prototype.createSegmentGroup = function (redirectTo, group, segments, posParams) {
2631 var _this = this;
2632 var updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
2633 var children = {};
2634 forEach(group.children, function (child, name) {
2635 children[name] = _this.createSegmentGroup(redirectTo, child, segments, posParams);
2636 });
2637 return new UrlSegmentGroup(updatedSegments, children);
2638 };
2639 ApplyRedirects.prototype.createSegments = function (redirectTo, redirectToSegments, actualSegments, posParams) {
2640 var _this = this;
2641 return redirectToSegments.map(function (s) { return s.path.startsWith(':') ? _this.findPosParam(redirectTo, s, posParams) :
2642 _this.findOrReturn(s, actualSegments); });
2643 };
2644 ApplyRedirects.prototype.findPosParam = function (redirectTo, redirectToUrlSegment, posParams) {
2645 var pos = posParams[redirectToUrlSegment.path.substring(1)];
2646 if (!pos)
2647 throw new Error("Cannot redirect to '" + redirectTo + "'. Cannot find '" + redirectToUrlSegment.path + "'.");
2648 return pos;
2649 };
2650 ApplyRedirects.prototype.findOrReturn = function (redirectToUrlSegment, actualSegments) {
2651 var e_1, _a;
2652 var idx = 0;
2653 try {
2654 for (var actualSegments_1 = __values(actualSegments), actualSegments_1_1 = actualSegments_1.next(); !actualSegments_1_1.done; actualSegments_1_1 = actualSegments_1.next()) {
2655 var s = actualSegments_1_1.value;
2656 if (s.path === redirectToUrlSegment.path) {
2657 actualSegments.splice(idx);
2658 return s;
2659 }
2660 idx++;
2661 }
2662 }
2663 catch (e_1_1) { e_1 = { error: e_1_1 }; }
2664 finally {
2665 try {
2666 if (actualSegments_1_1 && !actualSegments_1_1.done && (_a = actualSegments_1.return)) _a.call(actualSegments_1);
2667 }
2668 finally { if (e_1) throw e_1.error; }
2669 }
2670 return redirectToUrlSegment;
2671 };
2672 return ApplyRedirects;
2673}());
2674function runCanLoadGuard(moduleInjector, route, segments) {
2675 var canLoad = route.canLoad;
2676 if (!canLoad || canLoad.length === 0)
2677 return of(true);
2678 var obs = from(canLoad).pipe(map(function (injectionToken) {
2679 var guard = moduleInjector.get(injectionToken);
2680 var guardVal;
2681 if (isCanLoad(guard)) {
2682 guardVal = guard.canLoad(route, segments);
2683 }
2684 else if (isFunction(guard)) {
2685 guardVal = guard(route, segments);
2686 }
2687 else {
2688 throw new Error('Invalid CanLoad guard');
2689 }
2690 return wrapIntoObservable(guardVal);
2691 }));
2692 return obs.pipe(concatAll(), every(function (result) { return result === true; }));
2693}
2694function match(segmentGroup, route, segments) {
2695 if (route.path === '') {
2696 if ((route.pathMatch === 'full') && (segmentGroup.hasChildren() || segments.length > 0)) {
2697 return { matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
2698 }
2699 return { matched: true, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
2700 }
2701 var matcher = route.matcher || defaultUrlMatcher;
2702 var res = matcher(segments, segmentGroup, route);
2703 if (!res) {
2704 return {
2705 matched: false,
2706 consumedSegments: [],
2707 lastChild: 0,
2708 positionalParamSegments: {},
2709 };
2710 }
2711 return {
2712 matched: true,
2713 consumedSegments: res.consumed,
2714 lastChild: res.consumed.length,
2715 positionalParamSegments: res.posParams,
2716 };
2717}
2718function split(segmentGroup, consumedSegments, slicedSegments, config) {
2719 if (slicedSegments.length > 0 &&
2720 containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, slicedSegments, config)) {
2721 var s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptySegments(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
2722 return { segmentGroup: mergeTrivialChildren(s), slicedSegments: [] };
2723 }
2724 if (slicedSegments.length === 0 &&
2725 containsEmptyPathRedirects(segmentGroup, slicedSegments, config)) {
2726 var s = new UrlSegmentGroup(segmentGroup.segments, addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children));
2727 return { segmentGroup: mergeTrivialChildren(s), slicedSegments: slicedSegments };
2728 }
2729 return { segmentGroup: segmentGroup, slicedSegments: slicedSegments };
2730}
2731function mergeTrivialChildren(s) {
2732 if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
2733 var c = s.children[PRIMARY_OUTLET];
2734 return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
2735 }
2736 return s;
2737}
2738function addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) {
2739 var e_2, _a;
2740 var res = {};
2741 try {
2742 for (var routes_1 = __values(routes), routes_1_1 = routes_1.next(); !routes_1_1.done; routes_1_1 = routes_1.next()) {
2743 var r = routes_1_1.value;
2744 if (isEmptyPathRedirect(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
2745 res[getOutlet(r)] = new UrlSegmentGroup([], {});
2746 }
2747 }
2748 }
2749 catch (e_2_1) { e_2 = { error: e_2_1 }; }
2750 finally {
2751 try {
2752 if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
2753 }
2754 finally { if (e_2) throw e_2.error; }
2755 }
2756 return __assign({}, children, res);
2757}
2758function createChildrenForEmptySegments(routes, primarySegmentGroup) {
2759 var e_3, _a;
2760 var res = {};
2761 res[PRIMARY_OUTLET] = primarySegmentGroup;
2762 try {
2763 for (var routes_2 = __values(routes), routes_2_1 = routes_2.next(); !routes_2_1.done; routes_2_1 = routes_2.next()) {
2764 var r = routes_2_1.value;
2765 if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
2766 res[getOutlet(r)] = new UrlSegmentGroup([], {});
2767 }
2768 }
2769 }
2770 catch (e_3_1) { e_3 = { error: e_3_1 }; }
2771 finally {
2772 try {
2773 if (routes_2_1 && !routes_2_1.done && (_a = routes_2.return)) _a.call(routes_2);
2774 }
2775 finally { if (e_3) throw e_3.error; }
2776 }
2777 return res;
2778}
2779function containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, segments, routes) {
2780 return routes.some(function (r) { return isEmptyPathRedirect(segmentGroup, segments, r) && getOutlet(r) !== PRIMARY_OUTLET; });
2781}
2782function containsEmptyPathRedirects(segmentGroup, segments, routes) {
2783 return routes.some(function (r) { return isEmptyPathRedirect(segmentGroup, segments, r); });
2784}
2785function isEmptyPathRedirect(segmentGroup, segments, r) {
2786 if ((segmentGroup.hasChildren() || segments.length > 0) && r.pathMatch === 'full') {
2787 return false;
2788 }
2789 return r.path === '' && r.redirectTo !== undefined;
2790}
2791function getOutlet(route) {
2792 return route.outlet || PRIMARY_OUTLET;
2793}
2794
2795/**
2796 * @license
2797 * Copyright Google Inc. All Rights Reserved.
2798 *
2799 * Use of this source code is governed by an MIT-style license that can be
2800 * found in the LICENSE file at https://angular.io/license
2801 */
2802function applyRedirects$1(moduleInjector, configLoader, urlSerializer, config) {
2803 return function (source) {
2804 return source.pipe(switchMap(function (t) { return applyRedirects(moduleInjector, configLoader, urlSerializer, t.extractedUrl, config)
2805 .pipe(map(function (urlAfterRedirects) { return (__assign({}, t, { urlAfterRedirects: urlAfterRedirects })); })); }));
2806 };
2807}
2808
2809/**
2810 * @license
2811 * Copyright Google Inc. All Rights Reserved.
2812 *
2813 * Use of this source code is governed by an MIT-style license that can be
2814 * found in the LICENSE file at https://angular.io/license
2815 */
2816var CanActivate = /** @class */ (function () {
2817 function CanActivate(path) {
2818 this.path = path;
2819 this.route = this.path[this.path.length - 1];
2820 }
2821 return CanActivate;
2822}());
2823var CanDeactivate = /** @class */ (function () {
2824 function CanDeactivate(component, route) {
2825 this.component = component;
2826 this.route = route;
2827 }
2828 return CanDeactivate;
2829}());
2830function getAllRouteGuards(future, curr, parentContexts) {
2831 var futureRoot = future._root;
2832 var currRoot = curr ? curr._root : null;
2833 return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
2834}
2835function getCanActivateChild(p) {
2836 var canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
2837 if (!canActivateChild || canActivateChild.length === 0)
2838 return null;
2839 return { node: p, guards: canActivateChild };
2840}
2841function getToken(token, snapshot, moduleInjector) {
2842 var config = getClosestLoadedConfig(snapshot);
2843 var injector = config ? config.module.injector : moduleInjector;
2844 return injector.get(token);
2845}
2846function getClosestLoadedConfig(snapshot) {
2847 if (!snapshot)
2848 return null;
2849 for (var s = snapshot.parent; s; s = s.parent) {
2850 var route = s.routeConfig;
2851 if (route && route._loadedConfig)
2852 return route._loadedConfig;
2853 }
2854 return null;
2855}
2856function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks) {
2857 if (checks === void 0) { checks = {
2858 canDeactivateChecks: [],
2859 canActivateChecks: []
2860 }; }
2861 var prevChildren = nodeChildrenAsMap(currNode);
2862 // Process the children of the future route
2863 futureNode.children.forEach(function (c) {
2864 getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
2865 delete prevChildren[c.value.outlet];
2866 });
2867 // Process any children left from the current route (not active for the future route)
2868 forEach(prevChildren, function (v, k) {
2869 return deactivateRouteAndItsChildren(v, contexts.getContext(k), checks);
2870 });
2871 return checks;
2872}
2873function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks) {
2874 if (checks === void 0) { checks = {
2875 canDeactivateChecks: [],
2876 canActivateChecks: []
2877 }; }
2878 var future = futureNode.value;
2879 var curr = currNode ? currNode.value : null;
2880 var context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
2881 // reusing the node
2882 if (curr && future.routeConfig === curr.routeConfig) {
2883 var shouldRun = shouldRunGuardsAndResolvers(curr, future, future.routeConfig.runGuardsAndResolvers);
2884 if (shouldRun) {
2885 checks.canActivateChecks.push(new CanActivate(futurePath));
2886 }
2887 else {
2888 // we need to set the data
2889 future.data = curr.data;
2890 future._resolvedData = curr._resolvedData;
2891 }
2892 // If we have a component, we need to go through an outlet.
2893 if (future.component) {
2894 getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
2895 // if we have a componentless route, we recurse but keep the same outlet map.
2896 }
2897 else {
2898 getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
2899 }
2900 if (shouldRun) {
2901 var component = context && context.outlet && context.outlet.component || null;
2902 checks.canDeactivateChecks.push(new CanDeactivate(component, curr));
2903 }
2904 }
2905 else {
2906 if (curr) {
2907 deactivateRouteAndItsChildren(currNode, context, checks);
2908 }
2909 checks.canActivateChecks.push(new CanActivate(futurePath));
2910 // If we have a component, we need to go through an outlet.
2911 if (future.component) {
2912 getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
2913 // if we have a componentless route, we recurse but keep the same outlet map.
2914 }
2915 else {
2916 getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
2917 }
2918 }
2919 return checks;
2920}
2921function shouldRunGuardsAndResolvers(curr, future, mode) {
2922 if (typeof mode === 'function') {
2923 return mode(curr, future);
2924 }
2925 switch (mode) {
2926 case 'pathParamsChange':
2927 return !equalPath(curr.url, future.url);
2928 case 'pathParamsOrQueryParamsChange':
2929 return !equalPath(curr.url, future.url) ||
2930 !shallowEqual(curr.queryParams, future.queryParams);
2931 case 'always':
2932 return true;
2933 case 'paramsOrQueryParamsChange':
2934 return !equalParamsAndUrlSegments(curr, future) ||
2935 !shallowEqual(curr.queryParams, future.queryParams);
2936 case 'paramsChange':
2937 default:
2938 return !equalParamsAndUrlSegments(curr, future);
2939 }
2940}
2941function deactivateRouteAndItsChildren(route, context, checks) {
2942 var children = nodeChildrenAsMap(route);
2943 var r = route.value;
2944 forEach(children, function (node, childName) {
2945 if (!r.component) {
2946 deactivateRouteAndItsChildren(node, context, checks);
2947 }
2948 else if (context) {
2949 deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
2950 }
2951 else {
2952 deactivateRouteAndItsChildren(node, null, checks);
2953 }
2954 });
2955 if (!r.component) {
2956 checks.canDeactivateChecks.push(new CanDeactivate(null, r));
2957 }
2958 else if (context && context.outlet && context.outlet.isActivated) {
2959 checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
2960 }
2961 else {
2962 checks.canDeactivateChecks.push(new CanDeactivate(null, r));
2963 }
2964}
2965
2966/**
2967 * @license
2968 * Copyright Google Inc. All Rights Reserved.
2969 *
2970 * Use of this source code is governed by an MIT-style license that can be
2971 * found in the LICENSE file at https://angular.io/license
2972 */
2973var INITIAL_VALUE = Symbol('INITIAL_VALUE');
2974function prioritizedGuardValue() {
2975 return switchMap(function (obs) {
2976 return combineLatest.apply(void 0, __spread(obs.map(function (o) { return o.pipe(take(1), startWith(INITIAL_VALUE)); }))).pipe(scan(function (acc, list) {
2977 var isPending = false;
2978 return list.reduce(function (innerAcc, val, i) {
2979 if (innerAcc !== INITIAL_VALUE)
2980 return innerAcc;
2981 // Toggle pending flag if any values haven't been set yet
2982 if (val === INITIAL_VALUE)
2983 isPending = true;
2984 // Any other return values are only valid if we haven't yet hit a pending call.
2985 // This guarantees that in the case of a guard at the bottom of the tree that
2986 // returns a redirect, we will wait for the higher priority guard at the top to
2987 // finish before performing the redirect.
2988 if (!isPending) {
2989 // Early return when we hit a `false` value as that should always cancel
2990 // navigation
2991 if (val === false)
2992 return val;
2993 if (i === list.length - 1 || isUrlTree(val)) {
2994 return val;
2995 }
2996 }
2997 return innerAcc;
2998 }, acc);
2999 }, INITIAL_VALUE), filter(function (item) { return item !== INITIAL_VALUE; }), map(function (item) { return isUrlTree(item) ? item : item === true; }), //
3000 take(1));
3001 });
3002}
3003
3004/**
3005 * @license
3006 * Copyright Google Inc. All Rights Reserved.
3007 *
3008 * Use of this source code is governed by an MIT-style license that can be
3009 * found in the LICENSE file at https://angular.io/license
3010 */
3011function checkGuards(moduleInjector, forwardEvent) {
3012 return function (source) {
3013 return source.pipe(mergeMap(function (t) {
3014 var targetSnapshot = t.targetSnapshot, currentSnapshot = t.currentSnapshot, _a = t.guards, canActivateChecks = _a.canActivateChecks, canDeactivateChecks = _a.canDeactivateChecks;
3015 if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
3016 return of(__assign({}, t, { guardsResult: true }));
3017 }
3018 return runCanDeactivateChecks(canDeactivateChecks, targetSnapshot, currentSnapshot, moduleInjector)
3019 .pipe(mergeMap(function (canDeactivate) {
3020 return canDeactivate && isBoolean(canDeactivate) ?
3021 runCanActivateChecks(targetSnapshot, canActivateChecks, moduleInjector, forwardEvent) :
3022 of(canDeactivate);
3023 }), map(function (guardsResult) { return (__assign({}, t, { guardsResult: guardsResult })); }));
3024 }));
3025 };
3026}
3027function runCanDeactivateChecks(checks, futureRSS, currRSS, moduleInjector) {
3028 return from(checks).pipe(mergeMap(function (check) {
3029 return runCanDeactivate(check.component, check.route, currRSS, futureRSS, moduleInjector);
3030 }), first(function (result) { return result !== true; }, true));
3031}
3032function runCanActivateChecks(futureSnapshot, checks, moduleInjector, forwardEvent) {
3033 return from(checks).pipe(concatMap(function (check) {
3034 return from([
3035 fireChildActivationStart(check.route.parent, forwardEvent),
3036 fireActivationStart(check.route, forwardEvent),
3037 runCanActivateChild(futureSnapshot, check.path, moduleInjector),
3038 runCanActivate(futureSnapshot, check.route, moduleInjector)
3039 ])
3040 .pipe(concatAll(), first(function (result) {
3041 return result !== true;
3042 }, true));
3043 }), first(function (result) { return result !== true; }, true));
3044}
3045/**
3046 * This should fire off `ActivationStart` events for each route being activated at this
3047 * level.
3048 * In other words, if you're activating `a` and `b` below, `path` will contain the
3049 * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
3050 * return
3051 * `true` so checks continue to run.
3052 */
3053function fireActivationStart(snapshot, forwardEvent) {
3054 if (snapshot !== null && forwardEvent) {
3055 forwardEvent(new ActivationStart(snapshot));
3056 }
3057 return of(true);
3058}
3059/**
3060 * This should fire off `ChildActivationStart` events for each route being activated at this
3061 * level.
3062 * In other words, if you're activating `a` and `b` below, `path` will contain the
3063 * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
3064 * return
3065 * `true` so checks continue to run.
3066 */
3067function fireChildActivationStart(snapshot, forwardEvent) {
3068 if (snapshot !== null && forwardEvent) {
3069 forwardEvent(new ChildActivationStart(snapshot));
3070 }
3071 return of(true);
3072}
3073function runCanActivate(futureRSS, futureARS, moduleInjector) {
3074 var canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
3075 if (!canActivate || canActivate.length === 0)
3076 return of(true);
3077 var canActivateObservables = canActivate.map(function (c) {
3078 return defer(function () {
3079 var guard = getToken(c, futureARS, moduleInjector);
3080 var observable;
3081 if (isCanActivate(guard)) {
3082 observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
3083 }
3084 else if (isFunction(guard)) {
3085 observable = wrapIntoObservable(guard(futureARS, futureRSS));
3086 }
3087 else {
3088 throw new Error('Invalid CanActivate guard');
3089 }
3090 return observable.pipe(first());
3091 });
3092 });
3093 return of(canActivateObservables).pipe(prioritizedGuardValue());
3094}
3095function runCanActivateChild(futureRSS, path, moduleInjector) {
3096 var futureARS = path[path.length - 1];
3097 var canActivateChildGuards = path.slice(0, path.length - 1)
3098 .reverse()
3099 .map(function (p) { return getCanActivateChild(p); })
3100 .filter(function (_) { return _ !== null; });
3101 var canActivateChildGuardsMapped = canActivateChildGuards.map(function (d) {
3102 return defer(function () {
3103 var guardsMapped = d.guards.map(function (c) {
3104 var guard = getToken(c, d.node, moduleInjector);
3105 var observable;
3106 if (isCanActivateChild(guard)) {
3107 observable = wrapIntoObservable(guard.canActivateChild(futureARS, futureRSS));
3108 }
3109 else if (isFunction(guard)) {
3110 observable = wrapIntoObservable(guard(futureARS, futureRSS));
3111 }
3112 else {
3113 throw new Error('Invalid CanActivateChild guard');
3114 }
3115 return observable.pipe(first());
3116 });
3117 return of(guardsMapped).pipe(prioritizedGuardValue());
3118 });
3119 });
3120 return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
3121}
3122function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector) {
3123 var canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
3124 if (!canDeactivate || canDeactivate.length === 0)
3125 return of(true);
3126 var canDeactivateObservables = canDeactivate.map(function (c) {
3127 var guard = getToken(c, currARS, moduleInjector);
3128 var observable;
3129 if (isCanDeactivate(guard)) {
3130 observable =
3131 wrapIntoObservable(guard.canDeactivate(component, currARS, currRSS, futureRSS));
3132 }
3133 else if (isFunction(guard)) {
3134 observable = wrapIntoObservable(guard(component, currARS, currRSS, futureRSS));
3135 }
3136 else {
3137 throw new Error('Invalid CanDeactivate guard');
3138 }
3139 return observable.pipe(first());
3140 });
3141 return of(canDeactivateObservables).pipe(prioritizedGuardValue());
3142}
3143
3144/**
3145 * @license
3146 * Copyright Google Inc. All Rights Reserved.
3147 *
3148 * Use of this source code is governed by an MIT-style license that can be
3149 * found in the LICENSE file at https://angular.io/license
3150 */
3151var NoMatch$1 = /** @class */ (function () {
3152 function NoMatch() {
3153 }
3154 return NoMatch;
3155}());
3156function recognize(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution) {
3157 if (paramsInheritanceStrategy === void 0) { paramsInheritanceStrategy = 'emptyOnly'; }
3158 if (relativeLinkResolution === void 0) { relativeLinkResolution = 'legacy'; }
3159 return new Recognizer(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution)
3160 .recognize();
3161}
3162var Recognizer = /** @class */ (function () {
3163 function Recognizer(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution) {
3164 this.rootComponentType = rootComponentType;
3165 this.config = config;
3166 this.urlTree = urlTree;
3167 this.url = url;
3168 this.paramsInheritanceStrategy = paramsInheritanceStrategy;
3169 this.relativeLinkResolution = relativeLinkResolution;
3170 }
3171 Recognizer.prototype.recognize = function () {
3172 try {
3173 var rootSegmentGroup = split$1(this.urlTree.root, [], [], this.config, this.relativeLinkResolution).segmentGroup;
3174 var children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET);
3175 var root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(__assign({}, this.urlTree.queryParams)), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
3176 var rootNode = new TreeNode(root, children);
3177 var routeState = new RouterStateSnapshot(this.url, rootNode);
3178 this.inheritParamsAndData(routeState._root);
3179 return of(routeState);
3180 }
3181 catch (e) {
3182 return new Observable(function (obs) { return obs.error(e); });
3183 }
3184 };
3185 Recognizer.prototype.inheritParamsAndData = function (routeNode) {
3186 var _this = this;
3187 var route = routeNode.value;
3188 var i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
3189 route.params = Object.freeze(i.params);
3190 route.data = Object.freeze(i.data);
3191 routeNode.children.forEach(function (n) { return _this.inheritParamsAndData(n); });
3192 };
3193 Recognizer.prototype.processSegmentGroup = function (config, segmentGroup, outlet) {
3194 if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
3195 return this.processChildren(config, segmentGroup);
3196 }
3197 return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
3198 };
3199 Recognizer.prototype.processChildren = function (config, segmentGroup) {
3200 var _this = this;
3201 var children = mapChildrenIntoArray(segmentGroup, function (child, childOutlet) { return _this.processSegmentGroup(config, child, childOutlet); });
3202 checkOutletNameUniqueness(children);
3203 sortActivatedRouteSnapshots(children);
3204 return children;
3205 };
3206 Recognizer.prototype.processSegment = function (config, segmentGroup, segments, outlet) {
3207 var e_1, _a;
3208 try {
3209 for (var config_1 = __values(config), config_1_1 = config_1.next(); !config_1_1.done; config_1_1 = config_1.next()) {
3210 var r = config_1_1.value;
3211 try {
3212 return this.processSegmentAgainstRoute(r, segmentGroup, segments, outlet);
3213 }
3214 catch (e) {
3215 if (!(e instanceof NoMatch$1))
3216 throw e;
3217 }
3218 }
3219 }
3220 catch (e_1_1) { e_1 = { error: e_1_1 }; }
3221 finally {
3222 try {
3223 if (config_1_1 && !config_1_1.done && (_a = config_1.return)) _a.call(config_1);
3224 }
3225 finally { if (e_1) throw e_1.error; }
3226 }
3227 if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
3228 return [];
3229 }
3230 throw new NoMatch$1();
3231 };
3232 Recognizer.prototype.noLeftoversInUrl = function (segmentGroup, segments, outlet) {
3233 return segments.length === 0 && !segmentGroup.children[outlet];
3234 };
3235 Recognizer.prototype.processSegmentAgainstRoute = function (route, rawSegment, segments, outlet) {
3236 if (route.redirectTo)
3237 throw new NoMatch$1();
3238 if ((route.outlet || PRIMARY_OUTLET) !== outlet)
3239 throw new NoMatch$1();
3240 var snapshot;
3241 var consumedSegments = [];
3242 var rawSlicedSegments = [];
3243 if (route.path === '**') {
3244 var params = segments.length > 0 ? last(segments).parameters : {};
3245 snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze(__assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), outlet, route.component, route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + segments.length, getResolve(route));
3246 }
3247 else {
3248 var result = match$1(rawSegment, route, segments);
3249 consumedSegments = result.consumedSegments;
3250 rawSlicedSegments = segments.slice(result.lastChild);
3251 snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze(__assign({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), outlet, route.component, route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + consumedSegments.length, getResolve(route));
3252 }
3253 var childConfig = getChildConfig(route);
3254 var _a = split$1(rawSegment, consumedSegments, rawSlicedSegments, childConfig, this.relativeLinkResolution), segmentGroup = _a.segmentGroup, slicedSegments = _a.slicedSegments;
3255 if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3256 var children_1 = this.processChildren(childConfig, segmentGroup);
3257 return [new TreeNode(snapshot, children_1)];
3258 }
3259 if (childConfig.length === 0 && slicedSegments.length === 0) {
3260 return [new TreeNode(snapshot, [])];
3261 }
3262 var children = this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET);
3263 return [new TreeNode(snapshot, children)];
3264 };
3265 return Recognizer;
3266}());
3267function sortActivatedRouteSnapshots(nodes) {
3268 nodes.sort(function (a, b) {
3269 if (a.value.outlet === PRIMARY_OUTLET)
3270 return -1;
3271 if (b.value.outlet === PRIMARY_OUTLET)
3272 return 1;
3273 return a.value.outlet.localeCompare(b.value.outlet);
3274 });
3275}
3276function getChildConfig(route) {
3277 if (route.children) {
3278 return route.children;
3279 }
3280 if (route.loadChildren) {
3281 return route._loadedConfig.routes;
3282 }
3283 return [];
3284}
3285function match$1(segmentGroup, route, segments) {
3286 if (route.path === '') {
3287 if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
3288 throw new NoMatch$1();
3289 }
3290 return { consumedSegments: [], lastChild: 0, parameters: {} };
3291 }
3292 var matcher = route.matcher || defaultUrlMatcher;
3293 var res = matcher(segments, segmentGroup, route);
3294 if (!res)
3295 throw new NoMatch$1();
3296 var posParams = {};
3297 forEach(res.posParams, function (v, k) { posParams[k] = v.path; });
3298 var parameters = res.consumed.length > 0 ? __assign({}, posParams, res.consumed[res.consumed.length - 1].parameters) :
3299 posParams;
3300 return { consumedSegments: res.consumed, lastChild: res.consumed.length, parameters: parameters };
3301}
3302function checkOutletNameUniqueness(nodes) {
3303 var names = {};
3304 nodes.forEach(function (n) {
3305 var routeWithSameOutletName = names[n.value.outlet];
3306 if (routeWithSameOutletName) {
3307 var p = routeWithSameOutletName.url.map(function (s) { return s.toString(); }).join('/');
3308 var c = n.value.url.map(function (s) { return s.toString(); }).join('/');
3309 throw new Error("Two segments cannot have the same outlet name: '" + p + "' and '" + c + "'.");
3310 }
3311 names[n.value.outlet] = n.value;
3312 });
3313}
3314function getSourceSegmentGroup(segmentGroup) {
3315 var s = segmentGroup;
3316 while (s._sourceSegment) {
3317 s = s._sourceSegment;
3318 }
3319 return s;
3320}
3321function getPathIndexShift(segmentGroup) {
3322 var s = segmentGroup;
3323 var res = (s._segmentIndexShift ? s._segmentIndexShift : 0);
3324 while (s._sourceSegment) {
3325 s = s._sourceSegment;
3326 res += (s._segmentIndexShift ? s._segmentIndexShift : 0);
3327 }
3328 return res - 1;
3329}
3330function split$1(segmentGroup, consumedSegments, slicedSegments, config, relativeLinkResolution) {
3331 if (slicedSegments.length > 0 &&
3332 containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
3333 var s_1 = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
3334 s_1._sourceSegment = segmentGroup;
3335 s_1._segmentIndexShift = consumedSegments.length;
3336 return { segmentGroup: s_1, slicedSegments: [] };
3337 }
3338 if (slicedSegments.length === 0 &&
3339 containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
3340 var s_2 = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children, relativeLinkResolution));
3341 s_2._sourceSegment = segmentGroup;
3342 s_2._segmentIndexShift = consumedSegments.length;
3343 return { segmentGroup: s_2, slicedSegments: slicedSegments };
3344 }
3345 var s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
3346 s._sourceSegment = segmentGroup;
3347 s._segmentIndexShift = consumedSegments.length;
3348 return { segmentGroup: s, slicedSegments: slicedSegments };
3349}
3350function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children, relativeLinkResolution) {
3351 var e_2, _a;
3352 var res = {};
3353 try {
3354 for (var routes_1 = __values(routes), routes_1_1 = routes_1.next(); !routes_1_1.done; routes_1_1 = routes_1.next()) {
3355 var r = routes_1_1.value;
3356 if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet$1(r)]) {
3357 var s = new UrlSegmentGroup([], {});
3358 s._sourceSegment = segmentGroup;
3359 if (relativeLinkResolution === 'legacy') {
3360 s._segmentIndexShift = segmentGroup.segments.length;
3361 }
3362 else {
3363 s._segmentIndexShift = consumedSegments.length;
3364 }
3365 res[getOutlet$1(r)] = s;
3366 }
3367 }
3368 }
3369 catch (e_2_1) { e_2 = { error: e_2_1 }; }
3370 finally {
3371 try {
3372 if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
3373 }
3374 finally { if (e_2) throw e_2.error; }
3375 }
3376 return __assign({}, children, res);
3377}
3378function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
3379 var e_3, _a;
3380 var res = {};
3381 res[PRIMARY_OUTLET] = primarySegment;
3382 primarySegment._sourceSegment = segmentGroup;
3383 primarySegment._segmentIndexShift = consumedSegments.length;
3384 try {
3385 for (var routes_2 = __values(routes), routes_2_1 = routes_2.next(); !routes_2_1.done; routes_2_1 = routes_2.next()) {
3386 var r = routes_2_1.value;
3387 if (r.path === '' && getOutlet$1(r) !== PRIMARY_OUTLET) {
3388 var s = new UrlSegmentGroup([], {});
3389 s._sourceSegment = segmentGroup;
3390 s._segmentIndexShift = consumedSegments.length;
3391 res[getOutlet$1(r)] = s;
3392 }
3393 }
3394 }
3395 catch (e_3_1) { e_3 = { error: e_3_1 }; }
3396 finally {
3397 try {
3398 if (routes_2_1 && !routes_2_1.done && (_a = routes_2.return)) _a.call(routes_2);
3399 }
3400 finally { if (e_3) throw e_3.error; }
3401 }
3402 return res;
3403}
3404function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
3405 return routes.some(function (r) { return emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet$1(r) !== PRIMARY_OUTLET; });
3406}
3407function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
3408 return routes.some(function (r) { return emptyPathMatch(segmentGroup, slicedSegments, r); });
3409}
3410function emptyPathMatch(segmentGroup, slicedSegments, r) {
3411 if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
3412 return false;
3413 }
3414 return r.path === '' && r.redirectTo === undefined;
3415}
3416function getOutlet$1(route) {
3417 return route.outlet || PRIMARY_OUTLET;
3418}
3419function getData(route) {
3420 return route.data || {};
3421}
3422function getResolve(route) {
3423 return route.resolve || {};
3424}
3425
3426/**
3427 * @license
3428 * Copyright Google Inc. All Rights Reserved.
3429 *
3430 * Use of this source code is governed by an MIT-style license that can be
3431 * found in the LICENSE file at https://angular.io/license
3432 */
3433function recognize$1(rootComponentType, config, serializer, paramsInheritanceStrategy, relativeLinkResolution) {
3434 return function (source) {
3435 return source.pipe(mergeMap(function (t) { return recognize(rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects), paramsInheritanceStrategy, relativeLinkResolution)
3436 .pipe(map(function (targetSnapshot) { return (__assign({}, t, { targetSnapshot: targetSnapshot })); })); }));
3437 };
3438}
3439
3440/**
3441 * @license
3442 * Copyright Google Inc. All Rights Reserved.
3443 *
3444 * Use of this source code is governed by an MIT-style license that can be
3445 * found in the LICENSE file at https://angular.io/license
3446 */
3447function resolveData(paramsInheritanceStrategy, moduleInjector) {
3448 return function (source) {
3449 return source.pipe(mergeMap(function (t) {
3450 var targetSnapshot = t.targetSnapshot, canActivateChecks = t.guards.canActivateChecks;
3451 if (!canActivateChecks.length) {
3452 return of(t);
3453 }
3454 return from(canActivateChecks)
3455 .pipe(concatMap(function (check) { return runResolve(check.route, targetSnapshot, paramsInheritanceStrategy, moduleInjector); }), reduce(function (_, __) { return _; }), map(function (_) { return t; }));
3456 }));
3457 };
3458}
3459function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, moduleInjector) {
3460 var resolve = futureARS._resolve;
3461 return resolveNode(resolve, futureARS, futureRSS, moduleInjector)
3462 .pipe(map(function (resolvedData) {
3463 futureARS._resolvedData = resolvedData;
3464 futureARS.data = __assign({}, futureARS.data, inheritedParamsDataResolve(futureARS, paramsInheritanceStrategy).resolve);
3465 return null;
3466 }));
3467}
3468function resolveNode(resolve, futureARS, futureRSS, moduleInjector) {
3469 var keys = Object.keys(resolve);
3470 if (keys.length === 0) {
3471 return of({});
3472 }
3473 if (keys.length === 1) {
3474 var key_1 = keys[0];
3475 return getResolver(resolve[key_1], futureARS, futureRSS, moduleInjector)
3476 .pipe(map(function (value) {
3477 var _a;
3478 return _a = {}, _a[key_1] = value, _a;
3479 }));
3480 }
3481 var data = {};
3482 var runningResolvers$ = from(keys).pipe(mergeMap(function (key) {
3483 return getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
3484 .pipe(map(function (value) {
3485 data[key] = value;
3486 return value;
3487 }));
3488 }));
3489 return runningResolvers$.pipe(last$1(), map(function () { return data; }));
3490}
3491function getResolver(injectionToken, futureARS, futureRSS, moduleInjector) {
3492 var resolver = getToken(injectionToken, futureARS, moduleInjector);
3493 return resolver.resolve ? wrapIntoObservable(resolver.resolve(futureARS, futureRSS)) :
3494 wrapIntoObservable(resolver(futureARS, futureRSS));
3495}
3496
3497/**
3498 * @license
3499 * Copyright Google Inc. All Rights Reserved.
3500 *
3501 * Use of this source code is governed by an MIT-style license that can be
3502 * found in the LICENSE file at https://angular.io/license
3503 */
3504/**
3505 * Perform a side effect through a switchMap for every emission on the source Observable,
3506 * but return an Observable that is identical to the source. It's essentially the same as
3507 * the `tap` operator, but if the side effectful `next` function returns an ObservableInput,
3508 * it will wait before continuing with the original value.
3509 */
3510function switchTap(next) {
3511 return function (source) {
3512 return source.pipe(switchMap(function (v) {
3513 var nextResult = next(v);
3514 if (nextResult) {
3515 return from(nextResult).pipe(map(function () { return v; }));
3516 }
3517 return from([v]);
3518 }));
3519 };
3520}
3521
3522/**
3523 * @license
3524 * Copyright Google Inc. All Rights Reserved.
3525 *
3526 * Use of this source code is governed by an MIT-style license that can be
3527 * found in the LICENSE file at https://angular.io/license
3528 */
3529/**
3530 * @description
3531 *
3532 * Provides a way to customize when activated routes get reused.
3533 *
3534 * @publicApi
3535 */
3536var RouteReuseStrategy = /** @class */ (function () {
3537 function RouteReuseStrategy() {
3538 }
3539 return RouteReuseStrategy;
3540}());
3541/**
3542 * Does not detach any subtrees. Reuses routes as long as their route config is the same.
3543 */
3544var DefaultRouteReuseStrategy = /** @class */ (function () {
3545 function DefaultRouteReuseStrategy() {
3546 }
3547 DefaultRouteReuseStrategy.prototype.shouldDetach = function (route) { return false; };
3548 DefaultRouteReuseStrategy.prototype.store = function (route, detachedTree) { };
3549 DefaultRouteReuseStrategy.prototype.shouldAttach = function (route) { return false; };
3550 DefaultRouteReuseStrategy.prototype.retrieve = function (route) { return null; };
3551 DefaultRouteReuseStrategy.prototype.shouldReuseRoute = function (future, curr) {
3552 return future.routeConfig === curr.routeConfig;
3553 };
3554 return DefaultRouteReuseStrategy;
3555}());
3556
3557/**
3558 * @license
3559 * Copyright Google Inc. All Rights Reserved.
3560 *
3561 * Use of this source code is governed by an MIT-style license that can be
3562 * found in the LICENSE file at https://angular.io/license
3563 */
3564/**
3565 * The [DI token](guide/glossary/#di-token) for a router configuration.
3566 * @see `ROUTES`
3567 * @publicApi
3568 */
3569var ROUTES = new InjectionToken('ROUTES');
3570var RouterConfigLoader = /** @class */ (function () {
3571 function RouterConfigLoader(loader, compiler, onLoadStartListener, onLoadEndListener) {
3572 this.loader = loader;
3573 this.compiler = compiler;
3574 this.onLoadStartListener = onLoadStartListener;
3575 this.onLoadEndListener = onLoadEndListener;
3576 }
3577 RouterConfigLoader.prototype.load = function (parentInjector, route) {
3578 var _this = this;
3579 if (this.onLoadStartListener) {
3580 this.onLoadStartListener(route);
3581 }
3582 var moduleFactory$ = this.loadModuleFactory(route.loadChildren);
3583 return moduleFactory$.pipe(map(function (factory) {
3584 if (_this.onLoadEndListener) {
3585 _this.onLoadEndListener(route);
3586 }
3587 var module = factory.create(parentInjector);
3588 return new LoadedRouterConfig(flatten(module.injector.get(ROUTES)).map(standardizeConfig), module);
3589 }));
3590 };
3591 RouterConfigLoader.prototype.loadModuleFactory = function (loadChildren) {
3592 var _this = this;
3593 if (typeof loadChildren === 'string') {
3594 return from(this.loader.load(loadChildren));
3595 }
3596 else {
3597 return wrapIntoObservable(loadChildren()).pipe(mergeMap(function (t) {
3598 if (t instanceof NgModuleFactory) {
3599 return of(t);
3600 }
3601 else {
3602 return from(_this.compiler.compileModuleAsync(t));
3603 }
3604 }));
3605 }
3606 };
3607 return RouterConfigLoader;
3608}());
3609
3610/**
3611 * @license
3612 * Copyright Google Inc. All Rights Reserved.
3613 *
3614 * Use of this source code is governed by an MIT-style license that can be
3615 * found in the LICENSE file at https://angular.io/license
3616 */
3617/**
3618 * @description
3619 *
3620 * Provides a way to migrate AngularJS applications to Angular.
3621 *
3622 * @publicApi
3623 */
3624var UrlHandlingStrategy = /** @class */ (function () {
3625 function UrlHandlingStrategy() {
3626 }
3627 return UrlHandlingStrategy;
3628}());
3629/**
3630 * @publicApi
3631 */
3632var DefaultUrlHandlingStrategy = /** @class */ (function () {
3633 function DefaultUrlHandlingStrategy() {
3634 }
3635 DefaultUrlHandlingStrategy.prototype.shouldProcessUrl = function (url) { return true; };
3636 DefaultUrlHandlingStrategy.prototype.extract = function (url) { return url; };
3637 DefaultUrlHandlingStrategy.prototype.merge = function (newUrlPart, wholeUrl) { return newUrlPart; };
3638 return DefaultUrlHandlingStrategy;
3639}());
3640
3641/**
3642 * @license
3643 * Copyright Google Inc. All Rights Reserved.
3644 *
3645 * Use of this source code is governed by an MIT-style license that can be
3646 * found in the LICENSE file at https://angular.io/license
3647 */
3648function defaultErrorHandler(error) {
3649 throw error;
3650}
3651function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
3652 return urlSerializer.parse('/');
3653}
3654/**
3655 * @internal
3656 */
3657function defaultRouterHook(snapshot, runExtras) {
3658 return of(null);
3659}
3660/**
3661 * @description
3662 *
3663 * An NgModule that provides navigation and URL manipulation capabilities.
3664 *
3665 * @see `Route`.
3666 * @see [Routing and Navigation Guide](guide/router).
3667 *
3668 * @ngModule RouterModule
3669 *
3670 * @publicApi
3671 */
3672var Router = /** @class */ (function () {
3673 /**
3674 * Creates the router service.
3675 */
3676 // TODO: vsavkin make internal after the final is out.
3677 function Router(rootComponentType, urlSerializer, rootContexts, location, injector, loader, compiler, config) {
3678 var _this = this;
3679 this.rootComponentType = rootComponentType;
3680 this.urlSerializer = urlSerializer;
3681 this.rootContexts = rootContexts;
3682 this.location = location;
3683 this.config = config;
3684 this.lastSuccessfulNavigation = null;
3685 this.currentNavigation = null;
3686 this.navigationId = 0;
3687 this.isNgZoneEnabled = false;
3688 /**
3689 * An event stream for routing events in this NgModule.
3690 */
3691 this.events = new Subject();
3692 /**
3693 * A handler for navigation errors in this NgModule.
3694 */
3695 this.errorHandler = defaultErrorHandler;
3696 /**
3697 * A handler for errors thrown by `Router.parseUrl(url)`
3698 * when `url` contains an invalid character.
3699 * The most common case is a `%` sign
3700 * that's not encoded and is not part of a percent encoded sequence.
3701 */
3702 this.malformedUriErrorHandler = defaultMalformedUriErrorHandler;
3703 /**
3704 * True if at least one navigation event has occurred,
3705 * false otherwise.
3706 */
3707 this.navigated = false;
3708 this.lastSuccessfulId = -1;
3709 /**
3710 * Hooks that enable you to pause navigation,
3711 * either before or after the preactivation phase.
3712 * Used by `RouterModule`.
3713 *
3714 * @internal
3715 */
3716 this.hooks = {
3717 beforePreactivation: defaultRouterHook,
3718 afterPreactivation: defaultRouterHook
3719 };
3720 /**
3721 * A strategy for extracting and merging URLs.
3722 * Used for AngularJS to Angular migrations.
3723 */
3724 this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
3725 /**
3726 * A strategy for re-using routes.
3727 */
3728 this.routeReuseStrategy = new DefaultRouteReuseStrategy();
3729 /**
3730 * How to handle a navigation request to the current URL. One of:
3731 * - `'ignore'` : The router ignores the request.
3732 * - `'reload'` : The router reloads the URL. Use to implement a "refresh" feature.
3733 */
3734 this.onSameUrlNavigation = 'ignore';
3735 /**
3736 * How to merge parameters, data, and resolved data from parent to child
3737 * routes. One of:
3738 *
3739 * - `'emptyOnly'` : Inherit parent parameters, data, and resolved data
3740 * for path-less or component-less routes.
3741 * - `'always'` : Inherit parent parameters, data, and resolved data
3742 * for all child routes.
3743 */
3744 this.paramsInheritanceStrategy = 'emptyOnly';
3745 /**
3746 * Determines when the router updates the browser URL.
3747 * By default (`"deferred"`), udates the browser URL after navigation has finished.
3748 * Set to `'eager'` to update the browser URL at the beginning of navigation.
3749 * You can choose to update early so that, if navigation fails,
3750 * you can show an error message with the URL that failed.
3751 */
3752 this.urlUpdateStrategy = 'deferred';
3753 /**
3754 * Enables a bug fix that corrects relative link resolution in components with empty paths.
3755 * @see `RouterModule`
3756 */
3757 this.relativeLinkResolution = 'legacy';
3758 var onLoadStart = function (r) { return _this.triggerEvent(new RouteConfigLoadStart(r)); };
3759 var onLoadEnd = function (r) { return _this.triggerEvent(new RouteConfigLoadEnd(r)); };
3760 this.ngModule = injector.get(NgModuleRef);
3761 this.console = injector.get(ɵConsole);
3762 var ngZone = injector.get(NgZone);
3763 this.isNgZoneEnabled = ngZone instanceof NgZone;
3764 this.resetConfig(config);
3765 this.currentUrlTree = createEmptyUrlTree();
3766 this.rawUrlTree = this.currentUrlTree;
3767 this.browserUrlTree = this.currentUrlTree;
3768 this.configLoader = new RouterConfigLoader(loader, compiler, onLoadStart, onLoadEnd);
3769 this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
3770 this.transitions = new BehaviorSubject({
3771 id: 0,
3772 currentUrlTree: this.currentUrlTree,
3773 currentRawUrl: this.currentUrlTree,
3774 extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
3775 urlAfterRedirects: this.urlHandlingStrategy.extract(this.currentUrlTree),
3776 rawUrl: this.currentUrlTree,
3777 extras: {},
3778 resolve: null,
3779 reject: null,
3780 promise: Promise.resolve(true),
3781 source: 'imperative',
3782 restoredState: null,
3783 currentSnapshot: this.routerState.snapshot,
3784 targetSnapshot: null,
3785 currentRouterState: this.routerState,
3786 targetRouterState: null,
3787 guards: { canActivateChecks: [], canDeactivateChecks: [] },
3788 guardsResult: null,
3789 });
3790 this.navigations = this.setupNavigations(this.transitions);
3791 this.processNavigations();
3792 }
3793 Router.prototype.setupNavigations = function (transitions) {
3794 var _this = this;
3795 var eventsSubject = this.events;
3796 return transitions.pipe(filter(function (t) { return t.id !== 0; }),
3797 // Extract URL
3798 map(function (t) { return (__assign({}, t, { extractedUrl: _this.urlHandlingStrategy.extract(t.rawUrl) })); }),
3799 // Using switchMap so we cancel executing navigations when a new one comes in
3800 switchMap(function (t) {
3801 var completed = false;
3802 var errored = false;
3803 return of(t).pipe(
3804 // Store the Navigation object
3805 tap(function (t) {
3806 _this.currentNavigation = {
3807 id: t.id,
3808 initialUrl: t.currentRawUrl,
3809 extractedUrl: t.extractedUrl,
3810 trigger: t.source,
3811 extras: t.extras,
3812 previousNavigation: _this.lastSuccessfulNavigation ? __assign({}, _this.lastSuccessfulNavigation, { previousNavigation: null }) :
3813 null
3814 };
3815 }), switchMap(function (t) {
3816 var urlTransition = !_this.navigated || t.extractedUrl.toString() !== _this.browserUrlTree.toString();
3817 var processCurrentUrl = (_this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
3818 _this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
3819 if (processCurrentUrl) {
3820 return of(t).pipe(
3821 // Fire NavigationStart event
3822 switchMap(function (t) {
3823 var transition = _this.transitions.getValue();
3824 eventsSubject.next(new NavigationStart(t.id, _this.serializeUrl(t.extractedUrl), t.source, t.restoredState));
3825 if (transition !== _this.transitions.getValue()) {
3826 return EMPTY;
3827 }
3828 return [t];
3829 }),
3830 // This delay is required to match old behavior that forced navigation to
3831 // always be async
3832 switchMap(function (t) { return Promise.resolve(t); }),
3833 // ApplyRedirects
3834 applyRedirects$1(_this.ngModule.injector, _this.configLoader, _this.urlSerializer, _this.config),
3835 // Update the currentNavigation
3836 tap(function (t) {
3837 _this.currentNavigation = __assign({}, _this.currentNavigation, { finalUrl: t.urlAfterRedirects });
3838 }),
3839 // Recognize
3840 recognize$1(_this.rootComponentType, _this.config, function (url) { return _this.serializeUrl(url); }, _this.paramsInheritanceStrategy, _this.relativeLinkResolution),
3841 // Update URL if in `eager` update mode
3842 tap(function (t) {
3843 if (_this.urlUpdateStrategy === 'eager') {
3844 if (!t.extras.skipLocationChange) {
3845 _this.setBrowserUrl(t.urlAfterRedirects, !!t.extras.replaceUrl, t.id, t.extras.state);
3846 }
3847 _this.browserUrlTree = t.urlAfterRedirects;
3848 }
3849 }),
3850 // Fire RoutesRecognized
3851 tap(function (t) {
3852 var routesRecognized = new RoutesRecognized(t.id, _this.serializeUrl(t.extractedUrl), _this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
3853 eventsSubject.next(routesRecognized);
3854 }));
3855 }
3856 else {
3857 var processPreviousUrl = urlTransition && _this.rawUrlTree &&
3858 _this.urlHandlingStrategy.shouldProcessUrl(_this.rawUrlTree);
3859 /* When the current URL shouldn't be processed, but the previous one was, we
3860 * handle this "error condition" by navigating to the previously successful URL,
3861 * but leaving the URL intact.*/
3862 if (processPreviousUrl) {
3863 var id = t.id, extractedUrl = t.extractedUrl, source = t.source, restoredState = t.restoredState, extras = t.extras;
3864 var navStart = new NavigationStart(id, _this.serializeUrl(extractedUrl), source, restoredState);
3865 eventsSubject.next(navStart);
3866 var targetSnapshot = createEmptyState(extractedUrl, _this.rootComponentType).snapshot;
3867 return of(__assign({}, t, { targetSnapshot: targetSnapshot, urlAfterRedirects: extractedUrl, extras: __assign({}, extras, { skipLocationChange: false, replaceUrl: false }) }));
3868 }
3869 else {
3870 /* When neither the current or previous URL can be processed, do nothing other
3871 * than update router's internal reference to the current "settled" URL. This
3872 * way the next navigation will be coming from the current URL in the browser.
3873 */
3874 _this.rawUrlTree = t.rawUrl;
3875 _this.browserUrlTree = t.urlAfterRedirects;
3876 t.resolve(null);
3877 return EMPTY;
3878 }
3879 }
3880 }),
3881 // Before Preactivation
3882 switchTap(function (t) {
3883 var targetSnapshot = t.targetSnapshot, navigationId = t.id, appliedUrlTree = t.extractedUrl, rawUrlTree = t.rawUrl, _a = t.extras, skipLocationChange = _a.skipLocationChange, replaceUrl = _a.replaceUrl;
3884 return _this.hooks.beforePreactivation(targetSnapshot, {
3885 navigationId: navigationId,
3886 appliedUrlTree: appliedUrlTree,
3887 rawUrlTree: rawUrlTree,
3888 skipLocationChange: !!skipLocationChange,
3889 replaceUrl: !!replaceUrl,
3890 });
3891 }),
3892 // --- GUARDS ---
3893 tap(function (t) {
3894 var guardsStart = new GuardsCheckStart(t.id, _this.serializeUrl(t.extractedUrl), _this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
3895 _this.triggerEvent(guardsStart);
3896 }), map(function (t) { return (__assign({}, t, { guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, _this.rootContexts) })); }), checkGuards(_this.ngModule.injector, function (evt) { return _this.triggerEvent(evt); }), tap(function (t) {
3897 if (isUrlTree(t.guardsResult)) {
3898 var error = navigationCancelingError("Redirecting to \"" + _this.serializeUrl(t.guardsResult) + "\"");
3899 error.url = t.guardsResult;
3900 throw error;
3901 }
3902 }), tap(function (t) {
3903 var guardsEnd = new GuardsCheckEnd(t.id, _this.serializeUrl(t.extractedUrl), _this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
3904 _this.triggerEvent(guardsEnd);
3905 }), filter(function (t) {
3906 if (!t.guardsResult) {
3907 _this.resetUrlToCurrentUrlTree();
3908 var navCancel = new NavigationCancel(t.id, _this.serializeUrl(t.extractedUrl), '');
3909 eventsSubject.next(navCancel);
3910 t.resolve(false);
3911 return false;
3912 }
3913 return true;
3914 }),
3915 // --- RESOLVE ---
3916 switchTap(function (t) {
3917 if (t.guards.canActivateChecks.length) {
3918 return of(t).pipe(tap(function (t) {
3919 var resolveStart = new ResolveStart(t.id, _this.serializeUrl(t.extractedUrl), _this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
3920 _this.triggerEvent(resolveStart);
3921 }), resolveData(_this.paramsInheritanceStrategy, _this.ngModule.injector), //
3922 tap(function (t) {
3923 var resolveEnd = new ResolveEnd(t.id, _this.serializeUrl(t.extractedUrl), _this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
3924 _this.triggerEvent(resolveEnd);
3925 }));
3926 }
3927 return undefined;
3928 }),
3929 // --- AFTER PREACTIVATION ---
3930 switchTap(function (t) {
3931 var targetSnapshot = t.targetSnapshot, navigationId = t.id, appliedUrlTree = t.extractedUrl, rawUrlTree = t.rawUrl, _a = t.extras, skipLocationChange = _a.skipLocationChange, replaceUrl = _a.replaceUrl;
3932 return _this.hooks.afterPreactivation(targetSnapshot, {
3933 navigationId: navigationId,
3934 appliedUrlTree: appliedUrlTree,
3935 rawUrlTree: rawUrlTree,
3936 skipLocationChange: !!skipLocationChange,
3937 replaceUrl: !!replaceUrl,
3938 });
3939 }), map(function (t) {
3940 var targetRouterState = createRouterState(_this.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
3941 return (__assign({}, t, { targetRouterState: targetRouterState }));
3942 }),
3943 /* Once here, we are about to activate syncronously. The assumption is this will
3944 succeed, and user code may read from the Router service. Therefore before
3945 activation, we need to update router properties storing the current URL and the
3946 RouterState, as well as updated the browser URL. All this should happen *before*
3947 activating. */
3948 tap(function (t) {
3949 _this.currentUrlTree = t.urlAfterRedirects;
3950 _this.rawUrlTree = _this.urlHandlingStrategy.merge(_this.currentUrlTree, t.rawUrl);
3951 _this.routerState = t.targetRouterState;
3952 if (_this.urlUpdateStrategy === 'deferred') {
3953 if (!t.extras.skipLocationChange) {
3954 _this.setBrowserUrl(_this.rawUrlTree, !!t.extras.replaceUrl, t.id, t.extras.state);
3955 }
3956 _this.browserUrlTree = t.urlAfterRedirects;
3957 }
3958 }), activateRoutes(_this.rootContexts, _this.routeReuseStrategy, function (evt) { return _this.triggerEvent(evt); }), tap({ next: function () { completed = true; }, complete: function () { completed = true; } }), finalize(function () {
3959 /* When the navigation stream finishes either through error or success, we set the
3960 * `completed` or `errored` flag. However, there are some situations where we could
3961 * get here without either of those being set. For instance, a redirect during
3962 * NavigationStart. Therefore, this is a catch-all to make sure the NavigationCancel
3963 * event is fired when a navigation gets cancelled but not caught by other means. */
3964 if (!completed && !errored) {
3965 // Must reset to current URL tree here to ensure history.state is set. On a fresh
3966 // page load, if a new navigation comes in before a successful navigation
3967 // completes, there will be nothing in history.state.navigationId. This can cause
3968 // sync problems with AngularJS sync code which looks for a value here in order
3969 // to determine whether or not to handle a given popstate event or to leave it
3970 // to the Angualr router.
3971 _this.resetUrlToCurrentUrlTree();
3972 var navCancel = new NavigationCancel(t.id, _this.serializeUrl(t.extractedUrl), "Navigation ID " + t.id + " is not equal to the current navigation id " + _this.navigationId);
3973 eventsSubject.next(navCancel);
3974 t.resolve(false);
3975 }
3976 // currentNavigation should always be reset to null here. If navigation was
3977 // successful, lastSuccessfulTransition will have already been set. Therefore we
3978 // can safely set currentNavigation to null here.
3979 _this.currentNavigation = null;
3980 }), catchError(function (e) {
3981 errored = true;
3982 /* This error type is issued during Redirect, and is handled as a cancellation
3983 * rather than an error. */
3984 if (isNavigationCancelingError(e)) {
3985 var redirecting = isUrlTree(e.url);
3986 if (!redirecting) {
3987 // Set property only if we're not redirecting. If we landed on a page and
3988 // redirect to `/` route, the new navigation is going to see the `/` isn't
3989 // a change from the default currentUrlTree and won't navigate. This is
3990 // only applicable with initial navigation, so setting `navigated` only when
3991 // not redirecting resolves this scenario.
3992 _this.navigated = true;
3993 _this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
3994 }
3995 var navCancel = new NavigationCancel(t.id, _this.serializeUrl(t.extractedUrl), e.message);
3996 eventsSubject.next(navCancel);
3997 t.resolve(false);
3998 if (redirecting) {
3999 _this.navigateByUrl(e.url);
4000 }
4001 /* All other errors should reset to the router's internal URL reference to the
4002 * pre-error state. */
4003 }
4004 else {
4005 _this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
4006 var navError = new NavigationError(t.id, _this.serializeUrl(t.extractedUrl), e);
4007 eventsSubject.next(navError);
4008 try {
4009 t.resolve(_this.errorHandler(e));
4010 }
4011 catch (ee) {
4012 t.reject(ee);
4013 }
4014 }
4015 return EMPTY;
4016 }));
4017 // TODO(jasonaden): remove cast once g3 is on updated TypeScript
4018 }));
4019 };
4020 /**
4021 * @internal
4022 * TODO: this should be removed once the constructor of the router made internal
4023 */
4024 Router.prototype.resetRootComponentType = function (rootComponentType) {
4025 this.rootComponentType = rootComponentType;
4026 // TODO: vsavkin router 4.0 should make the root component set to null
4027 // this will simplify the lifecycle of the router.
4028 this.routerState.root.component = this.rootComponentType;
4029 };
4030 Router.prototype.getTransition = function () {
4031 var transition = this.transitions.value;
4032 // This value needs to be set. Other values such as extractedUrl are set on initial navigation
4033 // but the urlAfterRedirects may not get set if we aren't processing the new URL *and* not
4034 // processing the previous URL.
4035 transition.urlAfterRedirects = this.browserUrlTree;
4036 return transition;
4037 };
4038 Router.prototype.setTransition = function (t) {
4039 this.transitions.next(__assign({}, this.getTransition(), t));
4040 };
4041 /**
4042 * Sets up the location change listener and performs the initial navigation.
4043 */
4044 Router.prototype.initialNavigation = function () {
4045 this.setUpLocationChangeListener();
4046 if (this.navigationId === 0) {
4047 this.navigateByUrl(this.location.path(true), { replaceUrl: true });
4048 }
4049 };
4050 /**
4051 * Sets up the location change listener.
4052 */
4053 Router.prototype.setUpLocationChangeListener = function () {
4054 var _this = this;
4055 // Don't need to use Zone.wrap any more, because zone.js
4056 // already patch onPopState, so location change callback will
4057 // run into ngZone
4058 if (!this.locationSubscription) {
4059 this.locationSubscription = this.location.subscribe(function (change) {
4060 var rawUrlTree = _this.parseUrl(change['url']);
4061 var source = change['type'] === 'popstate' ? 'popstate' : 'hashchange';
4062 // Navigations coming from Angular router have a navigationId state property. When this
4063 // exists, restore the state.
4064 var state = change.state && change.state.navigationId ? change.state : null;
4065 setTimeout(function () { _this.scheduleNavigation(rawUrlTree, source, state, { replaceUrl: true }); }, 0);
4066 });
4067 }
4068 };
4069 Object.defineProperty(Router.prototype, "url", {
4070 /** The current URL. */
4071 get: function () { return this.serializeUrl(this.currentUrlTree); },
4072 enumerable: true,
4073 configurable: true
4074 });
4075 /** The current Navigation object if one exists */
4076 Router.prototype.getCurrentNavigation = function () { return this.currentNavigation; };
4077 /** @internal */
4078 Router.prototype.triggerEvent = function (event) { this.events.next(event); };
4079 /**
4080 * Resets the configuration used for navigation and generating links.
4081 *
4082 * @param config The route array for the new configuration.
4083 *
4084 * @usageNotes
4085 *
4086 * ```
4087 * router.resetConfig([
4088 * { path: 'team/:id', component: TeamCmp, children: [
4089 * { path: 'simple', component: SimpleCmp },
4090 * { path: 'user/:name', component: UserCmp }
4091 * ]}
4092 * ]);
4093 * ```
4094 */
4095 Router.prototype.resetConfig = function (config) {
4096 validateConfig(config);
4097 this.config = config.map(standardizeConfig);
4098 this.navigated = false;
4099 this.lastSuccessfulId = -1;
4100 };
4101 /** @docsNotRequired */
4102 Router.prototype.ngOnDestroy = function () { this.dispose(); };
4103 /** Disposes of the router. */
4104 Router.prototype.dispose = function () {
4105 if (this.locationSubscription) {
4106 this.locationSubscription.unsubscribe();
4107 this.locationSubscription = null;
4108 }
4109 };
4110 /**
4111 * Applies an array of commands to the current URL tree and creates a new URL tree.
4112 *
4113 * When given an activate route, applies the given commands starting from the route.
4114 * Otherwise, applies the given command starting from the root.
4115 *
4116 * @param commands An array of commands to apply.
4117 * @param navigationExtras Options that control the navigation strategy.
4118 * @returns The new URL tree.
4119 *
4120 * @usageNotes
4121 *
4122 * ```
4123 * // create /team/33/user/11
4124 * router.createUrlTree(['/team', 33, 'user', 11]);
4125 *
4126 * // create /team/33;expand=true/user/11
4127 * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
4128 *
4129 * // you can collapse static segments like this (this works only with the first passed-in value):
4130 * router.createUrlTree(['/team/33/user', userId]);
4131 *
4132 * // If the first segment can contain slashes, and you do not want the router to split it,
4133 * // you can do the following:
4134 * router.createUrlTree([{segmentPath: '/one/two'}]);
4135 *
4136 * // create /team/33/(user/11//right:chat)
4137 * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
4138 *
4139 * // remove the right secondary node
4140 * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
4141 *
4142 * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
4143 *
4144 * // navigate to /team/33/user/11/details
4145 * router.createUrlTree(['details'], {relativeTo: route});
4146 *
4147 * // navigate to /team/33/user/22
4148 * router.createUrlTree(['../22'], {relativeTo: route});
4149 *
4150 * // navigate to /team/44/user/22
4151 * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
4152 * ```
4153 */
4154 Router.prototype.createUrlTree = function (commands, navigationExtras) {
4155 if (navigationExtras === void 0) { navigationExtras = {}; }
4156 var relativeTo = navigationExtras.relativeTo, queryParams = navigationExtras.queryParams, fragment = navigationExtras.fragment, preserveQueryParams = navigationExtras.preserveQueryParams, queryParamsHandling = navigationExtras.queryParamsHandling, preserveFragment = navigationExtras.preserveFragment;
4157 if (isDevMode() && preserveQueryParams && console && console.warn) {
4158 console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
4159 }
4160 var a = relativeTo || this.routerState.root;
4161 var f = preserveFragment ? this.currentUrlTree.fragment : fragment;
4162 var q = null;
4163 if (queryParamsHandling) {
4164 switch (queryParamsHandling) {
4165 case 'merge':
4166 q = __assign({}, this.currentUrlTree.queryParams, queryParams);
4167 break;
4168 case 'preserve':
4169 q = this.currentUrlTree.queryParams;
4170 break;
4171 default:
4172 q = queryParams || null;
4173 }
4174 }
4175 else {
4176 q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams || null;
4177 }
4178 if (q !== null) {
4179 q = this.removeEmptyProps(q);
4180 }
4181 return createUrlTree(a, this.currentUrlTree, commands, q, f);
4182 };
4183 /**
4184 * Navigate based on the provided URL, which must be absolute.
4185 *
4186 * @param url An absolute URL. The function does not apply any delta to the current URL.
4187 * @param extras An object containing properties that modify the navigation strategy.
4188 * The function ignores any properties in the `NavigationExtras` that would change the
4189 * provided URL.
4190 *
4191 * @returns A Promise that resolves to 'true' when navigation succeeds,
4192 * to 'false' when navigation fails, or is rejected on error.
4193 *
4194 * @usageNotes
4195 *
4196 * ```
4197 * router.navigateByUrl("/team/33/user/11");
4198 *
4199 * // Navigate without updating the URL
4200 * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
4201 * ```
4202 *
4203 */
4204 Router.prototype.navigateByUrl = function (url, extras) {
4205 if (extras === void 0) { extras = { skipLocationChange: false }; }
4206 if (isDevMode() && this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
4207 this.console.warn("Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?");
4208 }
4209 var urlTree = isUrlTree(url) ? url : this.parseUrl(url);
4210 var mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
4211 return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
4212 };
4213 /**
4214 * Navigate based on the provided array of commands and a starting point.
4215 * If no starting route is provided, the navigation is absolute.
4216 *
4217 * Returns a promise that:
4218 * - resolves to 'true' when navigation succeeds,
4219 * - resolves to 'false' when navigation fails,
4220 * - is rejected when an error happens.
4221 *
4222 * @usageNotes
4223 *
4224 * ```
4225 * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
4226 *
4227 * // Navigate without updating the URL
4228 * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
4229 * ```
4230 *
4231 * The first parameter of `navigate()` is a delta to be applied to the current URL
4232 * or the one provided in the `relativeTo` property of the second parameter (the
4233 * `NavigationExtras`).
4234 *
4235 * In order to affect this browser's `history.state` entry, the `state`
4236 * parameter can be passed. This must be an object because the router
4237 * will add the `navigationId` property to this object before creating
4238 * the new history item.
4239 */
4240 Router.prototype.navigate = function (commands, extras) {
4241 if (extras === void 0) { extras = { skipLocationChange: false }; }
4242 validateCommands(commands);
4243 return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
4244 };
4245 /** Serializes a `UrlTree` into a string */
4246 Router.prototype.serializeUrl = function (url) { return this.urlSerializer.serialize(url); };
4247 /** Parses a string into a `UrlTree` */
4248 Router.prototype.parseUrl = function (url) {
4249 var urlTree;
4250 try {
4251 urlTree = this.urlSerializer.parse(url);
4252 }
4253 catch (e) {
4254 urlTree = this.malformedUriErrorHandler(e, this.urlSerializer, url);
4255 }
4256 return urlTree;
4257 };
4258 /** Returns whether the url is activated */
4259 Router.prototype.isActive = function (url, exact) {
4260 if (isUrlTree(url)) {
4261 return containsTree(this.currentUrlTree, url, exact);
4262 }
4263 var urlTree = this.parseUrl(url);
4264 return containsTree(this.currentUrlTree, urlTree, exact);
4265 };
4266 Router.prototype.removeEmptyProps = function (params) {
4267 return Object.keys(params).reduce(function (result, key) {
4268 var value = params[key];
4269 if (value !== null && value !== undefined) {
4270 result[key] = value;
4271 }
4272 return result;
4273 }, {});
4274 };
4275 Router.prototype.processNavigations = function () {
4276 var _this = this;
4277 this.navigations.subscribe(function (t) {
4278 _this.navigated = true;
4279 _this.lastSuccessfulId = t.id;
4280 _this.events
4281 .next(new NavigationEnd(t.id, _this.serializeUrl(t.extractedUrl), _this.serializeUrl(_this.currentUrlTree)));
4282 _this.lastSuccessfulNavigation = _this.currentNavigation;
4283 _this.currentNavigation = null;
4284 t.resolve(true);
4285 }, function (e) { _this.console.warn("Unhandled Navigation Error: "); });
4286 };
4287 Router.prototype.scheduleNavigation = function (rawUrl, source, restoredState, extras) {
4288 var lastNavigation = this.getTransition();
4289 // If the user triggers a navigation imperatively (e.g., by using navigateByUrl),
4290 // and that navigation results in 'replaceState' that leads to the same URL,
4291 // we should skip those.
4292 if (lastNavigation && source !== 'imperative' && lastNavigation.source === 'imperative' &&
4293 lastNavigation.rawUrl.toString() === rawUrl.toString()) {
4294 return Promise.resolve(true); // return value is not used
4295 }
4296 // Because of a bug in IE and Edge, the location class fires two events (popstate and
4297 // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
4298 // flicker. Handles the case when a popstate was emitted first.
4299 if (lastNavigation && source == 'hashchange' && lastNavigation.source === 'popstate' &&
4300 lastNavigation.rawUrl.toString() === rawUrl.toString()) {
4301 return Promise.resolve(true); // return value is not used
4302 }
4303 // Because of a bug in IE and Edge, the location class fires two events (popstate and
4304 // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
4305 // flicker. Handles the case when a hashchange was emitted first.
4306 if (lastNavigation && source == 'popstate' && lastNavigation.source === 'hashchange' &&
4307 lastNavigation.rawUrl.toString() === rawUrl.toString()) {
4308 return Promise.resolve(true); // return value is not used
4309 }
4310 var resolve = null;
4311 var reject = null;
4312 var promise = new Promise(function (res, rej) {
4313 resolve = res;
4314 reject = rej;
4315 });
4316 var id = ++this.navigationId;
4317 this.setTransition({
4318 id: id,
4319 source: source,
4320 restoredState: restoredState,
4321 currentUrlTree: this.currentUrlTree,
4322 currentRawUrl: this.rawUrlTree, rawUrl: rawUrl, extras: extras, resolve: resolve, reject: reject, promise: promise,
4323 currentSnapshot: this.routerState.snapshot,
4324 currentRouterState: this.routerState
4325 });
4326 // Make sure that the error is propagated even though `processNavigations` catch
4327 // handler does not rethrow
4328 return promise.catch(function (e) { return Promise.reject(e); });
4329 };
4330 Router.prototype.setBrowserUrl = function (url, replaceUrl, id, state) {
4331 var path = this.urlSerializer.serialize(url);
4332 state = state || {};
4333 if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
4334 // TODO(jasonaden): Remove first `navigationId` and rely on `ng` namespace.
4335 this.location.replaceState(path, '', __assign({}, state, { navigationId: id }));
4336 }
4337 else {
4338 this.location.go(path, '', __assign({}, state, { navigationId: id }));
4339 }
4340 };
4341 Router.prototype.resetStateAndUrl = function (storedState, storedUrl, rawUrl) {
4342 this.routerState = storedState;
4343 this.currentUrlTree = storedUrl;
4344 this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
4345 this.resetUrlToCurrentUrlTree();
4346 };
4347 Router.prototype.resetUrlToCurrentUrlTree = function () {
4348 this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', { navigationId: this.lastSuccessfulId });
4349 };
4350 return Router;
4351}());
4352function validateCommands(commands) {
4353 for (var i = 0; i < commands.length; i++) {
4354 var cmd = commands[i];
4355 if (cmd == null) {
4356 throw new Error("The requested path contains " + cmd + " segment at index " + i);
4357 }
4358 }
4359}
4360
4361/**
4362 * @license
4363 * Copyright Google Inc. All Rights Reserved.
4364 *
4365 * Use of this source code is governed by an MIT-style license that can be
4366 * found in the LICENSE file at https://angular.io/license
4367 */
4368/**
4369 * @description
4370 *
4371 * Lets you link to specific routes in your app.
4372 *
4373 * Consider the following route configuration:
4374 * `[{ path: 'user/:name', component: UserCmp }]`.
4375 * When linking to this `user/:name` route, you use the `RouterLink` directive.
4376 *
4377 * If the link is static, you can use the directive as follows:
4378 * `<a routerLink="/user/bob">link to user component</a>`
4379 *
4380 * If you use dynamic values to generate the link, you can pass an array of path
4381 * segments, followed by the params for each segment.
4382 *
4383 * For instance `['/team', teamId, 'user', userName, {details: true}]`
4384 * means that we want to generate a link to `/team/11/user/bob;details=true`.
4385 *
4386 * Multiple static segments can be merged into one
4387 * (e.g., `['/team/11/user', userName, {details: true}]`).
4388 *
4389 * The first segment name can be prepended with `/`, `./`, or `../`:
4390 * * If the first segment begins with `/`, the router will look up the route from the root of the
4391 * app.
4392 * * If the first segment begins with `./`, or doesn't begin with a slash, the router will
4393 * instead look in the children of the current activated route.
4394 * * And if the first segment begins with `../`, the router will go up one level.
4395 *
4396 * You can set query params and fragment as follows:
4397 *
4398 * ```
4399 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
4400 * link to user component
4401 * </a>
4402 * ```
4403 * RouterLink will use these to generate this link: `/user/bob#education?debug=true`.
4404 *
4405 * (Deprecated in v4.0.0 use `queryParamsHandling` instead) You can also tell the
4406 * directive to preserve the current query params and fragment:
4407 *
4408 * ```
4409 * <a [routerLink]="['/user/bob']" preserveQueryParams preserveFragment>
4410 * link to user component
4411 * </a>
4412 * ```
4413 *
4414 * You can tell the directive how to handle queryParams. Available options are:
4415 * - `'merge'`: merge the queryParams into the current queryParams
4416 * - `'preserve'`: preserve the current queryParams
4417 * - default/`''`: use the queryParams only
4418 *
4419 * Same options for {@link NavigationExtras#queryParamsHandling
4420 * NavigationExtras#queryParamsHandling}.
4421 *
4422 * ```
4423 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
4424 * link to user component
4425 * </a>
4426 * ```
4427 *
4428 * You can provide a `state` value to be persisted to the browser's History.state
4429 * property (See https://developer.mozilla.org/en-US/docs/Web/API/History#Properties). It's
4430 * used as follows:
4431 *
4432 * ```
4433 * <a [routerLink]="['/user/bob']" [state]="{tracingId: 123}">
4434 * link to user component
4435 * </a>
4436 * ```
4437 *
4438 * And later the value can be read from the router through `router.getCurrentNavigation`.
4439 * For example, to capture the `tracingId` above during the `NavigationStart` event:
4440 *
4441 * ```
4442 * // Get NavigationStart events
4443 * router.events.pipe(filter(e => e instanceof NavigationStart)).subscribe(e => {
4444 * const navigation = router.getCurrentNavigation();
4445 * tracingService.trace({id: navigation.extras.state.tracingId});
4446 * });
4447 * ```
4448 *
4449 * The router link directive always treats the provided input as a delta to the current url.
4450 *
4451 * For instance, if the current url is `/user/(box//aux:team)`.
4452 *
4453 * Then the following link `<a [routerLink]="['/user/jim']">Jim</a>` will generate the link
4454 * `/user/(jim//aux:team)`.
4455 *
4456 * See {@link Router#createUrlTree createUrlTree} for more information.
4457 *
4458 * @ngModule RouterModule
4459 *
4460 * @publicApi
4461 */
4462var RouterLink = /** @class */ (function () {
4463 function RouterLink(router, route, tabIndex, renderer, el) {
4464 this.router = router;
4465 this.route = route;
4466 this.commands = [];
4467 if (tabIndex == null) {
4468 renderer.setAttribute(el.nativeElement, 'tabindex', '0');
4469 }
4470 }
4471 Object.defineProperty(RouterLink.prototype, "routerLink", {
4472 set: function (commands) {
4473 if (commands != null) {
4474 this.commands = Array.isArray(commands) ? commands : [commands];
4475 }
4476 else {
4477 this.commands = [];
4478 }
4479 },
4480 enumerable: true,
4481 configurable: true
4482 });
4483 Object.defineProperty(RouterLink.prototype, "preserveQueryParams", {
4484 /**
4485 * @deprecated 4.0.0 use `queryParamsHandling` instead.
4486 */
4487 set: function (value) {
4488 if (isDevMode() && console && console.warn) {
4489 console.warn('preserveQueryParams is deprecated!, use queryParamsHandling instead.');
4490 }
4491 this.preserve = value;
4492 },
4493 enumerable: true,
4494 configurable: true
4495 });
4496 RouterLink.prototype.onClick = function () {
4497 var extras = {
4498 skipLocationChange: attrBoolValue(this.skipLocationChange),
4499 replaceUrl: attrBoolValue(this.replaceUrl),
4500 };
4501 this.router.navigateByUrl(this.urlTree, extras);
4502 return true;
4503 };
4504 Object.defineProperty(RouterLink.prototype, "urlTree", {
4505 get: function () {
4506 return this.router.createUrlTree(this.commands, {
4507 relativeTo: this.route,
4508 queryParams: this.queryParams,
4509 fragment: this.fragment,
4510 preserveQueryParams: attrBoolValue(this.preserve),
4511 queryParamsHandling: this.queryParamsHandling,
4512 preserveFragment: attrBoolValue(this.preserveFragment),
4513 });
4514 },
4515 enumerable: true,
4516 configurable: true
4517 });
4518 __decorate([
4519 Input(),
4520 __metadata("design:type", Object)
4521 ], RouterLink.prototype, "queryParams", void 0);
4522 __decorate([
4523 Input(),
4524 __metadata("design:type", String)
4525 ], RouterLink.prototype, "fragment", void 0);
4526 __decorate([
4527 Input(),
4528 __metadata("design:type", String)
4529 ], RouterLink.prototype, "queryParamsHandling", void 0);
4530 __decorate([
4531 Input(),
4532 __metadata("design:type", Boolean)
4533 ], RouterLink.prototype, "preserveFragment", void 0);
4534 __decorate([
4535 Input(),
4536 __metadata("design:type", Boolean)
4537 ], RouterLink.prototype, "skipLocationChange", void 0);
4538 __decorate([
4539 Input(),
4540 __metadata("design:type", Boolean)
4541 ], RouterLink.prototype, "replaceUrl", void 0);
4542 __decorate([
4543 Input(),
4544 __metadata("design:type", Object)
4545 ], RouterLink.prototype, "state", void 0);
4546 __decorate([
4547 Input(),
4548 __metadata("design:type", Object),
4549 __metadata("design:paramtypes", [Object])
4550 ], RouterLink.prototype, "routerLink", null);
4551 __decorate([
4552 Input(),
4553 __metadata("design:type", Boolean),
4554 __metadata("design:paramtypes", [Boolean])
4555 ], RouterLink.prototype, "preserveQueryParams", null);
4556 __decorate([
4557 HostListener('click'),
4558 __metadata("design:type", Function),
4559 __metadata("design:paramtypes", []),
4560 __metadata("design:returntype", Boolean)
4561 ], RouterLink.prototype, "onClick", null);
4562 RouterLink = __decorate([
4563 Directive({ selector: ':not(a):not(area)[routerLink]' }),
4564 __param(2, Attribute('tabindex')),
4565 __metadata("design:paramtypes", [Router, ActivatedRoute, String, Renderer2, ElementRef])
4566 ], RouterLink);
4567 return RouterLink;
4568}());
4569/**
4570 * @description
4571 *
4572 * Lets you link to specific routes in your app.
4573 *
4574 * See `RouterLink` for more information.
4575 *
4576 * @ngModule RouterModule
4577 *
4578 * @publicApi
4579 */
4580var RouterLinkWithHref = /** @class */ (function () {
4581 function RouterLinkWithHref(router, route, locationStrategy) {
4582 var _this = this;
4583 this.router = router;
4584 this.route = route;
4585 this.locationStrategy = locationStrategy;
4586 this.commands = [];
4587 this.subscription = router.events.subscribe(function (s) {
4588 if (s instanceof NavigationEnd) {
4589 _this.updateTargetUrlAndHref();
4590 }
4591 });
4592 }
4593 Object.defineProperty(RouterLinkWithHref.prototype, "routerLink", {
4594 set: function (commands) {
4595 if (commands != null) {
4596 this.commands = Array.isArray(commands) ? commands : [commands];
4597 }
4598 else {
4599 this.commands = [];
4600 }
4601 },
4602 enumerable: true,
4603 configurable: true
4604 });
4605 Object.defineProperty(RouterLinkWithHref.prototype, "preserveQueryParams", {
4606 set: function (value) {
4607 if (isDevMode() && console && console.warn) {
4608 console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
4609 }
4610 this.preserve = value;
4611 },
4612 enumerable: true,
4613 configurable: true
4614 });
4615 RouterLinkWithHref.prototype.ngOnChanges = function (changes) { this.updateTargetUrlAndHref(); };
4616 RouterLinkWithHref.prototype.ngOnDestroy = function () { this.subscription.unsubscribe(); };
4617 RouterLinkWithHref.prototype.onClick = function (button, ctrlKey, metaKey, shiftKey) {
4618 if (button !== 0 || ctrlKey || metaKey || shiftKey) {
4619 return true;
4620 }
4621 if (typeof this.target === 'string' && this.target != '_self') {
4622 return true;
4623 }
4624 var extras = {
4625 skipLocationChange: attrBoolValue(this.skipLocationChange),
4626 replaceUrl: attrBoolValue(this.replaceUrl),
4627 state: this.state
4628 };
4629 this.router.navigateByUrl(this.urlTree, extras);
4630 return false;
4631 };
4632 RouterLinkWithHref.prototype.updateTargetUrlAndHref = function () {
4633 this.href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree));
4634 };
4635 Object.defineProperty(RouterLinkWithHref.prototype, "urlTree", {
4636 get: function () {
4637 return this.router.createUrlTree(this.commands, {
4638 relativeTo: this.route,
4639 queryParams: this.queryParams,
4640 fragment: this.fragment,
4641 preserveQueryParams: attrBoolValue(this.preserve),
4642 queryParamsHandling: this.queryParamsHandling,
4643 preserveFragment: attrBoolValue(this.preserveFragment),
4644 });
4645 },
4646 enumerable: true,
4647 configurable: true
4648 });
4649 __decorate([
4650 HostBinding('attr.target'), Input(),
4651 __metadata("design:type", String)
4652 ], RouterLinkWithHref.prototype, "target", void 0);
4653 __decorate([
4654 Input(),
4655 __metadata("design:type", Object)
4656 ], RouterLinkWithHref.prototype, "queryParams", void 0);
4657 __decorate([
4658 Input(),
4659 __metadata("design:type", String)
4660 ], RouterLinkWithHref.prototype, "fragment", void 0);
4661 __decorate([
4662 Input(),
4663 __metadata("design:type", String)
4664 ], RouterLinkWithHref.prototype, "queryParamsHandling", void 0);
4665 __decorate([
4666 Input(),
4667 __metadata("design:type", Boolean)
4668 ], RouterLinkWithHref.prototype, "preserveFragment", void 0);
4669 __decorate([
4670 Input(),
4671 __metadata("design:type", Boolean)
4672 ], RouterLinkWithHref.prototype, "skipLocationChange", void 0);
4673 __decorate([
4674 Input(),
4675 __metadata("design:type", Boolean)
4676 ], RouterLinkWithHref.prototype, "replaceUrl", void 0);
4677 __decorate([
4678 Input(),
4679 __metadata("design:type", Object)
4680 ], RouterLinkWithHref.prototype, "state", void 0);
4681 __decorate([
4682 HostBinding(),
4683 __metadata("design:type", String)
4684 ], RouterLinkWithHref.prototype, "href", void 0);
4685 __decorate([
4686 Input(),
4687 __metadata("design:type", Object),
4688 __metadata("design:paramtypes", [Object])
4689 ], RouterLinkWithHref.prototype, "routerLink", null);
4690 __decorate([
4691 Input(),
4692 __metadata("design:type", Boolean),
4693 __metadata("design:paramtypes", [Boolean])
4694 ], RouterLinkWithHref.prototype, "preserveQueryParams", null);
4695 __decorate([
4696 HostListener('click', ['$event.button', '$event.ctrlKey', '$event.metaKey', '$event.shiftKey']),
4697 __metadata("design:type", Function),
4698 __metadata("design:paramtypes", [Number, Boolean, Boolean, Boolean]),
4699 __metadata("design:returntype", Boolean)
4700 ], RouterLinkWithHref.prototype, "onClick", null);
4701 RouterLinkWithHref = __decorate([
4702 Directive({ selector: 'a[routerLink],area[routerLink]' }),
4703 __metadata("design:paramtypes", [Router, ActivatedRoute,
4704 LocationStrategy])
4705 ], RouterLinkWithHref);
4706 return RouterLinkWithHref;
4707}());
4708function attrBoolValue(s) {
4709 return s === '' || !!s;
4710}
4711
4712/**
4713 * @license
4714 * Copyright Google Inc. All Rights Reserved.
4715 *
4716 * Use of this source code is governed by an MIT-style license that can be
4717 * found in the LICENSE file at https://angular.io/license
4718 */
4719/**
4720 *
4721 * @description
4722 *
4723 * Lets you add a CSS class to an element when the link's route becomes active.
4724 *
4725 * This directive lets you add a CSS class to an element when the link's route
4726 * becomes active.
4727 *
4728 * Consider the following example:
4729 *
4730 * ```
4731 * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
4732 * ```
4733 *
4734 * When the url is either '/user' or '/user/bob', the active-link class will
4735 * be added to the `a` tag. If the url changes, the class will be removed.
4736 *
4737 * You can set more than one class, as follows:
4738 *
4739 * ```
4740 * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
4741 * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
4742 * ```
4743 *
4744 * You can configure RouterLinkActive by passing `exact: true`. This will add the classes
4745 * only when the url matches the link exactly.
4746 *
4747 * ```
4748 * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
4749 * true}">Bob</a>
4750 * ```
4751 *
4752 * You can assign the RouterLinkActive instance to a template variable and directly check
4753 * the `isActive` status.
4754 * ```
4755 * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
4756 * Bob {{ rla.isActive ? '(already open)' : ''}}
4757 * </a>
4758 * ```
4759 *
4760 * Finally, you can apply the RouterLinkActive directive to an ancestor of a RouterLink.
4761 *
4762 * ```
4763 * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
4764 * <a routerLink="/user/jim">Jim</a>
4765 * <a routerLink="/user/bob">Bob</a>
4766 * </div>
4767 * ```
4768 *
4769 * This will set the active-link class on the div tag if the url is either '/user/jim' or
4770 * '/user/bob'.
4771 *
4772 * @ngModule RouterModule
4773 *
4774 * @publicApi
4775 */
4776var RouterLinkActive = /** @class */ (function () {
4777 function RouterLinkActive(router, element, renderer, link, linkWithHref) {
4778 var _this = this;
4779 this.router = router;
4780 this.element = element;
4781 this.renderer = renderer;
4782 this.link = link;
4783 this.linkWithHref = linkWithHref;
4784 this.classes = [];
4785 this.isActive = false;
4786 this.routerLinkActiveOptions = { exact: false };
4787 this.subscription = router.events.subscribe(function (s) {
4788 if (s instanceof NavigationEnd) {
4789 _this.update();
4790 }
4791 });
4792 }
4793 RouterLinkActive.prototype.ngAfterContentInit = function () {
4794 var _this = this;
4795 this.links.changes.subscribe(function (_) { return _this.update(); });
4796 this.linksWithHrefs.changes.subscribe(function (_) { return _this.update(); });
4797 this.update();
4798 };
4799 Object.defineProperty(RouterLinkActive.prototype, "routerLinkActive", {
4800 set: function (data) {
4801 var classes = Array.isArray(data) ? data : data.split(' ');
4802 this.classes = classes.filter(function (c) { return !!c; });
4803 },
4804 enumerable: true,
4805 configurable: true
4806 });
4807 RouterLinkActive.prototype.ngOnChanges = function (changes) { this.update(); };
4808 RouterLinkActive.prototype.ngOnDestroy = function () { this.subscription.unsubscribe(); };
4809 RouterLinkActive.prototype.update = function () {
4810 var _this = this;
4811 if (!this.links || !this.linksWithHrefs || !this.router.navigated)
4812 return;
4813 Promise.resolve().then(function () {
4814 var hasActiveLinks = _this.hasActiveLinks();
4815 if (_this.isActive !== hasActiveLinks) {
4816 _this.isActive = hasActiveLinks;
4817 _this.classes.forEach(function (c) {
4818 if (hasActiveLinks) {
4819 _this.renderer.addClass(_this.element.nativeElement, c);
4820 }
4821 else {
4822 _this.renderer.removeClass(_this.element.nativeElement, c);
4823 }
4824 });
4825 }
4826 });
4827 };
4828 RouterLinkActive.prototype.isLinkActive = function (router) {
4829 var _this = this;
4830 return function (link) {
4831 return router.isActive(link.urlTree, _this.routerLinkActiveOptions.exact);
4832 };
4833 };
4834 RouterLinkActive.prototype.hasActiveLinks = function () {
4835 var isActiveCheckFn = this.isLinkActive(this.router);
4836 return this.link && isActiveCheckFn(this.link) ||
4837 this.linkWithHref && isActiveCheckFn(this.linkWithHref) ||
4838 this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
4839 };
4840 __decorate([
4841 ContentChildren(RouterLink, { descendants: true }),
4842 __metadata("design:type", QueryList)
4843 ], RouterLinkActive.prototype, "links", void 0);
4844 __decorate([
4845 ContentChildren(RouterLinkWithHref, { descendants: true }),
4846 __metadata("design:type", QueryList)
4847 ], RouterLinkActive.prototype, "linksWithHrefs", void 0);
4848 __decorate([
4849 Input(),
4850 __metadata("design:type", Object)
4851 ], RouterLinkActive.prototype, "routerLinkActiveOptions", void 0);
4852 __decorate([
4853 Input(),
4854 __metadata("design:type", Object),
4855 __metadata("design:paramtypes", [Object])
4856 ], RouterLinkActive.prototype, "routerLinkActive", null);
4857 RouterLinkActive = __decorate([
4858 Directive({
4859 selector: '[routerLinkActive]',
4860 exportAs: 'routerLinkActive',
4861 }),
4862 __param(3, Optional()),
4863 __param(4, Optional()),
4864 __metadata("design:paramtypes", [Router, ElementRef, Renderer2,
4865 RouterLink,
4866 RouterLinkWithHref])
4867 ], RouterLinkActive);
4868 return RouterLinkActive;
4869}());
4870
4871/**
4872 * @license
4873 * Copyright Google Inc. All Rights Reserved.
4874 *
4875 * Use of this source code is governed by an MIT-style license that can be
4876 * found in the LICENSE file at https://angular.io/license
4877 */
4878/**
4879 * Store contextual information about a `RouterOutlet`
4880 *
4881 * @publicApi
4882 */
4883var OutletContext = /** @class */ (function () {
4884 function OutletContext() {
4885 this.outlet = null;
4886 this.route = null;
4887 this.resolver = null;
4888 this.children = new ChildrenOutletContexts();
4889 this.attachRef = null;
4890 }
4891 return OutletContext;
4892}());
4893/**
4894 * Store contextual information about the children (= nested) `RouterOutlet`
4895 *
4896 * @publicApi
4897 */
4898var ChildrenOutletContexts = /** @class */ (function () {
4899 function ChildrenOutletContexts() {
4900 // contexts for child outlets, by name.
4901 this.contexts = new Map();
4902 }
4903 /** Called when a `RouterOutlet` directive is instantiated */
4904 ChildrenOutletContexts.prototype.onChildOutletCreated = function (childName, outlet) {
4905 var context = this.getOrCreateContext(childName);
4906 context.outlet = outlet;
4907 this.contexts.set(childName, context);
4908 };
4909 /**
4910 * Called when a `RouterOutlet` directive is destroyed.
4911 * We need to keep the context as the outlet could be destroyed inside a NgIf and might be
4912 * re-created later.
4913 */
4914 ChildrenOutletContexts.prototype.onChildOutletDestroyed = function (childName) {
4915 var context = this.getContext(childName);
4916 if (context) {
4917 context.outlet = null;
4918 }
4919 };
4920 /**
4921 * Called when the corresponding route is deactivated during navigation.
4922 * Because the component get destroyed, all children outlet are destroyed.
4923 */
4924 ChildrenOutletContexts.prototype.onOutletDeactivated = function () {
4925 var contexts = this.contexts;
4926 this.contexts = new Map();
4927 return contexts;
4928 };
4929 ChildrenOutletContexts.prototype.onOutletReAttached = function (contexts) { this.contexts = contexts; };
4930 ChildrenOutletContexts.prototype.getOrCreateContext = function (childName) {
4931 var context = this.getContext(childName);
4932 if (!context) {
4933 context = new OutletContext();
4934 this.contexts.set(childName, context);
4935 }
4936 return context;
4937 };
4938 ChildrenOutletContexts.prototype.getContext = function (childName) { return this.contexts.get(childName) || null; };
4939 return ChildrenOutletContexts;
4940}());
4941
4942/**
4943 * @license
4944 * Copyright Google Inc. All Rights Reserved.
4945 *
4946 * Use of this source code is governed by an MIT-style license that can be
4947 * found in the LICENSE file at https://angular.io/license
4948 */
4949/**
4950 * @description
4951 *
4952 * Acts as a placeholder that Angular dynamically fills based on the current router state.
4953 *
4954 * ```
4955 * <router-outlet></router-outlet>
4956 * <router-outlet name='left'></router-outlet>
4957 * <router-outlet name='right'></router-outlet>
4958 * ```
4959 *
4960 * A router outlet will emit an activate event any time a new component is being instantiated,
4961 * and a deactivate event when it is being destroyed.
4962 *
4963 * ```
4964 * <router-outlet
4965 * (activate)='onActivate($event)'
4966 * (deactivate)='onDeactivate($event)'></router-outlet>
4967 * ```
4968 * @ngModule RouterModule
4969 *
4970 * @publicApi
4971 */
4972var RouterOutlet = /** @class */ (function () {
4973 function RouterOutlet(parentContexts, location, resolver, name, changeDetector) {
4974 this.parentContexts = parentContexts;
4975 this.location = location;
4976 this.resolver = resolver;
4977 this.changeDetector = changeDetector;
4978 this.activated = null;
4979 this._activatedRoute = null;
4980 this.activateEvents = new EventEmitter();
4981 this.deactivateEvents = new EventEmitter();
4982 this.name = name || PRIMARY_OUTLET;
4983 parentContexts.onChildOutletCreated(this.name, this);
4984 }
4985 RouterOutlet.prototype.ngOnDestroy = function () { this.parentContexts.onChildOutletDestroyed(this.name); };
4986 RouterOutlet.prototype.ngOnInit = function () {
4987 if (!this.activated) {
4988 // If the outlet was not instantiated at the time the route got activated we need to populate
4989 // the outlet when it is initialized (ie inside a NgIf)
4990 var context = this.parentContexts.getContext(this.name);
4991 if (context && context.route) {
4992 if (context.attachRef) {
4993 // `attachRef` is populated when there is an existing component to mount
4994 this.attach(context.attachRef, context.route);
4995 }
4996 else {
4997 // otherwise the component defined in the configuration is created
4998 this.activateWith(context.route, context.resolver || null);
4999 }
5000 }
5001 }
5002 };
5003 Object.defineProperty(RouterOutlet.prototype, "isActivated", {
5004 get: function () { return !!this.activated; },
5005 enumerable: true,
5006 configurable: true
5007 });
5008 Object.defineProperty(RouterOutlet.prototype, "component", {
5009 get: function () {
5010 if (!this.activated)
5011 throw new Error('Outlet is not activated');
5012 return this.activated.instance;
5013 },
5014 enumerable: true,
5015 configurable: true
5016 });
5017 Object.defineProperty(RouterOutlet.prototype, "activatedRoute", {
5018 get: function () {
5019 if (!this.activated)
5020 throw new Error('Outlet is not activated');
5021 return this._activatedRoute;
5022 },
5023 enumerable: true,
5024 configurable: true
5025 });
5026 Object.defineProperty(RouterOutlet.prototype, "activatedRouteData", {
5027 get: function () {
5028 if (this._activatedRoute) {
5029 return this._activatedRoute.snapshot.data;
5030 }
5031 return {};
5032 },
5033 enumerable: true,
5034 configurable: true
5035 });
5036 /**
5037 * Called when the `RouteReuseStrategy` instructs to detach the subtree
5038 */
5039 RouterOutlet.prototype.detach = function () {
5040 if (!this.activated)
5041 throw new Error('Outlet is not activated');
5042 this.location.detach();
5043 var cmp = this.activated;
5044 this.activated = null;
5045 this._activatedRoute = null;
5046 return cmp;
5047 };
5048 /**
5049 * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
5050 */
5051 RouterOutlet.prototype.attach = function (ref, activatedRoute) {
5052 this.activated = ref;
5053 this._activatedRoute = activatedRoute;
5054 this.location.insert(ref.hostView);
5055 };
5056 RouterOutlet.prototype.deactivate = function () {
5057 if (this.activated) {
5058 var c = this.component;
5059 this.activated.destroy();
5060 this.activated = null;
5061 this._activatedRoute = null;
5062 this.deactivateEvents.emit(c);
5063 }
5064 };
5065 RouterOutlet.prototype.activateWith = function (activatedRoute, resolver) {
5066 if (this.isActivated) {
5067 throw new Error('Cannot activate an already activated outlet');
5068 }
5069 this._activatedRoute = activatedRoute;
5070 var snapshot = activatedRoute._futureSnapshot;
5071 var component = snapshot.routeConfig.component;
5072 resolver = resolver || this.resolver;
5073 var factory = resolver.resolveComponentFactory(component);
5074 var childContexts = this.parentContexts.getOrCreateContext(this.name).children;
5075 var injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
5076 this.activated = this.location.createComponent(factory, this.location.length, injector);
5077 // Calling `markForCheck` to make sure we will run the change detection when the
5078 // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
5079 this.changeDetector.markForCheck();
5080 this.activateEvents.emit(this.activated.instance);
5081 };
5082 __decorate([
5083 Output('activate'),
5084 __metadata("design:type", Object)
5085 ], RouterOutlet.prototype, "activateEvents", void 0);
5086 __decorate([
5087 Output('deactivate'),
5088 __metadata("design:type", Object)
5089 ], RouterOutlet.prototype, "deactivateEvents", void 0);
5090 RouterOutlet = __decorate([
5091 Directive({ selector: 'router-outlet', exportAs: 'outlet' }),
5092 __param(3, Attribute('name')),
5093 __metadata("design:paramtypes", [ChildrenOutletContexts, ViewContainerRef,
5094 ComponentFactoryResolver, String, ChangeDetectorRef])
5095 ], RouterOutlet);
5096 return RouterOutlet;
5097}());
5098var OutletInjector = /** @class */ (function () {
5099 function OutletInjector(route, childContexts, parent) {
5100 this.route = route;
5101 this.childContexts = childContexts;
5102 this.parent = parent;
5103 }
5104 OutletInjector.prototype.get = function (token, notFoundValue) {
5105 if (token === ActivatedRoute) {
5106 return this.route;
5107 }
5108 if (token === ChildrenOutletContexts) {
5109 return this.childContexts;
5110 }
5111 return this.parent.get(token, notFoundValue);
5112 };
5113 return OutletInjector;
5114}());
5115
5116/**
5117*@license
5118*Copyright Google Inc. All Rights Reserved.
5119*
5120*Use of this source code is governed by an MIT-style license that can be
5121*found in the LICENSE file at https://angular.io/license
5122*/
5123/**
5124 * @description
5125 *
5126 * Provides a preloading strategy.
5127 *
5128 * @publicApi
5129 */
5130var PreloadingStrategy = /** @class */ (function () {
5131 function PreloadingStrategy() {
5132 }
5133 return PreloadingStrategy;
5134}());
5135/**
5136 * @description
5137 *
5138 * Provides a preloading strategy that preloads all modules as quickly as possible.
5139 *
5140 * ```
5141 * RouteModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
5142 * ```
5143 *
5144 * @publicApi
5145 */
5146var PreloadAllModules = /** @class */ (function () {
5147 function PreloadAllModules() {
5148 }
5149 PreloadAllModules.prototype.preload = function (route, fn) {
5150 return fn().pipe(catchError(function () { return of(null); }));
5151 };
5152 return PreloadAllModules;
5153}());
5154/**
5155 * @description
5156 *
5157 * Provides a preloading strategy that does not preload any modules.
5158 *
5159 * This strategy is enabled by default.
5160 *
5161 * @publicApi
5162 */
5163var NoPreloading = /** @class */ (function () {
5164 function NoPreloading() {
5165 }
5166 NoPreloading.prototype.preload = function (route, fn) { return of(null); };
5167 return NoPreloading;
5168}());
5169/**
5170 * The preloader optimistically loads all router configurations to
5171 * make navigations into lazily-loaded sections of the application faster.
5172 *
5173 * The preloader runs in the background. When the router bootstraps, the preloader
5174 * starts listening to all navigation events. After every such event, the preloader
5175 * will check if any configurations can be loaded lazily.
5176 *
5177 * If a route is protected by `canLoad` guards, the preloaded will not load it.
5178 *
5179 * @publicApi
5180 */
5181var RouterPreloader = /** @class */ (function () {
5182 function RouterPreloader(router, moduleLoader, compiler, injector, preloadingStrategy) {
5183 this.router = router;
5184 this.injector = injector;
5185 this.preloadingStrategy = preloadingStrategy;
5186 var onStartLoad = function (r) { return router.triggerEvent(new RouteConfigLoadStart(r)); };
5187 var onEndLoad = function (r) { return router.triggerEvent(new RouteConfigLoadEnd(r)); };
5188 this.loader = new RouterConfigLoader(moduleLoader, compiler, onStartLoad, onEndLoad);
5189 }
5190 RouterPreloader.prototype.setUpPreloading = function () {
5191 var _this = this;
5192 this.subscription =
5193 this.router.events
5194 .pipe(filter(function (e) { return e instanceof NavigationEnd; }), concatMap(function () { return _this.preload(); }))
5195 .subscribe(function () { });
5196 };
5197 RouterPreloader.prototype.preload = function () {
5198 var ngModule = this.injector.get(NgModuleRef);
5199 return this.processRoutes(ngModule, this.router.config);
5200 };
5201 // TODO(jasonaden): This class relies on code external to the class to call setUpPreloading. If
5202 // this hasn't been done, ngOnDestroy will fail as this.subscription will be undefined. This
5203 // should be refactored.
5204 RouterPreloader.prototype.ngOnDestroy = function () { this.subscription.unsubscribe(); };
5205 RouterPreloader.prototype.processRoutes = function (ngModule, routes) {
5206 var e_1, _a;
5207 var res = [];
5208 try {
5209 for (var routes_1 = __values(routes), routes_1_1 = routes_1.next(); !routes_1_1.done; routes_1_1 = routes_1.next()) {
5210 var route = routes_1_1.value;
5211 // we already have the config loaded, just recurse
5212 if (route.loadChildren && !route.canLoad && route._loadedConfig) {
5213 var childConfig = route._loadedConfig;
5214 res.push(this.processRoutes(childConfig.module, childConfig.routes));
5215 // no config loaded, fetch the config
5216 }
5217 else if (route.loadChildren && !route.canLoad) {
5218 res.push(this.preloadConfig(ngModule, route));
5219 // recurse into children
5220 }
5221 else if (route.children) {
5222 res.push(this.processRoutes(ngModule, route.children));
5223 }
5224 }
5225 }
5226 catch (e_1_1) { e_1 = { error: e_1_1 }; }
5227 finally {
5228 try {
5229 if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
5230 }
5231 finally { if (e_1) throw e_1.error; }
5232 }
5233 return from(res).pipe(mergeAll(), map(function (_) { return void 0; }));
5234 };
5235 RouterPreloader.prototype.preloadConfig = function (ngModule, route) {
5236 var _this = this;
5237 return this.preloadingStrategy.preload(route, function () {
5238 var loaded$ = _this.loader.load(ngModule.injector, route);
5239 return loaded$.pipe(mergeMap(function (config) {
5240 route._loadedConfig = config;
5241 return _this.processRoutes(config.module, config.routes);
5242 }));
5243 });
5244 };
5245 RouterPreloader = __decorate([
5246 Injectable(),
5247 __metadata("design:paramtypes", [Router, NgModuleFactoryLoader, Compiler,
5248 Injector, PreloadingStrategy])
5249 ], RouterPreloader);
5250 return RouterPreloader;
5251}());
5252
5253/**
5254 * @license
5255 * Copyright Google Inc. All Rights Reserved.
5256 *
5257 * Use of this source code is governed by an MIT-style license that can be
5258 * found in the LICENSE file at https://angular.io/license
5259 */
5260var RouterScroller = /** @class */ (function () {
5261 function RouterScroller(router,
5262 /** @docsNotRequired */ viewportScroller, options) {
5263 if (options === void 0) { options = {}; }
5264 this.router = router;
5265 this.viewportScroller = viewportScroller;
5266 this.options = options;
5267 this.lastId = 0;
5268 this.lastSource = 'imperative';
5269 this.restoredId = 0;
5270 this.store = {};
5271 // Default both options to 'disabled'
5272 options.scrollPositionRestoration = options.scrollPositionRestoration || 'disabled';
5273 options.anchorScrolling = options.anchorScrolling || 'disabled';
5274 }
5275 RouterScroller.prototype.init = function () {
5276 // we want to disable the automatic scrolling because having two places
5277 // responsible for scrolling results race conditions, especially given
5278 // that browser don't implement this behavior consistently
5279 if (this.options.scrollPositionRestoration !== 'disabled') {
5280 this.viewportScroller.setHistoryScrollRestoration('manual');
5281 }
5282 this.routerEventsSubscription = this.createScrollEvents();
5283 this.scrollEventsSubscription = this.consumeScrollEvents();
5284 };
5285 RouterScroller.prototype.createScrollEvents = function () {
5286 var _this = this;
5287 return this.router.events.subscribe(function (e) {
5288 if (e instanceof NavigationStart) {
5289 // store the scroll position of the current stable navigations.
5290 _this.store[_this.lastId] = _this.viewportScroller.getScrollPosition();
5291 _this.lastSource = e.navigationTrigger;
5292 _this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
5293 }
5294 else if (e instanceof NavigationEnd) {
5295 _this.lastId = e.id;
5296 _this.scheduleScrollEvent(e, _this.router.parseUrl(e.urlAfterRedirects).fragment);
5297 }
5298 });
5299 };
5300 RouterScroller.prototype.consumeScrollEvents = function () {
5301 var _this = this;
5302 return this.router.events.subscribe(function (e) {
5303 if (!(e instanceof Scroll))
5304 return;
5305 // a popstate event. The pop state event will always ignore anchor scrolling.
5306 if (e.position) {
5307 if (_this.options.scrollPositionRestoration === 'top') {
5308 _this.viewportScroller.scrollToPosition([0, 0]);
5309 }
5310 else if (_this.options.scrollPositionRestoration === 'enabled') {
5311 _this.viewportScroller.scrollToPosition(e.position);
5312 }
5313 // imperative navigation "forward"
5314 }
5315 else {
5316 if (e.anchor && _this.options.anchorScrolling === 'enabled') {
5317 _this.viewportScroller.scrollToAnchor(e.anchor);
5318 }
5319 else if (_this.options.scrollPositionRestoration !== 'disabled') {
5320 _this.viewportScroller.scrollToPosition([0, 0]);
5321 }
5322 }
5323 });
5324 };
5325 RouterScroller.prototype.scheduleScrollEvent = function (routerEvent, anchor) {
5326 this.router.triggerEvent(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
5327 };
5328 RouterScroller.prototype.ngOnDestroy = function () {
5329 if (this.routerEventsSubscription) {
5330 this.routerEventsSubscription.unsubscribe();
5331 }
5332 if (this.scrollEventsSubscription) {
5333 this.scrollEventsSubscription.unsubscribe();
5334 }
5335 };
5336 return RouterScroller;
5337}());
5338
5339/**
5340 * @license
5341 * Copyright Google Inc. All Rights Reserved.
5342 *
5343 * Use of this source code is governed by an MIT-style license that can be
5344 * found in the LICENSE file at https://angular.io/license
5345 */
5346/**
5347 * The directives defined in the `RouterModule`.
5348 */
5349var ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent];
5350/**
5351 * A [DI token](guide/glossary/#di-token) for the router service.
5352 *
5353 * @publicApi
5354 */
5355var ROUTER_CONFIGURATION = new InjectionToken('ROUTER_CONFIGURATION');
5356/**
5357 * @docsNotRequired
5358 */
5359var ROUTER_FORROOT_GUARD = new InjectionToken('ROUTER_FORROOT_GUARD');
5360var ɵ0 = { enableTracing: false };
5361var ROUTER_PROVIDERS = [
5362 Location,
5363 { provide: UrlSerializer, useClass: DefaultUrlSerializer },
5364 {
5365 provide: Router,
5366 useFactory: setupRouter,
5367 deps: [
5368 ApplicationRef, UrlSerializer, ChildrenOutletContexts, Location, Injector,
5369 NgModuleFactoryLoader, Compiler, ROUTES, ROUTER_CONFIGURATION,
5370 [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()]
5371 ]
5372 },
5373 ChildrenOutletContexts,
5374 { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
5375 { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader },
5376 RouterPreloader,
5377 NoPreloading,
5378 PreloadAllModules,
5379 { provide: ROUTER_CONFIGURATION, useValue: ɵ0 },
5380];
5381function routerNgProbeToken() {
5382 return new NgProbeToken('Router', Router);
5383}
5384/**
5385 * @usageNotes
5386 *
5387 * RouterModule can be imported multiple times: once per lazily-loaded bundle.
5388 * Since the router deals with a global shared resource--location, we cannot have
5389 * more than one router service active.
5390 *
5391 * That is why there are two ways to create the module: `RouterModule.forRoot` and
5392 * `RouterModule.forChild`.
5393 *
5394 * * `forRoot` creates a module that contains all the directives, the given routes, and the router
5395 * service itself.
5396 * * `forChild` creates a module that contains all the directives and the given routes, but does not
5397 * include the router service.
5398 *
5399 * When registered at the root, the module should be used as follows
5400 *
5401 * ```
5402 * @NgModule({
5403 * imports: [RouterModule.forRoot(ROUTES)]
5404 * })
5405 * class MyNgModule {}
5406 * ```
5407 *
5408 * For submodules and lazy loaded submodules the module should be used as follows:
5409 *
5410 * ```
5411 * @NgModule({
5412 * imports: [RouterModule.forChild(ROUTES)]
5413 * })
5414 * class MyNgModule {}
5415 * ```
5416 *
5417 * @description
5418 *
5419 * Adds router directives and providers.
5420 *
5421 * Managing state transitions is one of the hardest parts of building applications. This is
5422 * especially true on the web, where you also need to ensure that the state is reflected in the URL.
5423 * In addition, we often want to split applications into multiple bundles and load them on demand.
5424 * Doing this transparently is not trivial.
5425 *
5426 * The Angular router service solves these problems. Using the router, you can declaratively specify
5427 * application states, manage state transitions while taking care of the URL, and load bundles on
5428 * demand.
5429 *
5430 * @see [Routing and Navigation](guide/router.html) for an
5431 * overview of how the router service should be used.
5432 *
5433 * @publicApi
5434 */
5435var RouterModule = /** @class */ (function () {
5436 // Note: We are injecting the Router so it gets created eagerly...
5437 function RouterModule(guard, router) {
5438 }
5439 RouterModule_1 = RouterModule;
5440 /**
5441 * Creates and configures a module with all the router providers and directives.
5442 * Optionally sets up an application listener to perform an initial navigation.
5443 *
5444 * @param routes An array of `Route` objects that define the navigation paths for the application.
5445 * @param config An `ExtraOptions` configuration object that controls how navigation is performed.
5446 * @return The new router module.
5447 */
5448 RouterModule.forRoot = function (routes, config) {
5449 return {
5450 ngModule: RouterModule_1,
5451 providers: [
5452 ROUTER_PROVIDERS,
5453 provideRoutes(routes),
5454 {
5455 provide: ROUTER_FORROOT_GUARD,
5456 useFactory: provideForRootGuard,
5457 deps: [[Router, new Optional(), new SkipSelf()]]
5458 },
5459 { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
5460 {
5461 provide: LocationStrategy,
5462 useFactory: provideLocationStrategy,
5463 deps: [
5464 PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], ROUTER_CONFIGURATION
5465 ]
5466 },
5467 {
5468 provide: RouterScroller,
5469 useFactory: createRouterScroller,
5470 deps: [Router, ViewportScroller, ROUTER_CONFIGURATION]
5471 },
5472 {
5473 provide: PreloadingStrategy,
5474 useExisting: config && config.preloadingStrategy ? config.preloadingStrategy :
5475 NoPreloading
5476 },
5477 { provide: NgProbeToken, multi: true, useFactory: routerNgProbeToken },
5478 provideRouterInitializer(),
5479 ],
5480 };
5481 };
5482 /**
5483 * Creates a module with all the router directives and a provider registering routes.
5484 */
5485 RouterModule.forChild = function (routes) {
5486 return { ngModule: RouterModule_1, providers: [provideRoutes(routes)] };
5487 };
5488 var RouterModule_1;
5489 RouterModule = RouterModule_1 = __decorate([
5490 NgModule({
5491 declarations: ROUTER_DIRECTIVES,
5492 exports: ROUTER_DIRECTIVES,
5493 entryComponents: [ɵEmptyOutletComponent]
5494 }),
5495 __param(0, Optional()), __param(0, Inject(ROUTER_FORROOT_GUARD)), __param(1, Optional()),
5496 __metadata("design:paramtypes", [Object, Router])
5497 ], RouterModule);
5498 return RouterModule;
5499}());
5500function createRouterScroller(router, viewportScroller, config) {
5501 if (config.scrollOffset) {
5502 viewportScroller.setOffset(config.scrollOffset);
5503 }
5504 return new RouterScroller(router, viewportScroller, config);
5505}
5506function provideLocationStrategy(platformLocationStrategy, baseHref, options) {
5507 if (options === void 0) { options = {}; }
5508 return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
5509 new PathLocationStrategy(platformLocationStrategy, baseHref);
5510}
5511function provideForRootGuard(router) {
5512 if (router) {
5513 throw new Error("RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.");
5514 }
5515 return 'guarded';
5516}
5517/**
5518 * Registers a [DI provider](guide/glossary#provider) for a set of routes.
5519 * @param routes The route configuration to provide.
5520 *
5521 * @usageNotes
5522 *
5523 * ```
5524 * @NgModule({
5525 * imports: [RouterModule.forChild(ROUTES)],
5526 * providers: [provideRoutes(EXTRA_ROUTES)]
5527 * })
5528 * class MyNgModule {}
5529 * ```
5530 *
5531 * @publicApi
5532 */
5533function provideRoutes(routes) {
5534 return [
5535 { provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes },
5536 { provide: ROUTES, multi: true, useValue: routes },
5537 ];
5538}
5539function setupRouter(ref, urlSerializer, contexts, location, injector, loader, compiler, config, opts, urlHandlingStrategy, routeReuseStrategy) {
5540 if (opts === void 0) { opts = {}; }
5541 var router = new Router(null, urlSerializer, contexts, location, injector, loader, compiler, flatten(config));
5542 if (urlHandlingStrategy) {
5543 router.urlHandlingStrategy = urlHandlingStrategy;
5544 }
5545 if (routeReuseStrategy) {
5546 router.routeReuseStrategy = routeReuseStrategy;
5547 }
5548 if (opts.errorHandler) {
5549 router.errorHandler = opts.errorHandler;
5550 }
5551 if (opts.malformedUriErrorHandler) {
5552 router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
5553 }
5554 if (opts.enableTracing) {
5555 var dom_1 = ɵgetDOM();
5556 router.events.subscribe(function (e) {
5557 dom_1.logGroup("Router Event: " + e.constructor.name);
5558 dom_1.log(e.toString());
5559 dom_1.log(e);
5560 dom_1.logGroupEnd();
5561 });
5562 }
5563 if (opts.onSameUrlNavigation) {
5564 router.onSameUrlNavigation = opts.onSameUrlNavigation;
5565 }
5566 if (opts.paramsInheritanceStrategy) {
5567 router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
5568 }
5569 if (opts.urlUpdateStrategy) {
5570 router.urlUpdateStrategy = opts.urlUpdateStrategy;
5571 }
5572 if (opts.relativeLinkResolution) {
5573 router.relativeLinkResolution = opts.relativeLinkResolution;
5574 }
5575 return router;
5576}
5577function rootRoute(router) {
5578 return router.routerState.root;
5579}
5580/**
5581 * Router initialization requires two steps:
5582 *
5583 * First, we start the navigation in a `APP_INITIALIZER` to block the bootstrap if
5584 * a resolver or a guard executes asynchronously.
5585 *
5586 * Next, we actually run activation in a `BOOTSTRAP_LISTENER`, using the
5587 * `afterPreactivation` hook provided by the router.
5588 * The router navigation starts, reaches the point when preactivation is done, and then
5589 * pauses. It waits for the hook to be resolved. We then resolve it only in a bootstrap listener.
5590 */
5591var RouterInitializer = /** @class */ (function () {
5592 function RouterInitializer(injector) {
5593 this.injector = injector;
5594 this.initNavigation = false;
5595 this.resultOfPreactivationDone = new Subject();
5596 }
5597 RouterInitializer.prototype.appInitializer = function () {
5598 var _this = this;
5599 var p = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
5600 return p.then(function () {
5601 var resolve = null;
5602 var res = new Promise(function (r) { return resolve = r; });
5603 var router = _this.injector.get(Router);
5604 var opts = _this.injector.get(ROUTER_CONFIGURATION);
5605 if (_this.isLegacyDisabled(opts) || _this.isLegacyEnabled(opts)) {
5606 resolve(true);
5607 }
5608 else if (opts.initialNavigation === 'disabled') {
5609 router.setUpLocationChangeListener();
5610 resolve(true);
5611 }
5612 else if (opts.initialNavigation === 'enabled') {
5613 router.hooks.afterPreactivation = function () {
5614 // only the initial navigation should be delayed
5615 if (!_this.initNavigation) {
5616 _this.initNavigation = true;
5617 resolve(true);
5618 return _this.resultOfPreactivationDone;
5619 // subsequent navigations should not be delayed
5620 }
5621 else {
5622 return of(null);
5623 }
5624 };
5625 router.initialNavigation();
5626 }
5627 else {
5628 throw new Error("Invalid initialNavigation options: '" + opts.initialNavigation + "'");
5629 }
5630 return res;
5631 });
5632 };
5633 RouterInitializer.prototype.bootstrapListener = function (bootstrappedComponentRef) {
5634 var opts = this.injector.get(ROUTER_CONFIGURATION);
5635 var preloader = this.injector.get(RouterPreloader);
5636 var routerScroller = this.injector.get(RouterScroller);
5637 var router = this.injector.get(Router);
5638 var ref = this.injector.get(ApplicationRef);
5639 if (bootstrappedComponentRef !== ref.components[0]) {
5640 return;
5641 }
5642 if (this.isLegacyEnabled(opts)) {
5643 router.initialNavigation();
5644 }
5645 else if (this.isLegacyDisabled(opts)) {
5646 router.setUpLocationChangeListener();
5647 }
5648 preloader.setUpPreloading();
5649 routerScroller.init();
5650 router.resetRootComponentType(ref.componentTypes[0]);
5651 this.resultOfPreactivationDone.next(null);
5652 this.resultOfPreactivationDone.complete();
5653 };
5654 RouterInitializer.prototype.isLegacyEnabled = function (opts) {
5655 return opts.initialNavigation === 'legacy_enabled' || opts.initialNavigation === true ||
5656 opts.initialNavigation === undefined;
5657 };
5658 RouterInitializer.prototype.isLegacyDisabled = function (opts) {
5659 return opts.initialNavigation === 'legacy_disabled' || opts.initialNavigation === false;
5660 };
5661 RouterInitializer = __decorate([
5662 Injectable(),
5663 __metadata("design:paramtypes", [Injector])
5664 ], RouterInitializer);
5665 return RouterInitializer;
5666}());
5667function getAppInitializer(r) {
5668 return r.appInitializer.bind(r);
5669}
5670function getBootstrapListener(r) {
5671 return r.bootstrapListener.bind(r);
5672}
5673/**
5674 * A [DI token](guide/glossary/#di-token) for the router initializer that
5675 * is called after the app is bootstrapped.
5676 *
5677 * @publicApi
5678 */
5679var ROUTER_INITIALIZER = new InjectionToken('Router Initializer');
5680function provideRouterInitializer() {
5681 return [
5682 RouterInitializer,
5683 {
5684 provide: APP_INITIALIZER,
5685 multi: true,
5686 useFactory: getAppInitializer,
5687 deps: [RouterInitializer]
5688 },
5689 { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener, deps: [RouterInitializer] },
5690 { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
5691 ];
5692}
5693
5694/**
5695 * @license
5696 * Copyright Google Inc. All Rights Reserved.
5697 *
5698 * Use of this source code is governed by an MIT-style license that can be
5699 * found in the LICENSE file at https://angular.io/license
5700 */
5701/**
5702 * @publicApi
5703 */
5704var VERSION = new Version('8.2.0');
5705
5706/**
5707 * @license
5708 * Copyright Google Inc. All Rights Reserved.
5709 *
5710 * Use of this source code is governed by an MIT-style license that can be
5711 * found in the LICENSE file at https://angular.io/license
5712 */
5713
5714/**
5715 * @license
5716 * Copyright Google Inc. All Rights Reserved.
5717 *
5718 * Use of this source code is governed by an MIT-style license that can be
5719 * found in the LICENSE file at https://angular.io/license
5720 */
5721
5722/**
5723 * @license
5724 * Copyright Google Inc. All Rights Reserved.
5725 *
5726 * Use of this source code is governed by an MIT-style license that can be
5727 * found in the LICENSE file at https://angular.io/license
5728 */
5729// This file only reexports content of the `src` folder. Keep it that way.
5730
5731/**
5732 * @license
5733 * Copyright Google Inc. All Rights Reserved.
5734 *
5735 * Use of this source code is governed by an MIT-style license that can be
5736 * found in the LICENSE file at https://angular.io/license
5737 */
5738
5739/**
5740 * Generated bundle index. Do not edit.
5741 */
5742
5743export { ɵEmptyOutletComponent as ɵangular_packages_router_router_l, ɵEmptyOutletComponent, ROUTER_FORROOT_GUARD as ɵangular_packages_router_router_a, RouterInitializer as ɵangular_packages_router_router_h, createRouterScroller as ɵangular_packages_router_router_c, getAppInitializer as ɵangular_packages_router_router_i, getBootstrapListener as ɵangular_packages_router_router_j, provideForRootGuard as ɵangular_packages_router_router_e, provideLocationStrategy as ɵangular_packages_router_router_d, provideRouterInitializer as ɵangular_packages_router_router_k, rootRoute as ɵangular_packages_router_router_g, routerNgProbeToken as ɵangular_packages_router_router_b, setupRouter as ɵangular_packages_router_router_f, RouterScroller as ɵangular_packages_router_router_o, Tree as ɵangular_packages_router_router_m, TreeNode as ɵangular_packages_router_router_n, RouterLink, RouterLinkWithHref, RouterLinkActive, RouterOutlet, ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized, Scroll, RouteReuseStrategy, Router, ROUTES, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, RouterModule, provideRoutes, ChildrenOutletContexts, OutletContext, NoPreloading, PreloadAllModules, PreloadingStrategy, RouterPreloader, ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, PRIMARY_OUTLET, convertToParamMap, UrlHandlingStrategy, DefaultUrlSerializer, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, VERSION, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, flatten as ɵflatten };
5744//# sourceMappingURL=router.js.map