UNPKG

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