@angular/router 16.0.0-next.4 → 16.0.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/esm2022/src/apply_redirects.mjs +112 -0
  2. package/{esm2020 → esm2022}/src/components/empty_outlet.mjs +4 -4
  3. package/esm2022/src/create_url_tree.mjs +418 -0
  4. package/{esm2020 → esm2022}/src/directives/router_link.mjs +4 -4
  5. package/{esm2020 → esm2022}/src/directives/router_link_active.mjs +4 -4
  6. package/esm2022/src/directives/router_outlet.mjs +259 -0
  7. package/esm2022/src/navigation_transition.mjs +391 -0
  8. package/esm2022/src/operators/activate_routes.mjs +180 -0
  9. package/esm2022/src/operators/recognize.mjs +16 -0
  10. package/{esm2020 → esm2022}/src/page_title_strategy.mjs +7 -7
  11. package/esm2022/src/provide_router.mjs +478 -0
  12. package/esm2022/src/recognize.mjs +360 -0
  13. package/{esm2020 → esm2022}/src/route_reuse_strategy.mjs +7 -7
  14. package/esm2022/src/router.mjs +719 -0
  15. package/esm2022/src/router_config.mjs +18 -0
  16. package/esm2022/src/router_config_loader.mjs +132 -0
  17. package/esm2022/src/router_module.mjs +219 -0
  18. package/{esm2020 → esm2022}/src/router_outlet_context.mjs +4 -4
  19. package/esm2022/src/router_preloader.mjs +167 -0
  20. package/{esm2020 → esm2022}/src/router_scroller.mjs +4 -4
  21. package/esm2022/src/router_state.mjs +408 -0
  22. package/{esm2020 → esm2022}/src/url_handling_strategy.mjs +7 -7
  23. package/esm2022/src/url_tree.mjs +642 -0
  24. package/esm2022/src/utils/navigations.mjs +42 -0
  25. package/{esm2020 → esm2022}/src/version.mjs +1 -1
  26. package/{esm2020 → esm2022}/testing/src/router_testing_harness.mjs +7 -7
  27. package/{esm2020 → esm2022}/testing/src/router_testing_module.mjs +10 -10
  28. package/{fesm2020 → fesm2022}/router.mjs +450 -562
  29. package/fesm2022/router.mjs.map +1 -0
  30. package/{fesm2020 → fesm2022}/testing.mjs +16 -16
  31. package/{fesm2020 → fesm2022}/testing.mjs.map +1 -1
  32. package/{fesm2020 → fesm2022}/upgrade.mjs +1 -1
  33. package/index.d.ts +5 -2
  34. package/package.json +14 -24
  35. package/testing/index.d.ts +1 -1
  36. package/upgrade/index.d.ts +1 -1
  37. package/esm2020/src/apply_redirects.mjs +0 -331
  38. package/esm2020/src/create_url_tree.mjs +0 -417
  39. package/esm2020/src/directives/router_outlet.mjs +0 -259
  40. package/esm2020/src/navigation_transition.mjs +0 -399
  41. package/esm2020/src/operators/activate_routes.mjs +0 -177
  42. package/esm2020/src/operators/apply_redirects.mjs +0 -14
  43. package/esm2020/src/operators/recognize.mjs +0 -14
  44. package/esm2020/src/provide_router.mjs +0 -477
  45. package/esm2020/src/recognize.mjs +0 -270
  46. package/esm2020/src/router.mjs +0 -710
  47. package/esm2020/src/router_config.mjs +0 -19
  48. package/esm2020/src/router_config_loader.mjs +0 -131
  49. package/esm2020/src/router_module.mjs +0 -216
  50. package/esm2020/src/router_preloader.mjs +0 -167
  51. package/esm2020/src/router_state.mjs +0 -409
  52. package/esm2020/src/url_tree.mjs +0 -631
  53. package/esm2020/src/utils/navigations.mjs +0 -42
  54. package/fesm2015/router.mjs +0 -7001
  55. package/fesm2015/router.mjs.map +0 -1
  56. package/fesm2015/testing.mjs +0 -270
  57. package/fesm2015/testing.mjs.map +0 -1
  58. package/fesm2015/upgrade.mjs +0 -146
  59. package/fesm2015/upgrade.mjs.map +0 -1
  60. package/fesm2020/router.mjs.map +0 -1
  61. /package/{esm2020 → esm2022}/index.mjs +0 -0
  62. /package/{esm2020 → esm2022}/public_api.mjs +0 -0
  63. /package/{esm2020 → esm2022}/router.mjs +0 -0
  64. /package/{esm2020 → esm2022}/src/create_router_state.mjs +0 -0
  65. /package/{esm2020 → esm2022}/src/errors.mjs +0 -0
  66. /package/{esm2020 → esm2022}/src/events.mjs +0 -0
  67. /package/{esm2020 → esm2022}/src/index.mjs +0 -0
  68. /package/{esm2020 → esm2022}/src/models.mjs +0 -0
  69. /package/{esm2020 → esm2022}/src/models_deprecated.mjs +0 -0
  70. /package/{esm2020 → esm2022}/src/navigation_canceling_error.mjs +0 -0
  71. /package/{esm2020 → esm2022}/src/operators/check_guards.mjs +0 -0
  72. /package/{esm2020 → esm2022}/src/operators/prioritized_guard_value.mjs +0 -0
  73. /package/{esm2020 → esm2022}/src/operators/resolve_data.mjs +0 -0
  74. /package/{esm2020 → esm2022}/src/operators/switch_tap.mjs +0 -0
  75. /package/{esm2020 → esm2022}/src/private_export.mjs +0 -0
  76. /package/{esm2020 → esm2022}/src/shared.mjs +0 -0
  77. /package/{esm2020 → esm2022}/src/utils/collection.mjs +0 -0
  78. /package/{esm2020 → esm2022}/src/utils/config.mjs +0 -0
  79. /package/{esm2020 → esm2022}/src/utils/config_matching.mjs +0 -0
  80. /package/{esm2020 → esm2022}/src/utils/functional_guards.mjs +0 -0
  81. /package/{esm2020 → esm2022}/src/utils/preactivation.mjs +0 -0
  82. /package/{esm2020 → esm2022}/src/utils/tree.mjs +0 -0
  83. /package/{esm2020 → esm2022}/src/utils/type_guards.mjs +0 -0
  84. /package/{esm2020 → esm2022}/testing/index.mjs +0 -0
  85. /package/{esm2020 → esm2022}/testing/public_api.mjs +0 -0
  86. /package/{esm2020 → esm2022}/testing/src/testing.mjs +0 -0
  87. /package/{esm2020 → esm2022}/testing/testing.mjs +0 -0
  88. /package/{esm2020 → esm2022}/upgrade/index.mjs +0 -0
  89. /package/{esm2020 → esm2022}/upgrade/public_api.mjs +0 -0
  90. /package/{esm2020 → esm2022}/upgrade/src/upgrade.mjs +0 -0
  91. /package/{esm2020 → esm2022}/upgrade/upgrade.mjs +0 -0
  92. /package/{fesm2020 → fesm2022}/upgrade.mjs.map +0 -0
@@ -1,15 +1,15 @@
1
1
  /**
2
- * @license Angular v16.0.0-next.4
2
+ * @license Angular v16.0.0-next.5
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
6
6
 
7
7
  import * as i0 from '@angular/core';
8
- import { ɵisPromise, ɵRuntimeError, Injectable, EventEmitter, inject, ViewContainerRef, ChangeDetectorRef, EnvironmentInjector, Directive, Input, Output, Component, createEnvironmentInjector, ɵisNgModule, isStandalone, ɵisInjectable, InjectionToken, Compiler, InjectFlags, NgModuleFactory, ɵConsole, NgZone, ɵcoerceToBoolean, ɵɵsanitizeUrlOrResourceUrl, Attribute, HostBinding, HostListener, Optional, ContentChildren, makeEnvironmentProviders, APP_BOOTSTRAP_LISTENER, ENVIRONMENT_INITIALIZER, Injector, ApplicationRef, APP_INITIALIZER, NgProbeToken, SkipSelf, NgModule, Inject, Version } from '@angular/core';
9
- import { isObservable, from, of, BehaviorSubject, EmptyError, combineLatest, concat, defer, pipe, throwError, Observable, EMPTY, ConnectableObservable, Subject } from 'rxjs';
8
+ import { ɵisPromise, ɵRuntimeError, Injectable, EventEmitter, inject, ViewContainerRef, ChangeDetectorRef, EnvironmentInjector, Directive, Input, Output, Component, createEnvironmentInjector, ɵisNgModule, isStandalone, ɵisInjectable, InjectionToken, Compiler, InjectFlags, NgModuleFactory, ɵConsole, ɵInitialRenderPendingTasks, NgZone, ɵcoerceToBoolean, ɵɵsanitizeUrlOrResourceUrl, Attribute, HostBinding, HostListener, Optional, ContentChildren, makeEnvironmentProviders, APP_BOOTSTRAP_LISTENER, ENVIRONMENT_INITIALIZER, Injector, ApplicationRef, APP_INITIALIZER, NgProbeToken, SkipSelf, NgModule, Inject, Version } from '@angular/core';
9
+ import { isObservable, from, of, BehaviorSubject, EmptyError, combineLatest, concat, defer, pipe, throwError, EMPTY, ConnectableObservable, Subject } from 'rxjs';
10
10
  import * as i3 from '@angular/common';
11
11
  import { Location, ViewportScroller, LOCATION_INITIALIZED, LocationStrategy, HashLocationStrategy, PathLocationStrategy } from '@angular/common';
12
- import { map, switchMap, take, startWith, filter, mergeMap, first, concatMap, tap, catchError, scan, last as last$1, takeWhile, defaultIfEmpty, takeLast, mapTo, finalize, refCount, mergeAll } from 'rxjs/operators';
12
+ import { map, switchMap, take, startWith, filter, mergeMap, first, concatMap, tap, catchError, scan, defaultIfEmpty, last as last$1, takeLast, mapTo, finalize, refCount, mergeAll } from 'rxjs/operators';
13
13
  import * as i1 from '@angular/platform-browser';
14
14
 
15
15
  /**
@@ -162,7 +162,6 @@ function wrapIntoObservable(value) {
162
162
  return of(value);
163
163
  }
164
164
 
165
- const NG_DEV_MODE$a = typeof ngDevMode === 'undefined' || ngDevMode;
166
165
  const pathCompareMap = {
167
166
  'exact': equalSegmentGroups,
168
167
  'subset': containsSegmentGroup,
@@ -287,7 +286,7 @@ class UrlTree {
287
286
  this.root = root;
288
287
  this.queryParams = queryParams;
289
288
  this.fragment = fragment;
290
- if (NG_DEV_MODE$a) {
289
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
291
290
  if (root.segments.length > 0) {
292
291
  throw new ɵRuntimeError(4015 /* RuntimeErrorCode.INVALID_ROOT_URL_SEGMENT */, 'The root `UrlSegmentGroup` should not contain `segments`. ' +
293
292
  'Instead, these segments belong in the `children` so they can be associated with a named outlet.');
@@ -420,10 +419,10 @@ function mapChildrenIntoArray(segment, fn) {
420
419
  * @publicApi
421
420
  */
422
421
  class UrlSerializer {
422
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
423
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }); }
423
424
  }
424
- UrlSerializer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: UrlSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
425
- UrlSerializer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: UrlSerializer, providedIn: 'root', useFactory: () => new DefaultUrlSerializer() });
426
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: UrlSerializer, decorators: [{
425
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: UrlSerializer, decorators: [{
427
426
  type: Injectable,
428
427
  args: [{ providedIn: 'root', useFactory: () => new DefaultUrlSerializer() }]
429
428
  }] });
