You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
puhui-go-web/.angular/cache/17.0.7/vite/deps/chunk-CZEXXPIB.js

5588 lines
192 KiB

import {
Title
} from "./chunk-Y4CEYMY2.js";
import {
DOCUMENT,
HashLocationStrategy,
LOCATION_INITIALIZED,
Location,
LocationStrategy,
PathLocationStrategy,
ViewportScroller
} from "./chunk-OSQBUYO6.js";
import {
APP_BOOTSTRAP_LISTENER,
APP_INITIALIZER,
ApplicationRef,
Attribute,
BehaviorSubject,
ChangeDetectorRef,
Compiler,
Component,
ConnectableObservable,
Console,
ContentChildren,
Directive,
EMPTY,
ENVIRONMENT_INITIALIZER,
ElementRef,
EmptyError,
EnvironmentInjector,
EventEmitter,
HostBinding,
HostListener,
InitialRenderPendingTasks,
Inject,
InjectFlags,
Injectable,
InjectionToken,
Injector,
Input,
NgModule,
NgModuleFactory$1,
NgZone,
Optional,
Output,
Renderer2,
RuntimeError,
SkipSelf,
Subject,
Subscription,
Version,
ViewContainerRef,
afterNextRender,
booleanAttribute,
catchError,
combineLatest,
concat,
concatMap,
createEnvironmentInjector,
defaultIfEmpty,
defer,
filter,
finalize,
first,
from,
inject,
isInjectable,
isNgModule,
isObservable,
isPromise,
isStandalone,
last,
makeEnvironmentProviders,
map,
mapTo,
mergeAll,
mergeMap,
of,
pipe,
refCount,
reflectComponentType,
runInInjectionContext,
scan,
setClassMetadata,
startWith,
switchMap,
take,
takeLast,
takeUntil,
tap,
throwError,
ɵɵInputTransformsFeature,
ɵɵNgOnChangesFeature,
ɵɵStandaloneFeature,
ɵɵattribute,
ɵɵcontentQuery,
ɵɵdefineComponent,
ɵɵdefineDirective,
ɵɵdefineInjectable,
ɵɵdefineInjector,
ɵɵdefineNgModule,
ɵɵdirectiveInject,
ɵɵelement,
ɵɵgetInheritedFactory,
ɵɵinject,
ɵɵinjectAttribute,
ɵɵinvalidFactory,
ɵɵlistener,
ɵɵloadQuery,
ɵɵqueryRefresh,
ɵɵsanitizeUrlOrResourceUrl
} from "./chunk-FGESKT7O.js";
import {
__spreadProps,
__spreadValues
} from "./chunk-HSNDBVJ3.js";
// node_modules/@angular/router/fesm2022/router.mjs
var PRIMARY_OUTLET = "primary";
var RouteTitleKey = Symbol("RouteTitle");
var ParamsAsMap = class {
constructor(params) {
this.params = params || {};
}
has(name) {
return Object.prototype.hasOwnProperty.call(this.params, name);
}
get(name) {
if (this.has(name)) {
const v = this.params[name];
return Array.isArray(v) ? v[0] : v;
}
return null;
}
getAll(name) {
if (this.has(name)) {
const v = this.params[name];
return Array.isArray(v) ? v : [v];
}
return [];
}
get keys() {
return Object.keys(this.params);
}
};
function convertToParamMap(params) {
return new ParamsAsMap(params);
}
function defaultUrlMatcher(segments, segmentGroup, route) {
const parts = route.path.split("/");
if (parts.length > segments.length) {
return null;
}
if (route.pathMatch === "full" && (segmentGroup.hasChildren() || parts.length < segments.length)) {
return null;
}
const posParams = {};
for (let index = 0; index < parts.length; index++) {
const part = parts[index];
const segment = segments[index];
const isParameter = part.startsWith(":");
if (isParameter) {
posParams[part.substring(1)] = segment;
} else if (part !== segment.path) {
return null;
}
}
return {
consumed: segments.slice(0, parts.length),
posParams
};
}
function shallowEqualArrays(a, b) {
if (a.length !== b.length)
return false;
for (let i = 0; i < a.length; ++i) {
if (!shallowEqual(a[i], b[i]))
return false;
}
return true;
}
function shallowEqual(a, b) {
const k1 = a ? getDataKeys(a) : void 0;
const k2 = b ? getDataKeys(b) : void 0;
if (!k1 || !k2 || k1.length != k2.length) {
return false;
}
let key;
for (let i = 0; i < k1.length; i++) {
key = k1[i];
if (!equalArraysOrString(a[key], b[key])) {
return false;
}
}
return true;
}
function getDataKeys(obj) {
return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
}
function equalArraysOrString(a, b) {
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length)
return false;
const aSorted = [...a].sort();
const bSorted = [...b].sort();
return aSorted.every((val, index) => bSorted[index] === val);
} else {
return a === b;
}
}
function last2(a) {
return a.length > 0 ? a[a.length - 1] : null;
}
function wrapIntoObservable(value) {
if (isObservable(value)) {
return value;
}
if (isPromise(value)) {
return from(Promise.resolve(value));
}
return of(value);
}
var pathCompareMap = {
"exact": equalSegmentGroups,
"subset": containsSegmentGroup
};
var paramCompareMap = {
"exact": equalParams,
"subset": containsParams,
"ignored": () => true
};
function containsTree(container, containee, options) {
return pathCompareMap[options.paths](container.root, containee.root, options.matrixParams) && paramCompareMap[options.queryParams](container.queryParams, containee.queryParams) && !(options.fragment === "exact" && container.fragment !== containee.fragment);
}
function equalParams(container, containee) {
return shallowEqual(container, containee);
}
function equalSegmentGroups(container, containee, matrixParams) {
if (!equalPath(container.segments, containee.segments))
return false;
if (!matrixParamsMatch(container.segments, containee.segments, matrixParams)) {
return false;
}
if (container.numberOfChildren !== containee.numberOfChildren)
return false;
for (const c in containee.children) {
if (!container.children[c])
return false;
if (!equalSegmentGroups(container.children[c], containee.children[c], matrixParams))
return false;
}
return true;
}
function containsParams(container, containee) {
return Object.keys(containee).length <= Object.keys(container).length && Object.keys(containee).every((key) => equalArraysOrString(container[key], containee[key]));
}
function containsSegmentGroup(container, containee, matrixParams) {
return containsSegmentGroupHelper(container, containee, containee.segments, matrixParams);
}
function containsSegmentGroupHelper(container, containee, containeePaths, matrixParams) {
if (container.segments.length > containeePaths.length) {
const current = container.segments.slice(0, containeePaths.length);
if (!equalPath(current, containeePaths))
return false;
if (containee.hasChildren())
return false;
if (!matrixParamsMatch(current, containeePaths, matrixParams))
return false;
return true;
} else if (container.segments.length === containeePaths.length) {
if (!equalPath(container.segments, containeePaths))
return false;
if (!matrixParamsMatch(container.segments, containeePaths, matrixParams))
return false;
for (const c in containee.children) {
if (!container.children[c])
return false;
if (!containsSegmentGroup(container.children[c], containee.children[c], matrixParams)) {
return false;
}
}
return true;
} else {
const current = containeePaths.slice(0, container.segments.length);
const next = containeePaths.slice(container.segments.length);
if (!equalPath(container.segments, current))
return false;
if (!matrixParamsMatch(container.segments, current, matrixParams))
return false;
if (!container.children[PRIMARY_OUTLET])
return false;
return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next, matrixParams);
}
}
function matrixParamsMatch(containerPaths, containeePaths, options) {
return containeePaths.every((containeeSegment, i) => {
return paramCompareMap[options](containerPaths[i].parameters, containeeSegment.parameters);
});
}
var UrlTree = class {
constructor(root = new UrlSegmentGroup([], {}), queryParams = {}, fragment = null) {
this.root = root;
this.queryParams = queryParams;
this.fragment = fragment;
if (typeof ngDevMode === "undefined" || ngDevMode) {
if (root.segments.length > 0) {
throw new RuntimeError(4015, "The root `UrlSegmentGroup` should not contain `segments`. Instead, these segments belong in the `children` so they can be associated with a named outlet.");
}
}
}
get queryParamMap() {
if (!this._queryParamMap) {
this._queryParamMap = convertToParamMap(this.queryParams);
}
return this._queryParamMap;
}
/** @docsNotRequired */
toString() {
return DEFAULT_SERIALIZER.serialize(this);
}
};
var UrlSegmentGroup = class {
constructor(segments, children) {
this.segments = segments;
this.children = children;
this.parent = null;
Object.values(children).forEach((v) => v.parent = this);
}
/** Whether the segment has child segments */
hasChildren() {
return this.numberOfChildren > 0;
}
/** Number of child segments */
get numberOfChildren() {
return Object.keys(this.children).length;
}
/** @docsNotRequired */
toString() {
return serializePaths(this);
}
};
var UrlSegment = class {
constructor(path, parameters) {
this.path = path;
this.parameters = parameters;
}
get parameterMap() {
if (!this._parameterMap) {
this._parameterMap = convertToParamMap(this.parameters);
}
return this._parameterMap;
}
/** @docsNotRequired */
toString() {
return serializePath(this);
}
};
function equalSegments(as, bs) {
return equalPath(as, bs) && as.every((a, i) => shallowEqual(a.parameters, bs[i].parameters));
}
function equalPath(as, bs) {
if (as.length !== bs.length)
return false;
return as.every((a, i) => a.path === bs[i].path);
}
function mapChildrenIntoArray(segment, fn) {
let res = [];
Object.entries(segment.children).forEach(([childOutlet, child]) => {
if (childOutlet === PRIMARY_OUTLET) {
res = res.concat(fn(child, childOutlet));
}
});
Object.entries(segment.children).forEach(([childOutlet, child]) => {
if (childOutlet !== PRIMARY_OUTLET) {
res = res.concat(fn(child, childOutlet));
}
});
return res;
}
var _UrlSerializer = class _UrlSerializer {
};
_UrlSerializer.ɵfac = function UrlSerializer_Factory(t) {
return new (t || _UrlSerializer)();
};
_UrlSerializer.ɵprov = ɵɵdefineInjectable({
token: _UrlSerializer,
factory: () => (() => new DefaultUrlSerializer())(),
providedIn: "root"
});
var UrlSerializer = _UrlSerializer;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(UrlSerializer, [{
type: Injectable,
args: [{
providedIn: "root",
useFactory: () => new DefaultUrlSerializer()
}]
}], null, null);
})();
var DefaultUrlSerializer = class {
/** Parses a url into a `UrlTree` */
parse(url) {
const p = new UrlParser(url);
return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
}
/** Converts a `UrlTree` into a url */
serialize(tree2) {
const segment = `/${serializeSegment(tree2.root, true)}`;
const query = serializeQueryParams(tree2.queryParams);
const fragment = typeof tree2.fragment === `string` ? `#${encodeUriFragment(tree2.fragment)}` : "";
return `${segment}${query}${fragment}`;
}
};
var DEFAULT_SERIALIZER = new DefaultUrlSerializer();
function serializePaths(segment) {
return segment.segments.map((p) => serializePath(p)).join("/");
}
function serializeSegment(segment, root) {
if (!segment.hasChildren()) {
return serializePaths(segment);
}
if (root) {
const primary = segment.children[PRIMARY_OUTLET] ? serializeSegment(segment.children[PRIMARY_OUTLET], false) : "";
const children = [];
Object.entries(segment.children).forEach(([k, v]) => {
if (k !== PRIMARY_OUTLET) {
children.push(`${k}:${serializeSegment(v, false)}`);
}
});
return children.length > 0 ? `${primary}(${children.join("//")})` : primary;
} else {
const children = mapChildrenIntoArray(segment, (v, k) => {
if (k === PRIMARY_OUTLET) {
return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
}
return [`${k}:${serializeSegment(v, false)}`];
});
if (Object.keys(segment.children).length === 1 && segment.children[PRIMARY_OUTLET] != null) {
return `${serializePaths(segment)}/${children[0]}`;
}
return `${serializePaths(segment)}/(${children.join("//")})`;
}
}
function encodeUriString(s) {
return encodeURIComponent(s).replace(/%40/g, "@").replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",");
}
function encodeUriQuery(s) {
return encodeUriString(s).replace(/%3B/gi, ";");
}
function encodeUriFragment(s) {
return encodeURI(s);
}
function encodeUriSegment(s) {
return encodeUriString(s).replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/%26/gi, "&");
}
function decode(s) {
return decodeURIComponent(s);
}
function decodeQuery(s) {
return decode(s.replace(/\+/g, "%20"));
}
function serializePath(path) {
return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
}
function serializeMatrixParams(params) {
return Object.keys(params).map((key) => `;${encodeUriSegment(key)}=${encodeUriSegment(params[key])}`).join("");
}
function serializeQueryParams(params) {
const strParams = Object.keys(params).map((name) => {
const value = params[name];
return Array.isArray(value) ? value.map((v) => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`).join("&") : `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
}).filter((s) => !!s);
return strParams.length ? `?${strParams.join("&")}` : "";
}
var SEGMENT_RE = /^[^\/()?;#]+/;
function matchSegments(str) {
const match2 = str.match(SEGMENT_RE);
return match2 ? match2[0] : "";
}
var MATRIX_PARAM_SEGMENT_RE = /^[^\/()?;=#]+/;
function matchMatrixKeySegments(str) {
const match2 = str.match(MATRIX_PARAM_SEGMENT_RE);
return match2 ? match2[0] : "";
}
var QUERY_PARAM_RE = /^[^=?&#]+/;
function matchQueryParams(str) {
const match2 = str.match(QUERY_PARAM_RE);
return match2 ? match2[0] : "";
}
var QUERY_PARAM_VALUE_RE = /^[^&#]+/;
function matchUrlQueryParamValue(str) {
const match2 = str.match(QUERY_PARAM_VALUE_RE);
return match2 ? match2[0] : "";
}
var UrlParser = class {
constructor(url) {
this.url = url;
this.remaining = url;
}
parseRootSegment() {
this.consumeOptional("/");
if (this.remaining === "" || this.peekStartsWith("?") || this.peekStartsWith("#")) {
return new UrlSegmentGroup([], {});
}
return new UrlSegmentGroup([], this.parseChildren());
}
parseQueryParams() {
const params = {};
if (this.consumeOptional("?")) {
do {
this.parseQueryParam(params);
} while (this.consumeOptional("&"));
}
return params;
}
parseFragment() {
return this.consumeOptional("#") ? decodeURIComponent(this.remaining) : null;
}
parseChildren() {
if (this.remaining === "") {
return {};
}
this.consumeOptional("/");
const segments = [];
if (!this.peekStartsWith("(")) {
segments.push(this.parseSegment());
}
while (this.peekStartsWith("/") && !this.peekStartsWith("//") && !this.peekStartsWith("/(")) {
this.capture("/");
segments.push(this.parseSegment());
}
let children = {};
if (this.peekStartsWith("/(")) {
this.capture("/");
children = this.parseParens(true);
}
let res = {};
if (this.peekStartsWith("(")) {
res = this.parseParens(false);
}
if (segments.length > 0 || Object.keys(children).length > 0) {
res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
}
return res;
}
// parse a segment with its matrix parameters
// ie `name;k1=v1;k2`
parseSegment() {
const path = matchSegments(this.remaining);
if (path === "" && this.peekStartsWith(";")) {
throw new RuntimeError(4009, (typeof ngDevMode === "undefined" || ngDevMode) && `Empty path url segment cannot have parameters: '${this.remaining}'.`);
}
this.capture(path);
return new UrlSegment(decode(path), this.parseMatrixParams());
}
parseMatrixParams() {
const params = {};
while (this.consumeOptional(";")) {
this.parseParam(params);
}
return params;
}
parseParam(params) {
const key = matchMatrixKeySegments(this.remaining);
if (!key) {
return;
}
this.capture(key);
let value = "";
if (this.consumeOptional("=")) {
const valueMatch = matchSegments(this.remaining);
if (valueMatch) {
value = valueMatch;
this.capture(value);
}
}
params[decode(key)] = decode(value);
}
// Parse a single query parameter `name[=value]`
parseQueryParam(params) {
const key = matchQueryParams(this.remaining);
if (!key) {
return;
}
this.capture(key);
let value = "";
if (this.consumeOptional("=")) {
const valueMatch = matchUrlQueryParamValue(this.remaining);
if (valueMatch) {
value = valueMatch;
this.capture(value);
}
}
const decodedKey = decodeQuery(key);
const decodedVal = decodeQuery(value);
if (params.hasOwnProperty(decodedKey)) {
let currentVal = params[decodedKey];
if (!Array.isArray(currentVal)) {
currentVal = [currentVal];
params[decodedKey] = currentVal;
}
currentVal.push(decodedVal);
} else {
params[decodedKey] = decodedVal;
}
}
// parse `(a/b//outlet_name:c/d)`
parseParens(allowPrimary) {
const segments = {};
this.capture("(");
while (!this.consumeOptional(")") && this.remaining.length > 0) {
const path = matchSegments(this.remaining);
const next = this.remaining[path.length];
if (next !== "/" && next !== ")" && next !== ";") {
throw new RuntimeError(4010, (typeof ngDevMode === "undefined" || ngDevMode) && `Cannot parse url '${this.url}'`);
}
let outletName = void 0;
if (path.indexOf(":") > -1) {
outletName = path.slice(0, path.indexOf(":"));
this.capture(outletName);
this.capture(":");
} else if (allowPrimary) {
outletName = PRIMARY_OUTLET;
}
const children = this.parseChildren();
segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] : new UrlSegmentGroup([], children);
this.consumeOptional("//");
}
return segments;
}
peekStartsWith(str) {
return this.remaining.startsWith(str);
}
// Consumes the prefix when it is present and returns whether it has been consumed
consumeOptional(str) {
if (this.peekStartsWith(str)) {
this.remaining = this.remaining.substring(str.length);
return true;
}
return false;
}
capture(str) {
if (!this.consumeOptional(str)) {
throw new RuntimeError(4011, (typeof ngDevMode === "undefined" || ngDevMode) && `Expected "${str}".`);
}
}
};
function createRoot(rootCandidate) {
return rootCandidate.segments.length > 0 ? new UrlSegmentGroup([], {
[PRIMARY_OUTLET]: rootCandidate
}) : rootCandidate;
}
function squashSegmentGroup(segmentGroup) {
const newChildren = {};
for (const childOutlet of Object.keys(segmentGroup.children)) {
const child = segmentGroup.children[childOutlet];
const childCandidate = squashSegmentGroup(child);
if (childOutlet === PRIMARY_OUTLET && childCandidate.segments.length === 0 && childCandidate.hasChildren()) {
for (const [grandChildOutlet, grandChild] of Object.entries(childCandidate.children)) {
newChildren[grandChildOutlet] = grandChild;
}
} else if (childCandidate.segments.length > 0 || childCandidate.hasChildren()) {
newChildren[childOutlet] = childCandidate;
}
}
const s = new UrlSegmentGroup(segmentGroup.segments, newChildren);
return mergeTrivialChildren(s);
}
function mergeTrivialChildren(s) {
if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
const c = s.children[PRIMARY_OUTLET];
return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
}
return s;
}
function isUrlTree(v) {
return v instanceof UrlTree;
}
function createUrlTreeFromSnapshot(relativeTo, commands, queryParams = null, fragment = null) {
const relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeTo);
return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, queryParams, fragment);
}
function createSegmentGroupFromRoute(route) {
let targetGroup;
function createSegmentGroupFromRouteRecursive(currentRoute) {
const childOutlets = {};
for (const childSnapshot of currentRoute.children) {
const root = createSegmentGroupFromRouteRecursive(childSnapshot);
childOutlets[childSnapshot.outlet] = root;
}
const segmentGroup = new UrlSegmentGroup(currentRoute.url, childOutlets);
if (currentRoute === route) {
targetGroup = segmentGroup;
}
return segmentGroup;
}
const rootCandidate = createSegmentGroupFromRouteRecursive(route.root);
const rootSegmentGroup = createRoot(rootCandidate);
return targetGroup ?? rootSegmentGroup;
}
function createUrlTreeFromSegmentGroup(relativeTo, commands, queryParams, fragment) {
let root = relativeTo;
while (root.parent) {
root = root.parent;
}
if (commands.length === 0) {
return tree(root, root, root, queryParams, fragment);
}
const nav = computeNavigation(commands);
if (nav.toRoot()) {
return tree(root, root, new UrlSegmentGroup([], {}), queryParams, fragment);
}
const position = findStartingPositionForTargetGroup(nav, root, relativeTo);
const newSegmentGroup = position.processChildren ? updateSegmentGroupChildren(position.segmentGroup, position.index, nav.commands) : updateSegmentGroup(position.segmentGroup, position.index, nav.commands);
return tree(root, position.segmentGroup, newSegmentGroup, queryParams, fragment);
}
function isMatrixParams(command) {
return typeof command === "object" && command != null && !command.outlets && !command.segmentPath;
}
function isCommandWithOutlets(command) {
return typeof command === "object" && command != null && command.outlets;
}
function tree(oldRoot, oldSegmentGroup, newSegmentGroup, queryParams, fragment) {
let qp = {};
if (queryParams) {
Object.entries(queryParams).forEach(([name, value]) => {
qp[name] = Array.isArray(value) ? value.map((v) => `${v}`) : `${value}`;
});
}
let rootCandidate;
if (oldRoot === oldSegmentGroup) {
rootCandidate = newSegmentGroup;
} else {
rootCandidate = replaceSegment(oldRoot, oldSegmentGroup, newSegmentGroup);
}
const newRoot = createRoot(squashSegmentGroup(rootCandidate));
return new UrlTree(newRoot, qp, fragment);
}
function replaceSegment(current, oldSegment, newSegment) {
const children = {};
Object.entries(current.children).forEach(([outletName, c]) => {
if (c === oldSegment) {
children[outletName] = newSegment;
} else {
children[outletName] = replaceSegment(c, oldSegment, newSegment);
}
});
return new UrlSegmentGroup(current.segments, children);
}
var Navigation = class {
constructor(isAbsolute, numberOfDoubleDots, commands) {
this.isAbsolute = isAbsolute;
this.numberOfDoubleDots = numberOfDoubleDots;
this.commands = commands;
if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
throw new RuntimeError(4003, (typeof ngDevMode === "undefined" || ngDevMode) && "Root segment cannot have matrix parameters");
}
const cmdWithOutlet = commands.find(isCommandWithOutlets);
if (cmdWithOutlet && cmdWithOutlet !== last2(commands)) {
throw new RuntimeError(4004, (typeof ngDevMode === "undefined" || ngDevMode) && "{outlets:{}} has to be the last command");
}
}
toRoot() {
return this.isAbsolute && this.commands.length === 1 && this.commands[0] == "/";
}
};
function computeNavigation(commands) {
if (typeof commands[0] === "string" && commands.length === 1 && commands[0] === "/") {
return new Navigation(true, 0, commands);
}
let numberOfDoubleDots = 0;
let isAbsolute = false;
const res = commands.reduce((res2, cmd, cmdIdx) => {
if (typeof cmd === "object" && cmd != null) {
if (cmd.outlets) {
const outlets = {};
Object.entries(cmd.outlets).forEach(([name, commands2]) => {
outlets[name] = typeof commands2 === "string" ? commands2.split("/") : commands2;
});
return [...res2, {
outlets
}];
}
if (cmd.segmentPath) {
return [...res2, cmd.segmentPath];
}
}
if (!(typeof cmd === "string")) {
return [...res2, cmd];
}
if (cmdIdx === 0) {
cmd.split("/").forEach((urlPart, partIndex) => {
if (partIndex == 0 && urlPart === ".") {
} else if (partIndex == 0 && urlPart === "") {
isAbsolute = true;
} else if (urlPart === "..") {
numberOfDoubleDots++;
} else if (urlPart != "") {
res2.push(urlPart);
}
});
return res2;
}
return [...res2, cmd];
}, []);
return new Navigation(isAbsolute, numberOfDoubleDots, res);
}
var Position = class {
constructor(segmentGroup, processChildren, index) {
this.segmentGroup = segmentGroup;
this.processChildren = processChildren;
this.index = index;
}
};
function findStartingPositionForTargetGroup(nav, root, target) {
if (nav.isAbsolute) {
return new Position(root, true, 0);
}
if (!target) {
return new Position(root, false, NaN);
}
if (target.parent === null) {
return new Position(target, true, 0);
}
const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
const index = target.segments.length - 1 + modifier;
return createPositionApplyingDoubleDots(target, index, nav.numberOfDoubleDots);
}
function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
let g = group;
let ci = index;
let dd = numberOfDoubleDots;
while (dd > ci) {
dd -= ci;
g = g.parent;
if (!g) {
throw new RuntimeError(4005, (typeof ngDevMode === "undefined" || ngDevMode) && "Invalid number of '../'");
}
ci = g.segments.length;
}
return new Position(g, false, ci - dd);
}
function getOutlets(commands) {
if (isCommandWithOutlets(commands[0])) {
return commands[0].outlets;
}
return {
[PRIMARY_OUTLET]: commands
};
}
function updateSegmentGroup(segmentGroup, startIndex, commands) {
if (!segmentGroup) {
segmentGroup = new UrlSegmentGroup([], {});
}
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
}
const m = prefixedWith(segmentGroup, startIndex, commands);
const slicedCommands = commands.slice(m.commandIndex);
if (m.match && m.pathIndex < segmentGroup.segments.length) {
const g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
g.children[PRIMARY_OUTLET] = new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
return updateSegmentGroupChildren(g, 0, slicedCommands);
} else if (m.match && slicedCommands.length === 0) {
return new UrlSegmentGroup(segmentGroup.segments, {});
} else if (m.match && !segmentGroup.hasChildren()) {
return createNewSegmentGroup(segmentGroup, startIndex, commands);
} else if (m.match) {
return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
} else {
return createNewSegmentGroup(segmentGroup, startIndex, commands);
}
}
function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
if (commands.length === 0) {
return new UrlSegmentGroup(segmentGroup.segments, {});
} else {
const outlets = getOutlets(commands);
const children = {};
if (Object.keys(outlets).some((o) => o !== PRIMARY_OUTLET) && segmentGroup.children[PRIMARY_OUTLET] && segmentGroup.numberOfChildren === 1 && segmentGroup.children[PRIMARY_OUTLET].segments.length === 0) {
const childrenOfEmptyChild = updateSegmentGroupChildren(segmentGroup.children[PRIMARY_OUTLET], startIndex, commands);
return new UrlSegmentGroup(segmentGroup.segments, childrenOfEmptyChild.children);
}
Object.entries(outlets).forEach(([outlet, commands2]) => {
if (typeof commands2 === "string") {
commands2 = [commands2];
}
if (commands2 !== null) {
children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands2);
}
});
Object.entries(segmentGroup.children).forEach(([childOutlet, child]) => {
if (outlets[childOutlet] === void 0) {
children[childOutlet] = child;
}
});
return new UrlSegmentGroup(segmentGroup.segments, children);
}
}
function prefixedWith(segmentGroup, startIndex, commands) {
let currentCommandIndex = 0;
let currentPathIndex = startIndex;
const noMatch2 = {
match: false,
pathIndex: 0,
commandIndex: 0
};
while (currentPathIndex < segmentGroup.segments.length) {
if (currentCommandIndex >= commands.length)
return noMatch2;
const path = segmentGroup.segments[currentPathIndex];
const command = commands[currentCommandIndex];
if (isCommandWithOutlets(command)) {
break;
}
const curr = `${command}`;
const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
if (currentPathIndex > 0 && curr === void 0)
break;
if (curr && next && typeof next === "object" && next.outlets === void 0) {
if (!compare(curr, next, path))
return noMatch2;
currentCommandIndex += 2;
} else {
if (!compare(curr, {}, path))
return noMatch2;
currentCommandIndex++;
}
currentPathIndex++;
}
return {
match: true,
pathIndex: currentPathIndex,
commandIndex: currentCommandIndex
};
}
function createNewSegmentGroup(segmentGroup, startIndex, commands) {
const paths = segmentGroup.segments.slice(0, startIndex);
let i = 0;
while (i < commands.length) {
const command = commands[i];
if (isCommandWithOutlets(command)) {
const children = createNewSegmentChildren(command.outlets);
return new UrlSegmentGroup(paths, children);
}
if (i === 0 && isMatrixParams(commands[0])) {
const p = segmentGroup.segments[startIndex];
paths.push(new UrlSegment(p.path, stringify(commands[0])));
i++;
continue;
}
const curr = isCommandWithOutlets(command) ? command.outlets[PRIMARY_OUTLET] : `${command}`;
const next = i < commands.length - 1 ? commands[i + 1] : null;
if (curr && next && isMatrixParams(next)) {
paths.push(new UrlSegment(curr, stringify(next)));
i += 2;
} else {
paths.push(new UrlSegment(curr, {}));
i++;
}
}
return new UrlSegmentGroup(paths, {});
}
function createNewSegmentChildren(outlets) {
const children = {};
Object.entries(outlets).forEach(([outlet, commands]) => {
if (typeof commands === "string") {
commands = [commands];
}
if (commands !== null) {
children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
}
});
return children;
}
function stringify(params) {
const res = {};
Object.entries(params).forEach(([k, v]) => res[k] = `${v}`);
return res;
}
function compare(path, params, segment) {
return path == segment.path && shallowEqual(params, segment.parameters);
}
var IMPERATIVE_NAVIGATION = "imperative";
var RouterEvent = class {
constructor(id, url) {
this.id = id;
this.url = url;
}
};
var NavigationStart = class extends RouterEvent {
constructor(id, url, navigationTrigger = "imperative", restoredState = null) {
super(id, url);
this.type = 0;
this.navigationTrigger = navigationTrigger;
this.restoredState = restoredState;
}
/** @docsNotRequired */
toString() {
return `NavigationStart(id: ${this.id}, url: '${this.url}')`;
}
};
var NavigationEnd = class extends RouterEvent {
constructor(id, url, urlAfterRedirects) {
super(id, url);
this.urlAfterRedirects = urlAfterRedirects;
this.type = 1;
}
/** @docsNotRequired */
toString() {
return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
}
};
var NavigationCancel = class extends RouterEvent {
constructor(id, url, reason, code) {
super(id, url);
this.reason = reason;
this.code = code;
this.type = 2;
}
/** @docsNotRequired */
toString() {
return `NavigationCancel(id: ${this.id}, url: '${this.url}')`;
}
};
var NavigationSkipped = class extends RouterEvent {
constructor(id, url, reason, code) {
super(id, url);
this.reason = reason;
this.code = code;
this.type = 16;
}
};
var NavigationError = class extends RouterEvent {
constructor(id, url, error, target) {
super(id, url);
this.error = error;
this.target = target;
this.type = 3;
}
/** @docsNotRequired */
toString() {
return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
}
};
var RoutesRecognized = class extends RouterEvent {
constructor(id, url, urlAfterRedirects, state) {
super(id, url);
this.urlAfterRedirects = urlAfterRedirects;
this.state = state;
this.type = 4;
}
/** @docsNotRequired */
toString() {
return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
}
};
var GuardsCheckStart = class extends RouterEvent {
constructor(id, url, urlAfterRedirects, state) {
super(id, url);
this.urlAfterRedirects = urlAfterRedirects;
this.state = state;
this.type = 7;
}
toString() {
return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
}
};
var GuardsCheckEnd = class extends RouterEvent {
constructor(id, url, urlAfterRedirects, state, shouldActivate) {
super(id, url);
this.urlAfterRedirects = urlAfterRedirects;
this.state = state;
this.shouldActivate = shouldActivate;
this.type = 8;
}
toString() {
return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
}
};
var ResolveStart = class extends RouterEvent {
constructor(id, url, urlAfterRedirects, state) {
super(id, url);
this.urlAfterRedirects = urlAfterRedirects;
this.state = state;
this.type = 5;
}
toString() {
return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
}
};
var ResolveEnd = class extends RouterEvent {
constructor(id, url, urlAfterRedirects, state) {
super(id, url);
this.urlAfterRedirects = urlAfterRedirects;
this.state = state;
this.type = 6;
}
toString() {
return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
}
};
var RouteConfigLoadStart = class {
constructor(route) {
this.route = route;
this.type = 9;
}
toString() {
return `RouteConfigLoadStart(path: ${this.route.path})`;
}
};
var RouteConfigLoadEnd = class {
constructor(route) {
this.route = route;
this.type = 10;
}
toString() {
return `RouteConfigLoadEnd(path: ${this.route.path})`;
}
};
var ChildActivationStart = class {
constructor(snapshot) {
this.snapshot = snapshot;
this.type = 11;
}
toString() {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || "";
return `ChildActivationStart(path: '${path}')`;
}
};
var ChildActivationEnd = class {
constructor(snapshot) {
this.snapshot = snapshot;
this.type = 12;
}
toString() {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || "";
return `ChildActivationEnd(path: '${path}')`;
}
};
var ActivationStart = class {
constructor(snapshot) {
this.snapshot = snapshot;
this.type = 13;
}
toString() {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || "";
return `ActivationStart(path: '${path}')`;
}
};
var ActivationEnd = class {
constructor(snapshot) {
this.snapshot = snapshot;
this.type = 14;
}
toString() {
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || "";
return `ActivationEnd(path: '${path}')`;
}
};
var Scroll = class {
constructor(routerEvent, position, anchor) {
this.routerEvent = routerEvent;
this.position = position;
this.anchor = anchor;
this.type = 15;
}
toString() {
const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
}
};
var BeforeActivateRoutes = class {
};
var RedirectRequest = class {
constructor(url) {
this.url = url;
}
};
function stringifyEvent(routerEvent) {
switch (routerEvent.type) {
case 14:
return `ActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ""}')`;
case 13:
return `ActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ""}')`;
case 12:
return `ChildActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ""}')`;
case 11:
return `ChildActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ""}')`;
case 8:
return `GuardsCheckEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state}, shouldActivate: ${routerEvent.shouldActivate})`;
case 7:
return `GuardsCheckStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
case 2:
return `NavigationCancel(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
case 16:
return `NavigationSkipped(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
case 1:
return `NavigationEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}')`;
case 3:
return `NavigationError(id: ${routerEvent.id}, url: '${routerEvent.url}', error: ${routerEvent.error})`;
case 0:
return `NavigationStart(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
case 6:
return `ResolveEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
case 5:
return `ResolveStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
case 10:
return `RouteConfigLoadEnd(path: ${routerEvent.route.path})`;
case 9:
return `RouteConfigLoadStart(path: ${routerEvent.route.path})`;
case 4:
return `RoutesRecognized(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
case 15:
const pos = routerEvent.position ? `${routerEvent.position[0]}, ${routerEvent.position[1]}` : null;
return `Scroll(anchor: '${routerEvent.anchor}', position: '${pos}')`;
}
}
var OutletContext = class {
constructor() {
this.outlet = null;
this.route = null;
this.injector = null;
this.children = new ChildrenOutletContexts();
this.attachRef = null;
}
};
var _ChildrenOutletContexts = class _ChildrenOutletContexts {
constructor() {
this.contexts = /* @__PURE__ */ new Map();
}
/** Called when a `RouterOutlet` directive is instantiated */
onChildOutletCreated(childName, outlet) {
const context = this.getOrCreateContext(childName);
context.outlet = outlet;
this.contexts.set(childName, context);
}
/**
* Called when a `RouterOutlet` directive is destroyed.
* We need to keep the context as the outlet could be destroyed inside a NgIf and might be
* re-created later.
*/
onChildOutletDestroyed(childName) {
const context = this.getContext(childName);
if (context) {
context.outlet = null;
context.attachRef = null;
}
}
/**
* Called when the corresponding route is deactivated during navigation.
* Because the component get destroyed, all children outlet are destroyed.
*/
onOutletDeactivated() {
const contexts = this.contexts;
this.contexts = /* @__PURE__ */ new Map();
return contexts;
}
onOutletReAttached(contexts) {
this.contexts = contexts;
}
getOrCreateContext(childName) {
let context = this.getContext(childName);
if (!context) {
context = new OutletContext();
this.contexts.set(childName, context);
}
return context;
}
getContext(childName) {
return this.contexts.get(childName) || null;
}
};
_ChildrenOutletContexts.ɵfac = function ChildrenOutletContexts_Factory(t) {
return new (t || _ChildrenOutletContexts)();
};
_ChildrenOutletContexts.ɵprov = ɵɵdefineInjectable({
token: _ChildrenOutletContexts,
factory: _ChildrenOutletContexts.ɵfac,
providedIn: "root"
});
var ChildrenOutletContexts = _ChildrenOutletContexts;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ChildrenOutletContexts, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], null, null);
})();
var Tree = class {
constructor(root) {
this._root = root;
}
get root() {
return this._root.value;
}
/**
* @internal
*/
parent(t) {
const p = this.pathFromRoot(t);
return p.length > 1 ? p[p.length - 2] : null;
}
/**
* @internal
*/
children(t) {
const n = findNode(t, this._root);
return n ? n.children.map((t2) => t2.value) : [];
}
/**
* @internal
*/
firstChild(t) {
const n = findNode(t, this._root);
return n && n.children.length > 0 ? n.children[0].value : null;
}
/**
* @internal
*/
siblings(t) {
const p = findPath(t, this._root);
if (p.length < 2)
return [];
const c = p[p.length - 2].children.map((c2) => c2.value);
return c.filter((cc) => cc !== t);
}
/**
* @internal
*/
pathFromRoot(t) {
return findPath(t, this._root).map((s) => s.value);
}
};
function findNode(value, node) {
if (value === node.value)
return node;
for (const child of node.children) {
const node2 = findNode(value, child);
if (node2)
return node2;
}
return null;
}
function findPath(value, node) {
if (value === node.value)
return [node];
for (const child of node.children) {
const path = findPath(value, child);
if (path.length) {
path.unshift(node);
return path;
}
}
return [];
}
var TreeNode = class {
constructor(value, children) {
this.value = value;
this.children = children;
}
toString() {
return `TreeNode(${this.value})`;
}
};
function nodeChildrenAsMap(node) {
const map2 = {};
if (node) {
node.children.forEach((child) => map2[child.value.outlet] = child);
}
return map2;
}
var RouterState = class extends Tree {
/** @internal */
constructor(root, snapshot) {
super(root);
this.snapshot = snapshot;
setRouterState(this, root);
}
toString() {
return this.snapshot.toString();
}
};
function createEmptyState(urlTree, rootComponent) {
const snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
const emptyUrl = new BehaviorSubject([new UrlSegment("", {})]);
const emptyParams = new BehaviorSubject({});
const emptyData = new BehaviorSubject({});
const emptyQueryParams = new BehaviorSubject({});
const fragment = new BehaviorSubject("");
const activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
activated.snapshot = snapshot.root;
return new RouterState(new TreeNode(activated, []), snapshot);
}
function createEmptyStateSnapshot(urlTree, rootComponent) {
const emptyParams = {};
const emptyData = {};
const emptyQueryParams = {};
const fragment = "";
const activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, {});
return new RouterStateSnapshot("", new TreeNode(activated, []));
}
var ActivatedRoute = class {
/** @internal */
constructor(urlSubject, paramsSubject, queryParamsSubject, fragmentSubject, dataSubject, outlet, component, futureSnapshot) {
this.urlSubject = urlSubject;
this.paramsSubject = paramsSubject;
this.queryParamsSubject = queryParamsSubject;
this.fragmentSubject = fragmentSubject;
this.dataSubject = dataSubject;
this.outlet = outlet;
this.component = component;
this._futureSnapshot = futureSnapshot;
this.title = this.dataSubject?.pipe(map((d) => d[RouteTitleKey])) ?? of(void 0);
this.url = urlSubject;
this.params = paramsSubject;
this.queryParams = queryParamsSubject;
this.fragment = fragmentSubject;
this.data = dataSubject;
}
/** The configuration used to match this route. */
get routeConfig() {
return this._futureSnapshot.routeConfig;
}
/** The root of the router state. */
get root() {
return this._routerState.root;
}
/** The parent of this route in the router state tree. */
get parent() {
return this._routerState.parent(this);
}
/** The first child of this route in the router state tree. */
get firstChild() {
return this._routerState.firstChild(this);
}
/** The children of this route in the router state tree. */
get children() {
return this._routerState.children(this);
}
/** The path from the root of the router state tree to this route. */
get pathFromRoot() {
return this._routerState.pathFromRoot(this);
}
/**
* An Observable that contains a map of the required and optional parameters
* specific to the route.
* The map supports retrieving single and multiple values from the same parameter.
*/
get paramMap() {
if (!this._paramMap) {
this._paramMap = this.params.pipe(map((p) => convertToParamMap(p)));
}
return this._paramMap;
}
/**
* An Observable that contains a map of the query parameters available to all routes.
* The map supports retrieving single and multiple values from the query parameter.
*/
get queryParamMap() {
if (!this._queryParamMap) {
this._queryParamMap = this.queryParams.pipe(map((p) => convertToParamMap(p)));
}
return this._queryParamMap;
}
toString() {
return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`;
}
};
function getInherited(route, parent, paramsInheritanceStrategy = "emptyOnly") {
let inherited;
const {
routeConfig
} = route;
if (parent !== null && (paramsInheritanceStrategy === "always" || // inherit parent data if route is empty path
routeConfig?.path === "" || // inherit parent data if parent was componentless
!parent.component && !parent.routeConfig?.loadComponent)) {
inherited = {
params: __spreadValues(__spreadValues({}, parent.params), route.params),
data: __spreadValues(__spreadValues({}, parent.data), route.data),
resolve: __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, route.data), parent.data), routeConfig?.data), route._resolvedData)
};
} else {
inherited = {
params: route.params,
data: route.data,
resolve: __spreadValues(__spreadValues({}, route.data), route._resolvedData ?? {})
};
}
if (routeConfig && hasStaticTitle(routeConfig)) {
inherited.resolve[RouteTitleKey] = routeConfig.title;
}
return inherited;
}
var ActivatedRouteSnapshot = class {
/** The resolved route title */
get title() {
return this.data?.[RouteTitleKey];
}
/** @internal */
constructor(url, params, queryParams, fragment, data, outlet, component, routeConfig, resolve) {
this.url = url;
this.params = params;
this.queryParams = queryParams;
this.fragment = fragment;
this.data = data;
this.outlet = outlet;
this.component = component;
this.routeConfig = routeConfig;
this._resolve = resolve;
}
/** The root of the router state */
get root() {
return this._routerState.root;
}
/** The parent of this route in the router state tree */
get parent() {
return this._routerState.parent(this);
}
/** The first child of this route in the router state tree */
get firstChild() {
return this._routerState.firstChild(this);
}
/** The children of this route in the router state tree */
get children() {
return this._routerState.children(this);
}
/** The path from the root of the router state tree to this route */
get pathFromRoot() {
return this._routerState.pathFromRoot(this);
}
get paramMap() {
if (!this._paramMap) {
this._paramMap = convertToParamMap(this.params);
}
return this._paramMap;
}
get queryParamMap() {
if (!this._queryParamMap) {
this._queryParamMap = convertToParamMap(this.queryParams);
}
return this._queryParamMap;
}
toString() {
const url = this.url.map((segment) => segment.toString()).join("/");
const matched = this.routeConfig ? this.routeConfig.path : "";
return `Route(url:'${url}', path:'${matched}')`;
}
};
var RouterStateSnapshot = class extends Tree {
/** @internal */
constructor(url, root) {
super(root);
this.url = url;
setRouterState(this, root);
}
toString() {
return serializeNode(this._root);
}
};
function setRouterState(state, node) {
node.value._routerState = state;
node.children.forEach((c) => setRouterState(state, c));
}
function serializeNode(node) {
const c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(", ")} } ` : "";
return `${node.value}${c}`;
}
function advanceActivatedRoute(route) {
if (route.snapshot) {
const currentSnapshot = route.snapshot;
const nextSnapshot = route._futureSnapshot;
route.snapshot = nextSnapshot;
if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
route.queryParamsSubject.next(nextSnapshot.queryParams);
}
if (currentSnapshot.fragment !== nextSnapshot.fragment) {
route.fragmentSubject.next(nextSnapshot.fragment);
}
if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
route.paramsSubject.next(nextSnapshot.params);
}
if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
route.urlSubject.next(nextSnapshot.url);
}
if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
route.dataSubject.next(nextSnapshot.data);
}
} else {
route.snapshot = route._futureSnapshot;
route.dataSubject.next(route._futureSnapshot.data);
}
}
function equalParamsAndUrlSegments(a, b) {
const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
const parentsMismatch = !a.parent !== !b.parent;
return equalUrlParams && !parentsMismatch && (!a.parent || equalParamsAndUrlSegments(a.parent, b.parent));
}
function hasStaticTitle(config) {
return typeof config.title === "string" || config.title === null;
}
var _RouterOutlet = class _RouterOutlet {
constructor() {
this.activated = null;
this._activatedRoute = null;
this.name = PRIMARY_OUTLET;
this.activateEvents = new EventEmitter();
this.deactivateEvents = new EventEmitter();
this.attachEvents = new EventEmitter();
this.detachEvents = new EventEmitter();
this.parentContexts = inject(ChildrenOutletContexts);
this.location = inject(ViewContainerRef);
this.changeDetector = inject(ChangeDetectorRef);
this.environmentInjector = inject(EnvironmentInjector);
this.inputBinder = inject(INPUT_BINDER, {
optional: true
});
this.supportsBindingToComponentInputs = true;
}
/** @internal */
get activatedComponentRef() {
return this.activated;
}
/** @nodoc */
ngOnChanges(changes) {
if (changes["name"]) {
const {
firstChange,
previousValue
} = changes["name"];
if (firstChange) {
return;
}
if (this.isTrackedInParentContexts(previousValue)) {
this.deactivate();
this.parentContexts.onChildOutletDestroyed(previousValue);
}
this.initializeOutletWithName();
}
}
/** @nodoc */
ngOnDestroy() {
if (this.isTrackedInParentContexts(this.name)) {
this.parentContexts.onChildOutletDestroyed(this.name);
}
this.inputBinder?.unsubscribeFromRouteData(this);
}
isTrackedInParentContexts(outletName) {
return this.parentContexts.getContext(outletName)?.outlet === this;
}
/** @nodoc */
ngOnInit() {
this.initializeOutletWithName();
}
initializeOutletWithName() {
this.parentContexts.onChildOutletCreated(this.name, this);
if (this.activated) {
return;
}
const context = this.parentContexts.getContext(this.name);
if (context?.route) {
if (context.attachRef) {
this.attach(context.attachRef, context.route);
} else {
this.activateWith(context.route, context.injector);
}
}
}
get isActivated() {
return !!this.activated;
}
/**
* @returns The currently activated component instance.
* @throws An error if the outlet is not activated.
*/
get component() {
if (!this.activated)
throw new RuntimeError(4012, (typeof ngDevMode === "undefined" || ngDevMode) && "Outlet is not activated");
return this.activated.instance;
}
get activatedRoute() {
if (!this.activated)
throw new RuntimeError(4012, (typeof ngDevMode === "undefined" || ngDevMode) && "Outlet is not activated");
return this._activatedRoute;
}
get activatedRouteData() {
if (this._activatedRoute) {
return this._activatedRoute.snapshot.data;
}
return {};
}
/**
* Called when the `RouteReuseStrategy` instructs to detach the subtree
*/
detach() {
if (!this.activated)
throw new RuntimeError(4012, (typeof ngDevMode === "undefined" || ngDevMode) && "Outlet is not activated");
this.location.detach();
const cmp = this.activated;
this.activated = null;
this._activatedRoute = null;
this.detachEvents.emit(cmp.instance);
return cmp;
}
/**
* Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
*/
attach(ref, activatedRoute) {
this.activated = ref;
this._activatedRoute = activatedRoute;
this.location.insert(ref.hostView);
this.inputBinder?.bindActivatedRouteToOutletComponent(this);
this.attachEvents.emit(ref.instance);
}
deactivate() {
if (this.activated) {
const c = this.component;
this.activated.destroy();
this.activated = null;
this._activatedRoute = null;
this.deactivateEvents.emit(c);
}
}
activateWith(activatedRoute, environmentInjector) {
if (this.isActivated) {
throw new RuntimeError(4013, (typeof ngDevMode === "undefined" || ngDevMode) && "Cannot activate an already activated outlet");
}
this._activatedRoute = activatedRoute;
const location = this.location;
const snapshot = activatedRoute.snapshot;
const component = snapshot.component;
const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
const injector = new OutletInjector(activatedRoute, childContexts, location.injector);
this.activated = location.createComponent(component, {
index: location.length,
injector,
environmentInjector: environmentInjector ?? this.environmentInjector
});
this.changeDetector.markForCheck();
this.inputBinder?.bindActivatedRouteToOutletComponent(this);
this.activateEvents.emit(this.activated.instance);
}
};
_RouterOutlet.ɵfac = function RouterOutlet_Factory(t) {
return new (t || _RouterOutlet)();
};
_RouterOutlet.ɵdir = ɵɵdefineDirective({
type: _RouterOutlet,
selectors: [["router-outlet"]],
inputs: {
name: "name"
},
outputs: {
activateEvents: "activate",
deactivateEvents: "deactivate",
attachEvents: "attach",
detachEvents: "detach"
},
exportAs: ["outlet"],
standalone: true,
features: [ɵɵNgOnChangesFeature]
});
var RouterOutlet = _RouterOutlet;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouterOutlet, [{
type: Directive,
args: [{
selector: "router-outlet",
exportAs: "outlet",
standalone: true
}]
}], null, {
name: [{
type: Input
}],
activateEvents: [{
type: Output,
args: ["activate"]
}],
deactivateEvents: [{
type: Output,
args: ["deactivate"]
}],
attachEvents: [{
type: Output,
args: ["attach"]
}],
detachEvents: [{
type: Output,
args: ["detach"]
}]
});
})();
var OutletInjector = class {
constructor(route, childContexts, parent) {
this.route = route;
this.childContexts = childContexts;
this.parent = parent;
}
get(token, notFoundValue) {
if (token === ActivatedRoute) {
return this.route;
}
if (token === ChildrenOutletContexts) {
return this.childContexts;
}
return this.parent.get(token, notFoundValue);
}
};
var INPUT_BINDER = new InjectionToken("");
var _RoutedComponentInputBinder = class _RoutedComponentInputBinder {
constructor() {
this.outletDataSubscriptions = /* @__PURE__ */ new Map();
}
bindActivatedRouteToOutletComponent(outlet) {
this.unsubscribeFromRouteData(outlet);
this.subscribeToRouteData(outlet);
}
unsubscribeFromRouteData(outlet) {
this.outletDataSubscriptions.get(outlet)?.unsubscribe();
this.outletDataSubscriptions.delete(outlet);
}
subscribeToRouteData(outlet) {
const {
activatedRoute
} = outlet;
const dataSubscription = combineLatest([activatedRoute.queryParams, activatedRoute.params, activatedRoute.data]).pipe(switchMap(([queryParams, params, data], index) => {
data = __spreadValues(__spreadValues(__spreadValues({}, queryParams), params), data);
if (index === 0) {
return of(data);
}
return Promise.resolve(data);
})).subscribe((data) => {
if (!outlet.isActivated || !outlet.activatedComponentRef || outlet.activatedRoute !== activatedRoute || activatedRoute.component === null) {
this.unsubscribeFromRouteData(outlet);
return;
}
const mirror = reflectComponentType(activatedRoute.component);
if (!mirror) {
this.unsubscribeFromRouteData(outlet);
return;
}
for (const {
templateName
} of mirror.inputs) {
outlet.activatedComponentRef.setInput(templateName, data[templateName]);
}
});
this.outletDataSubscriptions.set(outlet, dataSubscription);
}
};
_RoutedComponentInputBinder.ɵfac = function RoutedComponentInputBinder_Factory(t) {
return new (t || _RoutedComponentInputBinder)();
};
_RoutedComponentInputBinder.ɵprov = ɵɵdefineInjectable({
token: _RoutedComponentInputBinder,
factory: _RoutedComponentInputBinder.ɵfac
});
var RoutedComponentInputBinder = _RoutedComponentInputBinder;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RoutedComponentInputBinder, [{
type: Injectable
}], null, null);
})();
function createRouterState(routeReuseStrategy, curr, prevState) {
const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : void 0);
return new RouterState(root, curr);
}
function createNode(routeReuseStrategy, curr, prevState) {
if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
const value = prevState.value;
value._futureSnapshot = curr.value;
const children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
return new TreeNode(value, children);
} else {
if (routeReuseStrategy.shouldAttach(curr.value)) {
const detachedRouteHandle = routeReuseStrategy.retrieve(curr.value);
if (detachedRouteHandle !== null) {
const tree2 = detachedRouteHandle.route;
tree2.value._futureSnapshot = curr.value;
tree2.children = curr.children.map((c) => createNode(routeReuseStrategy, c));
return tree2;
}
}
const value = createActivatedRoute(curr.value);
const children = curr.children.map((c) => createNode(routeReuseStrategy, c));
return new TreeNode(value, children);
}
}
function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
return curr.children.map((child) => {
for (const p of prevState.children) {
if (routeReuseStrategy.shouldReuseRoute(child.value, p.value.snapshot)) {
return createNode(routeReuseStrategy, child, p);
}
}
return createNode(routeReuseStrategy, child);
});
}
function createActivatedRoute(c) {
return new ActivatedRoute(new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams), new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
}
var NAVIGATION_CANCELING_ERROR = "ngNavigationCancelingError";
function redirectingNavigationError(urlSerializer, redirect) {
const {
redirectTo,
navigationBehaviorOptions
} = isUrlTree(redirect) ? {
redirectTo: redirect,
navigationBehaviorOptions: void 0
} : redirect;
const error = navigationCancelingError(ngDevMode && `Redirecting to "${urlSerializer.serialize(redirectTo)}"`, 0, redirect);
error.url = redirectTo;
error.navigationBehaviorOptions = navigationBehaviorOptions;
return error;
}
function navigationCancelingError(message, code, redirectUrl) {
const error = new Error("NavigationCancelingError: " + (message || ""));
error[NAVIGATION_CANCELING_ERROR] = true;
error.cancellationCode = code;
if (redirectUrl) {
error.url = redirectUrl;
}
return error;
}
function isRedirectingNavigationCancelingError$1(error) {
return isNavigationCancelingError$1(error) && isUrlTree(error.url);
}
function isNavigationCancelingError$1(error) {
return error && error[NAVIGATION_CANCELING_ERROR];
}
var _ɵEmptyOutletComponent = class _ɵEmptyOutletComponent {
};
_ɵEmptyOutletComponent.ɵfac = function ɵEmptyOutletComponent_Factory(t) {
return new (t || _ɵEmptyOutletComponent)();
};
_ɵEmptyOutletComponent.ɵcmp = ɵɵdefineComponent({
type: _ɵEmptyOutletComponent,
selectors: [["ng-component"]],
standalone: true,
features: [ɵɵStandaloneFeature],
decls: 1,
vars: 0,
template: function ɵEmptyOutletComponent_Template(rf, ctx) {
if (rf & 1) {
ɵɵelement(0, "router-outlet");
}
},
dependencies: [RouterOutlet],
encapsulation: 2
});
var ɵEmptyOutletComponent = _ɵEmptyOutletComponent;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ɵEmptyOutletComponent, [{
type: Component,
args: [{
template: `<router-outlet></router-outlet>`,
imports: [RouterOutlet],
standalone: true
}]
}], null, null);
})();
function getOrCreateRouteInjectorIfNeeded(route, currentInjector) {
if (route.providers && !route._injector) {
route._injector = createEnvironmentInjector(route.providers, currentInjector, `Route: ${route.path}`);
}
return route._injector ?? currentInjector;
}
function validateConfig(config, parentPath = "", requireStandaloneComponents = false) {
for (let i = 0; i < config.length; i++) {
const route = config[i];
const fullPath = getFullPath(parentPath, route);
validateNode(route, fullPath, requireStandaloneComponents);
}
}
function assertStandalone(fullPath, component) {
if (component && isNgModule(component)) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}'. You are using 'loadComponent' with a module, but it must be used with standalone components. Use 'loadChildren' instead.`);
} else if (component && !isStandalone(component)) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}'. The component must be standalone.`);
}
}
function validateNode(route, fullPath, requireStandaloneComponents) {
if (typeof ngDevMode === "undefined" || ngDevMode) {
if (!route) {
throw new RuntimeError(4014, `
Invalid configuration of route '${fullPath}': Encountered undefined route.
The reason might be an extra comma.
Example:
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },, << two commas
{ path: 'detail/:id', component: HeroDetailComponent }
];
`);
}
if (Array.isArray(route)) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': Array cannot be specified`);
}
if (!route.redirectTo && !route.component && !route.loadComponent && !route.children && !route.loadChildren && route.outlet && route.outlet !== PRIMARY_OUTLET) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
}
if (route.redirectTo && route.children) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
}
if (route.redirectTo && route.loadChildren) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
}
if (route.children && route.loadChildren) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
}
if (route.redirectTo && (route.component || route.loadComponent)) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`);
}
if (route.component && route.loadComponent) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`);
}
if (route.redirectTo && route.canActivate) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation so canActivate will never be executed.`);
}
if (route.path && route.matcher) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
}
if (route.redirectTo === void 0 && !route.component && !route.loadComponent && !route.children && !route.loadChildren) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`);
}
if (route.path === void 0 && route.matcher === void 0) {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
}
if (typeof route.path === "string" && route.path.charAt(0) === "/") {
throw new RuntimeError(4014, `Invalid configuration of route '${fullPath}': path cannot start with a slash`);
}
if (route.path === "" && route.redirectTo !== void 0 && route.pathMatch === void 0) {
const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
throw new RuntimeError(4014, `Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
}
if (requireStandaloneComponents) {
assertStandalone(fullPath, route.component);
}
}
if (route.children) {
validateConfig(route.children, fullPath, requireStandaloneComponents);
}
}
function getFullPath(parentPath, currentRoute) {
if (!currentRoute) {
return parentPath;
}
if (!parentPath && !currentRoute.path) {
return "";
} else if (parentPath && !currentRoute.path) {
return `${parentPath}/`;
} else if (!parentPath && currentRoute.path) {
return currentRoute.path;
} else {
return `${parentPath}/${currentRoute.path}`;
}
}
function standardizeConfig(r) {
const children = r.children && r.children.map(standardizeConfig);
const c = children ? __spreadProps(__spreadValues({}, r), {
children
}) : __spreadValues({}, r);
if (!c.component && !c.loadComponent && (children || c.loadChildren) && c.outlet && c.outlet !== PRIMARY_OUTLET) {
c.component = ɵEmptyOutletComponent;
}
return c;
}
function getOutlet(route) {
return route.outlet || PRIMARY_OUTLET;
}
function sortByMatchingOutlets(routes, outletName) {
const sortedConfig = routes.filter((r) => getOutlet(r) === outletName);
sortedConfig.push(...routes.filter((r) => getOutlet(r) !== outletName));
return sortedConfig;
}
function getClosestRouteInjector(snapshot) {
if (!snapshot)
return null;
if (snapshot.routeConfig?._injector) {
return snapshot.routeConfig._injector;
}
for (let s = snapshot.parent; s; s = s.parent) {
const route = s.routeConfig;
if (route?._loadedInjector)
return route._loadedInjector;
if (route?._injector)
return route._injector;
}
return null;
}
var warnedAboutUnsupportedInputBinding = false;
var activateRoutes = (rootContexts, routeReuseStrategy, forwardEvent, inputBindingEnabled) => map((t) => {
new ActivateRoutes(routeReuseStrategy, t.targetRouterState, t.currentRouterState, forwardEvent, inputBindingEnabled).activate(rootContexts);
return t;
});
var ActivateRoutes = class {
constructor(routeReuseStrategy, futureState, currState, forwardEvent, inputBindingEnabled) {
this.routeReuseStrategy = routeReuseStrategy;
this.futureState = futureState;
this.currState = currState;
this.forwardEvent = forwardEvent;
this.inputBindingEnabled = inputBindingEnabled;
}
activate(parentContexts) {
const futureRoot = this.futureState._root;
const currRoot = this.currState ? this.currState._root : null;
this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
advanceActivatedRoute(this.futureState.root);
this.activateChildRoutes(futureRoot, currRoot, parentContexts);
}
// De-activate the child route that are not re-used for the future state
deactivateChildRoutes(futureNode, currNode, contexts) {
const children = nodeChildrenAsMap(currNode);
futureNode.children.forEach((futureChild) => {
const childOutletName = futureChild.value.outlet;
this.deactivateRoutes(futureChild, children[childOutletName], contexts);
delete children[childOutletName];
});
Object.values(children).forEach((v) => {
this.deactivateRouteAndItsChildren(v, contexts);
});
}
deactivateRoutes(futureNode, currNode, parentContext) {
const future = futureNode.value;
const curr = currNode ? currNode.value : null;
if (future === curr) {
if (future.component) {
const context = parentContext.getContext(future.outlet);
if (context) {
this.deactivateChildRoutes(futureNode, currNode, context.children);
}
} else {
this.deactivateChildRoutes(futureNode, currNode, parentContext);
}
} else {
if (curr) {
this.deactivateRouteAndItsChildren(currNode, parentContext);
}
}
}
deactivateRouteAndItsChildren(route, parentContexts) {
if (route.value.component && this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
this.detachAndStoreRouteSubtree(route, parentContexts);
} else {
this.deactivateRouteAndOutlet(route, parentContexts);
}
}
detachAndStoreRouteSubtree(route, parentContexts) {
const context = parentContexts.getContext(route.value.outlet);
const contexts = context && route.value.component ? context.children : parentContexts;
const children = nodeChildrenAsMap(route);
for (const childOutlet of Object.keys(children)) {
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
}
if (context && context.outlet) {
const componentRef = context.outlet.detach();
const contexts2 = context.children.onOutletDeactivated();
this.routeReuseStrategy.store(route.value.snapshot, {
componentRef,
route,
contexts: contexts2
});
}
}
deactivateRouteAndOutlet(route, parentContexts) {
const context = parentContexts.getContext(route.value.outlet);
const contexts = context && route.value.component ? context.children : parentContexts;
const children = nodeChildrenAsMap(route);
for (const childOutlet of Object.keys(children)) {
this.deactivateRouteAndItsChildren(children[childOutlet], contexts);
}
if (context) {
if (context.outlet) {
context.outlet.deactivate();
context.children.onOutletDeactivated();
}
context.attachRef = null;
context.route = null;
}
}
activateChildRoutes(futureNode, currNode, contexts) {
const children = nodeChildrenAsMap(currNode);
futureNode.children.forEach((c) => {
this.activateRoutes(c, children[c.value.outlet], contexts);
this.forwardEvent(new ActivationEnd(c.value.snapshot));
});
if (futureNode.children.length) {
this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
}
}
activateRoutes(futureNode, currNode, parentContexts) {
const future = futureNode.value;
const curr = currNode ? currNode.value : null;
advanceActivatedRoute(future);
if (future === curr) {
if (future.component) {
const context = parentContexts.getOrCreateContext(future.outlet);
this.activateChildRoutes(futureNode, currNode, context.children);
} else {
this.activateChildRoutes(futureNode, currNode, parentContexts);
}
} else {
if (future.component) {
const context = parentContexts.getOrCreateContext(future.outlet);
if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
const stored = this.routeReuseStrategy.retrieve(future.snapshot);
this.routeReuseStrategy.store(future.snapshot, null);
context.children.onOutletReAttached(stored.contexts);
context.attachRef = stored.componentRef;
context.route = stored.route.value;
if (context.outlet) {
context.outlet.attach(stored.componentRef, stored.route.value);
}
advanceActivatedRoute(stored.route.value);
this.activateChildRoutes(futureNode, null, context.children);
} else {
const injector = getClosestRouteInjector(future.snapshot);
context.attachRef = null;
context.route = future;
context.injector = injector;
if (context.outlet) {
context.outlet.activateWith(future, context.injector);
}
this.activateChildRoutes(futureNode, null, context.children);
}
} else {
this.activateChildRoutes(futureNode, null, parentContexts);
}
}
if (typeof ngDevMode === "undefined" || ngDevMode) {
const context = parentContexts.getOrCreateContext(future.outlet);
const outlet = context.outlet;
if (outlet && this.inputBindingEnabled && !outlet.supportsBindingToComponentInputs && !warnedAboutUnsupportedInputBinding) {
console.warn(`'withComponentInputBinding' feature is enabled but this application is using an outlet that may not support binding to component inputs.`);
warnedAboutUnsupportedInputBinding = true;
}
}
}
};
var CanActivate = class {
constructor(path) {
this.path = path;
this.route = this.path[this.path.length - 1];
}
};
var CanDeactivate = class {
constructor(component, route) {
this.component = component;
this.route = route;
}
};
function getAllRouteGuards(future, curr, parentContexts) {
const futureRoot = future._root;
const currRoot = curr ? curr._root : null;
return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
}
function getCanActivateChild(p) {
const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
if (!canActivateChild || canActivateChild.length === 0)
return null;
return {
node: p,
guards: canActivateChild
};
}
function getTokenOrFunctionIdentity(tokenOrFunction, injector) {
const NOT_FOUND = Symbol();
const result = injector.get(tokenOrFunction, NOT_FOUND);
if (result === NOT_FOUND) {
if (typeof tokenOrFunction === "function" && !isInjectable(tokenOrFunction)) {
return tokenOrFunction;
} else {
return injector.get(tokenOrFunction);
}
}
return result;
}
function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
canDeactivateChecks: [],
canActivateChecks: []
}) {
const prevChildren = nodeChildrenAsMap(currNode);
futureNode.children.forEach((c) => {
getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
delete prevChildren[c.value.outlet];
});
Object.entries(prevChildren).forEach(([k, v]) => deactivateRouteAndItsChildren(v, contexts.getContext(k), checks));
return checks;
}
function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
canDeactivateChecks: [],
canActivateChecks: []
}) {
const future = futureNode.value;
const curr = currNode ? currNode.value : null;
const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
if (curr && future.routeConfig === curr.routeConfig) {
const shouldRun = shouldRunGuardsAndResolvers(curr, future, future.routeConfig.runGuardsAndResolvers);
if (shouldRun) {
checks.canActivateChecks.push(new CanActivate(futurePath));
} else {
future.data = curr.data;
future._resolvedData = curr._resolvedData;
}
if (future.component) {
getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
} else {
getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
}
if (shouldRun && context && context.outlet && context.outlet.isActivated) {
checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr));
}
} else {
if (curr) {
deactivateRouteAndItsChildren(currNode, context, checks);
}
checks.canActivateChecks.push(new CanActivate(futurePath));
if (future.component) {
getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
} else {
getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
}
}
return checks;
}
function shouldRunGuardsAndResolvers(curr, future, mode) {
if (typeof mode === "function") {
return mode(curr, future);
}
switch (mode) {
case "pathParamsChange":
return !equalPath(curr.url, future.url);
case "pathParamsOrQueryParamsChange":
return !equalPath(curr.url, future.url) || !shallowEqual(curr.queryParams, future.queryParams);
case "always":
return true;
case "paramsOrQueryParamsChange":
return !equalParamsAndUrlSegments(curr, future) || !shallowEqual(curr.queryParams, future.queryParams);
case "paramsChange":
default:
return !equalParamsAndUrlSegments(curr, future);
}
}
function deactivateRouteAndItsChildren(route, context, checks) {
const children = nodeChildrenAsMap(route);
const r = route.value;
Object.entries(children).forEach(([childName, node]) => {
if (!r.component) {
deactivateRouteAndItsChildren(node, context, checks);
} else if (context) {
deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
} else {
deactivateRouteAndItsChildren(node, null, checks);
}
});
if (!r.component) {
checks.canDeactivateChecks.push(new CanDeactivate(null, r));
} else if (context && context.outlet && context.outlet.isActivated) {
checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
} else {
checks.canDeactivateChecks.push(new CanDeactivate(null, r));
}
}
function isFunction(v) {
return typeof v === "function";
}
function isBoolean(v) {
return typeof v === "boolean";
}
function isCanLoad(guard) {
return guard && isFunction(guard.canLoad);
}
function isCanActivate(guard) {
return guard && isFunction(guard.canActivate);
}
function isCanActivateChild(guard) {
return guard && isFunction(guard.canActivateChild);
}
function isCanDeactivate(guard) {
return guard && isFunction(guard.canDeactivate);
}
function isCanMatch(guard) {
return guard && isFunction(guard.canMatch);
}
function isEmptyError(e) {
return e instanceof EmptyError || e?.name === "EmptyError";
}
var INITIAL_VALUE = Symbol("INITIAL_VALUE");
function prioritizedGuardValue() {
return switchMap((obs) => {
return combineLatest(obs.map((o) => o.pipe(take(1), startWith(INITIAL_VALUE)))).pipe(map((results) => {
for (const result of results) {
if (result === true) {
continue;
} else if (result === INITIAL_VALUE) {
return INITIAL_VALUE;
} else if (result === false || result instanceof UrlTree) {
return result;
}
}
return true;
}), filter((item) => item !== INITIAL_VALUE), take(1));
});
}
function checkGuards(injector, forwardEvent) {
return mergeMap((t) => {
const {
targetSnapshot,
currentSnapshot,
guards: {
canActivateChecks,
canDeactivateChecks
}
} = t;
if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
return of(__spreadProps(__spreadValues({}, t), {
guardsResult: true
}));
}
return runCanDeactivateChecks(canDeactivateChecks, targetSnapshot, currentSnapshot, injector).pipe(mergeMap((canDeactivate) => {
return canDeactivate && isBoolean(canDeactivate) ? runCanActivateChecks(targetSnapshot, canActivateChecks, injector, forwardEvent) : of(canDeactivate);
}), map((guardsResult) => __spreadProps(__spreadValues({}, t), {
guardsResult
})));
});
}
function runCanDeactivateChecks(checks, futureRSS, currRSS, injector) {
return from(checks).pipe(mergeMap((check) => runCanDeactivate(check.component, check.route, currRSS, futureRSS, injector)), first((result) => {
return result !== true;
}, true));
}
function runCanActivateChecks(futureSnapshot, checks, injector, forwardEvent) {
return from(checks).pipe(concatMap((check) => {
return concat(fireChildActivationStart(check.route.parent, forwardEvent), fireActivationStart(check.route, forwardEvent), runCanActivateChild(futureSnapshot, check.path, injector), runCanActivate(futureSnapshot, check.route, injector));
}), first((result) => {
return result !== true;
}, true));
}
function fireActivationStart(snapshot, forwardEvent) {
if (snapshot !== null && forwardEvent) {
forwardEvent(new ActivationStart(snapshot));
}
return of(true);
}
function fireChildActivationStart(snapshot, forwardEvent) {
if (snapshot !== null && forwardEvent) {
forwardEvent(new ChildActivationStart(snapshot));
}
return of(true);
}
function runCanActivate(futureRSS, futureARS, injector) {
const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
if (!canActivate || canActivate.length === 0)
return of(true);
const canActivateObservables = canActivate.map((canActivate2) => {
return defer(() => {
const closestInjector = getClosestRouteInjector(futureARS) ?? injector;
const guard = getTokenOrFunctionIdentity(canActivate2, closestInjector);
const guardVal = isCanActivate(guard) ? guard.canActivate(futureARS, futureRSS) : runInInjectionContext(closestInjector, () => guard(futureARS, futureRSS));
return wrapIntoObservable(guardVal).pipe(first());
});
});
return of(canActivateObservables).pipe(prioritizedGuardValue());
}
function runCanActivateChild(futureRSS, path, injector) {
const futureARS = path[path.length - 1];
const canActivateChildGuards = path.slice(0, path.length - 1).reverse().map((p) => getCanActivateChild(p)).filter((_) => _ !== null);
const canActivateChildGuardsMapped = canActivateChildGuards.map((d) => {
return defer(() => {
const guardsMapped = d.guards.map((canActivateChild) => {
const closestInjector = getClosestRouteInjector(d.node) ?? injector;
const guard = getTokenOrFunctionIdentity(canActivateChild, closestInjector);
const guardVal = isCanActivateChild(guard) ? guard.canActivateChild(futureARS, futureRSS) : runInInjectionContext(closestInjector, () => guard(futureARS, futureRSS));
return wrapIntoObservable(guardVal).pipe(first());
});
return of(guardsMapped).pipe(prioritizedGuardValue());
});
});
return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
}
function runCanDeactivate(component, currARS, currRSS, futureRSS, injector) {
const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
if (!canDeactivate || canDeactivate.length === 0)
return of(true);
const canDeactivateObservables = canDeactivate.map((c) => {
const closestInjector = getClosestRouteInjector(currARS) ?? injector;
const guard = getTokenOrFunctionIdentity(c, closestInjector);
const guardVal = isCanDeactivate(guard) ? guard.canDeactivate(component, currARS, currRSS, futureRSS) : runInInjectionContext(closestInjector, () => guard(component, currARS, currRSS, futureRSS));
return wrapIntoObservable(guardVal).pipe(first());
});
return of(canDeactivateObservables).pipe(prioritizedGuardValue());
}
function runCanLoadGuards(injector, route, segments, urlSerializer) {
const canLoad = route.canLoad;
if (canLoad === void 0 || canLoad.length === 0) {
return of(true);
}
const canLoadObservables = canLoad.map((injectionToken) => {
const guard = getTokenOrFunctionIdentity(injectionToken, injector);
const guardVal = isCanLoad(guard) ? guard.canLoad(route, segments) : runInInjectionContext(injector, () => guard(route, segments));
return wrapIntoObservable(guardVal);
});
return of(canLoadObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
}
function redirectIfUrlTree(urlSerializer) {
return pipe(tap((result) => {
if (!isUrlTree(result))
return;
throw redirectingNavigationError(urlSerializer, result);
}), map((result) => result === true));
}
function runCanMatchGuards(injector, route, segments, urlSerializer) {
const canMatch = route.canMatch;
if (!canMatch || canMatch.length === 0)
return of(true);
const canMatchObservables = canMatch.map((injectionToken) => {
const guard = getTokenOrFunctionIdentity(injectionToken, injector);
const guardVal = isCanMatch(guard) ? guard.canMatch(route, segments) : runInInjectionContext(injector, () => guard(route, segments));
return wrapIntoObservable(guardVal);
});
return of(canMatchObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
}
var NoMatch = class {
constructor(segmentGroup) {
this.segmentGroup = segmentGroup || null;
}
};
var AbsoluteRedirect = class extends Error {
constructor(urlTree) {
super();
this.urlTree = urlTree;
}
};
function noMatch$1(segmentGroup) {
return throwError(new NoMatch(segmentGroup));
}
function namedOutletsRedirect(redirectTo) {
return throwError(new RuntimeError(4e3, (typeof ngDevMode === "undefined" || ngDevMode) && `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
}
function canLoadFails(route) {
return throwError(navigationCancelingError(
(typeof ngDevMode === "undefined" || ngDevMode) && `Cannot load children because the guard of the route "path: '${route.path}'" returned false`,
3
/* NavigationCancellationCode.GuardRejected */
));
}
var ApplyRedirects = class {
constructor(urlSerializer, urlTree) {
this.urlSerializer = urlSerializer;
this.urlTree = urlTree;
}
lineralizeSegments(route, urlTree) {
let res = [];
let c = urlTree.root;
while (true) {
res = res.concat(c.segments);
if (c.numberOfChildren === 0) {
return of(res);
}
if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
return namedOutletsRedirect(route.redirectTo);
}
c = c.children[PRIMARY_OUTLET];
}
}
applyRedirectCommands(segments, redirectTo, posParams) {
const newTree = this.applyRedirectCreateUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
if (redirectTo.startsWith("/")) {
throw new AbsoluteRedirect(newTree);
}
return newTree;
}
applyRedirectCreateUrlTree(redirectTo, urlTree, segments, posParams) {
const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
}
createQueryParams(redirectToParams, actualParams) {
const res = {};
Object.entries(redirectToParams).forEach(([k, v]) => {
const copySourceValue = typeof v === "string" && v.startsWith(":");
if (copySourceValue) {
const sourceName = v.substring(1);
res[k] = actualParams[sourceName];
} else {
res[k] = v;
}
});
return res;
}
createSegmentGroup(redirectTo, group, segments, posParams) {
const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
let children = {};
Object.entries(group.children).forEach(([name, child]) => {
children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
});
return new UrlSegmentGroup(updatedSegments, children);
}
createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
return redirectToSegments.map((s) => s.path.startsWith(":") ? this.findPosParam(redirectTo, s, posParams) : this.findOrReturn(s, actualSegments));
}
findPosParam(redirectTo, redirectToUrlSegment, posParams) {
const pos = posParams[redirectToUrlSegment.path.substring(1)];
if (!pos)
throw new RuntimeError(4001, (typeof ngDevMode === "undefined" || ngDevMode) && `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
return pos;
}
findOrReturn(redirectToUrlSegment, actualSegments) {
let idx = 0;
for (const s of actualSegments) {
if (s.path === redirectToUrlSegment.path) {
actualSegments.splice(idx);
return s;
}
idx++;
}
return redirectToUrlSegment;
}
};
var noMatch = {
matched: false,
consumedSegments: [],
remainingSegments: [],
parameters: {},
positionalParamSegments: {}
};
function matchWithChecks(segmentGroup, route, segments, injector, urlSerializer) {
const result = match(segmentGroup, route, segments);
if (!result.matched) {
return of(result);
}
injector = getOrCreateRouteInjectorIfNeeded(route, injector);
return runCanMatchGuards(injector, route, segments, urlSerializer).pipe(map((v) => v === true ? result : __spreadValues({}, noMatch)));
}
function match(segmentGroup, route, segments) {
if (route.path === "**") {
return createWildcardMatchResult(segments);
}
if (route.path === "") {
if (route.pathMatch === "full" && (segmentGroup.hasChildren() || segments.length > 0)) {
return __spreadValues({}, noMatch);
}
return {
matched: true,
consumedSegments: [],
remainingSegments: segments,
parameters: {},
positionalParamSegments: {}
};
}
const matcher = route.matcher || defaultUrlMatcher;
const res = matcher(segments, segmentGroup, route);
if (!res)
return __spreadValues({}, noMatch);
const posParams = {};
Object.entries(res.posParams ?? {}).forEach(([k, v]) => {
posParams[k] = v.path;
});
const parameters = res.consumed.length > 0 ? __spreadValues(__spreadValues({}, posParams), res.consumed[res.consumed.length - 1].parameters) : posParams;
return {
matched: true,
consumedSegments: res.consumed,
remainingSegments: segments.slice(res.consumed.length),
// TODO(atscott): investigate combining parameters and positionalParamSegments
parameters,
positionalParamSegments: res.posParams ?? {}
};
}
function createWildcardMatchResult(segments) {
return {
matched: true,
parameters: segments.length > 0 ? last2(segments).parameters : {},
consumedSegments: segments,
remainingSegments: [],
positionalParamSegments: {}
};
}
function split(segmentGroup, consumedSegments, slicedSegments, config) {
if (slicedSegments.length > 0 && containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
const s2 = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
return {
segmentGroup: s2,
slicedSegments: []
};
}
if (slicedSegments.length === 0 && containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
const s2 = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children));
return {
segmentGroup: s2,
slicedSegments
};
}
const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
return {
segmentGroup: s,
slicedSegments
};
}
function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children) {
const res = {};
for (const r of routes) {
if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
const s = new UrlSegmentGroup([], {});
res[getOutlet(r)] = s;
}
}
return __spreadValues(__spreadValues({}, children), res);
}
function createChildrenForEmptyPaths(routes, primarySegment) {
const res = {};
res[PRIMARY_OUTLET] = primarySegment;
for (const r of routes) {
if (r.path === "" && getOutlet(r) !== PRIMARY_OUTLET) {
const s = new UrlSegmentGroup([], {});
res[getOutlet(r)] = s;
}
}
return res;
}
function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
return routes.some((r) => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet(r) !== PRIMARY_OUTLET);
}
function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
return routes.some((r) => emptyPathMatch(segmentGroup, slicedSegments, r));
}
function emptyPathMatch(segmentGroup, slicedSegments, r) {
if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === "full") {
return false;
}
return r.path === "";
}
function isImmediateMatch(route, rawSegment, segments, outlet) {
if (getOutlet(route) !== outlet && (outlet === PRIMARY_OUTLET || !emptyPathMatch(rawSegment, segments, route))) {
return false;
}
return match(rawSegment, route, segments).matched;
}
function noLeftoversInUrl(segmentGroup, segments, outlet) {
return segments.length === 0 && !segmentGroup.children[outlet];
}
var NoLeftoversInUrl = class {
};
function recognize$1(injector, configLoader, rootComponentType, config, urlTree, urlSerializer, paramsInheritanceStrategy = "emptyOnly") {
return new Recognizer(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer).recognize();
}
var MAX_ALLOWED_REDIRECTS = 31;
var Recognizer = class {
constructor(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer) {
this.injector = injector;
this.configLoader = configLoader;
this.rootComponentType = rootComponentType;
this.config = config;
this.urlTree = urlTree;
this.paramsInheritanceStrategy = paramsInheritanceStrategy;
this.urlSerializer = urlSerializer;
this.applyRedirects = new ApplyRedirects(this.urlSerializer, this.urlTree);
this.absoluteRedirectCount = 0;
this.allowRedirects = true;
}
noMatchError(e) {
return new RuntimeError(4002, typeof ngDevMode === "undefined" || ngDevMode ? `Cannot match any routes. URL Segment: '${e.segmentGroup}'` : `'${e.segmentGroup}'`);
}
recognize() {
const rootSegmentGroup = split(this.urlTree.root, [], [], this.config).segmentGroup;
return this.match(rootSegmentGroup).pipe(map((children) => {
const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(__spreadValues({}, this.urlTree.queryParams)), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, {});
const rootNode = new TreeNode(root, children);
const routeState = new RouterStateSnapshot("", rootNode);
const tree2 = createUrlTreeFromSnapshot(root, [], this.urlTree.queryParams, this.urlTree.fragment);
tree2.queryParams = this.urlTree.queryParams;
routeState.url = this.urlSerializer.serialize(tree2);
this.inheritParamsAndData(routeState._root, null);
return {
state: routeState,
tree: tree2
};
}));
}
match(rootSegmentGroup) {
const expanded$ = this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET);
return expanded$.pipe(catchError((e) => {
if (e instanceof AbsoluteRedirect) {
this.urlTree = e.urlTree;
return this.match(e.urlTree.root);
}
if (e instanceof NoMatch) {
throw this.noMatchError(e);
}
throw e;
}));
}
inheritParamsAndData(routeNode, parent) {
const route = routeNode.value;
const i = getInherited(route, parent, this.paramsInheritanceStrategy);
route.params = Object.freeze(i.params);
route.data = Object.freeze(i.data);
routeNode.children.forEach((n) => this.inheritParamsAndData(n, route));
}
processSegmentGroup(injector, config, segmentGroup, outlet) {
if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
return this.processChildren(injector, config, segmentGroup);
}
return this.processSegment(injector, config, segmentGroup, segmentGroup.segments, outlet, true).pipe(map((child) => child instanceof TreeNode ? [child] : []));
}
/**
* Matches every child outlet in the `segmentGroup` to a `Route` in the config. Returns `null` if
* we cannot find a match for _any_ of the children.
*
* @param config - The `Routes` to match against
* @param segmentGroup - The `UrlSegmentGroup` whose children need to be matched against the
* config.
*/
processChildren(injector, config, segmentGroup) {
const childOutlets = [];
for (const child of Object.keys(segmentGroup.children)) {
if (child === "primary") {
childOutlets.unshift(child);
} else {
childOutlets.push(child);
}
}
return from(childOutlets).pipe(concatMap((childOutlet) => {
const child = segmentGroup.children[childOutlet];
const sortedConfig = sortByMatchingOutlets(config, childOutlet);
return this.processSegmentGroup(injector, sortedConfig, child, childOutlet);
}), scan((children, outletChildren) => {
children.push(...outletChildren);
return children;
}), defaultIfEmpty(null), last(), mergeMap((children) => {
if (children === null)
return noMatch$1(segmentGroup);
const mergedChildren = mergeEmptyPathMatches(children);
if (typeof ngDevMode === "undefined" || ngDevMode) {
checkOutletNameUniqueness(mergedChildren);
}
sortActivatedRouteSnapshots(mergedChildren);
return of(mergedChildren);
}));
}
processSegment(injector, routes, segmentGroup, segments, outlet, allowRedirects) {
return from(routes).pipe(concatMap((r) => {
return this.processSegmentAgainstRoute(r._injector ?? injector, routes, r, segmentGroup, segments, outlet, allowRedirects).pipe(catchError((e) => {
if (e instanceof NoMatch) {
return of(null);
}
throw e;
}));
}), first((x) => !!x), catchError((e) => {
if (isEmptyError(e)) {
if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
return of(new NoLeftoversInUrl());
}
return noMatch$1(segmentGroup);
}
throw e;
}));
}
processSegmentAgainstRoute(injector, routes, route, rawSegment, segments, outlet, allowRedirects) {
if (!isImmediateMatch(route, rawSegment, segments, outlet))
return noMatch$1(rawSegment);
if (route.redirectTo === void 0) {
return this.matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet);
}
if (this.allowRedirects && allowRedirects) {
return this.expandSegmentAgainstRouteUsingRedirect(injector, rawSegment, routes, route, segments, outlet);
}
return noMatch$1(rawSegment);
}
expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
const {
matched,
consumedSegments,
positionalParamSegments,
remainingSegments
} = match(segmentGroup, route, segments);
if (!matched)
return noMatch$1(segmentGroup);
if (route.redirectTo.startsWith("/")) {
this.absoluteRedirectCount++;
if (this.absoluteRedirectCount > MAX_ALLOWED_REDIRECTS) {
if (ngDevMode) {
throw new RuntimeError(4016, `Detected possible infinite redirect when redirecting from '${this.urlTree}' to '${route.redirectTo}'.
This is currently a dev mode only error but will become a call stack size exceeded error in production in a future major version.`);
}
this.allowRedirects = false;
}
}
const newTree = this.applyRedirects.applyRedirectCommands(consumedSegments, route.redirectTo, positionalParamSegments);
return this.applyRedirects.lineralizeSegments(route, newTree).pipe(mergeMap((newSegments) => {
return this.processSegment(injector, routes, segmentGroup, newSegments.concat(remainingSegments), outlet, false);
}));
}
matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet) {
const matchResult = matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer);
if (route.path === "**") {
rawSegment.children = {};
}
return matchResult.pipe(switchMap((result) => {
if (!result.matched) {
return noMatch$1(rawSegment);
}
injector = route._injector ?? injector;
return this.getChildConfig(injector, route, segments).pipe(switchMap(({
routes: childConfig
}) => {
const childInjector = route._loadedInjector ?? injector;
const {
consumedSegments,
remainingSegments,
parameters
} = result;
const snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Object.freeze(__spreadValues({}, this.urlTree.queryParams)), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route));
const {
segmentGroup,
slicedSegments
} = split(rawSegment, consumedSegments, remainingSegments, childConfig);
if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
return this.processChildren(childInjector, childConfig, segmentGroup).pipe(map((children) => {
if (children === null) {
return null;
}
return new TreeNode(snapshot, children);
}));
}
if (childConfig.length === 0 && slicedSegments.length === 0) {
return of(new TreeNode(snapshot, []));
}
const matchedOnOutlet = getOutlet(route) === outlet;
return this.processSegment(childInjector, childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true).pipe(map((child) => {
return new TreeNode(snapshot, child instanceof TreeNode ? [child] : []);
}));
}));
}));
}
getChildConfig(injector, route, segments) {
if (route.children) {
return of({
routes: route.children,
injector
});
}
if (route.loadChildren) {
if (route._loadedRoutes !== void 0) {
return of({
routes: route._loadedRoutes,
injector: route._loadedInjector
});
}
return runCanLoadGuards(injector, route, segments, this.urlSerializer).pipe(mergeMap((shouldLoadResult) => {
if (shouldLoadResult) {
return this.configLoader.loadChildren(injector, route).pipe(tap((cfg) => {
route._loadedRoutes = cfg.routes;
route._loadedInjector = cfg.injector;
}));
}
return canLoadFails(route);
}));
}
return of({
routes: [],
injector
});
}
};
function sortActivatedRouteSnapshots(nodes) {
nodes.sort((a, b) => {
if (a.value.outlet === PRIMARY_OUTLET)
return -1;
if (b.value.outlet === PRIMARY_OUTLET)
return 1;
return a.value.outlet.localeCompare(b.value.outlet);
});
}
function hasEmptyPathConfig(node) {
const config = node.value.routeConfig;
return config && config.path === "";
}
function mergeEmptyPathMatches(nodes) {
const result = [];
const mergedNodes = /* @__PURE__ */ new Set();
for (const node of nodes) {
if (!hasEmptyPathConfig(node)) {
result.push(node);
continue;
}
const duplicateEmptyPathNode = result.find((resultNode) => node.value.routeConfig === resultNode.value.routeConfig);
if (duplicateEmptyPathNode !== void 0) {
duplicateEmptyPathNode.children.push(...node.children);
mergedNodes.add(duplicateEmptyPathNode);
} else {
result.push(node);
}
}
for (const mergedNode of mergedNodes) {
const mergedChildren = mergeEmptyPathMatches(mergedNode.children);
result.push(new TreeNode(mergedNode.value, mergedChildren));
}
return result.filter((n) => !mergedNodes.has(n));
}
function checkOutletNameUniqueness(nodes) {
const names = {};
nodes.forEach((n) => {
const routeWithSameOutletName = names[n.value.outlet];
if (routeWithSameOutletName) {
const p = routeWithSameOutletName.url.map((s) => s.toString()).join("/");
const c = n.value.url.map((s) => s.toString()).join("/");
throw new RuntimeError(4006, (typeof ngDevMode === "undefined" || ngDevMode) && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
}
names[n.value.outlet] = n.value;
});
}
function getData(route) {
return route.data || {};
}
function getResolve(route) {
return route.resolve || {};
}
function recognize(injector, configLoader, rootComponentType, config, serializer, paramsInheritanceStrategy) {
return mergeMap((t) => recognize$1(injector, configLoader, rootComponentType, config, t.extractedUrl, serializer, paramsInheritanceStrategy).pipe(map(({
state: targetSnapshot,
tree: urlAfterRedirects
}) => {
return __spreadProps(__spreadValues({}, t), {
targetSnapshot,
urlAfterRedirects
});
})));
}
function resolveData(paramsInheritanceStrategy, injector) {
return mergeMap((t) => {
const {
targetSnapshot,
guards: {
canActivateChecks
}
} = t;
if (!canActivateChecks.length) {
return of(t);
}
const routesWithResolversToRun = new Set(canActivateChecks.map((check) => check.route));
const routesNeedingDataUpdates = /* @__PURE__ */ new Set();
for (const route of routesWithResolversToRun) {
if (routesNeedingDataUpdates.has(route)) {
continue;
}
for (const newRoute of flattenRouteTree(route)) {
routesNeedingDataUpdates.add(newRoute);
}
}
let routesProcessed = 0;
return from(routesNeedingDataUpdates).pipe(concatMap((route) => {
if (routesWithResolversToRun.has(route)) {
return runResolve(route, targetSnapshot, paramsInheritanceStrategy, injector);
} else {
route.data = getInherited(route, route.parent, paramsInheritanceStrategy).resolve;
return of(void 0);
}
}), tap(() => routesProcessed++), takeLast(1), mergeMap((_) => routesProcessed === routesNeedingDataUpdates.size ? of(t) : EMPTY));
});
}
function flattenRouteTree(route) {
const descendants = route.children.map((child) => flattenRouteTree(child)).flat();
return [route, ...descendants];
}
function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, injector) {
const config = futureARS.routeConfig;
const resolve = futureARS._resolve;
if (config?.title !== void 0 && !hasStaticTitle(config)) {
resolve[RouteTitleKey] = config.title;
}
return resolveNode(resolve, futureARS, futureRSS, injector).pipe(map((resolvedData) => {
futureARS._resolvedData = resolvedData;
futureARS.data = getInherited(futureARS, futureARS.parent, paramsInheritanceStrategy).resolve;
return null;
}));
}
function resolveNode(resolve, futureARS, futureRSS, injector) {
const keys = getDataKeys(resolve);
if (keys.length === 0) {
return of({});
}
const data = {};
return from(keys).pipe(mergeMap((key) => getResolver(resolve[key], futureARS, futureRSS, injector).pipe(first(), tap((value) => {
data[key] = value;
}))), takeLast(1), mapTo(data), catchError((e) => isEmptyError(e) ? EMPTY : throwError(e)));
}
function getResolver(injectionToken, futureARS, futureRSS, injector) {
const closestInjector = getClosestRouteInjector(futureARS) ?? injector;
const resolver = getTokenOrFunctionIdentity(injectionToken, closestInjector);
const resolverValue = resolver.resolve ? resolver.resolve(futureARS, futureRSS) : runInInjectionContext(closestInjector, () => resolver(futureARS, futureRSS));
return wrapIntoObservable(resolverValue);
}
function switchTap(next) {
return switchMap((v) => {
const nextResult = next(v);
if (nextResult) {
return from(nextResult).pipe(map(() => v));
}
return of(v);
});
}
var _TitleStrategy = class _TitleStrategy {
/**
* @returns The `title` of the deepest primary route.
*/
buildTitle(snapshot) {
let pageTitle;
let route = snapshot.root;
while (route !== void 0) {
pageTitle = this.getResolvedTitleForRoute(route) ?? pageTitle;
route = route.children.find((child) => child.outlet === PRIMARY_OUTLET);
}
return pageTitle;
}
/**
* Given an `ActivatedRouteSnapshot`, returns the final value of the
* `Route.title` property, which can either be a static string or a resolved value.
*/
getResolvedTitleForRoute(snapshot) {
return snapshot.data[RouteTitleKey];
}
};
_TitleStrategy.ɵfac = function TitleStrategy_Factory(t) {
return new (t || _TitleStrategy)();
};
_TitleStrategy.ɵprov = ɵɵdefineInjectable({
token: _TitleStrategy,
factory: () => (() => inject(DefaultTitleStrategy))(),
providedIn: "root"
});
var TitleStrategy = _TitleStrategy;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(TitleStrategy, [{
type: Injectable,
args: [{
providedIn: "root",
useFactory: () => inject(DefaultTitleStrategy)
}]
}], null, null);
})();
var _DefaultTitleStrategy = class _DefaultTitleStrategy extends TitleStrategy {
constructor(title) {
super();
this.title = title;
}
/**
* Sets the title of the browser to the given value.
*
* @param title The `pageTitle` from the deepest primary route.
*/
updateTitle(snapshot) {
const title = this.buildTitle(snapshot);
if (title !== void 0) {
this.title.setTitle(title);
}
}
};
_DefaultTitleStrategy.ɵfac = function DefaultTitleStrategy_Factory(t) {
return new (t || _DefaultTitleStrategy)(ɵɵinject(Title));
};
_DefaultTitleStrategy.ɵprov = ɵɵdefineInjectable({
token: _DefaultTitleStrategy,
factory: _DefaultTitleStrategy.ɵfac,
providedIn: "root"
});
var DefaultTitleStrategy = _DefaultTitleStrategy;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(DefaultTitleStrategy, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], () => [{
type: Title
}], null);
})();
var ROUTER_CONFIGURATION = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "router config" : "", {
providedIn: "root",
factory: () => ({})
});
var ROUTES = new InjectionToken("ROUTES");
var _RouterConfigLoader = class _RouterConfigLoader {
constructor() {
this.componentLoaders = /* @__PURE__ */ new WeakMap();
this.childrenLoaders = /* @__PURE__ */ new WeakMap();
this.compiler = inject(Compiler);
}
loadComponent(route) {
if (this.componentLoaders.get(route)) {
return this.componentLoaders.get(route);
} else if (route._loadedComponent) {
return of(route._loadedComponent);
}
if (this.onLoadStartListener) {
this.onLoadStartListener(route);
}
const loadRunner = wrapIntoObservable(route.loadComponent()).pipe(map(maybeUnwrapDefaultExport), tap((component) => {
if (this.onLoadEndListener) {
this.onLoadEndListener(route);
}
(typeof ngDevMode === "undefined" || ngDevMode) && assertStandalone(route.path ?? "", component);
route._loadedComponent = component;
}), finalize(() => {
this.componentLoaders.delete(route);
}));
const loader = new ConnectableObservable(loadRunner, () => new Subject()).pipe(refCount());
this.componentLoaders.set(route, loader);
return loader;
}
loadChildren(parentInjector, route) {
if (this.childrenLoaders.get(route)) {
return this.childrenLoaders.get(route);
} else if (route._loadedRoutes) {
return of({
routes: route._loadedRoutes,
injector: route._loadedInjector
});
}
if (this.onLoadStartListener) {
this.onLoadStartListener(route);
}
const moduleFactoryOrRoutes$ = loadChildren(route, this.compiler, parentInjector, this.onLoadEndListener);
const loadRunner = moduleFactoryOrRoutes$.pipe(finalize(() => {
this.childrenLoaders.delete(route);
}));
const loader = new ConnectableObservable(loadRunner, () => new Subject()).pipe(refCount());
this.childrenLoaders.set(route, loader);
return loader;
}
};
_RouterConfigLoader.ɵfac = function RouterConfigLoader_Factory(t) {
return new (t || _RouterConfigLoader)();
};
_RouterConfigLoader.ɵprov = ɵɵdefineInjectable({
token: _RouterConfigLoader,
factory: _RouterConfigLoader.ɵfac,
providedIn: "root"
});
var RouterConfigLoader = _RouterConfigLoader;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouterConfigLoader, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], null, null);
})();
function loadChildren(route, compiler, parentInjector, onLoadEndListener) {
return wrapIntoObservable(route.loadChildren()).pipe(map(maybeUnwrapDefaultExport), mergeMap((t) => {
if (t instanceof NgModuleFactory$1 || Array.isArray(t)) {
return of(t);
} else {
return from(compiler.compileModuleAsync(t));
}
}), map((factoryOrRoutes) => {
if (onLoadEndListener) {
onLoadEndListener(route);
}
let injector;
let rawRoutes;
let requireStandaloneComponents = false;
if (Array.isArray(factoryOrRoutes)) {
rawRoutes = factoryOrRoutes;
requireStandaloneComponents = true;
} else {
injector = factoryOrRoutes.create(parentInjector).injector;
rawRoutes = injector.get(ROUTES, [], {
optional: true,
self: true
}).flat();
}
const routes = rawRoutes.map(standardizeConfig);
(typeof ngDevMode === "undefined" || ngDevMode) && validateConfig(routes, route.path, requireStandaloneComponents);
return {
routes,
injector
};
}));
}
function isWrappedDefaultExport(value) {
return value && typeof value === "object" && "default" in value;
}
function maybeUnwrapDefaultExport(input) {
return isWrappedDefaultExport(input) ? input["default"] : input;
}
var _UrlHandlingStrategy = class _UrlHandlingStrategy {
};
_UrlHandlingStrategy.ɵfac = function UrlHandlingStrategy_Factory(t) {
return new (t || _UrlHandlingStrategy)();
};
_UrlHandlingStrategy.ɵprov = ɵɵdefineInjectable({
token: _UrlHandlingStrategy,
factory: () => (() => inject(DefaultUrlHandlingStrategy))(),
providedIn: "root"
});
var UrlHandlingStrategy = _UrlHandlingStrategy;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(UrlHandlingStrategy, [{
type: Injectable,
args: [{
providedIn: "root",
useFactory: () => inject(DefaultUrlHandlingStrategy)
}]
}], null, null);
})();
var _DefaultUrlHandlingStrategy = class _DefaultUrlHandlingStrategy {
shouldProcessUrl(url) {
return true;
}
extract(url) {
return url;
}
merge(newUrlPart, wholeUrl) {
return newUrlPart;
}
};
_DefaultUrlHandlingStrategy.ɵfac = function DefaultUrlHandlingStrategy_Factory(t) {
return new (t || _DefaultUrlHandlingStrategy)();
};
_DefaultUrlHandlingStrategy.ɵprov = ɵɵdefineInjectable({
token: _DefaultUrlHandlingStrategy,
factory: _DefaultUrlHandlingStrategy.ɵfac,
providedIn: "root"
});
var DefaultUrlHandlingStrategy = _DefaultUrlHandlingStrategy;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(DefaultUrlHandlingStrategy, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], null, null);
})();
var CREATE_VIEW_TRANSITION = new InjectionToken(ngDevMode ? "view transition helper" : "");
var VIEW_TRANSITION_OPTIONS = new InjectionToken(ngDevMode ? "view transition options" : "");
function createViewTransition(injector, from2, to) {
const transitionOptions = injector.get(VIEW_TRANSITION_OPTIONS);
const document = injector.get(DOCUMENT);
return injector.get(NgZone).runOutsideAngular(() => {
if (!document.startViewTransition || transitionOptions.skipNextTransition) {
transitionOptions.skipNextTransition = false;
return Promise.resolve();
}
let resolveViewTransitionStarted;
const viewTransitionStarted = new Promise((resolve) => {
resolveViewTransitionStarted = resolve;
});
const transition = document.startViewTransition(() => {
resolveViewTransitionStarted();
return createRenderPromise(injector);
});
const {
onViewTransitionCreated
} = transitionOptions;
if (onViewTransitionCreated) {
runInInjectionContext(injector, () => onViewTransitionCreated({
transition,
from: from2,
to
}));
}
return viewTransitionStarted;
});
}
function createRenderPromise(injector) {
return new Promise((resolve) => {
afterNextRender(resolve, {
injector
});
});
}
var _NavigationTransitions = class _NavigationTransitions {
get hasRequestedNavigation() {
return this.navigationId !== 0;
}
constructor() {
this.currentNavigation = null;
this.currentTransition = null;
this.lastSuccessfulNavigation = null;
this.events = new Subject();
this.transitionAbortSubject = new Subject();
this.configLoader = inject(RouterConfigLoader);
this.environmentInjector = inject(EnvironmentInjector);
this.urlSerializer = inject(UrlSerializer);
this.rootContexts = inject(ChildrenOutletContexts);
this.location = inject(Location);
this.inputBindingEnabled = inject(INPUT_BINDER, {
optional: true
}) !== null;
this.titleStrategy = inject(TitleStrategy);
this.options = inject(ROUTER_CONFIGURATION, {
optional: true
}) || {};
this.paramsInheritanceStrategy = this.options.paramsInheritanceStrategy || "emptyOnly";
this.urlHandlingStrategy = inject(UrlHandlingStrategy);
this.createViewTransition = inject(CREATE_VIEW_TRANSITION, {
optional: true
});
this.navigationId = 0;
this.afterPreactivation = () => of(void 0);
this.rootComponentType = null;
const onLoadStart = (r) => this.events.next(new RouteConfigLoadStart(r));
const onLoadEnd = (r) => this.events.next(new RouteConfigLoadEnd(r));
this.configLoader.onLoadEndListener = onLoadEnd;
this.configLoader.onLoadStartListener = onLoadStart;
}
complete() {
this.transitions?.complete();
}
handleNavigationRequest(request) {
const id = ++this.navigationId;
this.transitions?.next(__spreadProps(__spreadValues(__spreadValues({}, this.transitions.value), request), {
id
}));
}
setupNavigations(router, initialUrlTree, initialRouterState) {
this.transitions = new BehaviorSubject({
id: 0,
currentUrlTree: initialUrlTree,
currentRawUrl: initialUrlTree,
extractedUrl: this.urlHandlingStrategy.extract(initialUrlTree),
urlAfterRedirects: this.urlHandlingStrategy.extract(initialUrlTree),
rawUrl: initialUrlTree,
extras: {},
resolve: null,
reject: null,
promise: Promise.resolve(true),
source: IMPERATIVE_NAVIGATION,
restoredState: null,
currentSnapshot: initialRouterState.snapshot,
targetSnapshot: null,
currentRouterState: initialRouterState,
targetRouterState: null,
guards: {
canActivateChecks: [],
canDeactivateChecks: []
},
guardsResult: null
});
return this.transitions.pipe(
filter((t) => t.id !== 0),
// Extract URL
map((t) => __spreadProps(__spreadValues({}, t), {
extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl)
})),
// Using switchMap so we cancel executing navigations when a new one comes in
switchMap((overallTransitionState) => {
this.currentTransition = overallTransitionState;
let completed = false;
let errored = false;
return of(overallTransitionState).pipe(
// Store the Navigation object
tap((t) => {
this.currentNavigation = {
id: t.id,
initialUrl: t.rawUrl,
extractedUrl: t.extractedUrl,
trigger: t.source,
extras: t.extras,
previousNavigation: !this.lastSuccessfulNavigation ? null : __spreadProps(__spreadValues({}, this.lastSuccessfulNavigation), {
previousNavigation: null
})
};
}),
switchMap((t) => {
const urlTransition = !router.navigated || this.isUpdatingInternalState() || this.isUpdatedBrowserUrl();
const onSameUrlNavigation = t.extras.onSameUrlNavigation ?? router.onSameUrlNavigation;
if (!urlTransition && onSameUrlNavigation !== "reload") {
const reason = typeof ngDevMode === "undefined" || ngDevMode ? `Navigation to ${t.rawUrl} was ignored because it is the same as the current Router URL.` : "";
this.events.next(new NavigationSkipped(
t.id,
this.urlSerializer.serialize(t.rawUrl),
reason,
0
/* NavigationSkippedCode.IgnoredSameUrlNavigation */
));
t.resolve(null);
return EMPTY;
}
if (this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl)) {
return of(t).pipe(
// Fire NavigationStart event
switchMap((t2) => {
const transition = this.transitions?.getValue();
this.events.next(new NavigationStart(t2.id, this.urlSerializer.serialize(t2.extractedUrl), t2.source, t2.restoredState));
if (transition !== this.transitions?.getValue()) {
return EMPTY;
}
return Promise.resolve(t2);
}),
// Recognize
recognize(this.environmentInjector, this.configLoader, this.rootComponentType, router.config, this.urlSerializer, this.paramsInheritanceStrategy),
// Update URL if in `eager` update mode
tap((t2) => {
overallTransitionState.targetSnapshot = t2.targetSnapshot;
overallTransitionState.urlAfterRedirects = t2.urlAfterRedirects;
this.currentNavigation = __spreadProps(__spreadValues({}, this.currentNavigation), {
finalUrl: t2.urlAfterRedirects
});
const routesRecognized = new RoutesRecognized(t2.id, this.urlSerializer.serialize(t2.extractedUrl), this.urlSerializer.serialize(t2.urlAfterRedirects), t2.targetSnapshot);
this.events.next(routesRecognized);
})
);
} else if (urlTransition && this.urlHandlingStrategy.shouldProcessUrl(t.currentRawUrl)) {
const {
id,
extractedUrl,
source,
restoredState,
extras
} = t;
const navStart = new NavigationStart(id, this.urlSerializer.serialize(extractedUrl), source, restoredState);
this.events.next(navStart);
const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
this.currentTransition = overallTransitionState = __spreadProps(__spreadValues({}, t), {
targetSnapshot,
urlAfterRedirects: extractedUrl,
extras: __spreadProps(__spreadValues({}, extras), {
skipLocationChange: false,
replaceUrl: false
})
});
this.currentNavigation.finalUrl = extractedUrl;
return of(overallTransitionState);
} else {
const reason = typeof ngDevMode === "undefined" || ngDevMode ? `Navigation was ignored because the UrlHandlingStrategy indicated neither the current URL ${t.currentRawUrl} nor target URL ${t.rawUrl} should be processed.` : "";
this.events.next(new NavigationSkipped(
t.id,
this.urlSerializer.serialize(t.extractedUrl),
reason,
1
/* NavigationSkippedCode.IgnoredByUrlHandlingStrategy */
));
t.resolve(null);
return EMPTY;
}
}),
// --- GUARDS ---
tap((t) => {
const guardsStart = new GuardsCheckStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
this.events.next(guardsStart);
}),
map((t) => {
this.currentTransition = overallTransitionState = __spreadProps(__spreadValues({}, t), {
guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts)
});
return overallTransitionState;
}),
checkGuards(this.environmentInjector, (evt) => this.events.next(evt)),
tap((t) => {
overallTransitionState.guardsResult = t.guardsResult;
if (isUrlTree(t.guardsResult)) {
throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
}
const guardsEnd = new GuardsCheckEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
this.events.next(guardsEnd);
}),
filter((t) => {
if (!t.guardsResult) {
this.cancelNavigationTransition(
t,
"",
3
/* NavigationCancellationCode.GuardRejected */
);
return false;
}
return true;
}),
// --- RESOLVE ---
switchTap((t) => {
if (t.guards.canActivateChecks.length) {
return of(t).pipe(tap((t2) => {
const resolveStart = new ResolveStart(t2.id, this.urlSerializer.serialize(t2.extractedUrl), this.urlSerializer.serialize(t2.urlAfterRedirects), t2.targetSnapshot);
this.events.next(resolveStart);
}), switchMap((t2) => {
let dataResolved = false;
return of(t2).pipe(resolveData(this.paramsInheritanceStrategy, this.environmentInjector), tap({
next: () => dataResolved = true,
complete: () => {
if (!dataResolved) {
this.cancelNavigationTransition(
t2,
typeof ngDevMode === "undefined" || ngDevMode ? `At least one route resolver didn't emit any value.` : "",
2
/* NavigationCancellationCode.NoDataFromResolver */
);
}
}
}));
}), tap((t2) => {
const resolveEnd = new ResolveEnd(t2.id, this.urlSerializer.serialize(t2.extractedUrl), this.urlSerializer.serialize(t2.urlAfterRedirects), t2.targetSnapshot);
this.events.next(resolveEnd);
}));
}
return void 0;
}),
// --- LOAD COMPONENTS ---
switchTap((t) => {
const loadComponents = (route) => {
const loaders = [];
if (route.routeConfig?.loadComponent && !route.routeConfig._loadedComponent) {
loaders.push(this.configLoader.loadComponent(route.routeConfig).pipe(tap((loadedComponent) => {
route.component = loadedComponent;
}), map(() => void 0)));
}
for (const child of route.children) {
loaders.push(...loadComponents(child));
}
return loaders;
};
return combineLatest(loadComponents(t.targetSnapshot.root)).pipe(defaultIfEmpty(), take(1));
}),
switchTap(() => this.afterPreactivation()),
switchMap(() => {
const {
currentSnapshot,
targetSnapshot
} = overallTransitionState;
const viewTransitionStarted = this.createViewTransition?.(this.environmentInjector, currentSnapshot.root, targetSnapshot.root);
return viewTransitionStarted ? from(viewTransitionStarted).pipe(map(() => overallTransitionState)) : of(overallTransitionState);
}),
map((t) => {
const targetRouterState = createRouterState(router.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
this.currentTransition = overallTransitionState = __spreadProps(__spreadValues({}, t), {
targetRouterState
});
this.currentNavigation.targetRouterState = targetRouterState;
return overallTransitionState;
}),
tap(() => {
this.events.next(new BeforeActivateRoutes());
}),
activateRoutes(this.rootContexts, router.routeReuseStrategy, (evt) => this.events.next(evt), this.inputBindingEnabled),
// Ensure that if some observable used to drive the transition doesn't
// complete, the navigation still finalizes This should never happen, but
// this is done as a safety measure to avoid surfacing this error (#49567).
take(1),
tap({
next: (t) => {
completed = true;
this.lastSuccessfulNavigation = this.currentNavigation;
this.events.next(new NavigationEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects)));
this.titleStrategy?.updateTitle(t.targetRouterState.snapshot);
t.resolve(true);
},
complete: () => {
completed = true;
}
}),
// There used to be a lot more logic happening directly within the
// transition Observable. Some of this logic has been refactored out to
// other places but there may still be errors that happen there. This gives
// us a way to cancel the transition from the outside. This may also be
// required in the future to support something like the abort signal of the
// Navigation API where the navigation gets aborted from outside the
// transition.
takeUntil(this.transitionAbortSubject.pipe(tap((err) => {
throw err;
}))),
finalize(() => {
if (!completed && !errored) {
const cancelationReason = typeof ngDevMode === "undefined" || ngDevMode ? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}` : "";
this.cancelNavigationTransition(
overallTransitionState,
cancelationReason,
1
/* NavigationCancellationCode.SupersededByNewNavigation */
);
}
if (this.currentNavigation?.id === overallTransitionState.id) {
this.currentNavigation = null;
}
}),
catchError((e) => {
errored = true;
if (isNavigationCancelingError$1(e)) {
this.events.next(new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e.message, e.cancellationCode));
if (!isRedirectingNavigationCancelingError$1(e)) {
overallTransitionState.resolve(false);
} else {
this.events.next(new RedirectRequest(e.url));
}
} else {
this.events.next(new NavigationError(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? void 0));
try {
overallTransitionState.resolve(router.errorHandler(e));
} catch (ee) {
overallTransitionState.reject(ee);
}
}
return EMPTY;
})
);
})
);
}
cancelNavigationTransition(t, reason, code) {
const navCancel = new NavigationCancel(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, code);
this.events.next(navCancel);
t.resolve(false);
}
/**
* @returns Whether we're navigating to somewhere that is not what the Router is
* currently set to.
*/
isUpdatingInternalState() {
return this.currentTransition?.extractedUrl.toString() !== this.currentTransition?.currentUrlTree.toString();
}
/**
* @returns Whether we're updating the browser URL to something new (navigation is going
* to somewhere not displayed in the URL bar and we will update the URL
* bar if navigation succeeds).
*/
isUpdatedBrowserUrl() {
const extractedBrowserUrl = this.urlHandlingStrategy.extract(this.urlSerializer.parse(this.location.path(true)));
return extractedBrowserUrl.toString() !== this.currentTransition?.extractedUrl.toString() && !this.currentTransition?.extras.skipLocationChange;
}
};
_NavigationTransitions.ɵfac = function NavigationTransitions_Factory(t) {
return new (t || _NavigationTransitions)();
};
_NavigationTransitions.ɵprov = ɵɵdefineInjectable({
token: _NavigationTransitions,
factory: _NavigationTransitions.ɵfac,
providedIn: "root"
});
var NavigationTransitions = _NavigationTransitions;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NavigationTransitions, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], () => [], null);
})();
function isBrowserTriggeredNavigation(source) {
return source !== IMPERATIVE_NAVIGATION;
}
var _RouteReuseStrategy = class _RouteReuseStrategy {
};
_RouteReuseStrategy.ɵfac = function RouteReuseStrategy_Factory(t) {
return new (t || _RouteReuseStrategy)();
};
_RouteReuseStrategy.ɵprov = ɵɵdefineInjectable({
token: _RouteReuseStrategy,
factory: () => (() => inject(DefaultRouteReuseStrategy))(),
providedIn: "root"
});
var RouteReuseStrategy = _RouteReuseStrategy;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouteReuseStrategy, [{
type: Injectable,
args: [{
providedIn: "root",
useFactory: () => inject(DefaultRouteReuseStrategy)
}]
}], null, null);
})();
var BaseRouteReuseStrategy = class {
/**
* Whether the given route should detach for later reuse.
* Always returns false for `BaseRouteReuseStrategy`.
* */
shouldDetach(route) {
return false;
}
/**
* A no-op; the route is never stored since this strategy never detaches routes for later re-use.
*/
store(route, detachedTree) {
}
/** Returns `false`, meaning the route (and its subtree) is never reattached */
shouldAttach(route) {
return false;
}
/** Returns `null` because this strategy does not store routes for later re-use. */
retrieve(route) {
return null;
}
/**
* Determines if a route should be reused.
* This strategy returns `true` when the future route config and current route config are
* identical.
*/
shouldReuseRoute(future, curr) {
return future.routeConfig === curr.routeConfig;
}
};
var _DefaultRouteReuseStrategy = class _DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
};
_DefaultRouteReuseStrategy.ɵfac = (() => {
let ɵDefaultRouteReuseStrategy_BaseFactory;
return function DefaultRouteReuseStrategy_Factory(t) {
return (ɵDefaultRouteReuseStrategy_BaseFactory || (ɵDefaultRouteReuseStrategy_BaseFactory = ɵɵgetInheritedFactory(_DefaultRouteReuseStrategy)))(t || _DefaultRouteReuseStrategy);
};
})();
_DefaultRouteReuseStrategy.ɵprov = ɵɵdefineInjectable({
token: _DefaultRouteReuseStrategy,
factory: _DefaultRouteReuseStrategy.ɵfac,
providedIn: "root"
});
var DefaultRouteReuseStrategy = _DefaultRouteReuseStrategy;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(DefaultRouteReuseStrategy, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], null, null);
})();
var _StateManager = class _StateManager {
};
_StateManager.ɵfac = function StateManager_Factory(t) {
return new (t || _StateManager)();
};
_StateManager.ɵprov = ɵɵdefineInjectable({
token: _StateManager,
factory: () => (() => inject(HistoryStateManager))(),
providedIn: "root"
});
var StateManager = _StateManager;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(StateManager, [{
type: Injectable,
args: [{
providedIn: "root",
useFactory: () => inject(HistoryStateManager)
}]
}], null, null);
})();
var _HistoryStateManager = class _HistoryStateManager extends StateManager {
constructor() {
super(...arguments);
this.location = inject(Location);
this.urlSerializer = inject(UrlSerializer);
this.options = inject(ROUTER_CONFIGURATION, {
optional: true
}) || {};
this.canceledNavigationResolution = this.options.canceledNavigationResolution || "replace";
this.urlHandlingStrategy = inject(UrlHandlingStrategy);
this.urlUpdateStrategy = this.options.urlUpdateStrategy || "deferred";
this.currentUrlTree = new UrlTree();
this.rawUrlTree = this.currentUrlTree;
this.currentPageId = 0;
this.lastSuccessfulId = -1;
this.routerState = createEmptyState(this.currentUrlTree, null);
this.stateMemento = this.createStateMemento();
}
getCurrentUrlTree() {
return this.currentUrlTree;
}
getRawUrlTree() {
return this.rawUrlTree;
}
restoredState() {
return this.location.getState();
}
/**
* The ɵrouterPageId of whatever page is currently active in the browser history. This is
* important for computing the target page id for new navigations because we need to ensure each
* page id in the browser history is 1 more than the previous entry.
*/
get browserPageId() {
if (this.canceledNavigationResolution !== "computed") {
return this.currentPageId;
}
return this.restoredState()?.ɵrouterPageId ?? this.currentPageId;
}
getRouterState() {
return this.routerState;
}
createStateMemento() {
return {
rawUrlTree: this.rawUrlTree,
currentUrlTree: this.currentUrlTree,
routerState: this.routerState
};
}
registerNonRouterCurrentEntryChangeListener(listener) {
return this.location.subscribe((event) => {
if (event["type"] === "popstate") {
listener(event["url"], event.state);
}
});
}
handleRouterEvent(e, currentTransition) {
if (e instanceof NavigationStart) {
this.stateMemento = this.createStateMemento();
} else if (e instanceof NavigationSkipped) {
this.rawUrlTree = currentTransition.initialUrl;
} else if (e instanceof RoutesRecognized) {
if (this.urlUpdateStrategy === "eager") {
if (!currentTransition.extras.skipLocationChange) {
const rawUrl = this.urlHandlingStrategy.merge(currentTransition.finalUrl, currentTransition.initialUrl);
this.setBrowserUrl(rawUrl, currentTransition);
}
}
} else if (e instanceof BeforeActivateRoutes) {
this.currentUrlTree = currentTransition.finalUrl;
this.rawUrlTree = this.urlHandlingStrategy.merge(currentTransition.finalUrl, currentTransition.initialUrl);
this.routerState = currentTransition.targetRouterState;
if (this.urlUpdateStrategy === "deferred") {
if (!currentTransition.extras.skipLocationChange) {
this.setBrowserUrl(this.rawUrlTree, currentTransition);
}
}
} else if (e instanceof NavigationCancel && (e.code === 3 || e.code === 2)) {
this.restoreHistory(currentTransition);
} else if (e instanceof NavigationError) {
this.restoreHistory(currentTransition, true);
} else if (e instanceof NavigationEnd) {
this.lastSuccessfulId = e.id;
this.currentPageId = this.browserPageId;
}
}
setBrowserUrl(url, transition) {
const path = this.urlSerializer.serialize(url);
if (this.location.isCurrentPathEqualTo(path) || !!transition.extras.replaceUrl) {
const currentBrowserPageId = this.browserPageId;
const state = __spreadValues(__spreadValues({}, transition.extras.state), this.generateNgRouterState(transition.id, currentBrowserPageId));
this.location.replaceState(path, "", state);
} else {
const state = __spreadValues(__spreadValues({}, transition.extras.state), this.generateNgRouterState(transition.id, this.browserPageId + 1));
this.location.go(path, "", state);
}
}
/**
* Performs the necessary rollback action to restore the browser URL to the
* state before the transition.
*/
restoreHistory(navigation, restoringFromCaughtError = false) {
if (this.canceledNavigationResolution === "computed") {
const currentBrowserPageId = this.browserPageId;
const targetPagePosition = this.currentPageId - currentBrowserPageId;
if (targetPagePosition !== 0) {
this.location.historyGo(targetPagePosition);
} else if (this.currentUrlTree === navigation.finalUrl && targetPagePosition === 0) {
this.resetState(navigation);
this.resetUrlToCurrentUrlTree();
} else {
}
} else if (this.canceledNavigationResolution === "replace") {
if (restoringFromCaughtError) {
this.resetState(navigation);
}
this.resetUrlToCurrentUrlTree();
}
}
resetState(navigation) {
this.routerState = this.stateMemento.routerState;
this.currentUrlTree = this.stateMemento.currentUrlTree;
this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, navigation.finalUrl ?? this.rawUrlTree);
}
resetUrlToCurrentUrlTree() {
this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), "", this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
}
generateNgRouterState(navigationId, routerPageId) {
if (this.canceledNavigationResolution === "computed") {
return {
navigationId,
ɵrouterPageId: routerPageId
};
}
return {
navigationId
};
}
};
_HistoryStateManager.ɵfac = (() => {
let ɵHistoryStateManager_BaseFactory;
return function HistoryStateManager_Factory(t) {
return (ɵHistoryStateManager_BaseFactory || (ɵHistoryStateManager_BaseFactory = ɵɵgetInheritedFactory(_HistoryStateManager)))(t || _HistoryStateManager);
};
})();
_HistoryStateManager.ɵprov = ɵɵdefineInjectable({
token: _HistoryStateManager,
factory: _HistoryStateManager.ɵfac,
providedIn: "root"
});
var HistoryStateManager = _HistoryStateManager;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(HistoryStateManager, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], null, null);
})();
var NavigationResult;
(function(NavigationResult2) {
NavigationResult2[NavigationResult2["COMPLETE"] = 0] = "COMPLETE";
NavigationResult2[NavigationResult2["FAILED"] = 1] = "FAILED";
NavigationResult2[NavigationResult2["REDIRECTING"] = 2] = "REDIRECTING";
})(NavigationResult || (NavigationResult = {}));
function afterNextNavigation(router, action) {
router.events.pipe(filter((e) => e instanceof NavigationEnd || e instanceof NavigationCancel || e instanceof NavigationError || e instanceof NavigationSkipped), map((e) => {
if (e instanceof NavigationEnd || e instanceof NavigationSkipped) {
return NavigationResult.COMPLETE;
}
const redirecting = e instanceof NavigationCancel ? e.code === 0 || e.code === 1 : false;
return redirecting ? NavigationResult.REDIRECTING : NavigationResult.FAILED;
}), filter((result) => result !== NavigationResult.REDIRECTING), take(1)).subscribe(() => {
action();
});
}
function defaultErrorHandler(error) {
throw error;
}
var exactMatchOptions = {
paths: "exact",
fragment: "ignored",
matrixParams: "ignored",
queryParams: "exact"
};
var subsetMatchOptions = {
paths: "subset",
fragment: "ignored",
matrixParams: "ignored",
queryParams: "subset"
};
var _Router = class _Router {
get currentUrlTree() {
return this.stateManager.getCurrentUrlTree();
}
get rawUrlTree() {
return this.stateManager.getRawUrlTree();
}
/**
* An event stream for routing events.
*/
get events() {
return this._events;
}
/**
* The current state of routing in this NgModule.
*/
get routerState() {
return this.stateManager.getRouterState();
}
constructor() {
this.disposed = false;
this.isNgZoneEnabled = false;
this.console = inject(Console);
this.stateManager = inject(StateManager);
this.options = inject(ROUTER_CONFIGURATION, {
optional: true
}) || {};
this.pendingTasks = inject(InitialRenderPendingTasks);
this.urlUpdateStrategy = this.options.urlUpdateStrategy || "deferred";
this.navigationTransitions = inject(NavigationTransitions);
this.urlSerializer = inject(UrlSerializer);
this.location = inject(Location);
this.urlHandlingStrategy = inject(UrlHandlingStrategy);
this._events = new Subject();
this.errorHandler = this.options.errorHandler || defaultErrorHandler;
this.navigated = false;
this.routeReuseStrategy = inject(RouteReuseStrategy);
this.onSameUrlNavigation = this.options.onSameUrlNavigation || "ignore";
this.config = inject(ROUTES, {
optional: true
})?.flat() ?? [];
this.componentInputBindingEnabled = !!inject(INPUT_BINDER, {
optional: true
});
this.eventsSubscription = new Subscription();
this.isNgZoneEnabled = inject(NgZone) instanceof NgZone && NgZone.isInAngularZone();
this.resetConfig(this.config);
this.navigationTransitions.setupNavigations(this, this.currentUrlTree, this.routerState).subscribe({
error: (e) => {
this.console.warn(ngDevMode ? `Unhandled Navigation Error: ${e}` : e);
}
});
this.subscribeToNavigationEvents();
}
subscribeToNavigationEvents() {
const subscription = this.navigationTransitions.events.subscribe((e) => {
try {
const currentTransition = this.navigationTransitions.currentTransition;
const currentNavigation = this.navigationTransitions.currentNavigation;
if (currentTransition !== null && currentNavigation !== null) {
this.stateManager.handleRouterEvent(e, currentNavigation);
if (e instanceof NavigationCancel && e.code !== 0 && e.code !== 1) {
this.navigated = true;
} else if (e instanceof NavigationEnd) {
this.navigated = true;
} else if (e instanceof RedirectRequest) {
const mergedTree = this.urlHandlingStrategy.merge(e.url, currentTransition.currentRawUrl);
const extras = {
skipLocationChange: currentTransition.extras.skipLocationChange,
// The URL is already updated at this point if we have 'eager' URL
// updates or if the navigation was triggered by the browser (back
// button, URL bar, etc). We want to replace that item in history
// if the navigation is rejected.
replaceUrl: this.urlUpdateStrategy === "eager" || isBrowserTriggeredNavigation(currentTransition.source)
};
this.scheduleNavigation(mergedTree, IMPERATIVE_NAVIGATION, null, extras, {
resolve: currentTransition.resolve,
reject: currentTransition.reject,
promise: currentTransition.promise
});
}
}
if (isPublicRouterEvent(e)) {
this._events.next(e);
}
} catch (e2) {
this.navigationTransitions.transitionAbortSubject.next(e2);
}
});
this.eventsSubscription.add(subscription);
}
/** @internal */
resetRootComponentType(rootComponentType) {
this.routerState.root.component = rootComponentType;
this.navigationTransitions.rootComponentType = rootComponentType;
}
/**
* Sets up the location change listener and performs the initial navigation.
*/
initialNavigation() {
this.setUpLocationChangeListener();
if (!this.navigationTransitions.hasRequestedNavigation) {
this.navigateToSyncWithBrowser(this.location.path(true), IMPERATIVE_NAVIGATION, this.stateManager.restoredState());
}
}
/**
* Sets up the location change listener. This listener detects navigations triggered from outside
* the Router (the browser back/forward buttons, for example) and schedules a corresponding Router
* navigation so that the correct events, guards, etc. are triggered.
*/
setUpLocationChangeListener() {
if (!this.nonRouterCurrentEntryChangeSubscription) {
this.nonRouterCurrentEntryChangeSubscription = this.stateManager.registerNonRouterCurrentEntryChangeListener((url, state) => {
setTimeout(() => {
this.navigateToSyncWithBrowser(url, "popstate", state);
}, 0);
});
}
}
/**
* Schedules a router navigation to synchronize Router state with the browser state.
*
* This is done as a response to a popstate event and the initial navigation. These
* two scenarios represent times when the browser URL/state has been updated and
* the Router needs to respond to ensure its internal state matches.
*/
navigateToSyncWithBrowser(url, source, state) {
const extras = {
replaceUrl: true
};
const restoredState = state?.navigationId ? state : null;
if (state) {
const stateCopy = __spreadValues({}, state);
delete stateCopy.navigationId;
delete stateCopy.ɵrouterPageId;
if (Object.keys(stateCopy).length !== 0) {
extras.state = stateCopy;
}
}
const urlTree = this.parseUrl(url);
this.scheduleNavigation(urlTree, source, restoredState, extras);
}
/** The current URL. */
get url() {
return this.serializeUrl(this.currentUrlTree);
}
/**
* Returns the current `Navigation` object when the router is navigating,
* and `null` when idle.
*/
getCurrentNavigation() {
return this.navigationTransitions.currentNavigation;
}
/**
* The `Navigation` object of the most recent navigation to succeed and `null` if there
* has not been a successful navigation yet.
*/
get lastSuccessfulNavigation() {
return this.navigationTransitions.lastSuccessfulNavigation;
}
/**
* Resets the route configuration used for navigation and generating links.
*
* @param config The route array for the new configuration.
*
* @usageNotes
*
* ```
* router.resetConfig([
* { path: 'team/:id', component: TeamCmp, children: [
* { path: 'simple', component: SimpleCmp },
* { path: 'user/:name', component: UserCmp }
* ]}
* ]);
* ```
*/
resetConfig(config) {
(typeof ngDevMode === "undefined" || ngDevMode) && validateConfig(config);
this.config = config.map(standardizeConfig);
this.navigated = false;
}
/** @nodoc */
ngOnDestroy() {
this.dispose();
}
/** Disposes of the router. */
dispose() {
this.navigationTransitions.complete();
if (this.nonRouterCurrentEntryChangeSubscription) {
this.nonRouterCurrentEntryChangeSubscription.unsubscribe();
this.nonRouterCurrentEntryChangeSubscription = void 0;
}
this.disposed = true;
this.eventsSubscription.unsubscribe();
}
/**
* Appends URL segments to the current URL tree to create a new URL tree.
*
* @param commands An array of URL fragments with which to construct the new URL tree.
* If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
* segments, followed by the parameters for each segment.
* The fragments are applied to the current URL tree or the one provided in the `relativeTo`
* property of the options object, if supplied.
* @param navigationExtras Options that control the navigation strategy.
* @returns The new URL tree.
*
* @usageNotes
*
* ```
* // create /team/33/user/11
* router.createUrlTree(['/team', 33, 'user', 11]);
*
* // create /team/33;expand=true/user/11
* router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
*
* // you can collapse static segments like this (this works only with the first passed-in value):
* router.createUrlTree(['/team/33/user', userId]);
*
* // If the first segment can contain slashes, and you do not want the router to split it,
* // you can do the following:
* router.createUrlTree([{segmentPath: '/one/two'}]);
*
* // create /team/33/(user/11//right:chat)
* router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
*
* // remove the right secondary node
* router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
*
* // assuming the current url is `/team/33/user/11` and the route points to `user/11`
*
* // navigate to /team/33/user/11/details
* router.createUrlTree(['details'], {relativeTo: route});
*
* // navigate to /team/33/user/22
* router.createUrlTree(['../22'], {relativeTo: route});
*
* // navigate to /team/44/user/22
* router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
*
* Note that a value of `null` or `undefined` for `relativeTo` indicates that the
* tree should be created relative to the root.
* ```
*/
createUrlTree(commands, navigationExtras = {}) {
const {
relativeTo,
queryParams,
fragment,
queryParamsHandling,
preserveFragment
} = navigationExtras;
const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
let q = null;
switch (queryParamsHandling) {
case "merge":
q = __spreadValues(__spreadValues({}, this.currentUrlTree.queryParams), queryParams);
break;
case "preserve":
q = this.currentUrlTree.queryParams;
break;
default:
q = queryParams || null;
}
if (q !== null) {
q = this.removeEmptyProps(q);
}
let relativeToUrlSegmentGroup;
try {
const relativeToSnapshot = relativeTo ? relativeTo.snapshot : this.routerState.snapshot.root;
relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeToSnapshot);
} catch (e) {
if (typeof commands[0] !== "string" || !commands[0].startsWith("/")) {
commands = [];
}
relativeToUrlSegmentGroup = this.currentUrlTree.root;
}
return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, q, f ?? null);
}
/**
* Navigates to a view using an absolute route path.
*
* @param url An absolute path for a defined route. The function does not apply any delta to the
* current URL.
* @param extras An object containing properties that modify the navigation strategy.
*
* @returns A Promise that resolves to 'true' when navigation succeeds,
* to 'false' when navigation fails, or is rejected on error.
*
* @usageNotes
*
* The following calls request navigation to an absolute path.
*
* ```
* router.navigateByUrl("/team/33/user/11");
*
* // Navigate without updating the URL
* router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
* ```
*
* @see [Routing and Navigation guide](guide/router)
*
*/
navigateByUrl(url, extras = {
skipLocationChange: false
}) {
if (typeof ngDevMode === "undefined" || ngDevMode) {
if (this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
this.console.warn(`Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
}
}
const urlTree = isUrlTree(url) ? url : this.parseUrl(url);
const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
return this.scheduleNavigation(mergedTree, IMPERATIVE_NAVIGATION, null, extras);
}
/**
* Navigate based on the provided array of commands and a starting point.
* If no starting route is provided, the navigation is absolute.
*
* @param commands An array of URL fragments with which to construct the target URL.
* If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
* segments, followed by the parameters for each segment.
* The fragments are applied to the current URL or the one provided in the `relativeTo` property
* of the options object, if supplied.
* @param extras An options object that determines how the URL should be constructed or
* interpreted.
*
* @returns A Promise that resolves to `true` when navigation succeeds, to `false` when navigation
* fails,
* or is rejected on error.
*
* @usageNotes
*
* The following calls request navigation to a dynamic route path relative to the current URL.
*
* ```
* router.navigate(['team', 33, 'user', 11], {relativeTo: route});
*
* // Navigate without updating the URL, overriding the default behavior
* router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
* ```
*
* @see [Routing and Navigation guide](guide/router)
*
*/
navigate(commands, extras = {
skipLocationChange: false
}) {
validateCommands(commands);
return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
}
/** Serializes a `UrlTree` into a string */
serializeUrl(url) {
return this.urlSerializer.serialize(url);
}
/** Parses a string into a `UrlTree` */
parseUrl(url) {
try {
return this.urlSerializer.parse(url);
} catch {
return this.urlSerializer.parse("/");
}
}
isActive(url, matchOptions) {
let options;
if (matchOptions === true) {
options = __spreadValues({}, exactMatchOptions);
} else if (matchOptions === false) {
options = __spreadValues({}, subsetMatchOptions);
} else {
options = matchOptions;
}
if (isUrlTree(url)) {
return containsTree(this.currentUrlTree, url, options);
}
const urlTree = this.parseUrl(url);
return containsTree(this.currentUrlTree, urlTree, options);
}
removeEmptyProps(params) {
return Object.keys(params).reduce((result, key) => {
const value = params[key];
if (value !== null && value !== void 0) {
result[key] = value;
}
return result;
}, {});
}
scheduleNavigation(rawUrl, source, restoredState, extras, priorPromise) {
if (this.disposed) {
return Promise.resolve(false);
}
let resolve;
let reject;
let promise;
if (priorPromise) {
resolve = priorPromise.resolve;
reject = priorPromise.reject;
promise = priorPromise.promise;
} else {
promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
}
const taskId = this.pendingTasks.add();
afterNextNavigation(this, () => {
queueMicrotask(() => this.pendingTasks.remove(taskId));
});
this.navigationTransitions.handleNavigationRequest({
source,
restoredState,
currentUrlTree: this.currentUrlTree,
currentRawUrl: this.currentUrlTree,
rawUrl,
extras,
resolve,
reject,
promise,
currentSnapshot: this.routerState.snapshot,
currentRouterState: this.routerState
});
return promise.catch((e) => {
return Promise.reject(e);
});
}
};
_Router.ɵfac = function Router_Factory(t) {
return new (t || _Router)();
};
_Router.ɵprov = ɵɵdefineInjectable({
token: _Router,
factory: _Router.ɵfac,
providedIn: "root"
});
var Router = _Router;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Router, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], () => [], null);
})();
function validateCommands(commands) {
for (let i = 0; i < commands.length; i++) {
const cmd = commands[i];
if (cmd == null) {
throw new RuntimeError(4008, (typeof ngDevMode === "undefined" || ngDevMode) && `The requested path contains ${cmd} segment at index ${i}`);
}
}
}
function isPublicRouterEvent(e) {
return !(e instanceof BeforeActivateRoutes) && !(e instanceof RedirectRequest);
}
var _RouterLink = class _RouterLink {
constructor(router, route, tabIndexAttribute, renderer, el, locationStrategy) {
this.router = router;
this.route = route;
this.tabIndexAttribute = tabIndexAttribute;
this.renderer = renderer;
this.el = el;
this.locationStrategy = locationStrategy;
this.href = null;
this.commands = null;
this.onChanges = new Subject();
this.preserveFragment = false;
this.skipLocationChange = false;
this.replaceUrl = false;
const tagName = el.nativeElement.tagName?.toLowerCase();
this.isAnchorElement = tagName === "a" || tagName === "area";
if (this.isAnchorElement) {
this.subscription = router.events.subscribe((s) => {
if (s instanceof NavigationEnd) {
this.updateHref();
}
});
} else {
this.setTabIndexIfNotOnNativeEl("0");
}
}
/**
* Modifies the tab index if there was not a tabindex attribute on the element during
* instantiation.
*/
setTabIndexIfNotOnNativeEl(newTabIndex) {
if (this.tabIndexAttribute != null || this.isAnchorElement) {
return;
}
this.applyAttributeValue("tabindex", newTabIndex);
}
/** @nodoc */
ngOnChanges(changes) {
if (this.isAnchorElement) {
this.updateHref();
}
this.onChanges.next(this);
}
/**
* Commands to pass to {@link Router#createUrlTree}.
* - **array**: commands to pass to {@link Router#createUrlTree}.
* - **string**: shorthand for array of commands with just the string, i.e. `['/route']`
* - **null|undefined**: effectively disables the `routerLink`
* @see {@link Router#createUrlTree}
*/
set routerLink(commands) {
if (commands != null) {
this.commands = Array.isArray(commands) ? commands : [commands];
this.setTabIndexIfNotOnNativeEl("0");
} else {
this.commands = null;
this.setTabIndexIfNotOnNativeEl(null);
}
}
/** @nodoc */
onClick(button, ctrlKey, shiftKey, altKey, metaKey) {
if (this.urlTree === null) {
return true;
}
if (this.isAnchorElement) {
if (button !== 0 || ctrlKey || shiftKey || altKey || metaKey) {
return true;
}
if (typeof this.target === "string" && this.target != "_self") {
return true;
}
}
const extras = {
skipLocationChange: this.skipLocationChange,
replaceUrl: this.replaceUrl,
state: this.state
};
this.router.navigateByUrl(this.urlTree, extras);
return !this.isAnchorElement;
}
/** @nodoc */
ngOnDestroy() {
this.subscription?.unsubscribe();
}
updateHref() {
this.href = this.urlTree !== null && this.locationStrategy ? this.locationStrategy?.prepareExternalUrl(this.router.serializeUrl(this.urlTree)) : null;
const sanitizedValue = this.href === null ? null : (
// This class represents a directive that can be added to both `<a>` elements,
// as well as other elements. As a result, we can't define security context at
// compile time. So the security context is deferred to runtime.
// The `ɵɵsanitizeUrlOrResourceUrl` selects the necessary sanitizer function
// based on the tag and property names. The logic mimics the one from
// `packages/compiler/src/schema/dom_security_schema.ts`, which is used at compile time.
//
// Note: we should investigate whether we can switch to using `@HostBinding('attr.href')`
// instead of applying a value via a renderer, after a final merge of the
// `RouterLinkWithHref` directive.
ɵɵsanitizeUrlOrResourceUrl(this.href, this.el.nativeElement.tagName.toLowerCase(), "href")
);
this.applyAttributeValue("href", sanitizedValue);
}
applyAttributeValue(attrName, attrValue) {
const renderer = this.renderer;
const nativeElement = this.el.nativeElement;
if (attrValue !== null) {
renderer.setAttribute(nativeElement, attrName, attrValue);
} else {
renderer.removeAttribute(nativeElement, attrName);
}
}
get urlTree() {
if (this.commands === null) {
return null;
}
return this.router.createUrlTree(this.commands, {
// If the `relativeTo` input is not defined, we want to use `this.route` by default.
// Otherwise, we should use the value provided by the user in the input.
relativeTo: this.relativeTo !== void 0 ? this.relativeTo : this.route,
queryParams: this.queryParams,
fragment: this.fragment,
queryParamsHandling: this.queryParamsHandling,
preserveFragment: this.preserveFragment
});
}
};
_RouterLink.ɵfac = function RouterLink_Factory(t) {
return new (t || _RouterLink)(ɵɵdirectiveInject(Router), ɵɵdirectiveInject(ActivatedRoute), ɵɵinjectAttribute("tabindex"), ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(ElementRef), ɵɵdirectiveInject(LocationStrategy));
};
_RouterLink.ɵdir = ɵɵdefineDirective({
type: _RouterLink,
selectors: [["", "routerLink", ""]],
hostVars: 1,
hostBindings: function RouterLink_HostBindings(rf, ctx) {
if (rf & 1) {
ɵɵlistener("click", function RouterLink_click_HostBindingHandler($event) {
return ctx.onClick($event.button, $event.ctrlKey, $event.shiftKey, $event.altKey, $event.metaKey);
});
}
if (rf & 2) {
ɵɵattribute("target", ctx.target);
}
},
inputs: {
target: "target",
queryParams: "queryParams",
fragment: "fragment",
queryParamsHandling: "queryParamsHandling",
state: "state",
relativeTo: "relativeTo",
preserveFragment: ["preserveFragment", "preserveFragment", booleanAttribute],
skipLocationChange: ["skipLocationChange", "skipLocationChange", booleanAttribute],
replaceUrl: ["replaceUrl", "replaceUrl", booleanAttribute],
routerLink: "routerLink"
},
standalone: true,
features: [ɵɵInputTransformsFeature, ɵɵNgOnChangesFeature]
});
var RouterLink = _RouterLink;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouterLink, [{
type: Directive,
args: [{
selector: "[routerLink]",
standalone: true
}]
}], () => [{
type: Router
}, {
type: ActivatedRoute
}, {
type: void 0,
decorators: [{
type: Attribute,
args: ["tabindex"]
}]
}, {
type: Renderer2
}, {
type: ElementRef
}, {
type: LocationStrategy
}], {
target: [{
type: HostBinding,
args: ["attr.target"]
}, {
type: Input
}],
queryParams: [{
type: Input
}],
fragment: [{
type: Input
}],
queryParamsHandling: [{
type: Input
}],
state: [{
type: Input
}],
relativeTo: [{
type: Input
}],
preserveFragment: [{
type: Input,
args: [{
transform: booleanAttribute
}]
}],
skipLocationChange: [{
type: Input,
args: [{
transform: booleanAttribute
}]
}],
replaceUrl: [{
type: Input,
args: [{
transform: booleanAttribute
}]
}],
routerLink: [{
type: Input
}],
onClick: [{
type: HostListener,
args: ["click", ["$event.button", "$event.ctrlKey", "$event.shiftKey", "$event.altKey", "$event.metaKey"]]
}]
});
})();
var _RouterLinkActive = class _RouterLinkActive {
get isActive() {
return this._isActive;
}
constructor(router, element, renderer, cdr, link) {
this.router = router;
this.element = element;
this.renderer = renderer;
this.cdr = cdr;
this.link = link;
this.classes = [];
this._isActive = false;
this.routerLinkActiveOptions = {
exact: false
};
this.isActiveChange = new EventEmitter();
this.routerEventsSubscription = router.events.subscribe((s) => {
if (s instanceof NavigationEnd) {
this.update();
}
});
}
/** @nodoc */
ngAfterContentInit() {
of(this.links.changes, of(null)).pipe(mergeAll()).subscribe((_) => {
this.update();
this.subscribeToEachLinkOnChanges();
});
}
subscribeToEachLinkOnChanges() {
this.linkInputChangesSubscription?.unsubscribe();
const allLinkChanges = [...this.links.toArray(), this.link].filter((link) => !!link).map((link) => link.onChanges);
this.linkInputChangesSubscription = from(allLinkChanges).pipe(mergeAll()).subscribe((link) => {
if (this._isActive !== this.isLinkActive(this.router)(link)) {
this.update();
}
});
}
set routerLinkActive(data) {
const classes = Array.isArray(data) ? data : data.split(" ");
this.classes = classes.filter((c) => !!c);
}
/** @nodoc */
ngOnChanges(changes) {
this.update();
}
/** @nodoc */
ngOnDestroy() {
this.routerEventsSubscription.unsubscribe();
this.linkInputChangesSubscription?.unsubscribe();
}
update() {
if (!this.links || !this.router.navigated)
return;
queueMicrotask(() => {
const hasActiveLinks = this.hasActiveLinks();
if (this._isActive !== hasActiveLinks) {
this._isActive = hasActiveLinks;
this.cdr.markForCheck();
this.classes.forEach((c) => {
if (hasActiveLinks) {
this.renderer.addClass(this.element.nativeElement, c);
} else {
this.renderer.removeClass(this.element.nativeElement, c);
}
});
if (hasActiveLinks && this.ariaCurrentWhenActive !== void 0) {
this.renderer.setAttribute(this.element.nativeElement, "aria-current", this.ariaCurrentWhenActive.toString());
} else {
this.renderer.removeAttribute(this.element.nativeElement, "aria-current");
}
this.isActiveChange.emit(hasActiveLinks);
}
});
}
isLinkActive(router) {
const options = isActiveMatchOptions(this.routerLinkActiveOptions) ? this.routerLinkActiveOptions : (
// While the types should disallow `undefined` here, it's possible without strict inputs
this.routerLinkActiveOptions.exact || false
);
return (link) => link.urlTree ? router.isActive(link.urlTree, options) : false;
}
hasActiveLinks() {
const isActiveCheckFn = this.isLinkActive(this.router);
return this.link && isActiveCheckFn(this.link) || this.links.some(isActiveCheckFn);
}
};
_RouterLinkActive.ɵfac = function RouterLinkActive_Factory(t) {
return new (t || _RouterLinkActive)(ɵɵdirectiveInject(Router), ɵɵdirectiveInject(ElementRef), ɵɵdirectiveInject(Renderer2), ɵɵdirectiveInject(ChangeDetectorRef), ɵɵdirectiveInject(RouterLink, 8));
};
_RouterLinkActive.ɵdir = ɵɵdefineDirective({
type: _RouterLinkActive,
selectors: [["", "routerLinkActive", ""]],
contentQueries: function RouterLinkActive_ContentQueries(rf, ctx, dirIndex) {
if (rf & 1) {
ɵɵcontentQuery(dirIndex, RouterLink, 5);
}
if (rf & 2) {
let _t;
ɵɵqueryRefresh(_t = ɵɵloadQuery()) && (ctx.links = _t);
}
},
inputs: {
routerLinkActiveOptions: "routerLinkActiveOptions",
ariaCurrentWhenActive: "ariaCurrentWhenActive",
routerLinkActive: "routerLinkActive"
},
outputs: {
isActiveChange: "isActiveChange"
},
exportAs: ["routerLinkActive"],
standalone: true,
features: [ɵɵNgOnChangesFeature]
});
var RouterLinkActive = _RouterLinkActive;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouterLinkActive, [{
type: Directive,
args: [{
selector: "[routerLinkActive]",
exportAs: "routerLinkActive",
standalone: true
}]
}], () => [{
type: Router
}, {
type: ElementRef
}, {
type: Renderer2
}, {
type: ChangeDetectorRef
}, {
type: RouterLink,
decorators: [{
type: Optional
}]
}], {
links: [{
type: ContentChildren,
args: [RouterLink, {
descendants: true
}]
}],
routerLinkActiveOptions: [{
type: Input
}],
ariaCurrentWhenActive: [{
type: Input
}],
isActiveChange: [{
type: Output
}],
routerLinkActive: [{
type: Input
}]
});
})();
function isActiveMatchOptions(options) {
return !!options.paths;
}
var PreloadingStrategy = class {
};
var _PreloadAllModules = class _PreloadAllModules {
preload(route, fn) {
return fn().pipe(catchError(() => of(null)));
}
};
_PreloadAllModules.ɵfac = function PreloadAllModules_Factory(t) {
return new (t || _PreloadAllModules)();
};
_PreloadAllModules.ɵprov = ɵɵdefineInjectable({
token: _PreloadAllModules,
factory: _PreloadAllModules.ɵfac,
providedIn: "root"
});
var PreloadAllModules = _PreloadAllModules;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PreloadAllModules, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], null, null);
})();
var _NoPreloading = class _NoPreloading {
preload(route, fn) {
return of(null);
}
};
_NoPreloading.ɵfac = function NoPreloading_Factory(t) {
return new (t || _NoPreloading)();
};
_NoPreloading.ɵprov = ɵɵdefineInjectable({
token: _NoPreloading,
factory: _NoPreloading.ɵfac,
providedIn: "root"
});
var NoPreloading = _NoPreloading;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NoPreloading, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], null, null);
})();
var _RouterPreloader = class _RouterPreloader {
constructor(router, compiler, injector, preloadingStrategy, loader) {
this.router = router;
this.injector = injector;
this.preloadingStrategy = preloadingStrategy;
this.loader = loader;
}
setUpPreloading() {
this.subscription = this.router.events.pipe(filter((e) => e instanceof NavigationEnd), concatMap(() => this.preload())).subscribe(() => {
});
}
preload() {
return this.processRoutes(this.injector, this.router.config);
}
/** @nodoc */
ngOnDestroy() {
if (this.subscription) {
this.subscription.unsubscribe();
}
}
processRoutes(injector, routes) {
const res = [];
for (const route of routes) {
if (route.providers && !route._injector) {
route._injector = createEnvironmentInjector(route.providers, injector, `Route: ${route.path}`);
}
const injectorForCurrentRoute = route._injector ?? injector;
const injectorForChildren = route._loadedInjector ?? injectorForCurrentRoute;
if (route.loadChildren && !route._loadedRoutes && route.canLoad === void 0 || route.loadComponent && !route._loadedComponent) {
res.push(this.preloadConfig(injectorForCurrentRoute, route));
}
if (route.children || route._loadedRoutes) {
res.push(this.processRoutes(injectorForChildren, route.children ?? route._loadedRoutes));
}
}
return from(res).pipe(mergeAll());
}
preloadConfig(injector, route) {
return this.preloadingStrategy.preload(route, () => {
let loadedChildren$;
if (route.loadChildren && route.canLoad === void 0) {
loadedChildren$ = this.loader.loadChildren(injector, route);
} else {
loadedChildren$ = of(null);
}
const recursiveLoadChildren$ = loadedChildren$.pipe(mergeMap((config) => {
if (config === null) {
return of(void 0);
}
route._loadedRoutes = config.routes;
route._loadedInjector = config.injector;
return this.processRoutes(config.injector ?? injector, config.routes);
}));
if (route.loadComponent && !route._loadedComponent) {
const loadComponent$ = this.loader.loadComponent(route);
return from([recursiveLoadChildren$, loadComponent$]).pipe(mergeAll());
} else {
return recursiveLoadChildren$;
}
});
}
};
_RouterPreloader.ɵfac = function RouterPreloader_Factory(t) {
return new (t || _RouterPreloader)(ɵɵinject(Router), ɵɵinject(Compiler), ɵɵinject(EnvironmentInjector), ɵɵinject(PreloadingStrategy), ɵɵinject(RouterConfigLoader));
};
_RouterPreloader.ɵprov = ɵɵdefineInjectable({
token: _RouterPreloader,
factory: _RouterPreloader.ɵfac,
providedIn: "root"
});
var RouterPreloader = _RouterPreloader;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouterPreloader, [{
type: Injectable,
args: [{
providedIn: "root"
}]
}], () => [{
type: Router
}, {
type: Compiler
}, {
type: EnvironmentInjector
}, {
type: PreloadingStrategy
}, {
type: RouterConfigLoader
}], null);
})();
var ROUTER_SCROLLER = new InjectionToken("");
var _RouterScroller = class _RouterScroller {
/** @nodoc */
constructor(urlSerializer, transitions, viewportScroller, zone, options = {}) {
this.urlSerializer = urlSerializer;
this.transitions = transitions;
this.viewportScroller = viewportScroller;
this.zone = zone;
this.options = options;
this.lastId = 0;
this.lastSource = "imperative";
this.restoredId = 0;
this.store = {};
options.scrollPositionRestoration = options.scrollPositionRestoration || "disabled";
options.anchorScrolling = options.anchorScrolling || "disabled";
}
init() {
if (this.options.scrollPositionRestoration !== "disabled") {
this.viewportScroller.setHistoryScrollRestoration("manual");
}
this.routerEventsSubscription = this.createScrollEvents();
this.scrollEventsSubscription = this.consumeScrollEvents();
}
createScrollEvents() {
return this.transitions.events.subscribe((e) => {
if (e instanceof NavigationStart) {
this.store[this.lastId] = this.viewportScroller.getScrollPosition();
this.lastSource = e.navigationTrigger;
this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
} else if (e instanceof NavigationEnd) {
this.lastId = e.id;
this.scheduleScrollEvent(e, this.urlSerializer.parse(e.urlAfterRedirects).fragment);
} else if (e instanceof NavigationSkipped && e.code === 0) {
this.lastSource = void 0;
this.restoredId = 0;
this.scheduleScrollEvent(e, this.urlSerializer.parse(e.url).fragment);
}
});
}
consumeScrollEvents() {
return this.transitions.events.subscribe((e) => {
if (!(e instanceof Scroll))
return;
if (e.position) {
if (this.options.scrollPositionRestoration === "top") {
this.viewportScroller.scrollToPosition([0, 0]);
} else if (this.options.scrollPositionRestoration === "enabled") {
this.viewportScroller.scrollToPosition(e.position);
}
} else {
if (e.anchor && this.options.anchorScrolling === "enabled") {
this.viewportScroller.scrollToAnchor(e.anchor);
} else if (this.options.scrollPositionRestoration !== "disabled") {
this.viewportScroller.scrollToPosition([0, 0]);
}
}
});
}
scheduleScrollEvent(routerEvent, anchor) {
this.zone.runOutsideAngular(() => {
setTimeout(() => {
this.zone.run(() => {
this.transitions.events.next(new Scroll(routerEvent, this.lastSource === "popstate" ? this.store[this.restoredId] : null, anchor));
});
}, 0);
});
}
/** @nodoc */
ngOnDestroy() {
this.routerEventsSubscription?.unsubscribe();
this.scrollEventsSubscription?.unsubscribe();
}
};
_RouterScroller.ɵfac = function RouterScroller_Factory(t) {
ɵɵinvalidFactory();
};
_RouterScroller.ɵprov = ɵɵdefineInjectable({
token: _RouterScroller,
factory: _RouterScroller.ɵfac
});
var RouterScroller = _RouterScroller;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouterScroller, [{
type: Injectable
}], () => [{
type: UrlSerializer
}, {
type: NavigationTransitions
}, {
type: ViewportScroller
}, {
type: NgZone
}, {
type: void 0
}], null);
})();
function provideRouter(routes, ...features) {
return makeEnvironmentProviders([{
provide: ROUTES,
multi: true,
useValue: routes
}, typeof ngDevMode === "undefined" || ngDevMode ? {
provide: ROUTER_IS_PROVIDED,
useValue: true
} : [], {
provide: ActivatedRoute,
useFactory: rootRoute,
deps: [Router]
}, {
provide: APP_BOOTSTRAP_LISTENER,
multi: true,
useFactory: getBootstrapListener
}, features.map((feature) => feature.ɵproviders)]);
}
function rootRoute(router) {
return router.routerState.root;
}
function routerFeature(kind, providers) {
return {
ɵkind: kind,
ɵproviders: providers
};
}
var ROUTER_IS_PROVIDED = new InjectionToken("", {
providedIn: "root",
factory: () => false
});
var routerIsProvidedDevModeCheck = {
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useFactory() {
return () => {
if (!inject(ROUTER_IS_PROVIDED)) {
console.warn("`provideRoutes` was called without `provideRouter` or `RouterModule.forRoot`. This is likely a mistake.");
}
};
}
};
function provideRoutes(routes) {
return [{
provide: ROUTES,
multi: true,
useValue: routes
}, typeof ngDevMode === "undefined" || ngDevMode ? routerIsProvidedDevModeCheck : []];
}
function withInMemoryScrolling(options = {}) {
const providers = [{
provide: ROUTER_SCROLLER,
useFactory: () => {
const viewportScroller = inject(ViewportScroller);
const zone = inject(NgZone);
const transitions = inject(NavigationTransitions);
const urlSerializer = inject(UrlSerializer);
return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, options);
}
}];
return routerFeature(4, providers);
}
function getBootstrapListener() {
const injector = inject(Injector);
return (bootstrappedComponentRef) => {
const ref = injector.get(ApplicationRef);
if (bootstrappedComponentRef !== ref.components[0]) {
return;
}
const router = injector.get(Router);
const bootstrapDone = injector.get(BOOTSTRAP_DONE);
if (injector.get(INITIAL_NAVIGATION) === 1) {
router.initialNavigation();
}
injector.get(ROUTER_PRELOADER, null, InjectFlags.Optional)?.setUpPreloading();
injector.get(ROUTER_SCROLLER, null, InjectFlags.Optional)?.init();
router.resetRootComponentType(ref.componentTypes[0]);
if (!bootstrapDone.closed) {
bootstrapDone.next();
bootstrapDone.complete();
bootstrapDone.unsubscribe();
}
};
}
var BOOTSTRAP_DONE = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "bootstrap done indicator" : "", {
factory: () => {
return new Subject();
}
});
var INITIAL_NAVIGATION = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "initial navigation" : "", {
providedIn: "root",
factory: () => 1
/* InitialNavigation.EnabledNonBlocking */
});
function withEnabledBlockingInitialNavigation() {
const providers = [{
provide: INITIAL_NAVIGATION,
useValue: 0
/* InitialNavigation.EnabledBlocking */
}, {
provide: APP_INITIALIZER,
multi: true,
deps: [Injector],
useFactory: (injector) => {
const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve());
return () => {
return locationInitialized.then(() => {
return new Promise((resolve) => {
const router = injector.get(Router);
const bootstrapDone = injector.get(BOOTSTRAP_DONE);
afterNextNavigation(router, () => {
resolve(true);
});
injector.get(NavigationTransitions).afterPreactivation = () => {
resolve(true);
return bootstrapDone.closed ? of(void 0) : bootstrapDone;
};
router.initialNavigation();
});
});
};
}
}];
return routerFeature(2, providers);
}
function withDisabledInitialNavigation() {
const providers = [{
provide: APP_INITIALIZER,
multi: true,
useFactory: () => {
const router = inject(Router);
return () => {
router.setUpLocationChangeListener();
};
}
}, {
provide: INITIAL_NAVIGATION,
useValue: 2
/* InitialNavigation.Disabled */
}];
return routerFeature(3, providers);
}
function withDebugTracing() {
let providers = [];
if (typeof ngDevMode === "undefined" || ngDevMode) {
providers = [{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useFactory: () => {
const router = inject(Router);
return () => router.events.subscribe((e) => {
console.group?.(`Router Event: ${e.constructor.name}`);
console.log(stringifyEvent(e));
console.log(e);
console.groupEnd?.();
});
}
}];
} else {
providers = [];
}
return routerFeature(1, providers);
}
var ROUTER_PRELOADER = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "router preloader" : "");
function withPreloading(preloadingStrategy) {
const providers = [{
provide: ROUTER_PRELOADER,
useExisting: RouterPreloader
}, {
provide: PreloadingStrategy,
useExisting: preloadingStrategy
}];
return routerFeature(0, providers);
}
function withRouterConfig(options) {
const providers = [{
provide: ROUTER_CONFIGURATION,
useValue: options
}];
return routerFeature(5, providers);
}
function withHashLocation() {
const providers = [{
provide: LocationStrategy,
useClass: HashLocationStrategy
}];
return routerFeature(6, providers);
}
function withNavigationErrorHandler(fn) {
const providers = [{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useValue: () => {
const injector = inject(EnvironmentInjector);
inject(Router).events.subscribe((e) => {
if (e instanceof NavigationError) {
runInInjectionContext(injector, () => fn(e));
}
});
}
}];
return routerFeature(7, providers);
}
function withComponentInputBinding() {
const providers = [RoutedComponentInputBinder, {
provide: INPUT_BINDER,
useExisting: RoutedComponentInputBinder
}];
return routerFeature(8, providers);
}
function withViewTransitions(options) {
const providers = [{
provide: CREATE_VIEW_TRANSITION,
useValue: createViewTransition
}, {
provide: VIEW_TRANSITION_OPTIONS,
useValue: __spreadValues({
skipNextTransition: !!options?.skipInitialTransition
}, options)
}];
return routerFeature(9, providers);
}
var ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent];
var ROUTER_FORROOT_GUARD = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "router duplicate forRoot guard" : "ROUTER_FORROOT_GUARD");
var ROUTER_PROVIDERS = [
Location,
{
provide: UrlSerializer,
useClass: DefaultUrlSerializer
},
Router,
ChildrenOutletContexts,
{
provide: ActivatedRoute,
useFactory: rootRoute,
deps: [Router]
},
RouterConfigLoader,
// Only used to warn when `provideRoutes` is used without `RouterModule` or `provideRouter`. Can
// be removed when `provideRoutes` is removed.
typeof ngDevMode === "undefined" || ngDevMode ? {
provide: ROUTER_IS_PROVIDED,
useValue: true
} : []
];
var _RouterModule = class _RouterModule {
constructor(guard) {
}
/**
* Creates and configures a module with all the router providers and directives.
* Optionally sets up an application listener to perform an initial navigation.
*
* When registering the NgModule at the root, import as follows:
*
* ```
* @NgModule({
* imports: [RouterModule.forRoot(ROUTES)]
* })
* class MyNgModule {}
* ```
*
* @param routes An array of `Route` objects that define the navigation paths for the application.
* @param config An `ExtraOptions` configuration object that controls how navigation is performed.
* @return The new `NgModule`.
*
*/
static forRoot(routes, config) {
return {
ngModule: _RouterModule,
providers: [ROUTER_PROVIDERS, typeof ngDevMode === "undefined" || ngDevMode ? config?.enableTracing ? withDebugTracing().ɵproviders : [] : [], {
provide: ROUTES,
multi: true,
useValue: routes
}, {
provide: ROUTER_FORROOT_GUARD,
useFactory: provideForRootGuard,
deps: [[Router, new Optional(), new SkipSelf()]]
}, {
provide: ROUTER_CONFIGURATION,
useValue: config ? config : {}
}, config?.useHash ? provideHashLocationStrategy() : providePathLocationStrategy(), provideRouterScroller(), config?.preloadingStrategy ? withPreloading(config.preloadingStrategy).ɵproviders : [], config?.initialNavigation ? provideInitialNavigation(config) : [], config?.bindToComponentInputs ? withComponentInputBinding().ɵproviders : [], config?.enableViewTransitions ? withViewTransitions().ɵproviders : [], provideRouterInitializer()]
};
}
/**
* Creates a module with all the router directives and a provider registering routes,
* without creating a new Router service.
* When registering for submodules and lazy-loaded submodules, create the NgModule as follows:
*
* ```
* @NgModule({
* imports: [RouterModule.forChild(ROUTES)]
* })
* class MyNgModule {}
* ```
*
* @param routes An array of `Route` objects that define the navigation paths for the submodule.
* @return The new NgModule.
*
*/
static forChild(routes) {
return {
ngModule: _RouterModule,
providers: [{
provide: ROUTES,
multi: true,
useValue: routes
}]
};
}
};
_RouterModule.ɵfac = function RouterModule_Factory(t) {
return new (t || _RouterModule)(ɵɵinject(ROUTER_FORROOT_GUARD, 8));
};
_RouterModule.ɵmod = ɵɵdefineNgModule({
type: _RouterModule,
imports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent],
exports: [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent]
});
_RouterModule.ɵinj = ɵɵdefineInjector({});
var RouterModule = _RouterModule;
(() => {
(typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(RouterModule, [{
type: NgModule,
args: [{
imports: ROUTER_DIRECTIVES,
exports: ROUTER_DIRECTIVES
}]
}], () => [{
type: void 0,
decorators: [{
type: Optional
}, {
type: Inject,
args: [ROUTER_FORROOT_GUARD]
}]
}], null);
})();
function provideRouterScroller() {
return {
provide: ROUTER_SCROLLER,
useFactory: () => {
const viewportScroller = inject(ViewportScroller);
const zone = inject(NgZone);
const config = inject(ROUTER_CONFIGURATION);
const transitions = inject(NavigationTransitions);
const urlSerializer = inject(UrlSerializer);
if (config.scrollOffset) {
viewportScroller.setOffset(config.scrollOffset);
}
return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, config);
}
};
}
function provideHashLocationStrategy() {
return {
provide: LocationStrategy,
useClass: HashLocationStrategy
};
}
function providePathLocationStrategy() {
return {
provide: LocationStrategy,
useClass: PathLocationStrategy
};
}
function provideForRootGuard(router) {
if ((typeof ngDevMode === "undefined" || ngDevMode) && router) {
throw new RuntimeError(4007, `The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector. Lazy loaded modules should use RouterModule.forChild() instead.`);
}
return "guarded";
}
function provideInitialNavigation(config) {
return [config.initialNavigation === "disabled" ? withDisabledInitialNavigation().ɵproviders : [], config.initialNavigation === "enabledBlocking" ? withEnabledBlockingInitialNavigation().ɵproviders : []];
}
var ROUTER_INITIALIZER = new InjectionToken(typeof ngDevMode === "undefined" || ngDevMode ? "Router Initializer" : "");
function provideRouterInitializer() {
return [
// ROUTER_INITIALIZER token should be removed. It's public API but shouldn't be. We can just
// have `getBootstrapListener` directly attached to APP_BOOTSTRAP_LISTENER.
{
provide: ROUTER_INITIALIZER,
useFactory: getBootstrapListener
},
{
provide: APP_BOOTSTRAP_LISTENER,
multi: true,
useExisting: ROUTER_INITIALIZER
}
];
}
function mapToCanMatch(providers) {
return providers.map((provider) => (...params) => inject(provider).canMatch(...params));
}
function mapToCanActivate(providers) {
return providers.map((provider) => (...params) => inject(provider).canActivate(...params));
}
function mapToCanActivateChild(providers) {
return providers.map((provider) => (...params) => inject(provider).canActivateChild(...params));
}
function mapToCanDeactivate(providers) {
return providers.map((provider) => (...params) => inject(provider).canDeactivate(...params));
}
function mapToResolve(provider) {
return (...params) => inject(provider).resolve(...params);
}
var VERSION = new Version("17.0.7");
export {
PRIMARY_OUTLET,
convertToParamMap,
defaultUrlMatcher,
UrlTree,
UrlSegmentGroup,
UrlSegment,
UrlSerializer,
DefaultUrlSerializer,
createUrlTreeFromSnapshot,
RouterEvent,
NavigationStart,
NavigationEnd,
NavigationCancel,
NavigationSkipped,
NavigationError,
RoutesRecognized,
GuardsCheckStart,
GuardsCheckEnd,
ResolveStart,
ResolveEnd,
RouteConfigLoadStart,
RouteConfigLoadEnd,
ChildActivationStart,
ChildActivationEnd,
ActivationStart,
ActivationEnd,
Scroll,
OutletContext,
ChildrenOutletContexts,
RouterState,
ActivatedRoute,
ActivatedRouteSnapshot,
RouterStateSnapshot,
RouterOutlet,
ɵEmptyOutletComponent,
TitleStrategy,
DefaultTitleStrategy,
ROUTER_CONFIGURATION,
ROUTES,
loadChildren,
UrlHandlingStrategy,
RouteReuseStrategy,
BaseRouteReuseStrategy,
afterNextNavigation,
Router,
RouterLink,
RouterLinkActive,
PreloadingStrategy,
PreloadAllModules,
NoPreloading,
RouterPreloader,
provideRouter,
provideRoutes,
withInMemoryScrolling,
withEnabledBlockingInitialNavigation,
withDisabledInitialNavigation,
withDebugTracing,
withPreloading,
withRouterConfig,
withHashLocation,
withNavigationErrorHandler,
withComponentInputBinding,
withViewTransitions,
ROUTER_PROVIDERS,
RouterModule,
ROUTER_INITIALIZER,
mapToCanMatch,
mapToCanActivate,
mapToCanActivateChild,
mapToCanDeactivate,
mapToResolve,
VERSION
};
/*! Bundled license information:
@angular/router/fesm2022/router.mjs:
(**
* @license Angular v17.0.7
* (c) 2010-2022 Google LLC. https://angular.io/
* License: MIT
*)
*/
//# sourceMappingURL=chunk-CZEXXPIB.js.map