@@ -635,7 +634,8 @@ class UrlParser {
635
634
  parseSegment() {
636
635
  const path = matchSegments(this.remaining);
637
636
  if (path === '' && this.peekStartsWith(';')) {
638
- throw new ɵRuntimeError(4009 /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */, NG_DEV_MODE$a && `Empty path url segment cannot have parameters: '${this.remaining}'.`);
637
+ throw new ɵRuntimeError(4009 /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
638
+ `Empty path url segment cannot have parameters: '${this.remaining}'.`);
639
639
  }
640
640
  this.capture(path);
641
641
  return new UrlSegment(decode(path), this.parseMatrixParams());
@@ -704,7 +704,7 @@ class UrlParser {
704
704
  // if is is not one of these characters, then the segment was unescaped
705
705
  // or the group was not closed
706
706
  if (next !== '/' && next !== ')' && next !== ';') {
707
- throw new ɵRuntimeError(4010 /* RuntimeErrorCode.UNPARSABLE_URL */, NG_DEV_MODE$a && `Cannot parse url '${this.url}'`);
707
+ throw new ɵRuntimeError(4010 /* RuntimeErrorCode.UNPARSABLE_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot parse url '${this.url}'`);
708
708
  }
709
709
  let outletName = undefined;
710
710
  if (path.indexOf(':') > -1) {
@@ -735,7 +735,7 @@ class UrlParser {
735
735
  }
736
736
  capture(str) {
737
737
  if (!this.consumeOptional(str)) {
738
- throw new ɵRuntimeError(4011 /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */, NG_DEV_MODE$a && `Expected "${str}".`);
738
+ throw new ɵRuntimeError(4011 /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Expected "${str}".`);
739
739
  }
740
740
  }
741
741
  }
@@ -745,17 +745,28 @@ function createRoot(rootCandidate) {
745
745
  rootCandidate;
746
746
  }
747
747
  /**
748
- * Recursively merges primary segment children into their parents and also drops empty children
749
- * (those which have no segments and no children themselves). The latter prevents serializing a
750
- * group into something like `/a(aux:)`, where `aux` is an empty child segment.
748
+ * Recursively
749
+ * - merges primary segment children into their parents
750
+ * - drops empty children (those which have no segments and no children themselves). This latter
751
+ * prevents serializing a group into something like `/a(aux:)`, where `aux` is an empty child
752
+ * segment.
753
+ * - merges named outlets without a primary segment sibling into the children. This prevents
754
+ * serializing a URL like `//(a:a)(b:b) instead of `/(a:a//b:b)` when the aux b route lives on the
755
+ * root but the `a` route lives under an empty path primary route.
751
756
  */
752
757
  function squashSegmentGroup(segmentGroup) {
753
758
  const newChildren = {};
754
759
  for (const childOutlet of Object.keys(segmentGroup.children)) {
755
760
  const child = segmentGroup.children[childOutlet];
756
761
  const childCandidate = squashSegmentGroup(child);
757
- // don't add empty children
758
- if (childCandidate.segments.length > 0 || childCandidate.hasChildren()) {
762
+ // moves named children in an empty path primary child into this group
763
+ if (childOutlet === PRIMARY_OUTLET && childCandidate.segments.length === 0 &&
764
+ childCandidate.hasChildren()) {
765
+ for (const [grandChildOutlet, grandChild] of Object.entries(childCandidate.children)) {
766
+ newChildren[grandChildOutlet] = grandChild;
767
+ }
768
+ } // don't add empty children
769
+ else if (childCandidate.segments.length > 0 || childCandidate.hasChildren()) {
759
770
  newChildren[childOutlet] = childCandidate;
760
771
  }
761
772
  }
@@ -781,7 +792,6 @@ function isUrlTree(v) {
781
792
  return v instanceof UrlTree;
782
793
  }
783
794
 
784
- const NG_DEV_MODE$9 = typeof ngDevMode === 'undefined' || ngDevMode;
785
795
  /**
786
796
  * Creates a `UrlTree` relative to an `ActivatedRouteSnapshot`.
787
797
  *
@@ -928,11 +938,13 @@ class Navigation {
928
938
  this.numberOfDoubleDots = numberOfDoubleDots;
929
939
  this.commands = commands;
930
940
  if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
931
- throw new ɵRuntimeError(4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, NG_DEV_MODE$9 && 'Root segment cannot have matrix parameters');
941
+ throw new ɵRuntimeError(4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
942
+ 'Root segment cannot have matrix parameters');
932
943
  }
933
944
  const cmdWithOutlet = commands.find(isCommandWithOutlets);
934
945
  if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
935
- throw new ɵRuntimeError(4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, NG_DEV_MODE$9 && '{outlets:{}} has to be the last command');
946
+ throw new ɵRuntimeError(4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
947
+ '{outlets:{}} has to be the last command');
936
948
  }
937
949
  }
938
950
  toRoot() {
@@ -1016,7 +1028,7 @@ function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
1016
1028
  dd -= ci;
1017
1029
  g = g.parent;
1018
1030
  if (!g) {
1019
- throw new ɵRuntimeError(4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, NG_DEV_MODE$9 && 'Invalid number of \'../\'');
1031
+ throw new ɵRuntimeError(4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Invalid number of \'../\'');
1020
1032
  }
1021
1033
  ci = g.segments.length;
1022
1034
  }
@@ -1881,9 +1893,8 @@ class ActivatedRoute {
1881
1893
  this.data = data;
1882
1894
  this.outlet = outlet;
1883
1895
  this.component = component;
1884
- /** An Observable of the resolved route title */
1885
- this.title = this.data?.pipe(map((d) => d[RouteTitleKey])) ?? of(undefined);
1886
1896
  this._futureSnapshot = futureSnapshot;
1897
+ this.title = this.data?.pipe(map((d) => d[RouteTitleKey])) ?? of(undefined);
1887
1898
  }
1888
1899
  /** The configuration used to match this route. */
1889
1900
  get routeConfig() {
@@ -2302,15 +2313,14 @@ class ChildrenOutletContexts {
2302
2313
  getContext(childName) {
2303
2314
  return this.contexts.get(childName) || null;
2304
2315
  }
2316
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: ChildrenOutletContexts, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2317
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' }); }
2305
2318
  }
2306
- ChildrenOutletContexts.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: ChildrenOutletContexts, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2307
- ChildrenOutletContexts.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: ChildrenOutletContexts, providedIn: 'root' });
2308
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2319
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: ChildrenOutletContexts, decorators: [{
2309
2320
  type: Injectable,
2310
2321
  args: [{ providedIn: 'root' }]
2311
2322
  }] });
2312
2323
 
2313
- const NG_DEV_MODE$8 = typeof ngDevMode === 'undefined' || ngDevMode;
2314
2324
  /**
2315
2325
  * @description
2316
2326
  *
@@ -2449,12 +2459,12 @@ class RouterOutlet {
2449
2459
  */
2450
2460
  get component() {
2451
2461
  if (!this.activated)
2452
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2462
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated');
2453
2463
  return this.activated.instance;
2454
2464
  }
2455
2465
  get activatedRoute() {
2456
2466
  if (!this.activated)
2457
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2467
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated');
2458
2468
  return this._activatedRoute;
2459
2469
  }
2460
2470
  get activatedRouteData() {
@@ -2468,7 +2478,7 @@ class RouterOutlet {
2468
2478
  */
2469
2479
  detach() {
2470
2480
  if (!this.activated)
2471
- throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$8 && 'Outlet is not activated');
2481
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated');
2472
2482
  this.location.detach();
2473
2483
  const cmp = this.activated;
2474
2484
  this.activated = null;
@@ -2496,7 +2506,8 @@ class RouterOutlet {
2496
2506
  }
2497
2507
  activateWith(activatedRoute, environmentInjector) {
2498
2508
  if (this.isActivated) {
2499
- throw new ɵRuntimeError(4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, NG_DEV_MODE$8 && 'Cannot activate an already activated outlet');
2509
+ throw new ɵRuntimeError(4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
2510
+ 'Cannot activate an already activated outlet');
2500
2511
  }
2501
2512
  this._activatedRoute = activatedRoute;
2502
2513
  const location = this.location;
@@ -2514,10 +2525,10 @@ class RouterOutlet {
2514
2525
  this.changeDetector.markForCheck();
2515
2526
  this.activateEvents.emit(this.activated.instance);
2516
2527
  }
2528
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2529
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.5", type: RouterOutlet, isStandalone: true, selector: "router-outlet", inputs: { name: "name" }, outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], usesOnChanges: true, ngImport: i0 }); }
2517
2530
  }
2518
- RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2519
- RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.4", type: RouterOutlet, isStandalone: true, selector: "router-outlet", inputs: { name: "name" }, outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], usesOnChanges: true, ngImport: i0 });
2520
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterOutlet, decorators: [{
2531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterOutlet, decorators: [{
2521
2532
  type: Directive,
2522
2533
  args: [{
2523
2534
  selector: 'router-outlet',
@@ -2566,10 +2577,10 @@ class OutletInjector {
2566
2577
  * to this `EmptyOutletComponent`.
2567
2578
  */
2568
2579
  class ɵEmptyOutletComponent {
2580
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2581
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0-next.5", type: ɵEmptyOutletComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] }); }
2569
2582
  }
2570
- ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2571
- ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0-next.4", type: ɵEmptyOutletComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
2572
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2573
2584
  type: Component,
2574
2585
  args: [{
2575
2586
  template: `<router-outlet></router-outlet>`,
@@ -2854,13 +2865,16 @@ class ActivateRoutes {
2854
2865
  for (const childOutlet of Object.keys(children)) {
2855
2866
  this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
2856
2867
  }
2857
- if (context && context.outlet) {
2858
- // Destroy the component
2859
- context.outlet.deactivate();
2860
- // Destroy the contexts for all the outlets that were in the component
2861
- context.children.onOutletDeactivated();
2868
+ if (context) {
2869
+ if (context.outlet) {
2870
+ // Destroy the component
2871
+ context.outlet.deactivate();
2872
+ // Destroy the contexts for all the outlets that were in the component
2873
+ context.children.onOutletDeactivated();
2874
+ }
2862
2875
  // Clear the information about the attached component on the context but keep the reference to
2863
- // the outlet.
2876
+ // the outlet. Clear even if outlet was not yet activated to avoid activating later with old
2877
+ // info
2864
2878
  context.attachRef = null;
2865
2879
  context.route = null;
2866
2880
  }
@@ -3287,7 +3301,107 @@ function runCanMatchGuards(injector, route, segments, urlSerializer) {
3287
3301
  .pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
3288
3302
  }
3289
3303
 
3290
- const noMatch$1 = {
3304
+ class NoMatch {
3305
+ constructor(segmentGroup) {
3306
+ this.segmentGroup = segmentGroup || null;
3307
+ }
3308
+ }
3309
+ class AbsoluteRedirect {
3310
+ constructor(urlTree) {
3311
+ this.urlTree = urlTree;
3312
+ }
3313
+ }
3314
+ function noMatch$1(segmentGroup) {
3315
+ return throwError(new NoMatch(segmentGroup));
3316
+ }
3317
+ function absoluteRedirect(newTree) {
3318
+ return throwError(new AbsoluteRedirect(newTree));
3319
+ }
3320
+ function namedOutletsRedirect(redirectTo) {
3321
+ return throwError(new ɵRuntimeError(4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
3322
+ `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
3323
+ }
3324
+ function canLoadFails(route) {
3325
+ return throwError(navigationCancelingError((typeof ngDevMode === 'undefined' || ngDevMode) &&
3326
+ `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, 3 /* NavigationCancellationCode.GuardRejected */));
3327
+ }
3328
+ class ApplyRedirects {
3329
+ constructor(urlSerializer, urlTree) {
3330
+ this.urlSerializer = urlSerializer;
3331
+ this.urlTree = urlTree;
3332
+ }
3333
+ noMatchError(e) {
3334
+ return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
3335
+ `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3336
+ }
3337
+ lineralizeSegments(route, urlTree) {
3338
+ let res = [];
3339
+ let c = urlTree.root;
3340
+ while (true) {
3341
+ res = res.concat(c.segments);
3342
+ if (c.numberOfChildren === 0) {
3343
+ return of(res);
3344
+ }
3345
+ if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
3346
+ return namedOutletsRedirect(route.redirectTo);
3347
+ }
3348
+ c = c.children[PRIMARY_OUTLET];
3349
+ }
3350
+ }
3351
+ applyRedirectCommands(segments, redirectTo, posParams) {
3352
+ return this.applyRedirectCreateUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
3353
+ }
3354
+ applyRedirectCreateUrlTree(redirectTo, urlTree, segments, posParams) {
3355
+ const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
3356
+ return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
3357
+ }
3358
+ createQueryParams(redirectToParams, actualParams) {
3359
+ const res = {};
3360
+ Object.entries(redirectToParams).forEach(([k, v]) => {
3361
+ const copySourceValue = typeof v === 'string' && v.startsWith(':');
3362
+ if (copySourceValue) {
3363
+ const sourceName = v.substring(1);
3364
+ res[k] = actualParams[sourceName];
3365
+ }
3366
+ else {
3367
+ res[k] = v;
3368
+ }
3369
+ });
3370
+ return res;
3371
+ }
3372
+ createSegmentGroup(redirectTo, group, segments, posParams) {
3373
+ const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
3374
+ let children = {};
3375
+ Object.entries(group.children).forEach(([name, child]) => {
3376
+ children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
3377
+ });
3378
+ return new UrlSegmentGroup(updatedSegments, children);
3379
+ }
3380
+ createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
3381
+ return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
3382
+ this.findOrReturn(s, actualSegments));
3383
+ }
3384
+ findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3385
+ const pos = posParams[redirectToUrlSegment.path.substring(1)];
3386
+ if (!pos)
3387
+ throw new ɵRuntimeError(4001 /* RuntimeErrorCode.MISSING_REDIRECT */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
3388
+ `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3389
+ return pos;
3390
+ }
3391
+ findOrReturn(redirectToUrlSegment, actualSegments) {
3392
+ let idx = 0;
3393
+ for (const s of actualSegments) {
3394
+ if (s.path === redirectToUrlSegment.path) {
3395
+ actualSegments.splice(idx);
3396
+ return s;
3397
+ }
3398
+ idx++;
3399
+ }
3400
+ return redirectToUrlSegment;
3401
+ }
3402
+ }
3403
+
3404
+ const noMatch = {
3291
3405
  matched: false,
3292
3406
  consumedSegments: [],
3293
3407
  remainingSegments: [],
@@ -3303,12 +3417,12 @@ function matchWithChecks(segmentGroup, route, segments, injector, urlSerializer)
3303
3417
  // navigation
3304
3418
  injector = getOrCreateRouteInjectorIfNeeded(route, injector);
3305
3419
  return runCanMatchGuards(injector, route, segments, urlSerializer)
3306
- .pipe(map((v) => v === true ? result : { ...noMatch$1 }));
3420
+ .pipe(map((v) => v === true ? result : { ...noMatch }));
3307
3421
  }
3308
3422
  function match(segmentGroup, route, segments) {
3309
3423
  if (route.path === '') {
3310
3424
  if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
3311
- return { ...noMatch$1 };
3425
+ return { ...noMatch };
3312
3426
  }
3313
3427
  return {
3314
3428
  matched: true,
@@ -3321,7 +3435,7 @@ function match(segmentGroup, route, segments) {
3321
3435
  const matcher = route.matcher || defaultUrlMatcher;
3322
3436
  const res = matcher(segments, segmentGroup, route);
3323
3437
  if (!res)
3324
- return { ...noMatch$1 };
3438
+ return { ...noMatch };
3325
3439
  const posParams = {};
3326
3440
  Object.entries(res.posParams ?? {}).forEach(([k, v]) => {
3327
3441
  posParams[k] = v.path;
@@ -3415,103 +3529,88 @@ function noLeftoversInUrl(segmentGroup, segments, outlet) {
3415
3529
  return segments.length === 0 && !segmentGroup.children[outlet];
3416
3530
  }
3417
3531
 
3418
- const NG_DEV_MODE$7 = typeof ngDevMode === 'undefined' || ngDevMode;
3419
- class NoMatch$1 {
3420
- constructor(segmentGroup) {
3421
- this.segmentGroup = segmentGroup || null;
3422
- }
3423
- }
3424
- class AbsoluteRedirect {
3425
- constructor(urlTree) {
3426
- this.urlTree = urlTree;
3427
- }
3428
- }
3429
- function noMatch(segmentGroup) {
3430
- return throwError(new NoMatch$1(segmentGroup));
3431
- }
3432
- function absoluteRedirect(newTree) {
3433
- return throwError(new AbsoluteRedirect(newTree));
3434
- }
3435
- function namedOutletsRedirect(redirectTo) {
3436
- return throwError(new ɵRuntimeError(4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, NG_DEV_MODE$7 &&
3437
- `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
3438
- }
3439
- function canLoadFails(route) {
3440
- return throwError(navigationCancelingError(NG_DEV_MODE$7 &&
3441
- `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, 3 /* NavigationCancellationCode.GuardRejected */));
3442
- }
3443
- /**
3444
- * Returns the `UrlTree` with the redirection applied.
3445
- *
3446
- * Lazy modules are loaded along the way.
3447
- */
3448
- function applyRedirects$1(injector, configLoader, urlSerializer, urlTree, config) {
3449
- return new ApplyRedirects(injector, configLoader, urlSerializer, urlTree, config).apply();
3532
+ function recognize$1(injector, configLoader, rootComponentType, config, urlTree, urlSerializer, paramsInheritanceStrategy = 'emptyOnly') {
3533
+ return new Recognizer(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer)
3534
+ .recognize();
3450
3535
  }
3451
- class ApplyRedirects {
3452
- constructor(injector, configLoader, urlSerializer, urlTree, config) {
3536
+ class Recognizer {
3537
+ constructor(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer) {
3453
3538
  this.injector = injector;
3454
3539
  this.configLoader = configLoader;
3455
- this.urlSerializer = urlSerializer;
3456
- this.urlTree = urlTree;
3540
+ this.rootComponentType = rootComponentType;
3457
3541
  this.config = config;
3542
+ this.urlTree = urlTree;
3543
+ this.paramsInheritanceStrategy = paramsInheritanceStrategy;
3544
+ this.urlSerializer = urlSerializer;
3458
3545
  this.allowRedirects = true;
3546
+ this.applyRedirects = new ApplyRedirects(this.urlSerializer, this.urlTree);
3459
3547
  }
3460
- apply() {
3461
- const splitGroup = split(this.urlTree.root, [], [], this.config).segmentGroup;
3462
- // TODO(atscott): creating a new segment removes the _sourceSegment _segmentIndexShift, which is
3463
- // only necessary to prevent failures in tests which assert exact object matches. The `split` is
3464
- // now shared between `applyRedirects` and `recognize` but only the `recognize` step needs these
3465
- // properties. Before the implementations were merged, the `applyRedirects` would not assign
3466
- // them. We should be able to remove this logic as a "breaking change" but should do some more
3467
- // investigation into the failures first.
3468
- const rootSegmentGroup = new UrlSegmentGroup(splitGroup.segments, splitGroup.children);
3469
- const expanded$ = this.expandSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET);
3470
- const urlTrees$ = expanded$.pipe(map((rootSegmentGroup) => {
3471
- return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), this.urlTree.queryParams, this.urlTree.fragment);
3472
- }));
3473
- return urlTrees$.pipe(catchError((e) => {
3548
+ noMatchError(e) {
3549
+ return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
3550
+ `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3551
+ }
3552
+ recognize() {
3553
+ const rootSegmentGroup = split(this.urlTree.root, [], [], this.config).segmentGroup;
3554
+ return this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET)
3555
+ .pipe(catchError((e) => {
3474
3556
  if (e instanceof AbsoluteRedirect) {
3475
3557
  // After an absolute redirect we do not apply any more redirects!
3476
3558
  // If this implementation changes, update the documentation note in `redirectTo`.
3477
3559
  this.allowRedirects = false;
3478
- // we need to run matching, so we can fetch all lazy-loaded modules
3560
+ this.urlTree = e.urlTree;
3479
3561
  return this.match(e.urlTree);
3480
3562
  }
3481
- if (e instanceof NoMatch$1) {
3563
+ if (e instanceof NoMatch) {
3482
3564
  throw this.noMatchError(e);
3483
3565
  }
3484
3566
  throw e;
3567
+ }), map(children => {
3568
+ // Use Object.freeze to prevent readers of the Router state from modifying it outside
3569
+ // of a navigation, resulting in the router being out of sync with the browser.
3570
+ const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, {});
3571
+ const rootNode = new TreeNode(root, children);
3572
+ const routeState = new RouterStateSnapshot('', rootNode);
3573
+ const tree = createUrlTreeFromSnapshot(root, [], this.urlTree.queryParams, this.urlTree.fragment);
3574
+ // https://github.com/angular/angular/issues/47307
3575
+ // Creating the tree stringifies the query params
3576
+ // We don't want to do this here so reassign them to the original.
3577
+ tree.queryParams = this.urlTree.queryParams;
3578
+ routeState.url = this.urlSerializer.serialize(tree);
3579
+ this.inheritParamsAndData(routeState._root);
3580
+ return { state: routeState, tree };
3485
3581
  }));
3486
3582
  }
3487
3583
  match(tree) {
3488
- const expanded$ = this.expandSegmentGroup(this.injector, this.config, tree.root, PRIMARY_OUTLET);
3489
- const mapped$ = expanded$.pipe(map((rootSegmentGroup) => {
3490
- return this.createUrlTree(squashSegmentGroup(rootSegmentGroup), tree.queryParams, tree.fragment);
3491
- }));
3492
- return mapped$.pipe(catchError((e) => {
3493
- if (e instanceof NoMatch$1) {
3584
+ const expanded$ = this.processSegmentGroup(this.injector, this.config, tree.root, PRIMARY_OUTLET);
3585
+ return expanded$.pipe(catchError((e) => {
3586
+ if (e instanceof NoMatch) {
3494
3587
  throw this.noMatchError(e);
3495
3588
  }
3496
3589
  throw e;
3497
3590
  }));
3498
3591
  }
3499
- noMatchError(e) {
3500
- return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, NG_DEV_MODE$7 && `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3501
- }
3502
- createUrlTree(rootCandidate, queryParams, fragment) {
3503
- const root = createRoot(rootCandidate);
3504
- return new UrlTree(root, queryParams, fragment);
3592
+ inheritParamsAndData(routeNode) {
3593
+ const route = routeNode.value;
3594
+ const i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
3595
+ route.params = Object.freeze(i.params);
3596
+ route.data = Object.freeze(i.data);
3597
+ routeNode.children.forEach(n => this.inheritParamsAndData(n));
3505
3598
  }
3506
- expandSegmentGroup(injector, routes, segmentGroup, outlet) {
3599
+ processSegmentGroup(injector, config, segmentGroup, outlet) {
3507
3600
  if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
3508
- return this.expandChildren(injector, routes, segmentGroup)
3509
- .pipe(map((children) => new UrlSegmentGroup([], children)));
3601
+ return this.processChildren(injector, config, segmentGroup);
3510
3602
  }
3511
- return this.expandSegment(injector, segmentGroup, routes, segmentGroup.segments, outlet, true);
3603
+ return this.processSegment(injector, config, segmentGroup, segmentGroup.segments, outlet, true);
3512
3604
  }
3513
- // Recursively expand segment groups for all the child outlets
3514
- expandChildren(injector, routes, segmentGroup) {
3605
+ /**
3606
+ * Matches every child outlet in the `segmentGroup` to a `Route` in the config. Returns `null` if
3607
+ * we cannot find a match for _any_ of the children.
3608
+ *
3609
+ * @param config - The `Routes` to match against
3610
+ * @param segmentGroup - The `UrlSegmentGroup` whose children need to be matched against the
3611
+ * config.
3612
+ */
3613
+ processChildren(injector, config, segmentGroup) {
3515
3614
  // Expand outlets one at a time, starting with the primary outlet. We need to do it this way
3516
3615
  // because an absolute redirect from the primary outlet takes precedence.
3517
3616
  const childOutlets = [];
@@ -3526,47 +3625,60 @@ class ApplyRedirects {
3526
3625
  return from(childOutlets)
3527
3626
  .pipe(concatMap(childOutlet => {
3528
3627
  const child = segmentGroup.children[childOutlet];
3529
- // Sort the routes so routes with outlets that match the segment appear
3530
- // first, followed by routes for other outlets, which might match if they have an
3531
- // empty path.
3532
- const sortedRoutes = sortByMatchingOutlets(routes, childOutlet);
3533
- return this.expandSegmentGroup(injector, sortedRoutes, child, childOutlet)
3534
- .pipe(map(s => ({ segment: s, outlet: childOutlet })));
3535
- }), scan((children, expandedChild) => {
3536
- children[expandedChild.outlet] = expandedChild.segment;
3628
+ // Sort the config so that routes with outlets that match the one being activated
3629
+ // appear first, followed by routes for other outlets, which might match if they have
3630
+ // an empty path.
3631
+ const sortedConfig = sortByMatchingOutlets(config, childOutlet);
3632
+ return this.processSegmentGroup(injector, sortedConfig, child, childOutlet);
3633
+ }), scan((children, outletChildren) => {
3634
+ children.push(...outletChildren);
3537
3635
  return children;
3538
- }, {}), last$1());
3636
+ }), defaultIfEmpty(null), last$1(), mergeMap(children => {
3637
+ if (children === null)
3638
+ return noMatch$1(segmentGroup);
3639
+ // Because we may have matched two outlets to the same empty path segment, we can have
3640
+ // multiple activated results for the same outlet. We should merge the children of
3641
+ // these results so the final return value is only one `TreeNode` per outlet.
3642
+ const mergedChildren = mergeEmptyPathMatches(children);
3643
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
3644
+ // This should really never happen - we are only taking the first match for each
3645
+ // outlet and merge the empty path matches.
3646
+ checkOutletNameUniqueness(mergedChildren);
3647
+ }
3648
+ sortActivatedRouteSnapshots(mergedChildren);
3649
+ return of(mergedChildren);
3650
+ }));
3539
3651
  }
3540
- expandSegment(injector, segmentGroup, routes, segments, outlet, allowRedirects) {
3652
+ processSegment(injector, routes, segmentGroup, segments, outlet, allowRedirects) {
3541
3653
  return from(routes).pipe(concatMap(r => {
3542
- const expanded$ = this.expandSegmentAgainstRoute(injector, segmentGroup, routes, r, segments, outlet, allowRedirects);
3543
- return expanded$.pipe(catchError((e) => {
3544
- if (e instanceof NoMatch$1) {
3654
+ return this
3655
+ .processSegmentAgainstRoute(r._injector ?? injector, routes, r, segmentGroup, segments, outlet, allowRedirects)
3656
+ .pipe(catchError((e) => {
3657
+ if (e instanceof NoMatch) {
3545
3658
  return of(null);
3546
3659
  }
3547
3660
  throw e;
3548
3661
  }));
3549
- }), first((s) => !!s), catchError((e, _) => {
3662
+ }), first((x) => !!x), catchError(e => {
3550
3663
  if (isEmptyError(e)) {
3551
3664
  if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
3552
- return of(new UrlSegmentGroup([], {}));
3665
+ return of([]);
3553
3666
  }
3554
- return noMatch(segmentGroup);
3667
+ return noMatch$1(segmentGroup);
3555
3668
  }
3556
3669
  throw e;
3557
3670
  }));
3558
3671
  }
3559
- expandSegmentAgainstRoute(injector, segmentGroup, routes, route, paths, outlet, allowRedirects) {
3560
- if (!isImmediateMatch(route, segmentGroup, paths, outlet)) {
3561
- return noMatch(segmentGroup);
3562
- }
3672
+ processSegmentAgainstRoute(injector, routes, route, rawSegment, segments, outlet, allowRedirects) {
3673
+ if (!isImmediateMatch(route, rawSegment, segments, outlet))
3674
+ return noMatch$1(rawSegment);
3563
3675
  if (route.redirectTo === undefined) {
3564
- return this.matchSegmentAgainstRoute(injector, segmentGroup, route, paths, outlet);
3676
+ return this.matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet, allowRedirects);
3565
3677
  }
3566
3678
  if (allowRedirects && this.allowRedirects) {
3567
- return this.expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, paths, outlet);
3679
+ return this.expandSegmentAgainstRouteUsingRedirect(injector, rawSegment, routes, route, segments, outlet);
3568
3680
  }
3569
- return noMatch(segmentGroup);
3681
+ return noMatch$1(rawSegment);
3570
3682
  }
3571
3683
  expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
3572
3684
  if (route.path === '**') {
@@ -3575,66 +3687,93 @@ class ApplyRedirects {
3575
3687
  return this.expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet);
3576
3688
  }
3577
3689
  expandWildCardWithParamsAgainstRouteUsingRedirect(injector, routes, route, outlet) {
3578
- const newTree = this.applyRedirectCommands([], route.redirectTo, {});
3690
+ const newTree = this.applyRedirects.applyRedirectCommands([], route.redirectTo, {});
3579
3691
  if (route.redirectTo.startsWith('/')) {
3580
3692
  return absoluteRedirect(newTree);
3581
3693
  }
3582
- return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
3694
+ return this.applyRedirects.lineralizeSegments(route, newTree)
3695
+ .pipe(mergeMap((newSegments) => {
3583
3696
  const group = new UrlSegmentGroup(newSegments, {});
3584
- return this.expandSegment(injector, group, routes, newSegments, outlet, false);
3697
+ return this.processSegment(injector, routes, group, newSegments, outlet, false);
3585
3698
  }));
3586
3699
  }
3587
3700
  expandRegularSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
3588
3701
  const { matched, consumedSegments, remainingSegments, positionalParamSegments } = match(segmentGroup, route, segments);
3589
3702
  if (!matched)
3590
- return noMatch(segmentGroup);
3591
- const newTree = this.applyRedirectCommands(consumedSegments, route.redirectTo, positionalParamSegments);
3703
+ return noMatch$1(segmentGroup);
3704
+ const newTree = this.applyRedirects.applyRedirectCommands(consumedSegments, route.redirectTo, positionalParamSegments);
3592
3705
  if (route.redirectTo.startsWith('/')) {
3593
3706
  return absoluteRedirect(newTree);
3594
3707
  }
3595
- return this.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
3596
- return this.expandSegment(injector, segmentGroup, routes, newSegments.concat(remainingSegments), outlet, false);
3708
+ return this.applyRedirects.lineralizeSegments(route, newTree)
3709
+ .pipe(mergeMap((newSegments) => {
3710
+ return this.processSegment(injector, routes, segmentGroup, newSegments.concat(remainingSegments), outlet, false);
3597
3711
  }));
3598
3712
  }
3599
- matchSegmentAgainstRoute(injector, rawSegmentGroup, route, segments, outlet) {
3713
+ matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet, allowRedirects) {
3714
+ let matchResult;
3600
3715
  if (route.path === '**') {
3601
- // Only create the Route's `EnvironmentInjector` if it matches the attempted navigation
3602
- injector = getOrCreateRouteInjectorIfNeeded(route, injector);
3603
- if (route.loadChildren) {
3604
- const loaded$ = route._loadedRoutes ?
3605
- of({ routes: route._loadedRoutes, injector: route._loadedInjector }) :
3606
- this.configLoader.loadChildren(injector, route);
3607
- return loaded$.pipe(map((cfg) => {
3608
- route._loadedRoutes = cfg.routes;
3609
- route._loadedInjector = cfg.injector;
3610
- return new UrlSegmentGroup(segments, {});
3716
+ const params = segments.length > 0 ? last(segments).parameters : {};
3717
+ const snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route));
3718
+ matchResult = of({
3719
+ snapshot,
3720
+ consumedSegments: [],
3721
+ remainingSegments: [],
3722
+ });
3723
+ // Prior versions of the route matching algorithm would stop matching at the wildcard route.
3724
+ // We should investigate a better strategy for any existing children. Otherwise, these
3725
+ // child segments are silently dropped from the navigation.
3726
+ // https://github.com/angular/angular/issues/40089
3727
+ rawSegment.children = {};
3728
+ }
3729
+ else {
3730
+ matchResult =
3731
+ matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer)
3732
+ .pipe(map(({ matched, consumedSegments, remainingSegments, parameters }) => {
3733
+ if (!matched) {
3734
+ return null;
3735
+ }
3736
+ const snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route));
3737
+ return { snapshot, consumedSegments, remainingSegments };
3611
3738
  }));
3612
- }
3613
- return of(new UrlSegmentGroup(segments, {}));
3614
3739
  }
3615
- return matchWithChecks(rawSegmentGroup, route, segments, injector, this.urlSerializer)
3616
- .pipe(switchMap(({ matched, consumedSegments, remainingSegments }) => {
3617
- if (!matched)
3618
- return noMatch(rawSegmentGroup);
3740
+ return matchResult.pipe(switchMap((result) => {
3741
+ if (result === null) {
3742
+ return noMatch$1(rawSegment);
3743
+ }
3619
3744
  // If the route has an injector created from providers, we should start using that.
3620
3745
  injector = route._injector ?? injector;
3621
- const childConfig$ = this.getChildConfig(injector, route, segments);
3622
- return childConfig$.pipe(mergeMap((routerConfig) => {
3623
- const childInjector = routerConfig.injector ?? injector;
3624
- const childConfig = routerConfig.routes;
3625
- const { segmentGroup: splitSegmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, remainingSegments, childConfig);
3626
- // See comment on the other call to `split` about why this is necessary.
3627
- const segmentGroup = new UrlSegmentGroup(splitSegmentGroup.segments, splitSegmentGroup.children);
3746
+ return this.getChildConfig(injector, route, segments)
3747
+ .pipe(switchMap(({ routes: childConfig }) => {
3748
+ const childInjector = route._loadedInjector ?? injector;
3749
+ const { snapshot, consumedSegments, remainingSegments } = result;
3750
+ const { segmentGroup, slicedSegments } = split(rawSegment, consumedSegments, remainingSegments, childConfig);
3628
3751
  if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3629
- const expanded$ = this.expandChildren(childInjector, childConfig, segmentGroup);
3630
- return expanded$.pipe(map((children) => new UrlSegmentGroup(consumedSegments, children)));
3752
+ return this.processChildren(childInjector, childConfig, segmentGroup)
3753
+ .pipe(map(children => {
3754
+ if (children === null) {
3755
+ return null;
3756
+ }
3757
+ return [new TreeNode(snapshot, children)];
3758
+ }));
3631
3759
  }
3632
3760
  if (childConfig.length === 0 && slicedSegments.length === 0) {
3633
- return of(new UrlSegmentGroup(consumedSegments, {}));
3761
+ return of([new TreeNode(snapshot, [])]);
3634
3762
  }
3635
3763
  const matchedOnOutlet = getOutlet(route) === outlet;
3636
- const expanded$ = this.expandSegment(childInjector, segmentGroup, childConfig, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true);
3637
- return expanded$.pipe(map((cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children)));
3764
+ // If we matched a config due to empty path match on a different outlet, we need to
3765
+ // continue passing the current outlet for the segment rather than switch to PRIMARY.
3766
+ // Note that we switch to primary when we have a match because outlet configs look like
3767
+ // this: {path: 'a', outlet: 'a', children: [
3768
+ // {path: 'b', component: B},
3769
+ // {path: 'c', component: C},
3770
+ // ]}
3771
+ // Notice that the children of the named outlet are configured with the primary outlet
3772
+ return this
3773
+ .processSegment(childInjector, childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true)
3774
+ .pipe(map(children => {
3775
+ return [new TreeNode(snapshot, children)];
3776
+ }));
3638
3777
  }));
3639
3778
  }));
3640
3779
  }
@@ -3662,256 +3801,6 @@ class ApplyRedirects {
3662
3801
  }
3663
3802
  return of({ routes: [], injector });
3664
3803
  }
3665
- lineralizeSegments(route, urlTree) {
3666
- let res = [];
3667
- let c = urlTree.root;
3668
- while (true) {
3669
- res = res.concat(c.segments);
3670
- if (c.numberOfChildren === 0) {
3671
- return of(res);
3672
- }
3673
- if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
3674
- return namedOutletsRedirect(route.redirectTo);
3675
- }
3676
- c = c.children[PRIMARY_OUTLET];
3677
- }
3678
- }
3679
- applyRedirectCommands(segments, redirectTo, posParams) {
3680
- return this.applyRedirectCreateUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
3681
- }
3682
- applyRedirectCreateUrlTree(redirectTo, urlTree, segments, posParams) {
3683
- const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
3684
- return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
3685
- }
3686
- createQueryParams(redirectToParams, actualParams) {
3687
- const res = {};
3688
- Object.entries(redirectToParams).forEach(([k, v]) => {
3689
- const copySourceValue = typeof v === 'string' && v.startsWith(':');
3690
- if (copySourceValue) {
3691
- const sourceName = v.substring(1);
3692
- res[k] = actualParams[sourceName];
3693
- }
3694
- else {
3695
- res[k] = v;
3696
- }
3697
- });
3698
- return res;
3699
- }
3700
- createSegmentGroup(redirectTo, group, segments, posParams) {
3701
- const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
3702
- let children = {};
3703
- Object.entries(group.children).forEach(([name, child]) => {
3704
- children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
3705
- });
3706
- return new UrlSegmentGroup(updatedSegments, children);
3707
- }
3708
- createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
3709
- return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
3710
- this.findOrReturn(s, actualSegments));
3711
- }
3712
- findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3713
- const pos = posParams[redirectToUrlSegment.path.substring(1)];
3714
- if (!pos)
3715
- throw new ɵRuntimeError(4001 /* RuntimeErrorCode.MISSING_REDIRECT */, NG_DEV_MODE$7 &&
3716
- `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3717
- return pos;
3718
- }
3719
- findOrReturn(redirectToUrlSegment, actualSegments) {
3720
- let idx = 0;
3721
- for (const s of actualSegments) {
3722
- if (s.path === redirectToUrlSegment.path) {
3723
- actualSegments.splice(idx);
3724
- return s;
3725
- }
3726
- idx++;
3727
- }
3728
- return redirectToUrlSegment;
3729
- }
3730
- }
3731
-
3732
- function applyRedirects(environmentInjector, configLoader, urlSerializer, config) {
3733
- return switchMap(t => applyRedirects$1(environmentInjector, configLoader, urlSerializer, t.extractedUrl, config)
3734
- .pipe(map(urlAfterRedirects => ({ ...t, urlAfterRedirects }))));
3735
- }
3736
-
3737
- const NG_DEV_MODE$6 = typeof ngDevMode === 'undefined' || !!ngDevMode;
3738
- class NoMatch {
3739
- }
3740
- function newObservableError(e) {
3741
- // TODO(atscott): This pattern is used throughout the router code and can be `throwError` instead.
3742
- return new Observable((obs) => obs.error(e));
3743
- }
3744
- function recognize$1(injector, rootComponentType, config, urlTree, url, urlSerializer, paramsInheritanceStrategy = 'emptyOnly') {
3745
- return new Recognizer(injector, rootComponentType, config, urlTree, url, paramsInheritanceStrategy, urlSerializer)
3746
- .recognize()
3747
- .pipe(switchMap(result => {
3748
- if (result === null) {
3749
- return newObservableError(new NoMatch());
3750
- }
3751
- else {
3752
- return of(result);
3753
- }
3754
- }));
3755
- }
3756
- class Recognizer {
3757
- constructor(injector, rootComponentType, config, urlTree, url, paramsInheritanceStrategy, urlSerializer) {
3758
- this.injector = injector;
3759
- this.rootComponentType = rootComponentType;
3760
- this.config = config;
3761
- this.urlTree = urlTree;
3762
- this.url = url;
3763
- this.paramsInheritanceStrategy = paramsInheritanceStrategy;
3764
- this.urlSerializer = urlSerializer;
3765
- }
3766
- recognize() {
3767
- const rootSegmentGroup = split(this.urlTree.root, [], [], this.config.filter(c => c.redirectTo === undefined))
3768
- .segmentGroup;
3769
- return this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET)
3770
- .pipe(map(children => {
3771
- if (children === null) {
3772
- return null;
3773
- }
3774
- // Use Object.freeze to prevent readers of the Router state from modifying it outside of a
3775
- // navigation, resulting in the router being out of sync with the browser.
3776
- const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, {});
3777
- const rootNode = new TreeNode(root, children);
3778
- const routeState = new RouterStateSnapshot(this.url, rootNode);
3779
- this.inheritParamsAndData(routeState._root);
3780
- return routeState;
3781
- }));
3782
- }
3783
- inheritParamsAndData(routeNode) {
3784
- const route = routeNode.value;
3785
- const i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
3786
- route.params = Object.freeze(i.params);
3787
- route.data = Object.freeze(i.data);
3788
- routeNode.children.forEach(n => this.inheritParamsAndData(n));
3789
- }
3790
- processSegmentGroup(injector, config, segmentGroup, outlet) {
3791
- if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
3792
- return this.processChildren(injector, config, segmentGroup);
3793
- }
3794
- return this.processSegment(injector, config, segmentGroup, segmentGroup.segments, outlet);
3795
- }
3796
- /**
3797
- * Matches every child outlet in the `segmentGroup` to a `Route` in the config. Returns `null` if
3798
- * we cannot find a match for _any_ of the children.
3799
- *
3800
- * @param config - The `Routes` to match against
3801
- * @param segmentGroup - The `UrlSegmentGroup` whose children need to be matched against the
3802
- * config.
3803
- */
3804
- processChildren(injector, config, segmentGroup) {
3805
- return from(Object.keys(segmentGroup.children))
3806
- .pipe(concatMap(childOutlet => {
3807
- const child = segmentGroup.children[childOutlet];
3808
- // Sort the config so that routes with outlets that match the one being activated
3809
- // appear first, followed by routes for other outlets, which might match if they have
3810
- // an empty path.
3811
- const sortedConfig = sortByMatchingOutlets(config, childOutlet);
3812
- return this.processSegmentGroup(injector, sortedConfig, child, childOutlet);
3813
- }), scan((children, outletChildren) => {
3814
- if (!children || !outletChildren)
3815
- return null;
3816
- children.push(...outletChildren);
3817
- return children;
3818
- }), takeWhile(children => children !== null), defaultIfEmpty(null), last$1(), map(children => {
3819
- if (children === null)
3820
- return null;
3821
- // Because we may have matched two outlets to the same empty path segment, we can have
3822
- // multiple activated results for the same outlet. We should merge the children of
3823
- // these results so the final return value is only one `TreeNode` per outlet.
3824
- const mergedChildren = mergeEmptyPathMatches(children);
3825
- if (NG_DEV_MODE$6) {
3826
- // This should really never happen - we are only taking the first match for each
3827
- // outlet and merge the empty path matches.
3828
- checkOutletNameUniqueness(mergedChildren);
3829
- }
3830
- sortActivatedRouteSnapshots(mergedChildren);
3831
- return mergedChildren;
3832
- }));
3833
- }
3834
- processSegment(injector, routes, segmentGroup, segments, outlet) {
3835
- return from(routes).pipe(concatMap(r => {
3836
- return this.processSegmentAgainstRoute(r._injector ?? injector, r, segmentGroup, segments, outlet);
3837
- }), first((x) => !!x), catchError(e => {
3838
- if (isEmptyError(e)) {
3839
- if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
3840
- return of([]);
3841
- }
3842
- return of(null);
3843
- }
3844
- throw e;
3845
- }));
3846
- }
3847
- processSegmentAgainstRoute(injector, route, rawSegment, segments, outlet) {
3848
- if (route.redirectTo || !isImmediateMatch(route, rawSegment, segments, outlet))
3849
- return of(null);
3850
- let matchResult;
3851
- if (route.path === '**') {
3852
- const params = segments.length > 0 ? last(segments).parameters : {};
3853
- const snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route));
3854
- matchResult = of({
3855
- snapshot,
3856
- consumedSegments: [],
3857
- remainingSegments: [],
3858
- });
3859
- }
3860
- else {
3861
- matchResult =
3862
- matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer)
3863
- .pipe(map(({ matched, consumedSegments, remainingSegments, parameters }) => {
3864
- if (!matched) {
3865
- return null;
3866
- }
3867
- const snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Object.freeze({ ...this.urlTree.queryParams }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route));
3868
- return { snapshot, consumedSegments, remainingSegments };
3869
- }));
3870
- }
3871
- return matchResult.pipe(switchMap((result) => {
3872
- if (result === null) {
3873
- return of(null);
3874
- }
3875
- const { snapshot, consumedSegments, remainingSegments } = result;
3876
- // If the route has an injector created from providers, we should start using that.
3877
- injector = route._injector ?? injector;
3878
- const childInjector = route._loadedInjector ?? injector;
3879
- const childConfig = getChildConfig(route);
3880
- const { segmentGroup, slicedSegments } = split(rawSegment, consumedSegments, remainingSegments,
3881
- // Filter out routes with redirectTo because we are trying to create activated route
3882
- // snapshots and don't handle redirects here. That should have been done in
3883
- // `applyRedirects`.
3884
- childConfig.filter(c => c.redirectTo === undefined));
3885
- if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
3886
- return this.processChildren(childInjector, childConfig, segmentGroup).pipe(map(children => {
3887
- if (children === null) {
3888
- return null;
3889
- }
3890
- return [new TreeNode(snapshot, children)];
3891
- }));
3892
- }
3893
- if (childConfig.length === 0 && slicedSegments.length === 0) {
3894
- return of([new TreeNode(snapshot, [])]);
3895
- }
3896
- const matchedOnOutlet = getOutlet(route) === outlet;
3897
- // If we matched a config due to empty path match on a different outlet, we need to
3898
- // continue passing the current outlet for the segment rather than switch to PRIMARY.
3899
- // Note that we switch to primary when we have a match because outlet configs look like
3900
- // this: {path: 'a', outlet: 'a', children: [
3901
- // {path: 'b', component: B},
3902
- // {path: 'c', component: C},
3903
- // ]}
3904
- // Notice that the children of the named outlet are configured with the primary outlet
3905
- return this
3906
- .processSegment(childInjector, childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet)
3907
- .pipe(map(children => {
3908
- if (children === null) {
3909
- return null;
3910
- }
3911
- return [new TreeNode(snapshot, children)];
3912
- }));
3913
- }));
3914
- }
3915
3804
  }
3916
3805
  function sortActivatedRouteSnapshots(nodes) {
3917
3806
  nodes.sort((a, b) => {
@@ -3922,18 +3811,9 @@ function sortActivatedRouteSnapshots(nodes) {
3922
3811
  return a.value.outlet.localeCompare(b.value.outlet);
3923
3812
  });
3924
3813
  }
3925
- function getChildConfig(route) {
3926
- if (route.children) {
3927
- return route.children;
3928
- }
3929
- if (route.loadChildren) {
3930
- return route._loadedRoutes;
3931
- }
3932
- return [];
3933
- }
3934
3814
  function hasEmptyPathConfig(node) {
3935
3815
  const config = node.value.routeConfig;
3936
- return config && config.path === '' && config.redirectTo === undefined;
3816
+ return config && config.path === '';
3937
3817
  }
3938
3818
  /**
3939
3819
  * Finds `TreeNode`s with matching empty path route configs and merges them into `TreeNode` with
@@ -3975,7 +3855,8 @@ function checkOutletNameUniqueness(nodes) {
3975
3855
  if (routeWithSameOutletName) {
3976
3856
  const p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
3977
3857
  const c = n.value.url.map(s => s.toString()).join('/');
3978
- throw new ɵRuntimeError(4006 /* RuntimeErrorCode.TWO_SEGMENTS_WITH_SAME_OUTLET */, NG_DEV_MODE$6 && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
3858
+ throw new ɵRuntimeError(4006 /* RuntimeErrorCode.TWO_SEGMENTS_WITH_SAME_OUTLET */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
3859
+ `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
3979
3860
  }
3980
3861
  names[n.value.outlet] = n.value;
3981
3862
  });
@@ -3987,9 +3868,11 @@ function getResolve(route) {
3987
3868
  return route.resolve || {};
3988
3869
  }
3989
3870
 
3990
- function recognize(injector, rootComponentType, config, serializer, paramsInheritanceStrategy) {
3991
- return mergeMap(t => recognize$1(injector, rootComponentType, config, t.urlAfterRedirects, serializer.serialize(t.urlAfterRedirects), serializer, paramsInheritanceStrategy)
3992
- .pipe(map(targetSnapshot => ({ ...t, targetSnapshot }))));
3871
+ function recognize(injector, configLoader, rootComponentType, config, serializer, paramsInheritanceStrategy) {
3872
+ return mergeMap(t => recognize$1(injector, configLoader, rootComponentType, config, t.extractedUrl, serializer, paramsInheritanceStrategy)
3873
+ .pipe(map(({ state: targetSnapshot, tree: urlAfterRedirects }) => {
3874
+ return { ...t, targetSnapshot, urlAfterRedirects };
3875
+ })));
3993
3876
  }
3994
3877
 
3995
3878
  function resolveData(paramsInheritanceStrategy, injector) {
@@ -4060,7 +3943,6 @@ function switchTap(next) {
4060
3943
  });
4061
3944
  }
4062
3945
 
4063
- const NG_DEV_MODE$5 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4064
3946
  /**
4065
3947
  * The [DI token](guide/glossary/#di-token) for a router configuration.
4066
3948
  *
@@ -4093,7 +3975,8 @@ class RouterConfigLoader {
4093
3975
  if (this.onLoadEndListener) {
4094
3976
  this.onLoadEndListener(route);
4095
3977
  }
4096
- NG_DEV_MODE$5 && assertStandalone(route.path ?? '', component);
3978
+ (typeof ngDevMode === 'undefined' || ngDevMode) &&
3979
+ assertStandalone(route.path ?? '', component);
4097
3980
  route._loadedComponent = component;
4098
3981
  }), finalize(() => {
4099
3982
  this.componentLoaders.delete(route);
@@ -4136,7 +4019,8 @@ class RouterConfigLoader {
4136
4019
  rawRoutes = injector.get(ROUTES, [], InjectFlags.Self | InjectFlags.Optional).flat();
4137
4020
  }
4138
4021
  const routes = rawRoutes.map(standardizeConfig);
4139
- NG_DEV_MODE$5 && validateConfig(routes, route.path, requireStandaloneComponents);
4022
+ (typeof ngDevMode === 'undefined' || ngDevMode) &&
4023
+ validateConfig(routes, route.path, requireStandaloneComponents);
4140
4024
  return { routes, injector };
4141
4025
  }), finalize(() => {
4142
4026
  this.childrenLoaders.delete(route);
@@ -4158,10 +4042,10 @@ class RouterConfigLoader {
4158
4042
  }
4159
4043
  }));
4160
4044
  }
4045
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterConfigLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4046
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' }); }
4161
4047
  }
4162
- RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterConfigLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4163
- RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterConfigLoader, providedIn: 'root' });
4164
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterConfigLoader, decorators: [{
4048
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterConfigLoader, decorators: [{
4165
4049
  type: Injectable,
4166
4050
  args: [{ providedIn: 'root' }]
4167
4051
  }] });
@@ -4177,7 +4061,6 @@ function maybeUnwrapDefaultExport(input) {
4177
4061
  return isWrappedDefaultExport(input) ? input['default'] : input;
4178
4062
  }
4179
4063
 
4180
- const NG_DEV_MODE$4 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4181
4064
  class NavigationTransitions {
4182
4065
  get hasRequestedNavigation() {
4183
4066
  return this.navigationId !== 0;
@@ -4267,7 +4150,7 @@ class NavigationTransitions {
4267
4150
  browserUrlTree !== router.currentUrlTree.toString();
4268
4151
  const onSameUrlNavigation = t.extras.onSameUrlNavigation ?? router.onSameUrlNavigation;
4269
4152
  if (!urlTransition && onSameUrlNavigation !== 'reload') {
4270
- const reason = NG_DEV_MODE$4 ?
4153
+ const reason = (typeof ngDevMode === 'undefined' || ngDevMode) ?
4271
4154
  `Navigation to ${t.rawUrl} was ignored because it is the same as the current Router URL.` :
4272
4155
  '';
4273
4156
  this.events.next(new NavigationSkipped(t.id, router.serializeUrl(overallTransitionState.rawUrl), reason, 0 /* NavigationSkippedCode.IgnoredSameUrlNavigation */));
@@ -4293,22 +4176,16 @@ class NavigationTransitions {
4293
4176
  // navigation to always be async
4294
4177
  return Promise.resolve(t);
4295
4178
  }),
4296
- // ApplyRedirects
4297
- applyRedirects(this.environmentInjector, this.configLoader, this.urlSerializer, router.config),
4298
- // Update the currentNavigation
4299
- // `urlAfterRedirects` is guaranteed to be set after this point
4179
+ // Recognize
4180
+ recognize(this.environmentInjector, this.configLoader, this.rootComponentType, router.config, this.urlSerializer, router.paramsInheritanceStrategy),
4181
+ // Update URL if in `eager` update mode
4300
4182
  tap(t => {
4183
+ overallTransitionState.targetSnapshot = t.targetSnapshot;
4184
+ overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
4301
4185
  this.currentNavigation = {
4302
4186
  ...this.currentNavigation,
4303
4187
  finalUrl: t.urlAfterRedirects
4304
4188
  };
4305
- overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
4306
- }),
4307
- // Recognize
4308
- recognize(this.environmentInjector, this.rootComponentType, router.config, this.urlSerializer, router.paramsInheritanceStrategy),
4309
- // Update URL if in `eager` update mode
4310
- tap(t => {
4311
- overallTransitionState.targetSnapshot = t.targetSnapshot;
4312
4189
  if (router.urlUpdateStrategy === 'eager') {
4313
4190
  if (!t.extras.skipLocationChange) {
4314
4191
  const rawUrl = router.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
@@ -4344,7 +4221,7 @@ class NavigationTransitions {
4344
4221
  * current "settled" URL. This way the next navigation will be coming
4345
4222
  * from the current URL in the browser.
4346
4223
  */
4347
- const reason = NG_DEV_MODE$4 ?
4224
+ const reason = (typeof ngDevMode === 'undefined' || ngDevMode) ?
4348
4225
  `Navigation was ignored because the UrlHandlingStrategy` +
4349
4226
  ` indicated neither the current URL ${router.rawUrlTree} nor target URL ${t.rawUrl} should be processed.` :
4350
4227
  '';
@@ -4392,7 +4269,7 @@ class NavigationTransitions {
4392
4269
  complete: () => {
4393
4270
  if (!dataResolved) {
4394
4271
  router.restoreHistory(t);
4395
- this.cancelNavigationTransition(t, NG_DEV_MODE$4 ?
4272
+ this.cancelNavigationTransition(t, (typeof ngDevMode === 'undefined' || ngDevMode) ?
4396
4273
  `At least one route resolver didn't emit any value.` :
4397
4274
  '', 2 /* NavigationCancellationCode.NoDataFromResolver */);
4398
4275
  }
@@ -4465,7 +4342,7 @@ class NavigationTransitions {
4465
4342
  * catch-all to make sure the NavigationCancel event is fired when a
4466
4343
  * navigation gets cancelled but not caught by other means. */
4467
4344
  if (!completed && !errored) {
4468
- const cancelationReason = NG_DEV_MODE$4 ?
4345
+ const cancelationReason = (typeof ngDevMode === 'undefined' || ngDevMode) ?
4469
4346
  `Navigation ID ${overallTransitionState
4470
4347
  .id} is not equal to the current navigation id ${this.navigationId}` :
4471
4348
  '';
@@ -4539,10 +4416,10 @@ class NavigationTransitions {
4539
4416
  this.events.next(navCancel);
4540
4417
  t.resolve(false);
4541
4418
  }
4419
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4420
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: NavigationTransitions, providedIn: 'root' }); }
4542
4421
  }
4543
- NavigationTransitions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: NavigationTransitions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4544
- NavigationTransitions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: NavigationTransitions, providedIn: 'root' });
4545
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: NavigationTransitions, decorators: [{
4422
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: NavigationTransitions, decorators: [{
4546
4423
  type: Injectable,
4547
4424
  args: [{ providedIn: 'root' }]
4548
4425
  }], ctorParameters: function () { return []; } });
@@ -4593,10 +4470,10 @@ class TitleStrategy {
4593
4470
  getResolvedTitleForRoute(snapshot) {
4594
4471
  return snapshot.data[RouteTitleKey];
4595
4472
  }
4473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4474
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }); }
4596
4475
  }
4597
- TitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4598
- TitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
4599
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: TitleStrategy, decorators: [{
4476
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: TitleStrategy, decorators: [{
4600
4477
  type: Injectable,
4601
4478
  args: [{ providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }]
4602
4479
  }] });
@@ -4619,10 +4496,10 @@ class DefaultTitleStrategy extends TitleStrategy {
4619
4496
  this.title.setTitle(title);
4620
4497
  }
4621
4498
  }
4499
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable }); }
4500
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' }); }
4622
4501
  }
4623
- DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
4624
- DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
4625
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
4626
4503
  type: Injectable,
4627
4504
  args: [{ providedIn: 'root' }]
4628
4505
  }], ctorParameters: function () { return [{ type: i1.Title }]; } });
@@ -4635,10 +4512,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4",
4635
4512
  * @publicApi
4636
4513
  */
4637
4514
  class RouteReuseStrategy {
4515
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouteReuseStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4516
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouteReuseStrategy, providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) }); }
4638
4517
  }
4639
- RouteReuseStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouteReuseStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4640
- RouteReuseStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouteReuseStrategy, providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) });
4641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouteReuseStrategy, decorators: [{
4518
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouteReuseStrategy, decorators: [{
4642
4519
  type: Injectable,
4643
4520
  args: [{ providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy) }]
4644
4521
  }] });
@@ -4689,21 +4566,20 @@ class BaseRouteReuseStrategy {
4689
4566
  }
4690
4567
  }
4691
4568
  class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
4569
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultRouteReuseStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
4570
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultRouteReuseStrategy, providedIn: 'root' }); }
4692
4571
  }
4693
- DefaultRouteReuseStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultRouteReuseStrategy, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
4694
- DefaultRouteReuseStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultRouteReuseStrategy, providedIn: 'root' });
4695
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultRouteReuseStrategy, decorators: [{
4572
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultRouteReuseStrategy, decorators: [{
4696
4573
  type: Injectable,
4697
4574
  args: [{ providedIn: 'root' }]
4698
4575
  }] });
4699
4576
 
4700
- const NG_DEV_MODE$3 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4701
4577
  /**
4702
4578
  * A [DI token](guide/glossary/#di-token) for the router service.
4703
4579
  *
4704
4580
  * @publicApi
4705
4581
  */
4706
- const ROUTER_CONFIGURATION = new InjectionToken(NG_DEV_MODE$3 ? 'router config' : '', {
4582
+ const ROUTER_CONFIGURATION = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'router config' : '', {
4707
4583
  providedIn: 'root',
4708
4584
  factory: () => ({}),
4709
4585
  });
@@ -4716,10 +4592,10 @@ const ROUTER_CONFIGURATION = new InjectionToken(NG_DEV_MODE$3 ? 'router config'
4716
4592
  * @publicApi
4717
4593
  */
4718
4594
  class UrlHandlingStrategy {
4595
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: UrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4596
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: UrlHandlingStrategy, providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) }); }
4719
4597
  }
4720
- UrlHandlingStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: UrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4721
- UrlHandlingStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: UrlHandlingStrategy, providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) });
4722
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: UrlHandlingStrategy, decorators: [{
4598
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: UrlHandlingStrategy, decorators: [{
4723
4599
  type: Injectable,
4724
4600
  args: [{ providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy) }]
4725
4601
  }] });
@@ -4736,15 +4612,47 @@ class DefaultUrlHandlingStrategy {
4736
4612
  merge(newUrlPart, wholeUrl) {
4737
4613
  return newUrlPart;
4738
4614
  }
4615
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultUrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4616
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultUrlHandlingStrategy, providedIn: 'root' }); }
4739
4617
  }
4740
- DefaultUrlHandlingStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultUrlHandlingStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
4741
- DefaultUrlHandlingStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultUrlHandlingStrategy, providedIn: 'root' });
4742
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: DefaultUrlHandlingStrategy, decorators: [{
4618
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: DefaultUrlHandlingStrategy, decorators: [{
4743
4619
  type: Injectable,
4744
4620
  args: [{ providedIn: 'root' }]
4745
4621
  }] });
4746
4622
 
4747
- const NG_DEV_MODE$2 = typeof ngDevMode === 'undefined' || !!ngDevMode;
4623
+ var NavigationResult;
4624
+ (function (NavigationResult) {
4625
+ NavigationResult[NavigationResult["COMPLETE"] = 0] = "COMPLETE";
4626
+ NavigationResult[NavigationResult["FAILED"] = 1] = "FAILED";
4627
+ NavigationResult[NavigationResult["REDIRECTING"] = 2] = "REDIRECTING";
4628
+ })(NavigationResult || (NavigationResult = {}));
4629
+ /**
4630
+ * Performs the given action once the router finishes its next/current navigation.
4631
+ *
4632
+ * The navigation is considered complete under the following conditions:
4633
+ * - `NavigationCancel` event emits and the code is not `NavigationCancellationCode.Redirect` or
4634
+ * `NavigationCancellationCode.SupersededByNewNavigation`. In these cases, the
4635
+ * redirecting/superseding navigation must finish.
4636
+ * - `NavigationError`, `NavigationEnd`, or `NavigationSkipped` event emits
4637
+ */
4638
+ function afterNextNavigation(router, action) {
4639
+ router.events
4640
+ .pipe(filter((e) => e instanceof NavigationEnd || e instanceof NavigationCancel ||
4641
+ e instanceof NavigationError || e instanceof NavigationSkipped), map(e => {
4642
+ if (e instanceof NavigationEnd || e instanceof NavigationSkipped) {
4643
+ return NavigationResult.COMPLETE;
4644
+ }
4645
+ const redirecting = e instanceof NavigationCancel ?
4646
+ (e.code === 0 /* NavigationCancellationCode.Redirect */ ||
4647
+ e.code === 1 /* NavigationCancellationCode.SupersededByNewNavigation */) :
4648
+ false;
4649
+ return redirecting ? NavigationResult.REDIRECTING : NavigationResult.FAILED;
4650
+ }), filter((result) => result !== NavigationResult.REDIRECTING), take(1))
4651
+ .subscribe(() => {
4652
+ action();
4653
+ });
4654
+ }
4655
+
4748
4656
  function defaultErrorHandler(error) {
4749
4657
  throw error;
4750
4658
  }
@@ -4821,6 +4729,7 @@ class Router {
4821
4729
  this.console = inject(ɵConsole);
4822
4730
  this.isNgZoneEnabled = false;
4823
4731
  this.options = inject(ROUTER_CONFIGURATION, { optional: true }) || {};
4732
+ this.pendingTasks = inject(ɵInitialRenderPendingTasks);
4824
4733
  /**
4825
4734
  * A handler for navigation errors in this NgModule.
4826
4735
  *
@@ -5054,7 +4963,7 @@ class Router {
5054
4963
  * ```
5055
4964
  */
5056
4965
  resetConfig(config) {
5057
- NG_DEV_MODE$2 && validateConfig(config);
4966
+ (typeof ngDevMode === 'undefined' || ngDevMode) && validateConfig(config);
5058
4967
  this.config = config.map(standardizeConfig);
5059
4968
  this.navigated = false;
5060
4969
  this.lastSuccessfulId = -1;
@@ -5189,7 +5098,7 @@ class Router {
5189
5098
  navigateByUrl(url, extras = {
5190
5099
  skipLocationChange: false
5191
5100
  }) {
5192
- if (NG_DEV_MODE$2) {
5101
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
5193
5102
  if (this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
5194
5103
  this.console.warn(`Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
5195
5104
  }
@@ -5318,6 +5227,13 @@ class Router {
5318
5227
  // This is unused when `canceledNavigationResolution` is not computed.
5319
5228
  targetPageId = 0;
5320
5229
  }
5230
+ // Indicate that the navigation is happening.
5231
+ const taskId = this.pendingTasks.add();
5232
+ afterNextNavigation(this, () => {
5233
+ // Remove pending task in a microtask to allow for cancelled
5234
+ // initial navigations and redirects within the same task.
5235
+ Promise.resolve().then(() => this.pendingTasks.remove(taskId));
5236
+ });
5321
5237
  this.navigationTransitions.handleNavigationRequest({
5322
5238
  targetPageId,
5323
5239
  source,
@@ -5416,10 +5332,10 @@ class Router {
5416
5332
  }
5417
5333
  return { navigationId };
5418
5334
  }
5335
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: Router, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5336
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: Router, providedIn: 'root' }); }
5419
5337
  }
5420
- Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: Router, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5421
- Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: Router, providedIn: 'root' });
5422
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: Router, decorators: [{
5338
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: Router, decorators: [{
5423
5339
  type: Injectable,
5424
5340
  args: [{ providedIn: 'root' }]
5425
5341
  }], ctorParameters: function () { return []; } });
@@ -5427,7 +5343,8 @@ function validateCommands(commands) {
5427
5343
  for (let i = 0; i < commands.length; i++) {
5428
5344
  const cmd = commands[i];
5429
5345
  if (cmd == null) {
5430
- throw new ɵRuntimeError(4008 /* RuntimeErrorCode.NULLISH_COMMAND */, NG_DEV_MODE$2 && `The requested path contains ${cmd} segment at index ${i}`);
5346
+ throw new ɵRuntimeError(4008 /* RuntimeErrorCode.NULLISH_COMMAND */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
5347
+ `The requested path contains ${cmd} segment at index ${i}`);
5431
5348
  }
5432
5349
  }
5433
5350
  }
@@ -5704,10 +5621,10 @@ class RouterLink {
5704
5621
  preserveFragment: this.preserveFragment,
5705
5622
  });
5706
5623
  }
5624
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive }); }
5625
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.5", type: RouterLink, isStandalone: true, selector: "[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", state: "state", relativeTo: "relativeTo", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target" } }, usesOnChanges: true, ngImport: i0 }); }
5707
5626
  }
5708
- RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
5709
- RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.4", type: RouterLink, isStandalone: true, selector: "[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", state: "state", relativeTo: "relativeTo", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target" } }, usesOnChanges: true, ngImport: i0 });
5710
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterLink, decorators: [{
5627
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterLink, decorators: [{
5711
5628
  type: Directive,
5712
5629
  args: [{
5713
5630
  selector: '[routerLink]',
@@ -5927,10 +5844,10 @@ class RouterLinkActive {
5927
5844
  const isActiveCheckFn = this.isLinkActive(this.router);
5928
5845
  return this.link && isActiveCheckFn(this.link) || this.links.some(isActiveCheckFn);
5929
5846
  }
5847
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
5848
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.5", type: RouterLinkActive, isStandalone: true, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 }); }
5930
5849
  }
5931
- RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
5932
- RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0-next.4", type: RouterLinkActive, isStandalone: true, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
5933
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterLinkActive, decorators: [{
5850
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterLinkActive, decorators: [{
5934
5851
  type: Directive,
5935
5852
  args: [{
5936
5853
  selector: '[routerLinkActive]',
@@ -5982,10 +5899,10 @@ class PreloadAllModules {
5982
5899
  preload(route, fn) {
5983
5900
  return fn().pipe(catchError(() => of(null)));
5984
5901
  }
5902
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5903
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: PreloadAllModules, providedIn: 'root' }); }
5985
5904
  }
5986
- PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
5987
- PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
5988
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: PreloadAllModules, decorators: [{
5905
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: PreloadAllModules, decorators: [{
5989
5906
  type: Injectable,
5990
5907
  args: [{ providedIn: 'root' }]
5991
5908
  }] });
@@ -6002,10 +5919,10 @@ class NoPreloading {
6002
5919
  preload(route, fn) {
6003
5920
  return of(null);
6004
5921
  }
5922
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5923
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: NoPreloading, providedIn: 'root' }); }
6005
5924
  }
6006
- NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6007
- NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6008
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: NoPreloading, decorators: [{
5925
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: NoPreloading, decorators: [{
6009
5926
  type: Injectable,
6010
5927
  args: [{ providedIn: 'root' }]
6011
5928
  }] });
@@ -6064,7 +5981,7 @@ class RouterPreloader {
6064
5981
  (route.loadComponent && !route._loadedComponent)) {
6065
5982
  res.push(this.preloadConfig(injectorForCurrentRoute, route));
6066
5983
  }
6067
- else if (route.children || route._loadedRoutes) {
5984
+ if (route.children || route._loadedRoutes) {
6068
5985
  res.push(this.processRoutes(injectorForChildren, (route.children ?? route._loadedRoutes)));
6069
5986
  }
6070
5987
  }
@@ -6098,10 +6015,10 @@ class RouterPreloader {
6098
6015
  }
6099
6016
  });
6100
6017
  }
6018
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable }); }
6019
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterPreloader, providedIn: 'root' }); }
6101
6020
  }
6102
- RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6103
- RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterPreloader, providedIn: 'root' });
6104
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterPreloader, decorators: [{
6021
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterPreloader, decorators: [{
6105
6022
  type: Injectable,
6106
6023
  args: [{ providedIn: 'root' }]
6107
6024
  }], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }]; } });
@@ -6194,47 +6111,13 @@ class RouterScroller {
6194
6111
  this.routerEventsSubscription?.unsubscribe();
6195
6112
  this.scrollEventsSubscription?.unsubscribe();
6196
6113
  }
6114
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable }); }
6115
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterScroller }); }
6197
6116
  }
6198
- RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6199
- RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterScroller });
6200
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterScroller, decorators: [{
6117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterScroller, decorators: [{
6201
6118
  type: Injectable
6202
6119
  }], ctorParameters: function () { return [{ type: UrlSerializer }, { type: NavigationTransitions }, { type: i3.ViewportScroller }, { type: i0.NgZone }, { type: undefined }]; } });
6203
6120
 
6204
- var NavigationResult;
6205
- (function (NavigationResult) {
6206
- NavigationResult[NavigationResult["COMPLETE"] = 0] = "COMPLETE";
6207
- NavigationResult[NavigationResult["FAILED"] = 1] = "FAILED";
6208
- NavigationResult[NavigationResult["REDIRECTING"] = 2] = "REDIRECTING";
6209
- })(NavigationResult || (NavigationResult = {}));
6210
- /**
6211
- * Performs the given action once the router finishes its next/current navigation.
6212
- *
6213
- * The navigation is considered complete under the following conditions:
6214
- * - `NavigationCancel` event emits and the code is not `NavigationCancellationCode.Redirect` or
6215
- * `NavigationCancellationCode.SupersededByNewNavigation`. In these cases, the
6216
- * redirecting/superseding navigation must finish.
6217
- * - `NavigationError`, `NavigationEnd`, or `NavigationSkipped` event emits
6218
- */
6219
- function afterNextNavigation(router, action) {
6220
- router.events
6221
- .pipe(filter((e) => e instanceof NavigationEnd || e instanceof NavigationCancel ||
6222
- e instanceof NavigationError || e instanceof NavigationSkipped), map(e => {
6223
- if (e instanceof NavigationEnd || e instanceof NavigationSkipped) {
6224
- return NavigationResult.COMPLETE;
6225
- }
6226
- const redirecting = e instanceof NavigationCancel ?
6227
- (e.code === 0 /* NavigationCancellationCode.Redirect */ ||
6228
- e.code === 1 /* NavigationCancellationCode.SupersededByNewNavigation */) :
6229
- false;
6230
- return redirecting ? NavigationResult.REDIRECTING : NavigationResult.FAILED;
6231
- }), filter((result) => result !== NavigationResult.REDIRECTING), take(1))
6232
- .subscribe(() => {
6233
- action();
6234
- });
6235
- }
6236
-
6237
- const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || ngDevMode;
6238
6121
  /**
6239
6122
  * Sets up providers necessary to enable `Router` functionality for the application.
6240
6123
  * Allows to configure a set of routes as well as extra features that should be enabled.
@@ -6274,7 +6157,9 @@ const NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || ngDevMode;
6274
6157
  function provideRouter(routes, ...features) {
6275
6158
  return makeEnvironmentProviders([
6276
6159
  { provide: ROUTES, multi: true, useValue: routes },
6277
- NG_DEV_MODE$1 ? { provide: ROUTER_IS_PROVIDED, useValue: true } : [],
6160
+ (typeof ngDevMode === 'undefined' || ngDevMode) ?
6161
+ { provide: ROUTER_IS_PROVIDED, useValue: true } :
6162
+ [],
6278
6163
  { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
6279
6164
  { provide: APP_BOOTSTRAP_LISTENER, multi: true, useFactory: getBootstrapListener },
6280
6165
  features.map(feature => feature.ɵproviders),
@@ -6326,7 +6211,7 @@ const routerIsProvidedDevModeCheck = {
6326
6211
  function provideRoutes(routes) {
6327
6212
  return [
6328
6213
  { provide: ROUTES, multi: true, useValue: routes },
6329
- NG_DEV_MODE$1 ? routerIsProvidedDevModeCheck : [],
6214
+ (typeof ngDevMode === 'undefined' || ngDevMode) ? routerIsProvidedDevModeCheck : [],
6330
6215
  ];
6331
6216
  }
6332
6217
  /**
@@ -6393,12 +6278,12 @@ function getBootstrapListener() {
6393
6278
  * `enabledBlocking`, the first navigation waits until bootstrapping is finished before continuing
6394
6279
  * to the activation phase.
6395
6280
  */
6396
- const BOOTSTRAP_DONE = new InjectionToken(NG_DEV_MODE$1 ? 'bootstrap done indicator' : '', {
6281
+ const BOOTSTRAP_DONE = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'bootstrap done indicator' : '', {
6397
6282
  factory: () => {
6398
6283
  return new Subject();
6399
6284
  }
6400
6285
  });
6401
- const INITIAL_NAVIGATION = new InjectionToken(NG_DEV_MODE$1 ? 'initial navigation' : '', { providedIn: 'root', factory: () => 1 /* InitialNavigation.EnabledNonBlocking */ });
6286
+ const INITIAL_NAVIGATION = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'initial navigation' : '', { providedIn: 'root', factory: () => 1 /* InitialNavigation.EnabledNonBlocking */ });
6402
6287
  /**
6403
6288
  * Configures initial navigation to start before the root component is created.
6404
6289
  *
@@ -6527,7 +6412,7 @@ function withDisabledInitialNavigation() {
6527
6412
  */
6528
6413
  function withDebugTracing() {
6529
6414
  let providers = [];
6530
- if (NG_DEV_MODE$1) {
6415
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
6531
6416
  providers = [{
6532
6417
  provide: ENVIRONMENT_INITIALIZER,
6533
6418
  multi: true,
@@ -6549,7 +6434,7 @@ function withDebugTracing() {
6549
6434
  }
6550
6435
  return routerFeature(1 /* RouterFeatureKind.DebugTracingFeature */, providers);
6551
6436
  }
6552
- const ROUTER_PRELOADER = new InjectionToken(NG_DEV_MODE$1 ? 'router preloader' : '');
6437
+ const ROUTER_PRELOADER = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'router preloader' : '');
6553
6438
  /**
6554
6439
  * Allows to configure a preloading strategy to use. The strategy is configured by providing a
6555
6440
  * reference to a class that implements a `PreloadingStrategy`.
@@ -6691,7 +6576,6 @@ function withNavigationErrorHandler(fn) {
6691
6576
  return routerFeature(7 /* RouterFeatureKind.NavigationErrorHandlerFeature */, providers);
6692
6577
  }
6693
6578
 
6694
- const NG_DEV_MODE = typeof ngDevMode === 'undefined' || ngDevMode;
6695
6579
  /**
6696
6580
  * The directives defined in the `RouterModule`.
6697
6581
  */
@@ -6699,7 +6583,8 @@ const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOu
6699
6583
  /**
6700
6584
  * @docsNotRequired
6701
6585
  */
6702
- const ROUTER_FORROOT_GUARD = new InjectionToken(NG_DEV_MODE ? 'router duplicate forRoot guard' : 'ROUTER_FORROOT_GUARD');
6586
+ const ROUTER_FORROOT_GUARD = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'router duplicate forRoot guard' :
6587
+ 'ROUTER_FORROOT_GUARD');
6703
6588
  // TODO(atscott): All of these except `ActivatedRoute` are `providedIn: 'root'`. They are only kept
6704
6589
  // here to avoid a breaking change whereby the provider order matters based on where the
6705
6590
  // `RouterModule`/`RouterTestingModule` is imported. These can/should be removed as a "breaking"
@@ -6713,7 +6598,8 @@ const ROUTER_PROVIDERS = [
6713
6598
  RouterConfigLoader,
6714
6599
  // Only used to warn when `provideRoutes` is used without `RouterModule` or `provideRouter`. Can
6715
6600
  // be removed when `provideRoutes` is removed.
6716
- NG_DEV_MODE ? { provide: ROUTER_IS_PROVIDED, useValue: true } : [],
6601
+ (typeof ngDevMode === 'undefined' || ngDevMode) ? { provide: ROUTER_IS_PROVIDED, useValue: true } :
6602
+ [],
6717
6603
  ];
6718
6604
  function routerNgProbeToken() {
6719
6605
  return new NgProbeToken('Router', Router);
@@ -6764,7 +6650,9 @@ class RouterModule {
6764
6650
  ngModule: RouterModule,
6765
6651
  providers: [
6766
6652
  ROUTER_PROVIDERS,
6767
- NG_DEV_MODE ? (config?.enableTracing ? withDebugTracing().ɵproviders : []) : [],
6653
+ (typeof ngDevMode === 'undefined' || ngDevMode) ?
6654
+ (config?.enableTracing ? withDebugTracing().ɵproviders : []) :
6655
+ [],
6768
6656
  { provide: ROUTES, multi: true, useValue: routes },
6769
6657
  {
6770
6658
  provide: ROUTER_FORROOT_GUARD,
@@ -6803,11 +6691,11 @@ class RouterModule {
6803
6691
  providers: [{ provide: ROUTES, multi: true, useValue: routes }],
6804
6692
  };
6805
6693
  }
6694
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
6695
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterModule, imports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent] }); }
6696
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterModule, imports: [ɵEmptyOutletComponent] }); }
6806
6697
  }
6807
- RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
6808
- RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterModule, imports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent] });
6809
- RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterModule, imports: [ɵEmptyOutletComponent] });
6810
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.4", ngImport: i0, type: RouterModule, decorators: [{
6698
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0-next.5", ngImport: i0, type: RouterModule, decorators: [{
6811
6699
  type: NgModule,
6812
6700
  args: [{
6813
6701
  imports: ROUTER_DIRECTIVES,
@@ -6850,7 +6738,7 @@ function providePathLocationStrategy() {
6850
6738
  return { provide: LocationStrategy, useClass: PathLocationStrategy };
6851
6739
  }
6852
6740
  function provideForRootGuard(router) {
6853
- if (NG_DEV_MODE && router) {
6741
+ if ((typeof ngDevMode === 'undefined' || ngDevMode) && router) {
6854
6742
  throw new ɵRuntimeError(4007 /* RuntimeErrorCode.FOR_ROOT_CALLED_TWICE */, `The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector.` +
6855
6743
  ` Lazy loaded modules should use RouterModule.forChild() instead.`);
6856
6744
  }
@@ -6873,7 +6761,7 @@ function provideInitialNavigation(config) {
6873
6761
  *
6874
6762
  * @publicApi
6875
6763
  */
6876
- const ROUTER_INITIALIZER = new InjectionToken(NG_DEV_MODE ? 'Router Initializer' : '');
6764
+ const ROUTER_INITIALIZER = new InjectionToken((typeof ngDevMode === 'undefined' || ngDevMode) ? 'Router Initializer' : '');
6877
6765
  function provideRouterInitializer() {
6878
6766
  return [
6879
6767
  // ROUTER_INITIALIZER token should be removed. It's public API but shouldn't be. We can just
@@ -6952,7 +6840,7 @@ function mapToResolve(provider) {
6952
6840
  /**
6953
6841
  * @publicApi
6954
6842
  */
6955
- const VERSION = new Version('16.0.0-next.4');
6843
+ const VERSION = new Version('16.0.0-next.5');
6956
6844
 
6957
6845
  /**
6958
6846
  * @module