{"version":3,"file":"router.js","names":[],"sources":["../../src/router.ts"],"sourcesContent":["import { createBrowserHistory, parseHref } from '@tanstack/history'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport {\n DEFAULT_PROTOCOL_ALLOWLIST,\n createControlledPromise,\n decodePath,\n deepEqual,\n encodePathLikeUrl,\n findLast,\n functionalUpdate,\n hasKeys,\n isDangerousProtocol,\n last,\n nullReplaceEqualDeep,\n replaceEqualDeep,\n} from './utils'\nimport {\n buildRouteBranch,\n findFlatMatch,\n findRouteMatch,\n findSingleMatch,\n processRouteMasks,\n processRouteTree,\n} from './new-process-route-tree'\nimport {\n cleanPath,\n compileDecodeCharMap,\n interpolatePath,\n resolvePath,\n trimPath,\n trimPathRight,\n} from './path'\nimport { createLRUCache } from './lru-cache'\nimport { isNotFound } from './not-found'\nimport { setupScrollRestoration } from './scroll-restoration'\nimport { defaultParseSearch, defaultStringifySearch } from './searchParams'\nimport { rootRouteId } from './root'\nimport { isRedirect, redirect } from './redirect'\nimport { loadMatches, loadRouteChunk, routeNeedsPreload } from './load-matches'\nimport {\n composeRewrites,\n executeRewriteInput,\n executeRewriteOutput,\n rewriteBasepath,\n} from './rewrite'\nimport { createRouterStores } from './stores'\nimport type { LRUCache } from './lru-cache'\nimport type {\n ProcessRouteTreeResult,\n ProcessedTree,\n} from './new-process-route-tree'\nimport type { SearchParser, SearchSerializer } from './searchParams'\nimport type { AnyRedirect, ResolvedRedirect } from './redirect'\nimport type {\n HistoryLocation,\n HistoryState,\n ParsedHistoryState,\n RouterHistory,\n} from '@tanstack/history'\n\nimport type {\n Awaitable,\n Constrain,\n ControlledPromise,\n NoInfer,\n NonNullableUpdater,\n PickAsRequired,\n Updater,\n} from './utils'\nimport type { ParsedLocation } from './location'\nimport type {\n AnyContext,\n AnyRoute,\n AnyRouteWithContext,\n LoaderStaleReloadMode,\n MakeRemountDepsOptionsUnion,\n RouteContextOptions,\n RouteLike,\n RouteMask,\n SearchMiddleware,\n} from './route'\nimport type {\n FullSearchSchema,\n RouteById,\n RoutePaths,\n RoutesById,\n RoutesByPath,\n} from './routeInfo'\nimport type {\n AnyRouteMatch,\n MakeRouteMatch,\n MakeRouteMatchUnion,\n MatchRouteOptions,\n} from './Matches'\nimport type {\n BuildLocationFn,\n CommitLocationOptions,\n NavigateFn,\n} from './RouterProvider'\nimport type { Manifest, RouterManagedTag } from './manifest'\nimport type { AnySchema, AnyValidator } from './validators'\nimport type { NavigateOptions, ResolveRelativePath, ToOptions } from './link'\nimport type { NotFoundError } from './not-found'\nimport type {\n AnySerializationAdapter,\n ValidateSerializableInput,\n} from './ssr/serializer/transformer'\nimport type { GetStoreConfig, RouterStores } from './stores'\n\nexport type ControllablePromise = Promise & {\n resolve: (value: T) => void\n reject: (value?: any) => void\n}\n\nexport type InjectedHtmlEntry = Promise\n\nexport interface Register {\n // Lots of things on here like...\n // router\n // config\n // ssr\n}\n\nexport type RegisteredSsr = TRegister extends {\n ssr: infer TSSR\n}\n ? TSSR\n : false\n\nexport type RegisteredRouter = TRegister extends {\n router: infer TRouter\n}\n ? TRouter\n : AnyRouter\n\nexport type RegisteredConfigType = TRegister extends {\n config: infer TConfig\n}\n ? TConfig extends {\n '~types': infer TTypes\n }\n ? TKey extends keyof TTypes\n ? TTypes[TKey]\n : unknown\n : unknown\n : unknown\n\nexport type DefaultRemountDepsFn = (\n opts: MakeRemountDepsOptionsUnion,\n) => any\n\nexport interface DefaultRouterOptionsExtensions {}\n\nexport interface RouterOptionsExtensions extends DefaultRouterOptionsExtensions {}\n\nexport type SSROption = boolean | 'data-only'\n\nexport interface RouterOptions<\n TRouteTree extends AnyRoute,\n TTrailingSlashOption extends TrailingSlashOption,\n TDefaultStructuralSharingOption extends boolean = false,\n TRouterHistory extends RouterHistory = RouterHistory,\n TDehydrated = undefined,\n> extends RouterOptionsExtensions {\n /**\n * The history object that will be used to manage the browser history.\n *\n * If not provided, a new createBrowserHistory instance will be created and used.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#history-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/history-types)\n */\n history?: TRouterHistory\n /**\n * A function that will be used to stringify search params when generating links.\n *\n * @default defaultStringifySearch\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#stringifysearch-method)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization)\n */\n stringifySearch?: SearchSerializer\n /**\n * A function that will be used to parse search params when parsing the current location.\n *\n * @default defaultParseSearch\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#parsesearch-method)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization)\n */\n parseSearch?: SearchParser\n /**\n * If `false`, routes will not be preloaded by default in any way.\n *\n * If `'intent'`, routes will be preloaded by default when the user hovers over a link or a `touchstart` event is detected on a ``.\n *\n * If `'viewport'`, routes will be preloaded by default when they are within the viewport.\n *\n * @default false\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreload-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading)\n */\n defaultPreload?: false | 'intent' | 'viewport' | 'render'\n /**\n * The delay in milliseconds that a route must be hovered over or touched before it is preloaded.\n *\n * @default 50\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreloaddelay-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading#preload-delay)\n */\n defaultPreloadDelay?: number\n /**\n * The default `preloadIntentProximity` a route should use if no preloadIntentProximity is provided.\n *\n * @default 0\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreloadintentproximity-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading#preload-intent-proximity)\n */\n defaultPreloadIntentProximity?: number\n /**\n * The default `pendingMs` a route should use if no pendingMs is provided.\n *\n * @default 1000\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpendingms-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#avoiding-pending-component-flash)\n */\n defaultPendingMs?: number\n /**\n * The default `pendingMinMs` a route should use if no pendingMinMs is provided.\n *\n * @default 500\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpendingminms-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#avoiding-pending-component-flash)\n */\n defaultPendingMinMs?: number\n /**\n * The default `staleTime` a route should use if no staleTime is provided. This is the time in milliseconds that a route will be considered fresh.\n *\n * @default 0\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultstaletime-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#key-options)\n */\n defaultStaleTime?: number\n /**\n * The default stale reload mode a route loader should use if no `loader.staleReloadMode` is provided.\n *\n * `'background'` preserves the current stale-while-revalidate behavior.\n * `'blocking'` waits for stale loader reloads to complete before resolving navigation.\n *\n * @default 'background'\n */\n defaultStaleReloadMode?: LoaderStaleReloadMode\n /**\n * The default `preloadStaleTime` a route should use if no preloadStaleTime is provided.\n *\n * @default 30_000 `(30 seconds)`\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreloadstaletime-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading)\n */\n defaultPreloadStaleTime?: number\n /**\n * The default `defaultPreloadGcTime` a route should use if no preloadGcTime is provided.\n *\n * @default 1_800_000 `(30 minutes)`\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreloadgctime-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading)\n */\n defaultPreloadGcTime?: number\n /**\n * If `true`, route navigations will called using `document.startViewTransition()`.\n *\n * If the browser does not support this api, this option will be ignored.\n *\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition) for more information on how this function works.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultviewtransition-property)\n */\n defaultViewTransition?: boolean | ViewTransitionOptions\n /**\n * The default `hashScrollIntoView` a route should use if no hashScrollIntoView is provided while navigating\n *\n * See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView) for more information on `ScrollIntoViewOptions`.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaulthashscrollintoview-property)\n */\n defaultHashScrollIntoView?: boolean | ScrollIntoViewOptions\n /**\n * @default 'fuzzy'\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#notfoundmode-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/not-found-errors#the-notfoundmode-option)\n */\n notFoundMode?: 'root' | 'fuzzy'\n /**\n * The default `gcTime` a route should use if no gcTime is provided.\n *\n * @default 1_800_000 `(30 minutes)`\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultgctime-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#key-options)\n */\n defaultGcTime?: number\n /**\n * If `true`, all routes will be matched as case-sensitive.\n *\n * @default false\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#casesensitive-property)\n */\n caseSensitive?: boolean\n /**\n *\n * The route tree that will be used to configure the router instance.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#routetree-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/routing/route-trees)\n */\n routeTree?: TRouteTree\n /**\n * The basepath for then entire router. This is useful for mounting a router instance at a subpath.\n * ```\n * @default '/'\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#basepath-property)\n */\n basepath?: string\n /**\n * The root context that will be provided to all routes in the route tree.\n *\n * This can be used to provide a context to all routes in the tree without having to provide it to each route individually.\n *\n * Optional or required if the root route was created with [`createRootRouteWithContext()`](https://tanstack.com/router/latest/docs/framework/react/api/router/createRootRouteWithContextFunction).\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#context-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/router-context)\n */\n context?: InferRouterContext\n\n additionalContext?: any\n\n /**\n * A function that will be called when the router is dehydrated.\n *\n * The return value of this function will be serialized and stored in the router's dehydrated state.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#dehydrate-method)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/external-data-loading#critical-dehydrationhydration)\n */\n dehydrate?: () => Constrain<\n TDehydrated,\n ValidateSerializableInput\n >\n /**\n * A function that will be called when the router is hydrated.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#hydrate-method)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/external-data-loading#critical-dehydrationhydration)\n */\n hydrate?: (dehydrated: TDehydrated) => Awaitable\n /**\n * An array of route masks that will be used to mask routes in the route tree.\n *\n * Route masking is when you display a route at a different path than the one it is configured to match, like a modal popup that when shared will unmask to the modal's content instead of the modal's context.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#routemasks-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/route-masking)\n */\n routeMasks?: Array>\n /**\n * If `true`, route masks will, by default, be removed when the page is reloaded.\n *\n * This can be overridden on a per-mask basis by setting the `unmaskOnReload` option on the mask, or on a per-navigation basis by setting the `unmaskOnReload` option in the `Navigate` options.\n *\n * @default false\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#unmaskonreload-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/route-masking#unmasking-on-page-reload)\n */\n unmaskOnReload?: boolean\n\n /**\n * Use `notFoundComponent` instead.\n *\n * @deprecated\n * See https://tanstack.com/router/v1/docs/guide/not-found-errors#migrating-from-notfoundroute for more info.\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#notfoundroute-property)\n */\n notFoundRoute?: AnyRoute\n /**\n * Configures how trailing slashes are treated.\n *\n * - `'always'` will add a trailing slash if not present\n * - `'never'` will remove the trailing slash if present\n * - `'preserve'` will not modify the trailing slash.\n *\n * @default 'never'\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#trailingslash-property)\n */\n trailingSlash?: TTrailingSlashOption\n /**\n * While usually automatic, sometimes it can be useful to force the router into a server-side state, e.g. when using the router in a non-browser environment that has access to a global.document object.\n *\n * @default typeof document !== 'undefined'\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#isserver-property)\n */\n isServer?: boolean\n\n /**\n * @default false\n */\n isShell?: boolean\n\n /**\n * @default false\n */\n isPrerendering?: boolean\n\n /**\n * The default `ssr` a route should use if no `ssr` is provided.\n *\n * @default true\n */\n defaultSsr?: SSROption\n\n search?: {\n /**\n * Configures how unknown search params (= not returned by any `validateSearch`) are treated.\n *\n * @default false\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#search.strict-property)\n */\n strict?: boolean\n }\n\n /**\n * Configures whether structural sharing is enabled by default for fine-grained selectors.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultstructuralsharing-property)\n */\n defaultStructuralSharing?: TDefaultStructuralSharingOption\n\n /**\n * Configures which URI characters are allowed in path params that would ordinarily be escaped by encodeURIComponent.\n *\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#pathparamsallowedcharacters-property)\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/path-params#allowed-characters)\n */\n pathParamsAllowedCharacters?: Array<\n ';' | ':' | '@' | '&' | '=' | '+' | '$' | ','\n >\n\n defaultRemountDeps?: DefaultRemountDepsFn\n\n /**\n * If `true`, scroll restoration will be enabled\n *\n * @default false\n */\n scrollRestoration?:\n | boolean\n | ((opts: { location: ParsedLocation }) => boolean)\n\n /**\n * A function that will be called to get the key for the scroll restoration cache.\n *\n * @default (location) => location.href\n */\n getScrollRestorationKey?: (location: ParsedLocation) => string\n /**\n * The default behavior for scroll restoration.\n *\n * @default 'auto'\n */\n scrollRestorationBehavior?: ScrollBehavior\n /**\n * An array of selectors that will be used to scroll to the top of the page in addition to `window`\n *\n * @default ['window']\n */\n scrollToTopSelectors?: Array Element | null | undefined)>\n\n /**\n * When `true`, disables the global catch boundary that normally wraps all route matches.\n * This allows unhandled errors to bubble up to top-level error handlers in the browser.\n *\n * Useful for testing tools (like Storybook Test Runner), error reporting services,\n * and debugging scenarios where you want errors to reach the browser's global error handlers.\n *\n * @default false\n */\n disableGlobalCatchBoundary?: boolean\n\n /**\n * An array of URL protocols to allow in links, redirects, and navigation.\n * Absolute URLs with protocols not in this list will be rejected.\n *\n * @default DEFAULT_PROTOCOL_ALLOWLIST (http:, https:, mailto:, tel:)\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#protocolallowlist-property)\n */\n protocolAllowlist?: Array\n\n serializationAdapters?: ReadonlyArray\n /**\n * Configures how the router will rewrite the location between the actual href and the internal href of the router.\n *\n * @default undefined\n * @description You can provide a custom rewrite pair (in/out).\n * This is useful for shifting data from the origin to the path (for things like subdomain routing), or other advanced use cases.\n */\n rewrite?: LocationRewrite\n origin?: string\n ssr?: {\n nonce?: string\n }\n}\n\nexport type LocationRewrite = {\n /**\n * A function that will be called to rewrite the URL before it is interpreted by the router from the history instance.\n *\n * @default undefined\n */\n input?: LocationRewriteFunction\n /**\n * A function that will be called to rewrite the URL before it is committed to the actual history instance from the router.\n *\n * @default undefined\n */\n output?: LocationRewriteFunction\n}\n\n/**\n * A function that will be called to rewrite the URL.\n *\n * @param url The URL to rewrite.\n * @returns The rewritten URL (as a URL instance or full href string) or undefined if no rewrite is needed.\n */\nexport type LocationRewriteFunction = ({\n url,\n}: {\n url: URL\n}) => undefined | string | URL\n\nexport interface RouterState<\n in out TRouteTree extends AnyRoute = AnyRoute,\n in out TRouteMatch = MakeRouteMatchUnion,\n> {\n status: 'pending' | 'idle'\n loadedAt: number\n isLoading: boolean\n isTransitioning: boolean\n matches: Array\n location: ParsedLocation>\n resolvedLocation?: ParsedLocation>\n statusCode: number\n redirect?: AnyRedirect\n}\n\nexport interface BuildNextOptions {\n to?: string | number | null\n params?: true | Updater\n search?: true | Updater\n hash?: true | Updater\n state?: true | NonNullableUpdater\n mask?: {\n to?: string | number | null\n params?: true | Updater\n search?: true | Updater\n hash?: true | Updater\n state?: true | NonNullableUpdater\n unmaskOnReload?: boolean\n }\n from?: string\n href?: string\n _fromLocation?: ParsedLocation\n unsafeRelative?: 'path'\n _isNavigate?: boolean\n}\n\ntype NavigationEventInfo = {\n fromLocation?: ParsedLocation\n toLocation: ParsedLocation\n pathChanged: boolean\n hrefChanged: boolean\n hashChanged: boolean\n}\n\nexport interface RouterEvents {\n onBeforeNavigate: {\n type: 'onBeforeNavigate'\n } & NavigationEventInfo\n onBeforeLoad: {\n type: 'onBeforeLoad'\n } & NavigationEventInfo\n onLoad: {\n type: 'onLoad'\n } & NavigationEventInfo\n onResolved: {\n type: 'onResolved'\n } & NavigationEventInfo\n onBeforeRouteMount: {\n type: 'onBeforeRouteMount'\n } & NavigationEventInfo\n onRendered: {\n type: 'onRendered'\n } & NavigationEventInfo\n}\n\nexport type RouterEvent = RouterEvents[keyof RouterEvents]\n\nexport type ListenerFn = (event: TEvent) => void\n\nexport type RouterListener = {\n eventType: TRouterEvent['type']\n fn: ListenerFn\n}\n\nexport type SubscribeFn = (\n eventType: TType,\n fn: ListenerFn,\n) => () => void\n\nexport interface MatchRoutesOpts {\n preload?: boolean\n throwOnError?: boolean\n dest?: BuildNextOptions\n}\n\nexport type InferRouterContext =\n TRouteTree['types']['routerContext']\n\nexport type RouterContextOptions =\n AnyContext extends InferRouterContext\n ? {\n context?: InferRouterContext\n }\n : {\n context: InferRouterContext\n }\n\nexport type RouterConstructorOptions<\n TRouteTree extends AnyRoute,\n TTrailingSlashOption extends TrailingSlashOption,\n TDefaultStructuralSharingOption extends boolean,\n TRouterHistory extends RouterHistory,\n TDehydrated extends Record,\n> = Omit<\n RouterOptions<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n >,\n 'context' | 'serializationAdapters' | 'defaultSsr'\n> &\n RouterContextOptions\n\nexport type PreloadRouteFn<\n TRouteTree extends AnyRoute,\n TTrailingSlashOption extends TrailingSlashOption,\n TDefaultStructuralSharingOption extends boolean,\n TRouterHistory extends RouterHistory,\n> = <\n TFrom extends RoutePaths | string = string,\n TTo extends string | undefined = undefined,\n TMaskFrom extends RoutePaths | string = TFrom,\n TMaskTo extends string = '',\n>(\n opts: NavigateOptions<\n RouterCore<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory\n >,\n TFrom,\n TTo,\n TMaskFrom,\n TMaskTo\n > & {\n /**\n * @internal\n * A **trusted** built location that can be used to redirect to.\n */\n _builtLocation?: ParsedLocation\n },\n) => Promise | undefined>\n\nexport type MatchRouteFn<\n TRouteTree extends AnyRoute,\n TTrailingSlashOption extends TrailingSlashOption,\n TDefaultStructuralSharingOption extends boolean,\n TRouterHistory extends RouterHistory,\n> = <\n TFrom extends RoutePaths = '/',\n TTo extends string | undefined = undefined,\n TResolved = ResolveRelativePath>,\n>(\n location: ToOptions<\n RouterCore<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory\n >,\n TFrom,\n TTo\n >,\n opts?: MatchRouteOptions,\n) => false | RouteById['types']['allParams']\n\nexport type UpdateFn<\n TRouteTree extends AnyRoute,\n TTrailingSlashOption extends TrailingSlashOption,\n TDefaultStructuralSharingOption extends boolean,\n TRouterHistory extends RouterHistory,\n TDehydrated extends Record,\n> = (\n newOptions: RouterConstructorOptions<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n >,\n) => void\n\nexport type InvalidateFn = (opts?: {\n filter?: (d: MakeRouteMatchUnion) => boolean\n sync?: boolean\n forcePending?: boolean\n}) => Promise\n\nexport type ParseLocationFn = (\n locationToParse: HistoryLocation,\n previousLocation?: ParsedLocation>,\n) => ParsedLocation>\n\nexport type GetMatchRoutesFn = (pathname: string) => {\n matchedRoutes: ReadonlyArray\n /** exhaustive params, still in their string form */\n routeParams: Record\n foundRoute: AnyRoute | undefined\n parseError?: unknown\n}\n\nexport type EmitFn = (routerEvent: RouterEvent) => void\n\nexport type LoadFn = (opts?: { sync?: boolean }) => Promise\n\nexport type CommitLocationFn = ({\n viewTransition,\n ignoreBlocker,\n ...next\n}: ParsedLocation & CommitLocationOptions) => Promise\n\nexport type StartTransitionFn = (fn: () => void) => void\n\nexport interface MatchRoutesFn {\n (\n pathname: string,\n locationSearch?: AnySchema,\n opts?: MatchRoutesOpts,\n ): Array\n /**\n * @deprecated use the following signature instead\n */\n (next: ParsedLocation, opts?: MatchRoutesOpts): Array\n (\n pathnameOrNext: string | ParsedLocation,\n locationSearchOrOpts?: AnySchema | MatchRoutesOpts,\n opts?: MatchRoutesOpts,\n ): Array\n}\n\nexport type GetMatchFn = (matchId: string) => AnyRouteMatch | undefined\n\nexport type UpdateMatchFn = (\n id: string,\n updater: (match: AnyRouteMatch) => AnyRouteMatch,\n) => void\n\nexport type LoadRouteChunkFn = (route: AnyRoute) => Promise>\n\nexport type ResolveRedirect = (err: AnyRedirect) => ResolvedRedirect\n\nexport type ClearCacheFn = (opts?: {\n filter?: (d: MakeRouteMatchUnion) => boolean\n}) => void\n\nexport interface ServerSsr {\n /**\n * Injects HTML synchronously into the stream.\n * Emits an onInjectedHtml event that listeners can handle.\n * If no subscriber is listening, the HTML is buffered and can be retrieved via takeBufferedHtml().\n */\n injectHtml: (html: string) => void\n /**\n * Injects a script tag synchronously into the stream.\n */\n injectScript: (script: string) => void\n isDehydrated: () => boolean\n isSerializationFinished: () => boolean\n onRenderFinished: (listener: () => void) => void\n setRenderFinished: () => void\n cleanup: () => void\n onSerializationFinished: (listener: () => void) => void\n dehydrate: (opts?: {\n requestAssets?: Array\n }) => Promise\n takeBufferedScripts: () => RouterManagedTag | undefined\n /**\n * Takes any buffered HTML that was injected.\n * Returns the buffered HTML string (which may include multiple script tags) or undefined if empty.\n */\n takeBufferedHtml: () => string | undefined\n liftScriptBarrier: () => void\n}\n\nexport type AnyRouterWithContext = RouterCore<\n AnyRouteWithContext,\n any,\n any,\n any,\n any\n>\n\nexport type AnyRouter = RouterCore\n\nexport interface ViewTransitionOptions {\n types:\n | Array\n | ((locationChangeInfo: {\n fromLocation?: ParsedLocation\n toLocation: ParsedLocation\n pathChanged: boolean\n hrefChanged: boolean\n hashChanged: boolean\n }) => Array | false)\n}\n\n// TODO where is this used? can we remove this?\n/**\n * Convert an unknown error into a minimal, serializable object.\n * Includes name and message (and stack in development).\n */\nexport function defaultSerializeError(err: unknown) {\n if (err instanceof Error) {\n const obj = {\n name: err.name,\n message: err.message,\n }\n\n if (process.env.NODE_ENV === 'development') {\n ;(obj as any).stack = err.stack\n }\n\n return obj\n }\n\n return {\n data: err,\n }\n}\n\n/** Options for configuring trailing-slash behavior. */\nexport const trailingSlashOptions = {\n always: 'always',\n never: 'never',\n preserve: 'preserve',\n} as const\n\nexport type TrailingSlashOption =\n (typeof trailingSlashOptions)[keyof typeof trailingSlashOptions]\n\n/**\n * Compute whether path, href or hash changed between previous and current\n * resolved locations.\n */\nexport function getLocationChangeInfo(\n location: ParsedLocation,\n resolvedLocation?: ParsedLocation,\n) {\n const fromLocation = resolvedLocation\n const toLocation = location\n const pathChanged = fromLocation?.pathname !== toLocation.pathname\n const hrefChanged = fromLocation?.href !== toLocation.href\n const hashChanged = fromLocation?.hash !== toLocation.hash\n return { fromLocation, toLocation, pathChanged, hrefChanged, hashChanged }\n}\n\nexport type CreateRouterFn = <\n TRouteTree extends AnyRoute,\n TTrailingSlashOption extends TrailingSlashOption = 'never',\n TDefaultStructuralSharingOption extends boolean = false,\n TRouterHistory extends RouterHistory = RouterHistory,\n TDehydrated extends Record = Record,\n>(\n options: undefined extends number\n ? 'strictNullChecks must be enabled in tsconfig.json'\n : RouterConstructorOptions<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n >,\n) => RouterCore<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n>\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __TSR_CACHE__:\n | {\n routeTree: AnyRoute\n processRouteTreeResult: ProcessRouteTreeResult\n resolvePathCache: LRUCache\n }\n | undefined\n}\n\n/**\n * Core, framework-agnostic router engine that powers TanStack Router.\n *\n * Provides navigation, matching, loading, preloading, caching and event APIs\n * used by framework adapters (React/Solid). Prefer framework helpers like\n * `createRouter` in app code.\n *\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterType\n */\nexport class RouterCore<\n in out TRouteTree extends AnyRoute,\n in out TTrailingSlashOption extends TrailingSlashOption,\n in out TDefaultStructuralSharingOption extends boolean,\n in out TRouterHistory extends RouterHistory = RouterHistory,\n in out TDehydrated extends Record = Record,\n> {\n // Option-independent properties\n tempLocationKey: string | undefined = `${Math.round(\n Math.random() * 10000000,\n )}`\n resetNextScroll = true\n shouldViewTransition?: boolean | ViewTransitionOptions = undefined\n isViewTransitionTypesSupported?: boolean = undefined\n subscribers = new Set>()\n viewTransitionPromise?: ControlledPromise\n isScrollRestoring = false\n isScrollRestorationSetup = false\n\n // Must build in constructor\n stores!: RouterStores\n private getStoreConfig!: GetStoreConfig\n batch!: (fn: () => void) => void\n\n options!: PickAsRequired<\n RouterOptions<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n >,\n 'stringifySearch' | 'parseSearch' | 'context'\n >\n history!: TRouterHistory\n rewrite?: LocationRewrite\n origin?: string\n latestLocation!: ParsedLocation>\n pendingBuiltLocation?: ParsedLocation>\n basepath!: string\n routeTree!: TRouteTree\n routesById!: RoutesById\n routesByPath!: RoutesByPath\n processedTree!: ProcessedTree\n resolvePathCache!: LRUCache\n private routeBranchCache = new WeakMap>()\n isServer!: boolean\n pathParamsDecoder?: (encoded: string) => string\n protocolAllowlist!: Set\n\n /**\n * @deprecated Use the `createRouter` function instead\n */\n constructor(\n options: RouterConstructorOptions<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n >,\n getStoreConfig: GetStoreConfig,\n ) {\n this.getStoreConfig = getStoreConfig\n\n this.update({\n defaultPreloadDelay: 50,\n defaultPendingMs: 1000,\n defaultPendingMinMs: 500,\n context: undefined!,\n ...options,\n caseSensitive: options.caseSensitive ?? false,\n notFoundMode: options.notFoundMode ?? 'fuzzy',\n stringifySearch: options.stringifySearch ?? defaultStringifySearch,\n parseSearch: options.parseSearch ?? defaultParseSearch,\n protocolAllowlist:\n options.protocolAllowlist ?? DEFAULT_PROTOCOL_ALLOWLIST,\n })\n\n if (typeof document !== 'undefined') {\n self.__TSR_ROUTER__ = this\n }\n }\n\n // This is a default implementation that can optionally be overridden\n // by the router provider once rendered. We provide this so that the\n // router can be used in a non-react environment if necessary\n startTransition: StartTransitionFn = (fn) => fn()\n\n isShell() {\n return !!this.options.isShell\n }\n\n isPrerendering() {\n return !!this.options.isPrerendering\n }\n\n update: UpdateFn<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n > = (newOptions) => {\n if (process.env.NODE_ENV !== 'production') {\n if (newOptions.notFoundRoute) {\n console.warn(\n 'The notFoundRoute API is deprecated and will be removed in the next major version. See https://tanstack.com/router/v1/docs/framework/react/guide/not-found-errors#migrating-from-notfoundroute for more info.',\n )\n }\n }\n\n const prevOptions = this.options\n const prevBasepath = this.basepath ?? prevOptions?.basepath ?? '/'\n const basepathWasUnset = this.basepath === undefined\n const prevRewriteOption = prevOptions?.rewrite\n\n this.options = {\n ...prevOptions,\n ...newOptions,\n }\n\n this.isServer = this.options.isServer ?? typeof document === 'undefined'\n\n this.protocolAllowlist = new Set(this.options.protocolAllowlist)\n\n if (this.options.pathParamsAllowedCharacters)\n this.pathParamsDecoder = compileDecodeCharMap(\n this.options.pathParamsAllowedCharacters,\n )\n\n if (\n !this.history ||\n (this.options.history && this.options.history !== this.history)\n ) {\n if (!this.options.history) {\n if (!(isServer ?? this.isServer)) {\n this.history = createBrowserHistory() as TRouterHistory\n }\n } else {\n this.history = this.options.history\n }\n }\n\n this.origin = this.options.origin\n if (!this.origin) {\n if (\n !(isServer ?? this.isServer) &&\n window?.origin &&\n window.origin !== 'null'\n ) {\n this.origin = window.origin\n } else {\n // fallback for the server, can be overridden by calling router.update({origin}) on the server\n this.origin = 'http://localhost'\n }\n }\n\n if (this.history) {\n this.updateLatestLocation()\n }\n\n if (this.options.routeTree !== this.routeTree) {\n this.routeTree = this.options.routeTree as TRouteTree\n let processRouteTreeResult: ProcessRouteTreeResult\n if (\n (isServer ?? this.isServer) &&\n process.env.NODE_ENV !== 'development' &&\n globalThis.__TSR_CACHE__ &&\n globalThis.__TSR_CACHE__.routeTree === this.routeTree\n ) {\n const cached = globalThis.__TSR_CACHE__\n this.resolvePathCache = cached.resolvePathCache\n processRouteTreeResult = cached.processRouteTreeResult as any\n } else {\n this.resolvePathCache = createLRUCache(1000)\n processRouteTreeResult = this.buildRouteTree()\n // only cache if nothing else is cached yet\n if (\n (isServer ?? this.isServer) &&\n process.env.NODE_ENV !== 'development' &&\n globalThis.__TSR_CACHE__ === undefined\n ) {\n globalThis.__TSR_CACHE__ = {\n routeTree: this.routeTree,\n processRouteTreeResult: processRouteTreeResult as any,\n resolvePathCache: this.resolvePathCache,\n }\n }\n }\n this.setRoutes(processRouteTreeResult)\n }\n\n if (!this.stores && this.latestLocation) {\n const config = this.getStoreConfig(this)\n this.batch = config.batch\n this.stores = createRouterStores(\n getInitialRouterState(this.latestLocation),\n config,\n )\n\n if (!(isServer ?? this.isServer)) {\n setupScrollRestoration(this)\n }\n }\n\n let needsLocationUpdate = false\n const nextBasepath = this.options.basepath ?? '/'\n const nextRewriteOption = this.options.rewrite\n const basepathChanged = basepathWasUnset || prevBasepath !== nextBasepath\n const rewriteChanged = prevRewriteOption !== nextRewriteOption\n\n if (basepathChanged || rewriteChanged) {\n this.basepath = nextBasepath\n\n const rewrites: Array = []\n const trimmed = trimPath(nextBasepath)\n if (trimmed && trimmed !== '/') {\n rewrites.push(\n rewriteBasepath({\n basepath: nextBasepath,\n }),\n )\n }\n if (nextRewriteOption) {\n rewrites.push(nextRewriteOption)\n }\n\n this.rewrite =\n rewrites.length === 0\n ? undefined\n : rewrites.length === 1\n ? rewrites[0]\n : composeRewrites(rewrites)\n\n if (this.history) {\n this.updateLatestLocation()\n }\n\n needsLocationUpdate = true\n }\n\n if (needsLocationUpdate && this.stores) {\n this.stores.location.set(this.latestLocation)\n }\n\n if (\n typeof window !== 'undefined' &&\n 'CSS' in window &&\n typeof window.CSS?.supports === 'function'\n ) {\n this.isViewTransitionTypesSupported = window.CSS.supports(\n 'selector(:active-view-transition-type(a)',\n )\n }\n }\n\n get state(): RouterState {\n return this.stores.__store.get()\n }\n\n updateLatestLocation = () => {\n this.latestLocation = this.parseLocation(\n this.history.location,\n this.latestLocation,\n )\n }\n\n buildRouteTree = () => {\n const result = processRouteTree(\n this.routeTree,\n this.options.caseSensitive,\n (route, i) => {\n route.init({\n originalIndex: i,\n })\n },\n )\n if (this.options.routeMasks) {\n processRouteMasks(this.options.routeMasks, result.processedTree)\n }\n\n return result\n }\n\n setRoutes({\n routesById,\n routesByPath,\n processedTree,\n }: ProcessRouteTreeResult) {\n this.routesById = routesById as RoutesById\n this.routesByPath = routesByPath as RoutesByPath\n this.processedTree = processedTree\n\n const notFoundRoute = this.options.notFoundRoute\n\n if (notFoundRoute) {\n notFoundRoute.init({\n originalIndex: 99999999999,\n })\n this.routesById[notFoundRoute.id] = notFoundRoute\n }\n }\n\n /**\n * Subscribe to router lifecycle events like `onBeforeNavigate`, `onLoad`,\n * `onResolved`, etc. Returns an unsubscribe function.\n *\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterEventsType\n */\n subscribe: SubscribeFn = (eventType, fn) => {\n const listener: RouterListener = {\n eventType,\n fn,\n }\n\n this.subscribers.add(listener)\n\n return () => {\n this.subscribers.delete(listener)\n }\n }\n\n emit: EmitFn = (routerEvent) => {\n this.subscribers.forEach((listener) => {\n if (listener.eventType === routerEvent.type) {\n listener.fn(routerEvent)\n }\n })\n }\n\n /**\n * Parse a HistoryLocation into a strongly-typed ParsedLocation using the\n * current router options, rewrite rules and search parser/stringifier.\n */\n parseLocation: ParseLocationFn = (\n locationToParse,\n previousLocation,\n ) => {\n const parse = ({\n pathname,\n search,\n hash,\n href,\n state,\n }: HistoryLocation): ParsedLocation> => {\n // Fast path: no rewrite configured and pathname doesn't need encoding\n // Characters that need encoding: space, high unicode, control chars\n // eslint-disable-next-line no-control-regex\n if (!this.rewrite && !/[ \\x00-\\x1f\\x7f\\u0080-\\uffff]/.test(pathname)) {\n const parsedSearch = this.options.parseSearch(search)\n const searchStr = this.options.stringifySearch(parsedSearch)\n\n return {\n href: pathname + searchStr + hash,\n publicHref: pathname + searchStr + hash,\n pathname: decodePath(pathname).path,\n external: false,\n searchStr,\n search: nullReplaceEqualDeep(\n previousLocation?.search,\n parsedSearch,\n ) as any,\n hash: decodePath(hash.slice(1)).path,\n state: replaceEqualDeep(previousLocation?.state, state),\n }\n }\n\n // Before we do any processing, we need to allow rewrites to modify the URL\n // build up the full URL by combining the href from history with the router's origin\n const fullUrl = new URL(href, this.origin)\n\n const url = executeRewriteInput(this.rewrite, fullUrl)\n\n const parsedSearch = this.options.parseSearch(url.search)\n const searchStr = this.options.stringifySearch(parsedSearch)\n // Make sure our final url uses the re-stringified pathname, search, and has for consistency\n // (We were already doing this, so just keeping it for now)\n url.search = searchStr\n\n const fullPath = url.href.replace(url.origin, '')\n\n return {\n href: fullPath,\n publicHref: href,\n pathname: decodePath(url.pathname).path,\n external: !!this.rewrite && url.origin !== this.origin,\n searchStr,\n search: nullReplaceEqualDeep(\n previousLocation?.search,\n parsedSearch,\n ) as any,\n hash: decodePath(url.hash.slice(1)).path,\n state: replaceEqualDeep(previousLocation?.state, state),\n }\n }\n\n const location = parse(locationToParse)\n\n const { __tempLocation, __tempKey } = location.state\n\n if (__tempLocation && (!__tempKey || __tempKey === this.tempLocationKey)) {\n // Sync up the location keys\n const parsedTempLocation = parse(__tempLocation) as any\n parsedTempLocation.state.key = location.state.key // TODO: Remove in v2 - use __TSR_key instead\n parsedTempLocation.state.__TSR_key = location.state.__TSR_key\n\n delete parsedTempLocation.state.__tempLocation\n\n return {\n ...parsedTempLocation,\n maskedLocation: location,\n }\n }\n return location\n }\n\n /** Resolve a path using the router's trailing-slash policy. */\n resolvePathWithBase = (from: string, path: string) => {\n return resolvePath({\n base: from,\n to: path.includes('//') ? cleanPath(path) : path,\n trailingSlash: this.options.trailingSlash,\n cache: this.resolvePathCache,\n })\n }\n\n private getRouteBranch(route: AnyRoute) {\n let branch = this.routeBranchCache.get(route)\n if (!branch) {\n branch = buildRouteBranch(route)\n this.routeBranchCache.set(route, branch)\n }\n return branch\n }\n\n get looseRoutesById() {\n return this.routesById as Record\n }\n\n matchRoutes: MatchRoutesFn = (\n pathnameOrNext: string | ParsedLocation,\n locationSearchOrOpts?: AnySchema | MatchRoutesOpts,\n opts?: MatchRoutesOpts,\n ) => {\n if (typeof pathnameOrNext === 'string') {\n return this.matchRoutesInternal(\n {\n pathname: pathnameOrNext,\n search: locationSearchOrOpts,\n } as ParsedLocation,\n opts,\n )\n }\n\n return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts)\n }\n\n private getParentContext(parentMatch?: AnyRouteMatch) {\n const parentMatchId = parentMatch?.id\n\n const parentContext = !parentMatchId\n ? ((this.options.context as any) ?? undefined)\n : (parentMatch.context ?? this.options.context ?? undefined)\n\n return parentContext\n }\n\n private matchRoutesInternal(\n next: ParsedLocation,\n opts?: MatchRoutesOpts,\n ): Array {\n const matchedRoutesResult = this.getMatchedRoutes(next.pathname)\n const { foundRoute, routeParams } = matchedRoutesResult\n let { matchedRoutes } = matchedRoutesResult\n let isGlobalNotFound = false\n\n // Check to see if the route needs a 404 entry\n if (\n // If we found a route, and it's not an index route and we have left over path\n foundRoute\n ? foundRoute.path !== '/' && routeParams['**']\n : // Or if we didn't find a route and we have left over path\n trimPathRight(next.pathname)\n ) {\n // If the user has defined an (old) 404 route, use it\n if (this.options.notFoundRoute) {\n matchedRoutes = [...matchedRoutes, this.options.notFoundRoute]\n } else {\n // If there is no routes found during path matching\n isGlobalNotFound = true\n }\n }\n\n const globalNotFoundRouteId = isGlobalNotFound\n ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes)\n : undefined\n\n const matches = new Array(matchedRoutes.length)\n // Snapshot of active match state keyed by routeId, used to stabilise\n // params/search across navigations.\n const previousActiveMatchesByRouteId = new Map()\n for (const store of this.stores.matchStores.values()) {\n if (store.routeId) {\n previousActiveMatchesByRouteId.set(store.routeId, store.get())\n }\n }\n\n for (let index = 0; index < matchedRoutes.length; index++) {\n const route = matchedRoutes[index]!\n // Take each matched route and resolve + validate its search params\n // This has to happen serially because each route's search params\n // can depend on the parent route's search params\n // It must also happen before we create the match so that we can\n // pass the search params to the route's potential key function\n // which is used to uniquely identify the route match in state\n\n const parentMatch = matches[index - 1]\n\n let preMatchSearch: Record\n let strictMatchSearch: Record\n let searchError: any\n {\n // Validate the search params and stabilize them\n const parentSearch = parentMatch?.search ?? next.search\n const parentStrictSearch = parentMatch?._strictSearch ?? undefined\n\n try {\n const strictSearch =\n validateSearch(route.options.validateSearch, { ...parentSearch }) ??\n undefined\n\n preMatchSearch = {\n ...parentSearch,\n ...strictSearch,\n }\n strictMatchSearch = { ...parentStrictSearch, ...strictSearch }\n searchError = undefined\n } catch (err: any) {\n let searchParamError = err\n if (!(err instanceof SearchParamError)) {\n searchParamError = new SearchParamError(err.message, {\n cause: err,\n })\n }\n\n if (opts?.throwOnError) {\n throw searchParamError\n }\n\n preMatchSearch = parentSearch\n strictMatchSearch = {}\n searchError = searchParamError\n }\n }\n\n // This is where we need to call route.options.loaderDeps() to get any additional\n // deps that the route's loader function might need to run. We need to do this\n // before we create the match so that we can pass the deps to the route's\n // potential key function which is used to uniquely identify the route match in state\n\n const loaderDeps =\n route.options.loaderDeps?.({\n search: preMatchSearch,\n }) ?? ''\n\n const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : ''\n\n const { interpolatedPath, usedParams } = interpolatePath({\n path: route.fullPath,\n params: routeParams,\n decoder: this.pathParamsDecoder,\n server: this.isServer,\n })\n\n // Waste not, want not. If we already have a match for this route,\n // reuse it. This is important for layout routes, which might stick\n // around between navigation actions that only change leaf routes.\n\n // Existing matches are matches that are already loaded along with\n // pending matches that are still loading\n const matchId =\n // route.id for disambiguation\n route.id +\n // interpolatedPath for param changes\n interpolatedPath +\n // explicit deps\n loaderDepsHash\n\n const existingMatch = this.getMatch(matchId)\n\n const previousMatch = previousActiveMatchesByRouteId.get(route.id)\n\n const strictParams = existingMatch?._strictParams ?? usedParams\n\n let paramsError: unknown = undefined\n\n if (!existingMatch) {\n try {\n extractStrictParams(route, strictParams)\n } catch (err: any) {\n if (isNotFound(err) || isRedirect(err)) {\n paramsError = err\n } else {\n paramsError = new PathParamError(err.message, {\n cause: err,\n })\n }\n\n if (opts?.throwOnError) {\n throw paramsError\n }\n }\n }\n\n Object.assign(routeParams, strictParams)\n\n const cause = previousMatch ? 'stay' : 'enter'\n\n let match: AnyRouteMatch\n\n if (existingMatch) {\n match = {\n ...existingMatch,\n cause,\n params: previousMatch?.params ?? routeParams,\n _strictParams: strictParams,\n search: previousMatch\n ? nullReplaceEqualDeep(previousMatch.search, preMatchSearch)\n : nullReplaceEqualDeep(existingMatch.search, preMatchSearch),\n _strictSearch: strictMatchSearch,\n }\n } else {\n const status =\n route.options.loader ||\n route.options.beforeLoad ||\n route.lazyFn ||\n routeNeedsPreload(route)\n ? 'pending'\n : 'success'\n\n match = {\n id: matchId,\n ssr: (isServer ?? this.isServer) ? undefined : route.options.ssr,\n index,\n routeId: route.id,\n params: previousMatch?.params ?? routeParams,\n _strictParams: strictParams,\n pathname: interpolatedPath,\n updatedAt: Date.now(),\n search: previousMatch\n ? nullReplaceEqualDeep(previousMatch.search, preMatchSearch)\n : preMatchSearch,\n _strictSearch: strictMatchSearch,\n searchError: undefined,\n status,\n isFetching: false,\n error: undefined,\n paramsError,\n __routeContext: undefined,\n _nonReactive: {\n loadPromise: createControlledPromise(),\n },\n __beforeLoadContext: undefined,\n context: {},\n abortController: new AbortController(),\n fetchCount: 0,\n cause,\n loaderDeps: previousMatch\n ? replaceEqualDeep(previousMatch.loaderDeps, loaderDeps)\n : loaderDeps,\n invalid: false,\n preload: false,\n links: undefined,\n scripts: undefined,\n headScripts: undefined,\n meta: undefined,\n staticData: route.options.staticData || {},\n fullPath: route.fullPath,\n }\n }\n\n if (!opts?.preload) {\n // If we have a global not found, mark the right match as global not found\n match.globalNotFound = globalNotFoundRouteId === route.id\n }\n\n // update the searchError if there is one\n match.searchError = searchError\n\n const parentContext = this.getParentContext(parentMatch)\n\n match.context = {\n ...parentContext,\n ...match.__routeContext,\n ...match.__beforeLoadContext,\n }\n\n matches[index] = match\n }\n\n for (let index = 0; index < matches.length; index++) {\n const match = matches[index]!\n const route = this.looseRoutesById[match.routeId]!\n const existingMatch = this.getMatch(match.id)\n\n // Update the match's params\n const previousMatch = previousActiveMatchesByRouteId.get(match.routeId)\n match.params = previousMatch\n ? nullReplaceEqualDeep(previousMatch.params, routeParams)\n : routeParams\n\n if (!existingMatch) {\n const parentMatch = matches[index - 1]\n const parentContext = this.getParentContext(parentMatch)\n\n // Update the match's context\n\n if (route.options.context) {\n const contextFnContext: RouteContextOptions =\n {\n deps: match.loaderDeps,\n params: match.params,\n context: parentContext ?? {},\n location: next,\n navigate: (opts: any) =>\n this.navigate({ ...opts, _fromLocation: next }),\n buildLocation: this.buildLocation,\n cause: match.cause,\n abortController: match.abortController,\n preload: !!match.preload,\n matches,\n routeId: route.id,\n }\n // Get the route context\n match.__routeContext =\n route.options.context(contextFnContext) ?? undefined\n }\n\n match.context = {\n ...parentContext,\n ...match.__routeContext,\n ...match.__beforeLoadContext,\n }\n }\n }\n\n return matches\n }\n\n getMatchedRoutes: GetMatchRoutesFn = (pathname) => {\n return getMatchedRoutes({\n pathname,\n routesById: this.routesById,\n processedTree: this.processedTree,\n })\n }\n\n /**\n * Lightweight route matching for buildLocation.\n * Only computes fullPath, accumulated search, and params - skipping expensive\n * operations like AbortController, ControlledPromise, loaderDeps, and full match objects.\n */\n private matchRoutesLightweight(location: ParsedLocation): {\n matchedRoutes: ReadonlyArray\n fullPath: string\n search: Record\n params: Record\n } {\n const { matchedRoutes, routeParams } = this.getMatchedRoutes(\n location.pathname,\n )\n const lastRoute = last(matchedRoutes)!\n\n // I don't know if we should run the full search middleware chain, or just validateSearch\n // // Accumulate search validation through the route chain\n // const accumulatedSearch: Record = applySearchMiddleware({\n // search: { ...location.search },\n // dest: location,\n // destRoutes: matchedRoutes,\n // _includeValidateSearch: true,\n // })\n\n // Accumulate search validation through route chain\n const accumulatedSearch = { ...location.search }\n for (const route of matchedRoutes) {\n try {\n Object.assign(\n accumulatedSearch,\n validateSearch(route.options.validateSearch, accumulatedSearch),\n )\n } catch {\n // Ignore errors, we're not actually routing\n }\n }\n\n // Determine params: reuse from state if possible, otherwise parse\n const lastStateMatchId = last(this.stores.matchesId.get())\n const lastStateMatch =\n lastStateMatchId && this.stores.matchStores.get(lastStateMatchId)?.get()\n const canReuseParams =\n lastStateMatch &&\n lastStateMatch.routeId === lastRoute.id &&\n lastStateMatch.pathname === location.pathname\n\n let params: Record\n if (canReuseParams) {\n params = lastStateMatch.params\n } else {\n // Parse params through the route chain\n const strictParams: Record = Object.assign(\n Object.create(null),\n routeParams,\n )\n for (const route of matchedRoutes) {\n try {\n extractStrictParams(route, strictParams)\n } catch {\n // Ignore errors, we're not actually routing\n }\n }\n params = strictParams\n }\n\n return {\n matchedRoutes,\n fullPath: lastRoute.fullPath,\n search: accumulatedSearch,\n params,\n }\n }\n\n cancelMatch = (id: string) => {\n const match = this.getMatch(id)\n\n if (!match) return\n\n match.abortController.abort()\n clearTimeout(match._nonReactive.pendingTimeout)\n match._nonReactive.pendingTimeout = undefined\n }\n\n cancelMatches = () => {\n this.stores.pendingIds.get().forEach((matchId) => {\n this.cancelMatch(matchId)\n })\n\n this.stores.matchesId.get().forEach((matchId) => {\n if (this.stores.pendingMatchStores.has(matchId)) {\n return\n }\n\n const match = this.stores.matchStores.get(matchId)?.get()\n if (!match) {\n return\n }\n\n if (match.status === 'pending' || match.isFetching === 'loader') {\n this.cancelMatch(matchId)\n }\n })\n }\n\n /**\n * Build the next ParsedLocation from navigation options without committing.\n * Resolves `to`/`from`, params/search/hash/state, applies search validation\n * and middlewares, and returns a stable, stringified location object.\n *\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterType#buildlocation-method\n */\n buildLocation: BuildLocationFn = (opts) => {\n const build = (\n dest: BuildNextOptions & {\n unmaskOnReload?: boolean\n } = {},\n ): ParsedLocation => {\n // We allow the caller to override the current location\n const currentLocation =\n dest._fromLocation || this.pendingBuiltLocation || this.latestLocation\n\n // Use lightweight matching - only computes what buildLocation needs\n // (fullPath, search, params) without creating full match objects\n const lightweightResult = this.matchRoutesLightweight(currentLocation)\n\n // check that from path exists in the current route tree\n // do this check only on navigations during test or development\n if (\n dest.from &&\n process.env.NODE_ENV !== 'production' &&\n dest._isNavigate\n ) {\n const allFromMatches = this.getMatchedRoutes(dest.from).matchedRoutes\n\n const matchedFrom = findLast(lightweightResult.matchedRoutes, (d) => {\n return comparePaths(d.fullPath, dest.from!)\n })\n\n const matchedCurrent = findLast(allFromMatches, (d) => {\n return comparePaths(d.fullPath, lightweightResult.fullPath)\n })\n\n // for from to be invalid it shouldn't just be unmatched to currentLocation\n // but the currentLocation should also be unmatched to from\n if (!matchedFrom && !matchedCurrent) {\n console.warn(`Could not find match for from: ${dest.from}`)\n }\n }\n\n const defaultedFromPath =\n dest.unsafeRelative === 'path'\n ? currentLocation.pathname\n : (dest.from ?? lightweightResult.fullPath)\n const destTo = dest.to ? `${dest.to}` : undefined\n\n // From search should always use the current location\n const fromSearch = lightweightResult.search\n // Same with params. It can't hurt to provide as many as possible\n const fromParams = Object.assign(\n Object.create(null),\n lightweightResult.params,\n )\n\n const isAbsoluteTo = destTo?.charCodeAt(0) === 47\n const sourcePath = isAbsoluteTo\n ? '/'\n : this.resolvePathWithBase(defaultedFromPath, '.')\n\n // Resolve the destination. Absolute destinations don't need the source path.\n const nextTo = destTo\n ? this.resolvePathWithBase(sourcePath, destTo)\n : sourcePath\n\n // Resolve the next params\n const nextParams =\n dest.params === false || dest.params === null\n ? Object.create(null)\n : (dest.params ?? true) === true\n ? fromParams\n : Object.assign(\n fromParams,\n functionalUpdate(dest.params as any, fromParams),\n )\n\n const destRoute = this.routesByPath[\n trimPathRight(nextTo) as keyof typeof this.routesByPath\n ] as AnyRoute | undefined\n\n let destRoutes: ReadonlyArray\n if (destRoute) {\n destRoutes = this.getRouteBranch(destRoute)\n } else if (nextTo.includes('$')) {\n // Route templates must match routesByPath exactly. A miss here is a\n // typed destination mismatch, not a concrete URL to route-match.\n destRoutes = []\n } else {\n const destMatchResult = this.getMatchedRoutes(nextTo)\n destRoutes = destMatchResult.matchedRoutes\n\n if (\n this.options.notFoundRoute &&\n (!destMatchResult.foundRoute ||\n (destMatchResult.foundRoute.path !== '/' &&\n destMatchResult.routeParams['**']))\n ) {\n destRoutes = [...destRoutes, this.options.notFoundRoute]\n }\n }\n\n // If there are any params, we need to stringify them\n if (destRoutes.length && hasKeys(nextParams)) {\n for (const route of destRoutes) {\n const fn =\n route.options.params?.stringify ?? route.options.stringifyParams\n if (fn) {\n try {\n Object.assign(nextParams, fn(nextParams))\n } catch {\n // Ignore errors here. When a paired parseParams is defined,\n // extractStrictParams will re-throw during route matching,\n // storing the error on the match and allowing the route's\n // errorComponent to render. If no parseParams is defined,\n // the stringify error is silently dropped.\n }\n }\n }\n }\n\n const nextPathname = opts.leaveParams\n ? // Keep path params uninterpolated for matchRoute/template matching.\n nextTo\n : decodePath(\n interpolatePath({\n path: nextTo,\n params: nextParams,\n decoder: this.pathParamsDecoder,\n server: this.isServer,\n }).interpolatedPath,\n ).path\n\n if (\n process.env.NODE_ENV !== 'production' &&\n destRoute &&\n !opts.leaveParams\n ) {\n try {\n const roundTrip = this.getMatchedRoutes(nextPathname)\n if (roundTrip.foundRoute?.id !== destRoute.id) {\n console.warn(\n `Generated path \"${nextPathname}\" for route \"${destRoute.id}\" did not match the same route after params.stringify.`,\n )\n }\n } catch {\n // Ignore roundtrip validation errors. The generated location will be\n // handled by the normal navigation flow.\n }\n }\n\n // Resolve the next search\n let nextSearch = fromSearch\n if (opts._includeValidateSearch && this.options.search?.strict) {\n const validatedSearch = {}\n destRoutes.forEach((route) => {\n if (route.options.validateSearch) {\n try {\n Object.assign(\n validatedSearch,\n validateSearch(route.options.validateSearch, {\n ...validatedSearch,\n ...nextSearch,\n }),\n )\n } catch {\n // ignore errors here because they are already handled in matchRoutes\n }\n }\n })\n nextSearch = validatedSearch\n }\n\n nextSearch = applySearchMiddleware({\n search: nextSearch,\n dest,\n destRoutes,\n _includeValidateSearch: opts._includeValidateSearch,\n })\n\n // Replace the equal deep\n nextSearch = nullReplaceEqualDeep(fromSearch, nextSearch)\n\n // Stringify the next search\n const searchStr = this.options.stringifySearch(nextSearch)\n\n // Resolve the next hash\n const hash =\n dest.hash === true\n ? currentLocation.hash\n : dest.hash\n ? functionalUpdate(dest.hash, currentLocation.hash)\n : undefined\n\n // Resolve the next hash string\n const hashStr = hash ? `#${hash}` : ''\n\n // Resolve the next state\n let nextState =\n dest.state === true\n ? currentLocation.state\n : dest.state\n ? functionalUpdate(dest.state, currentLocation.state)\n : {}\n\n // Replace the equal deep\n nextState = replaceEqualDeep(currentLocation.state, nextState)\n\n // Create the full path of the location\n const fullPath = `${nextPathname}${searchStr}${hashStr}`\n\n // Compute href and publicHref without URL construction when no rewrite\n let href: string\n let publicHref: string\n let external = false\n\n if (this.rewrite) {\n // With rewrite, we need to construct URL to apply the rewrite\n const url = new URL(fullPath, this.origin)\n const rewrittenUrl = executeRewriteOutput(this.rewrite, url)\n href = url.href.replace(url.origin, '')\n // If rewrite changed the origin, publicHref needs full URL\n // Otherwise just use the path components\n if (rewrittenUrl.origin !== this.origin) {\n publicHref = rewrittenUrl.href\n external = true\n } else {\n publicHref =\n rewrittenUrl.pathname + rewrittenUrl.search + rewrittenUrl.hash\n }\n } else {\n // Fast path: no rewrite, skip URL construction entirely\n // fullPath is already the correct href (origin-stripped)\n // We need to encode non-ASCII (unicode) characters for the href\n // since decodePath decoded them from the interpolated path\n href = encodePathLikeUrl(fullPath)\n publicHref = href\n }\n\n return {\n publicHref,\n href,\n pathname: nextPathname,\n search: nextSearch,\n searchStr,\n state: nextState as any,\n hash: hash ?? '',\n external,\n unmaskOnReload: dest.unmaskOnReload,\n }\n }\n\n const buildWithMatches = (\n dest: BuildNextOptions = {},\n maskedDest?: BuildNextOptions,\n ) => {\n const next = build(dest)\n\n let maskedNext = maskedDest ? build(maskedDest) : undefined\n\n if (!maskedNext) {\n const params = Object.create(null)\n\n if (this.options.routeMasks) {\n const match = findFlatMatch>(\n next.pathname,\n this.processedTree,\n )\n if (match) {\n Object.assign(params, match.rawParams) // Copy params, because they're cached\n const {\n from: _from,\n params: maskParams,\n ...maskProps\n } = match.route\n\n // If mask has a params function, call it with the matched params as context\n // Otherwise, use the matched params or the provided params value\n const nextParams =\n maskParams === false || maskParams === null\n ? Object.create(null)\n : (maskParams ?? true) === true\n ? params\n : Object.assign(params, functionalUpdate(maskParams, params))\n\n maskedDest = {\n from: opts.from,\n ...maskProps,\n params: nextParams,\n }\n maskedNext = build(maskedDest)\n }\n }\n }\n\n if (maskedNext) {\n next.maskedLocation = maskedNext\n }\n\n return next\n }\n\n if (opts.mask) {\n return buildWithMatches(opts, {\n from: opts.from,\n ...opts.mask,\n })\n }\n\n return buildWithMatches(opts)\n }\n\n commitLocationPromise: undefined | ControlledPromise\n\n /**\n * Commit a previously built location to history (push/replace), optionally\n * using view transitions and scroll restoration options.\n */\n commitLocation: CommitLocationFn = async ({\n viewTransition,\n ignoreBlocker,\n ...next\n }) => {\n const isSameState = () => {\n // the following props are ignored but may still be provided when navigating,\n // temporarily add the previous values to the next state so they don't affect\n // the comparison\n const ignoredProps = [\n 'key', // TODO: Remove in v2 - use __TSR_key instead\n '__TSR_key',\n '__TSR_index',\n '__hashScrollIntoViewOptions',\n ] as const\n ignoredProps.forEach((prop) => {\n ;(next.state as any)[prop] = this.latestLocation.state[prop]\n })\n const isEqual = deepEqual(next.state, this.latestLocation.state)\n ignoredProps.forEach((prop) => {\n delete next.state[prop]\n })\n return isEqual\n }\n\n const isSameUrl =\n trimPathRight(this.latestLocation.href) === trimPathRight(next.href)\n\n let previousCommitPromise = this.commitLocationPromise\n this.commitLocationPromise = createControlledPromise(() => {\n previousCommitPromise?.resolve()\n previousCommitPromise = undefined\n })\n\n // Don't commit to history if nothing changed\n if (isSameUrl && isSameState()) {\n this.load()\n } else {\n let {\n // eslint-disable-next-line prefer-const\n maskedLocation,\n // eslint-disable-next-line prefer-const\n hashScrollIntoView,\n ...nextHistory\n } = next\n\n if (maskedLocation) {\n nextHistory = {\n ...maskedLocation,\n state: {\n ...maskedLocation.state,\n __tempKey: undefined,\n __tempLocation: {\n ...nextHistory,\n search: nextHistory.searchStr,\n state: {\n ...nextHistory.state,\n __tempKey: undefined!,\n __tempLocation: undefined!,\n __TSR_key: undefined!,\n key: undefined!, // TODO: Remove in v2 - use __TSR_key instead\n },\n },\n },\n }\n\n if (\n nextHistory.unmaskOnReload ??\n this.options.unmaskOnReload ??\n false\n ) {\n nextHistory.state.__tempKey = this.tempLocationKey\n }\n }\n\n nextHistory.state.__hashScrollIntoViewOptions =\n hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true\n\n this.shouldViewTransition = viewTransition\n\n this.history[next.replace ? 'replace' : 'push'](\n nextHistory.publicHref,\n nextHistory.state,\n { ignoreBlocker },\n )\n }\n\n this.resetNextScroll = next.resetScroll ?? true\n\n if (!this.history.subscribers.size) {\n this.load()\n }\n\n return this.commitLocationPromise\n }\n\n /** Convenience helper: build a location from options, then commit it. */\n buildAndCommitLocation = ({\n replace,\n resetScroll,\n hashScrollIntoView,\n viewTransition,\n ignoreBlocker,\n href,\n ...rest\n }: BuildNextOptions & CommitLocationOptions = {}) => {\n if (href) {\n const currentIndex = this.history.location.state.__TSR_index\n\n const parsed = parseHref(href, {\n __TSR_index: replace ? currentIndex : currentIndex + 1,\n })\n\n // If the href contains the basepath, we need to strip it before setting `to`\n // because `buildLocation` will add the basepath back when creating the final URL.\n // Without this, hrefs like '/app/about' would become '/app/app/about'.\n const hrefUrl = new URL(parsed.pathname, this.origin)\n const rewrittenUrl = executeRewriteInput(this.rewrite, hrefUrl)\n\n rest.to = rewrittenUrl.pathname\n rest.search = this.options.parseSearch(parsed.search)\n // remove the leading `#` from the hash\n rest.hash = parsed.hash.slice(1)\n }\n\n const location = this.buildLocation({\n ...(rest as any),\n _includeValidateSearch: true,\n })\n\n this.pendingBuiltLocation = location as ParsedLocation<\n FullSearchSchema\n >\n\n const commitPromise = this.commitLocation({\n ...location,\n viewTransition,\n replace,\n resetScroll,\n hashScrollIntoView,\n ignoreBlocker,\n })\n\n // Clear pending location after commit starts\n // We do this on next microtask to allow synchronous navigate calls to chain\n Promise.resolve().then(() => {\n if (this.pendingBuiltLocation === location) {\n this.pendingBuiltLocation = undefined\n }\n })\n\n return commitPromise\n }\n\n /**\n * Imperatively navigate using standard `NavigateOptions`. When `reloadDocument`\n * or an absolute `href` is provided, performs a full document navigation.\n * Otherwise, builds and commits a client-side location.\n *\n * @link https://tanstack.com/router/latest/docs/framework/react/api/router/NavigateOptionsType\n */\n navigate: NavigateFn = async ({\n to,\n reloadDocument,\n href,\n publicHref,\n ...rest\n }) => {\n let hrefIsUrl = false\n\n if (href) {\n try {\n new URL(`${href}`)\n hrefIsUrl = true\n } catch {}\n }\n\n if (hrefIsUrl && !reloadDocument) {\n reloadDocument = true\n }\n\n if (reloadDocument) {\n // When to is provided, always build a location to get the proper publicHref\n // (this handles redirects where href might be an internal path from resolveRedirect)\n // When only href is provided (no to), use it directly as it should already\n // be a complete path (possibly with basepath)\n if (to !== undefined || !href) {\n const location = this.buildLocation({ to, ...rest } as any)\n // Use publicHref which contains the path (origin-stripped is fine for reload)\n href = href ?? location.publicHref\n publicHref = publicHref ?? location.publicHref\n }\n\n // Use publicHref when available and href is not a full URL,\n // otherwise use href directly (which may already include basepath)\n const reloadHref = !hrefIsUrl && publicHref ? publicHref : href\n\n // Block dangerous protocols like javascript:, blob:, data:\n // These could execute arbitrary code if passed to window.location\n if (isDangerousProtocol(reloadHref, this.protocolAllowlist)) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n `Blocked navigation to dangerous protocol: ${reloadHref}`,\n )\n }\n return Promise.resolve()\n }\n\n // Check blockers for external URLs unless ignoreBlocker is true\n if (!rest.ignoreBlocker) {\n // Cast to access internal getBlockers method\n const historyWithBlockers = this.history as any\n const blockers = historyWithBlockers.getBlockers?.() ?? []\n for (const blocker of blockers) {\n if (blocker?.blockerFn) {\n const shouldBlock = await blocker.blockerFn({\n currentLocation: this.latestLocation,\n nextLocation: this.latestLocation, // External URLs don't have a next location in our router\n action: 'PUSH',\n })\n if (shouldBlock) {\n return Promise.resolve()\n }\n }\n }\n }\n\n if (rest.replace) {\n window.location.replace(reloadHref)\n } else {\n window.location.href = reloadHref\n }\n return Promise.resolve()\n }\n\n return this.buildAndCommitLocation({\n ...rest,\n href,\n to: to as string,\n _isNavigate: true,\n })\n }\n\n latestLoadPromise: undefined | Promise\n\n beforeLoad = () => {\n // Cancel any pending matches\n this.cancelMatches()\n this.updateLatestLocation()\n\n if (isServer ?? this.isServer) {\n // for SPAs on the initial load, this is handled by the Transitioner\n const nextLocation = this.buildLocation({\n to: this.latestLocation.pathname,\n search: true,\n params: true,\n hash: true,\n state: true,\n _includeValidateSearch: true,\n })\n\n // Check if location changed - origin check is unnecessary since buildLocation\n // always uses this.origin when constructing URLs\n if (this.latestLocation.publicHref !== nextLocation.publicHref) {\n const href = this.getParsedLocationHref(nextLocation)\n if (nextLocation.external) {\n throw redirect({ href })\n } else {\n throw redirect({ href, _builtLocation: nextLocation })\n }\n }\n }\n\n // Match the routes\n const pendingMatches = this.matchRoutes(this.latestLocation)\n\n const nextCachedMatches = this.stores.cachedMatches\n .get()\n .filter((d) => !pendingMatches.some((e) => e.id === d.id))\n\n // Ingest the new matches\n this.batch(() => {\n this.stores.status.set('pending')\n this.stores.statusCode.set(200)\n this.stores.isLoading.set(true)\n this.stores.location.set(this.latestLocation)\n this.stores.setPending(pendingMatches)\n // If a cached match moved to pending matches, remove it from cached matches\n this.stores.setCached(nextCachedMatches)\n })\n }\n\n load: LoadFn = async (opts?: { sync?: boolean }): Promise => {\n let redirect: AnyRedirect | undefined\n let notFound: NotFoundError | undefined\n let loadPromise: Promise\n const previousLocation =\n this.stores.resolvedLocation.get() ?? this.stores.location.get()\n\n // eslint-disable-next-line prefer-const\n loadPromise = new Promise((resolve) => {\n this.startTransition(async () => {\n try {\n this.beforeLoad()\n const next = this.latestLocation\n const prevLocation = this.stores.resolvedLocation.get()\n const locationChangeInfo = getLocationChangeInfo(next, prevLocation)\n\n if (!this.stores.redirect.get()) {\n this.emit({\n type: 'onBeforeNavigate',\n ...locationChangeInfo,\n })\n }\n\n this.emit({\n type: 'onBeforeLoad',\n ...locationChangeInfo,\n })\n\n await loadMatches({\n router: this,\n sync: opts?.sync,\n forceStaleReload: previousLocation.href === next.href,\n matches: this.stores.pendingMatches.get(),\n location: next,\n updateMatch: this.updateMatch,\n // eslint-disable-next-line @typescript-eslint/require-await\n onReady: async () => {\n // Wrap batch in framework-specific transition wrapper (e.g., Solid's startTransition)\n this.startTransition(() => {\n this.startViewTransition(async () => {\n // this.viewTransitionPromise = createControlledPromise()\n\n // Commit the pending matches. If a previous match was\n // removed, place it in the cachedMatches\n //\n // exitingMatches uses match.id (routeId + params + loaderDeps) so\n // navigating /foo?page=1 → /foo?page=2 correctly caches the page=1 entry.\n let exitingMatches: Array | null = null\n\n // Lifecycle-hook identity uses routeId only so that navigating between\n // different params/deps of the same route fires onStay (not onLeave+onEnter).\n let hookExitingMatches: Array | null = null\n let hookEnteringMatches: Array | null = null\n let hookStayingMatches: Array | null = null\n\n this.batch(() => {\n const pendingMatches = this.stores.pendingMatches.get()\n const mountPending = pendingMatches.length\n const currentMatches = this.stores.matches.get()\n\n exitingMatches = mountPending\n ? currentMatches.filter(\n (match) =>\n !this.stores.pendingMatchStores.has(match.id),\n )\n : null\n\n // Lifecycle-hook identity: routeId only (route presence in tree)\n // Build routeId sets from pools to avoid derived stores.\n const pendingRouteIds = new Set()\n for (const s of this.stores.pendingMatchStores.values()) {\n if (s.routeId) pendingRouteIds.add(s.routeId)\n }\n const activeRouteIds = new Set()\n for (const s of this.stores.matchStores.values()) {\n if (s.routeId) activeRouteIds.add(s.routeId)\n }\n\n hookExitingMatches = mountPending\n ? currentMatches.filter(\n (match) => !pendingRouteIds.has(match.routeId),\n )\n : null\n hookEnteringMatches = mountPending\n ? pendingMatches.filter(\n (match) => !activeRouteIds.has(match.routeId),\n )\n : null\n hookStayingMatches = mountPending\n ? pendingMatches.filter((match) =>\n activeRouteIds.has(match.routeId),\n )\n : currentMatches\n\n this.stores.isLoading.set(false)\n this.stores.loadedAt.set(Date.now())\n /**\n * When committing new matches, cache any exiting matches that are still usable.\n * Routes that resolved with `status: 'error'` or `status: 'notFound'` are\n * deliberately excluded from `cachedMatches` so that subsequent invalidations\n * or reloads re-run their loaders instead of reusing the failed/not-found data.\n */\n if (mountPending) {\n this.stores.setMatches(pendingMatches)\n this.stores.setPending([])\n this.stores.setCached([\n ...this.stores.cachedMatches.get(),\n ...exitingMatches!.filter(\n (d) =>\n d.status !== 'error' &&\n d.status !== 'notFound' &&\n d.status !== 'redirected',\n ),\n ])\n this.clearExpiredCache()\n }\n })\n\n //\n for (const [matches, hook] of [\n [hookExitingMatches, 'onLeave'],\n [hookEnteringMatches, 'onEnter'],\n [hookStayingMatches, 'onStay'],\n ] as const) {\n if (!matches) continue\n for (const match of matches as Array) {\n this.looseRoutesById[match.routeId]!.options[hook]?.(\n match,\n )\n }\n }\n })\n })\n },\n })\n } catch (err) {\n if (isRedirect(err)) {\n redirect = err\n if (!(isServer ?? this.isServer)) {\n this.navigate({\n ...redirect.options,\n replace: true,\n ignoreBlocker: true,\n })\n }\n } else if (isNotFound(err)) {\n notFound = err\n }\n\n const nextStatusCode = redirect\n ? redirect.status\n : notFound\n ? 404\n : this.stores.matches.get().some((d) => d.status === 'error')\n ? 500\n : 200\n\n this.batch(() => {\n this.stores.statusCode.set(nextStatusCode)\n this.stores.redirect.set(redirect)\n })\n }\n\n if (this.latestLoadPromise === loadPromise) {\n this.commitLocationPromise?.resolve()\n this.latestLoadPromise = undefined\n this.commitLocationPromise = undefined\n }\n\n resolve()\n })\n })\n\n this.latestLoadPromise = loadPromise\n\n await loadPromise\n\n while (\n (this.latestLoadPromise as any) &&\n loadPromise !== this.latestLoadPromise\n ) {\n await this.latestLoadPromise\n }\n\n let newStatusCode: number | undefined = undefined\n if (this.hasNotFoundMatch()) {\n newStatusCode = 404\n } else if (this.stores.matches.get().some((d) => d.status === 'error')) {\n newStatusCode = 500\n }\n if (newStatusCode !== undefined) {\n this.stores.statusCode.set(newStatusCode)\n }\n }\n\n startViewTransition = (fn: () => Promise) => {\n // Determine if we should start a view transition from the navigation\n // or from the router default\n const shouldViewTransition =\n this.shouldViewTransition ?? this.options.defaultViewTransition\n\n // Reset the view transition flag\n this.shouldViewTransition = undefined\n\n // Attempt to start a view transition (or just apply the changes if we can't)\n if (\n shouldViewTransition &&\n typeof document !== 'undefined' &&\n 'startViewTransition' in document &&\n typeof document.startViewTransition === 'function'\n ) {\n // lib.dom.ts doesn't support viewTransition types variant yet.\n // TODO: Fix this when dom types are updated\n let startViewTransitionParams: any\n\n if (\n typeof shouldViewTransition === 'object' &&\n this.isViewTransitionTypesSupported\n ) {\n const next = this.latestLocation\n const prevLocation = this.stores.resolvedLocation.get()\n\n const resolvedViewTransitionTypes =\n typeof shouldViewTransition.types === 'function'\n ? shouldViewTransition.types(\n getLocationChangeInfo(next, prevLocation),\n )\n : shouldViewTransition.types\n\n if (resolvedViewTransitionTypes === false) {\n fn()\n return\n }\n\n startViewTransitionParams = {\n update: fn,\n types: resolvedViewTransitionTypes,\n }\n } else {\n startViewTransitionParams = fn\n }\n\n document.startViewTransition(startViewTransitionParams)\n } else {\n fn()\n }\n }\n\n updateMatch: UpdateMatchFn = (id, updater) => {\n this.startTransition(() => {\n const pendingMatch = this.stores.pendingMatchStores.get(id)\n if (pendingMatch) {\n pendingMatch.set(updater)\n return\n }\n\n const activeMatch = this.stores.matchStores.get(id)\n if (activeMatch) {\n activeMatch.set(updater)\n return\n }\n\n const cachedMatch = this.stores.cachedMatchStores.get(id)\n if (cachedMatch) {\n const next = updater(cachedMatch.get())\n if (next.status === 'redirected') {\n const deleted = this.stores.cachedMatchStores.delete(id)\n if (deleted) {\n this.stores.cachedIds.set((prev) =>\n prev.filter((matchId) => matchId !== id),\n )\n }\n } else {\n cachedMatch.set(next)\n }\n }\n })\n }\n\n getMatch: GetMatchFn = (matchId: string): AnyRouteMatch | undefined => {\n return (\n this.stores.cachedMatchStores.get(matchId)?.get() ??\n this.stores.pendingMatchStores.get(matchId)?.get() ??\n this.stores.matchStores.get(matchId)?.get()\n )\n }\n\n /**\n * Invalidate the current matches and optionally force them back into a pending state.\n *\n * - Marks all matches that pass the optional `filter` as `invalid: true`.\n * - If `forcePending` is true, or a match is currently in `'error'` or `'notFound'` status,\n * its status is reset to `'pending'` and its `error` cleared so that the loader is re-run\n * on the next `load()` call (eg. after HMR or a manual invalidation).\n */\n invalidate: InvalidateFn<\n RouterCore<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory,\n TDehydrated\n >\n > = (opts) => {\n const invalidate = (d: MakeRouteMatch) => {\n if (opts?.filter?.(d as MakeRouteMatchUnion) ?? true) {\n return {\n ...d,\n invalid: true,\n ...(opts?.forcePending ||\n d.status === 'error' ||\n d.status === 'notFound'\n ? ({ status: 'pending', error: undefined } as const)\n : undefined),\n }\n }\n return d\n }\n\n this.batch(() => {\n this.stores.setMatches(this.stores.matches.get().map(invalidate))\n this.stores.setCached(this.stores.cachedMatches.get().map(invalidate))\n this.stores.setPending(this.stores.pendingMatches.get().map(invalidate))\n })\n\n this.shouldViewTransition = false\n return this.load({ sync: opts?.sync })\n }\n\n getParsedLocationHref = (location: ParsedLocation) => {\n // For redirects and external use, we need publicHref (with rewrite output applied)\n // href is the internal path after rewrite input, publicHref is user-facing\n return location.publicHref || '/'\n }\n\n resolveRedirect = (redirect: AnyRedirect): AnyRedirect => {\n const locationHeader = redirect.headers.get('Location')\n\n if (!redirect.options.href || redirect.options._builtLocation) {\n const location =\n redirect.options._builtLocation ?? this.buildLocation(redirect.options)\n const href = this.getParsedLocationHref(location)\n redirect.options.href = href\n redirect.headers.set('Location', href)\n } else if (locationHeader) {\n try {\n const url = new URL(locationHeader)\n if (this.origin && url.origin === this.origin) {\n const href = url.pathname + url.search + url.hash\n redirect.options.href = href\n redirect.headers.set('Location', href)\n }\n } catch {\n // ignore invalid URLs\n }\n }\n\n if (\n redirect.options.href &&\n !redirect.options._builtLocation &&\n // Check for dangerous protocols before processing the redirect\n isDangerousProtocol(redirect.options.href, this.protocolAllowlist)\n ) {\n throw new Error(\n process.env.NODE_ENV !== 'production'\n ? `Redirect blocked: unsafe protocol in href \"${redirect.options.href}\". Allowed protocols: ${Array.from(this.protocolAllowlist).join(', ')}.`\n : 'Redirect blocked: unsafe protocol',\n )\n }\n\n if (!redirect.headers.get('Location')) {\n redirect.headers.set('Location', redirect.options.href)\n }\n\n return redirect\n }\n\n clearCache: ClearCacheFn = (opts) => {\n const filter = opts?.filter\n if (filter !== undefined) {\n this.stores.setCached(\n this.stores.cachedMatches\n .get()\n .filter((m) => !filter(m as MakeRouteMatchUnion)),\n )\n } else {\n this.stores.setCached([])\n }\n }\n\n clearExpiredCache = () => {\n const now = Date.now()\n // This is where all of the garbage collection magic happens\n const filter = (d: MakeRouteMatch) => {\n const route = this.looseRoutesById[d.routeId]!\n\n if (!route.options.loader) {\n return true\n }\n\n // If the route was preloaded, use the preloadGcTime\n // otherwise, use the gcTime\n const gcTime =\n (d.preload\n ? (route.options.preloadGcTime ?? this.options.defaultPreloadGcTime)\n : (route.options.gcTime ?? this.options.defaultGcTime)) ??\n 5 * 60 * 1000\n\n const isError = d.status === 'error'\n if (isError) return true\n\n const gcEligible = now - d.updatedAt >= gcTime\n return gcEligible\n }\n this.clearCache({ filter })\n }\n\n loadRouteChunk = loadRouteChunk\n\n preloadRoute: PreloadRouteFn<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory\n > = async (opts) => {\n const next = opts._builtLocation ?? this.buildLocation(opts as any)\n\n let matches = this.matchRoutes(next, {\n throwOnError: true,\n preload: true,\n dest: opts,\n })\n\n const activeMatchIds = new Set([\n ...this.stores.matchesId.get(),\n ...this.stores.pendingIds.get(),\n ])\n\n const loadedMatchIds = new Set([\n ...activeMatchIds,\n ...this.stores.cachedIds.get(),\n ])\n\n // If the matches are already loaded, we need to add them to the cached matches.\n const matchesToCache = matches.filter(\n (match) => !loadedMatchIds.has(match.id),\n )\n if (matchesToCache.length) {\n const cachedMatches = this.stores.cachedMatches.get()\n this.stores.setCached([...cachedMatches, ...matchesToCache])\n }\n\n try {\n matches = await loadMatches({\n router: this,\n matches,\n location: next,\n preload: true,\n updateMatch: (id, updater) => {\n // Don't update the match if it's currently loaded\n if (activeMatchIds.has(id)) {\n matches = matches.map((d) => (d.id === id ? updater(d) : d))\n } else {\n this.updateMatch(id, updater)\n }\n },\n })\n\n return matches\n } catch (err) {\n if (isRedirect(err)) {\n if (err.options.reloadDocument) {\n return undefined\n }\n\n return await this.preloadRoute({\n ...err.options,\n _fromLocation: next,\n })\n }\n if (!isNotFound(err)) {\n // Preload errors are not fatal, but we should still log them\n console.error(err)\n }\n return undefined\n }\n }\n\n matchRoute: MatchRouteFn<\n TRouteTree,\n TTrailingSlashOption,\n TDefaultStructuralSharingOption,\n TRouterHistory\n > = (location, opts) => {\n const matchLocation = {\n ...location,\n to: location.to\n ? this.resolvePathWithBase(location.from || '', location.to as string)\n : undefined,\n params: location.params || {},\n leaveParams: true,\n }\n const next = this.buildLocation(matchLocation as any)\n\n if (opts?.pending && this.stores.status.get() !== 'pending') {\n return false\n }\n\n const pending =\n opts?.pending === undefined ? !this.stores.isLoading.get() : opts.pending\n\n const baseLocation = pending\n ? this.latestLocation\n : this.stores.resolvedLocation.get() || this.stores.location.get()\n\n const match = findSingleMatch(\n next.pathname,\n opts?.caseSensitive ?? false,\n opts?.fuzzy ?? false,\n baseLocation.pathname,\n this.processedTree,\n )\n\n if (!match) {\n return false\n }\n\n if (location.params) {\n if (!deepEqual(match.rawParams, location.params, { partial: true })) {\n return false\n }\n }\n\n if (opts?.includeSearch ?? true) {\n return deepEqual(baseLocation.search, next.search, { partial: true })\n ? match.rawParams\n : false\n }\n\n return match.rawParams\n }\n\n ssr?: {\n manifest: Manifest | undefined\n }\n\n serverSsr?: ServerSsr\n\n hasNotFoundMatch = () => {\n return this.stores.matches\n .get()\n .some((d) => d.status === 'notFound' || d.globalNotFound)\n }\n}\n\n/** Error thrown when search parameter validation fails. */\nexport class SearchParamError extends Error {}\n\n/** Error thrown when path parameter parsing/validation fails. */\nexport class PathParamError extends Error {}\n\nconst normalize = (str: string) =>\n str.endsWith('/') && str.length > 1 ? str.slice(0, -1) : str\nfunction comparePaths(a: string, b: string) {\n return normalize(a) === normalize(b)\n}\n\n/**\n * Lazily import a module function and forward arguments to it, retaining\n * parameter and return types for the selected export key.\n */\nexport function lazyFn<\n T extends Record) => any>,\n TKey extends keyof T = 'default',\n>(fn: () => Promise, key?: TKey) {\n return async (\n ...args: Parameters\n ): Promise>> => {\n const imported = await fn()\n return imported[key || 'default'](...args)\n }\n}\n\n/** Create an initial RouterState from a parsed location. */\nexport function getInitialRouterState(\n location: ParsedLocation,\n): RouterState {\n return {\n loadedAt: 0,\n isLoading: false,\n isTransitioning: false,\n status: 'idle',\n resolvedLocation: undefined,\n location,\n matches: [],\n statusCode: 200,\n }\n}\n\nfunction validateSearch(validateSearch: AnyValidator, input: unknown): unknown {\n if (validateSearch == null) return {}\n\n if ('~standard' in validateSearch) {\n const result = validateSearch['~standard'].validate(input)\n\n if (result instanceof Promise)\n throw new SearchParamError('Async validation not supported')\n\n if (result.issues)\n throw new SearchParamError(JSON.stringify(result.issues, undefined, 2), {\n cause: result,\n })\n\n return result.value\n }\n\n if ('parse' in validateSearch) {\n return validateSearch.parse(input)\n }\n\n if (typeof validateSearch === 'function') {\n return validateSearch(input)\n }\n\n return {}\n}\n\n/**\n * Build the matched route chain and extract params for a pathname.\n * Falls back to the root route if no specific route is found.\n */\nexport function getMatchedRoutes({\n pathname,\n routesById,\n processedTree,\n}: {\n pathname: string\n routesById: Record\n processedTree: ProcessedTree\n}) {\n const routeParams: Record = Object.create(null)\n const trimmedPath = trimPathRight(pathname)\n\n let foundRoute: TRouteLike | undefined = undefined\n const match = findRouteMatch(trimmedPath, processedTree, true)\n if (match) {\n foundRoute = match.route\n Object.assign(routeParams, match.rawParams) // Copy params, because they're cached\n }\n\n const matchedRoutes = match?.branch || [routesById[rootRouteId]!]\n\n return { matchedRoutes, routeParams, foundRoute }\n}\n\n/**\n * TODO: once caches are persisted across requests on the server,\n * we can cache the built middleware chain using `last(destRoutes)` as the key\n */\nfunction applySearchMiddleware({\n search,\n dest,\n destRoutes,\n _includeValidateSearch,\n}: {\n search: any\n dest: { search?: unknown }\n destRoutes: ReadonlyArray\n _includeValidateSearch: boolean | undefined\n}) {\n const middleware = buildMiddlewareChain(destRoutes)\n return middleware(search, dest, _includeValidateSearch ?? false)\n}\n\nfunction buildMiddlewareChain(destRoutes: ReadonlyArray) {\n const context = {\n dest: null as unknown as BuildNextOptions,\n _includeValidateSearch: false,\n middlewares: [] as Array>,\n }\n\n for (const route of destRoutes) {\n if ('search' in route.options) {\n if (route.options.search?.middlewares) {\n context.middlewares.push(...route.options.search.middlewares)\n }\n }\n // TODO remove preSearchFilters and postSearchFilters in v2\n else if (\n route.options.preSearchFilters ||\n route.options.postSearchFilters\n ) {\n const legacyMiddleware: SearchMiddleware = ({ search, next }) => {\n let nextSearch = search\n\n if (\n 'preSearchFilters' in route.options &&\n route.options.preSearchFilters\n ) {\n nextSearch = route.options.preSearchFilters.reduce(\n (prev, next) => next(prev),\n search,\n )\n }\n\n const result = next(nextSearch)\n\n if (\n 'postSearchFilters' in route.options &&\n route.options.postSearchFilters\n ) {\n return route.options.postSearchFilters.reduce(\n (prev, next) => next(prev),\n result,\n )\n }\n\n return result\n }\n context.middlewares.push(legacyMiddleware)\n }\n\n if (route.options.validateSearch) {\n const validate: SearchMiddleware = ({ search, next }) => {\n const result = next(search)\n if (!context._includeValidateSearch) return result\n try {\n const validatedSearch = {\n ...result,\n ...(validateSearch(route.options.validateSearch, result) ??\n undefined),\n }\n return validatedSearch\n } catch {\n // ignore errors here because they are already handled in matchRoutes\n return result\n }\n }\n\n context.middlewares.push(validate)\n }\n }\n\n // the chain ends here since `next` is not called\n const final: SearchMiddleware = ({ search }) => {\n const dest = context.dest\n if (!dest.search) {\n return {}\n }\n if (dest.search === true) {\n return search\n }\n return functionalUpdate(dest.search, search)\n }\n\n context.middlewares.push(final)\n\n const applyNext = (\n index: number,\n currentSearch: any,\n middlewares: Array>,\n ): any => {\n // no more middlewares left, return the current search\n if (index >= middlewares.length) {\n return currentSearch\n }\n\n const middleware = middlewares[index]!\n\n const next = (newSearch: any): any => {\n return applyNext(index + 1, newSearch, middlewares)\n }\n\n return middleware({ search: currentSearch, next })\n }\n\n return function middleware(\n search: any,\n dest: BuildNextOptions,\n _includeValidateSearch: boolean,\n ) {\n context.dest = dest\n context._includeValidateSearch = _includeValidateSearch\n return applyNext(0, search, context.middlewares)\n }\n}\n\nfunction findGlobalNotFoundRouteId(\n notFoundMode: 'root' | 'fuzzy' | undefined,\n routes: ReadonlyArray,\n) {\n if (notFoundMode !== 'root') {\n for (let i = routes.length - 1; i >= 0; i--) {\n const route = routes[i]!\n if (route.children) {\n return route.id\n }\n }\n }\n return rootRouteId\n}\n\nfunction extractStrictParams(\n route: AnyRoute,\n accumulatedParams: Record,\n) {\n const parseParams = route.options.params?.parse ?? route.options.parseParams\n if (parseParams) {\n const result = parseParams(accumulatedParams as Record)\n if (result === false) {\n throw new Error('Route params.parse returned false for a matched route')\n }\n Object.assign(accumulatedParams, result)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAw0BA,SAAgB,sBAAsB,KAAc;AAClD,KAAI,eAAe,OAAO;EACxB,MAAM,MAAM;GACV,MAAM,IAAI;GACV,SAAS,IAAI;GACd;AAED,MAAA,QAAA,IAAA,aAA6B,cACzB,KAAY,QAAQ,IAAI;AAG5B,SAAO;;AAGT,QAAO,EACL,MAAM,KACP;;;AAIH,MAAa,uBAAuB;CAClC,QAAQ;CACR,OAAO;CACP,UAAU;CACX;;;;;AASD,SAAgB,sBACd,UACA,kBACA;CACA,MAAM,eAAe;CACrB,MAAM,aAAa;AAInB,QAAO;EAAE;EAAc;EAAY,aAHf,cAAc,aAAa,WAAW;EAGV,aAF5B,cAAc,SAAS,WAAW;EAEO,aADzC,cAAc,SAAS,WAAW;EACoB;;;;;;;;;;;AA+C5E,IAAa,aAAb,MAME;;;;CA+CA,YACE,SAOA,gBACA;yBAtDoC,GAAG,KAAK,MAC5C,KAAK,QAAQ,GAAG,IACjB;yBACiB;8BACuC,KAAA;wCACd,KAAA;qCAC7B,IAAI,KAAkC;2BAEhC;kCACO;0CA4BA,IAAI,SAA4C;0BA0CrC,OAAO,IAAI;iBAgB5C,eAAe;AAClB,OAAA,QAAA,IAAA,aAA6B;QACvB,WAAW,cACb,SAAQ,KACN,gNACD;;GAIL,MAAM,cAAc,KAAK;GACzB,MAAM,eAAe,KAAK,YAAY,aAAa,YAAY;GAC/D,MAAM,mBAAmB,KAAK,aAAa,KAAA;GAC3C,MAAM,oBAAoB,aAAa;AAEvC,QAAK,UAAU;IACb,GAAG;IACH,GAAG;IACJ;AAED,QAAK,WAAW,KAAK,QAAQ,YAAY,OAAO,aAAa;AAE7D,QAAK,oBAAoB,IAAI,IAAI,KAAK,QAAQ,kBAAkB;AAEhE,OAAI,KAAK,QAAQ,4BACf,MAAK,oBAAoB,qBACvB,KAAK,QAAQ,4BACd;AAEH,OACE,CAAC,KAAK,WACL,KAAK,QAAQ,WAAW,KAAK,QAAQ,YAAY,KAAK,QAEvD,KAAI,CAAC,KAAK,QAAQ;QACZ,EAAE,YAAY,KAAK,UACrB,MAAK,UAAU,sBAAsB;SAGvC,MAAK,UAAU,KAAK,QAAQ;AAIhC,QAAK,SAAS,KAAK,QAAQ;AAC3B,OAAI,CAAC,KAAK,OACR,KACE,EAAE,YAAY,KAAK,aACnB,QAAQ,UACR,OAAO,WAAW,OAElB,MAAK,SAAS,OAAO;OAGrB,MAAK,SAAS;AAIlB,OAAI,KAAK,QACP,MAAK,sBAAsB;AAG7B,OAAI,KAAK,QAAQ,cAAc,KAAK,WAAW;AAC7C,SAAK,YAAY,KAAK,QAAQ;IAC9B,IAAI;AACJ,SACG,YAAY,KAAK,aAAA,QAAA,IAAA,aACO,iBACzB,WAAW,iBACX,WAAW,cAAc,cAAc,KAAK,WAC5C;KACA,MAAM,SAAS,WAAW;AAC1B,UAAK,mBAAmB,OAAO;AAC/B,8BAAyB,OAAO;WAC3B;AACL,UAAK,mBAAmB,eAAe,IAAK;AAC5C,8BAAyB,KAAK,gBAAgB;AAE9C,UACG,YAAY,KAAK,aAAA,QAAA,IAAA,aACO,iBACzB,WAAW,kBAAkB,KAAA,EAE7B,YAAW,gBAAgB;MACzB,WAAW,KAAK;MACQ;MACxB,kBAAkB,KAAK;MACxB;;AAGL,SAAK,UAAU,uBAAuB;;AAGxC,OAAI,CAAC,KAAK,UAAU,KAAK,gBAAgB;IACvC,MAAM,SAAS,KAAK,eAAe,KAAK;AACxC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,mBACZ,sBAAsB,KAAK,eAAe,EAC1C,OACD;AAED,QAAI,EAAE,YAAY,KAAK,UACrB,wBAAuB,KAAK;;GAIhC,IAAI,sBAAsB;GAC1B,MAAM,eAAe,KAAK,QAAQ,YAAY;GAC9C,MAAM,oBAAoB,KAAK,QAAQ;AAIvC,OAHwB,oBAAoB,iBAAiB,gBACtC,sBAAsB,mBAEN;AACrC,SAAK,WAAW;IAEhB,MAAM,WAAmC,EAAE;IAC3C,MAAM,UAAU,SAAS,aAAa;AACtC,QAAI,WAAW,YAAY,IACzB,UAAS,KACP,gBAAgB,EACd,UAAU,cACX,CAAC,CACH;AAEH,QAAI,kBACF,UAAS,KAAK,kBAAkB;AAGlC,SAAK,UACH,SAAS,WAAW,IAChB,KAAA,IACA,SAAS,WAAW,IAClB,SAAS,KACT,gBAAgB,SAAS;AAEjC,QAAI,KAAK,QACP,MAAK,sBAAsB;AAG7B,0BAAsB;;AAGxB,OAAI,uBAAuB,KAAK,OAC9B,MAAK,OAAO,SAAS,IAAI,KAAK,eAAe;AAG/C,OACE,OAAO,WAAW,eAClB,SAAS,UACT,OAAO,OAAO,KAAK,aAAa,WAEhC,MAAK,iCAAiC,OAAO,IAAI,SAC/C,2CACD;;oCAQwB;AAC3B,QAAK,iBAAiB,KAAK,cACzB,KAAK,QAAQ,UACb,KAAK,eACN;;8BAGoB;GACrB,MAAM,SAAS,iBACb,KAAK,WACL,KAAK,QAAQ,gBACZ,OAAO,MAAM;AACZ,UAAM,KAAK,EACT,eAAe,GAChB,CAAC;KAEL;AACD,OAAI,KAAK,QAAQ,WACf,mBAAkB,KAAK,QAAQ,YAAY,OAAO,cAAc;AAGlE,UAAO;;oBA4BiB,WAAW,OAAO;GAC1C,MAAM,WAAgC;IACpC;IACA;IACD;AAED,QAAK,YAAY,IAAI,SAAS;AAE9B,gBAAa;AACX,SAAK,YAAY,OAAO,SAAS;;;eAIrB,gBAAgB;AAC9B,QAAK,YAAY,SAAS,aAAa;AACrC,QAAI,SAAS,cAAc,YAAY,KACrC,UAAS,GAAG,YAAY;KAE1B;;wBAQF,iBACA,qBACG;GACH,MAAM,SAAS,EACb,UACA,QACA,MACA,MACA,YACmE;AAInE,QAAI,CAAC,KAAK,WAAW,CAAC,gCAAgC,KAAK,SAAS,EAAE;KACpE,MAAM,eAAe,KAAK,QAAQ,YAAY,OAAO;KACrD,MAAM,YAAY,KAAK,QAAQ,gBAAgB,aAAa;AAE5D,YAAO;MACL,MAAM,WAAW,YAAY;MAC7B,YAAY,WAAW,YAAY;MACnC,UAAU,WAAW,SAAS,CAAC;MAC/B,UAAU;MACV;MACA,QAAQ,qBACN,kBAAkB,QAClB,aACD;MACD,MAAM,WAAW,KAAK,MAAM,EAAE,CAAC,CAAC;MAChC,OAAO,iBAAiB,kBAAkB,OAAO,MAAM;MACxD;;IAKH,MAAM,UAAU,IAAI,IAAI,MAAM,KAAK,OAAO;IAE1C,MAAM,MAAM,oBAAoB,KAAK,SAAS,QAAQ;IAEtD,MAAM,eAAe,KAAK,QAAQ,YAAY,IAAI,OAAO;IACzD,MAAM,YAAY,KAAK,QAAQ,gBAAgB,aAAa;AAG5D,QAAI,SAAS;AAIb,WAAO;KACL,MAHe,IAAI,KAAK,QAAQ,IAAI,QAAQ,GAAG;KAI/C,YAAY;KACZ,UAAU,WAAW,IAAI,SAAS,CAAC;KACnC,UAAU,CAAC,CAAC,KAAK,WAAW,IAAI,WAAW,KAAK;KAChD;KACA,QAAQ,qBACN,kBAAkB,QAClB,aACD;KACD,MAAM,WAAW,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;KACpC,OAAO,iBAAiB,kBAAkB,OAAO,MAAM;KACxD;;GAGH,MAAM,WAAW,MAAM,gBAAgB;GAEvC,MAAM,EAAE,gBAAgB,cAAc,SAAS;AAE/C,OAAI,mBAAmB,CAAC,aAAa,cAAc,KAAK,kBAAkB;IAExE,MAAM,qBAAqB,MAAM,eAAe;AAChD,uBAAmB,MAAM,MAAM,SAAS,MAAM;AAC9C,uBAAmB,MAAM,YAAY,SAAS,MAAM;AAEpD,WAAO,mBAAmB,MAAM;AAEhC,WAAO;KACL,GAAG;KACH,gBAAgB;KACjB;;AAEH,UAAO;;8BAIc,MAAc,SAAiB;AACpD,UAAO,YAAY;IACjB,MAAM;IACN,IAAI,KAAK,SAAS,KAAK,GAAG,UAAU,KAAK,GAAG;IAC5C,eAAe,KAAK,QAAQ;IAC5B,OAAO,KAAK;IACb,CAAC;;sBAiBF,gBACA,sBACA,SACG;AACH,OAAI,OAAO,mBAAmB,SAC5B,QAAO,KAAK,oBACV;IACE,UAAU;IACV,QAAQ;IACT,EACD,KACD;AAGH,UAAO,KAAK,oBAAoB,gBAAgB,qBAAqB;;2BAuSjC,aAAa;AACjD,UAAO,iBAAiB;IACtB;IACA,YAAY,KAAK;IACjB,eAAe,KAAK;IACrB,CAAC;;sBA6EW,OAAe;GAC5B,MAAM,QAAQ,KAAK,SAAS,GAAG;AAE/B,OAAI,CAAC,MAAO;AAEZ,SAAM,gBAAgB,OAAO;AAC7B,gBAAa,MAAM,aAAa,eAAe;AAC/C,SAAM,aAAa,iBAAiB,KAAA;;6BAGhB;AACpB,QAAK,OAAO,WAAW,KAAK,CAAC,SAAS,YAAY;AAChD,SAAK,YAAY,QAAQ;KACzB;AAEF,QAAK,OAAO,UAAU,KAAK,CAAC,SAAS,YAAY;AAC/C,QAAI,KAAK,OAAO,mBAAmB,IAAI,QAAQ,CAC7C;IAGF,MAAM,QAAQ,KAAK,OAAO,YAAY,IAAI,QAAQ,EAAE,KAAK;AACzD,QAAI,CAAC,MACH;AAGF,QAAI,MAAM,WAAW,aAAa,MAAM,eAAe,SACrD,MAAK,YAAY,QAAQ;KAE3B;;wBAU8B,SAAS;GACzC,MAAM,SACJ,OAEI,EAAE,KACa;IAEnB,MAAM,kBACJ,KAAK,iBAAiB,KAAK,wBAAwB,KAAK;IAI1D,MAAM,oBAAoB,KAAK,uBAAuB,gBAAgB;AAItE,QACE,KAAK,QAAA,QAAA,IAAA,aACoB,gBACzB,KAAK,aACL;KACA,MAAM,iBAAiB,KAAK,iBAAiB,KAAK,KAAK,CAAC;KAExD,MAAM,cAAc,SAAS,kBAAkB,gBAAgB,MAAM;AACnE,aAAO,aAAa,EAAE,UAAU,KAAK,KAAM;OAC3C;KAEF,MAAM,iBAAiB,SAAS,iBAAiB,MAAM;AACrD,aAAO,aAAa,EAAE,UAAU,kBAAkB,SAAS;OAC3D;AAIF,SAAI,CAAC,eAAe,CAAC,eACnB,SAAQ,KAAK,kCAAkC,KAAK,OAAO;;IAI/D,MAAM,oBACJ,KAAK,mBAAmB,SACpB,gBAAgB,WACf,KAAK,QAAQ,kBAAkB;IACtC,MAAM,SAAS,KAAK,KAAK,GAAG,KAAK,OAAO,KAAA;IAGxC,MAAM,aAAa,kBAAkB;IAErC,MAAM,aAAa,OAAO,OACxB,OAAO,OAAO,KAAK,EACnB,kBAAkB,OACnB;IAGD,MAAM,aADe,QAAQ,WAAW,EAAE,KAAK,KAE3C,MACA,KAAK,oBAAoB,mBAAmB,IAAI;IAGpD,MAAM,SAAS,SACX,KAAK,oBAAoB,YAAY,OAAO,GAC5C;IAGJ,MAAM,aACJ,KAAK,WAAW,SAAS,KAAK,WAAW,OACrC,OAAO,OAAO,KAAK,IAClB,KAAK,UAAU,UAAU,OACxB,aACA,OAAO,OACL,YACA,iBAAiB,KAAK,QAAe,WAAW,CACjD;IAET,MAAM,YAAY,KAAK,aACrB,cAAc,OAAO;IAGvB,IAAI;AACJ,QAAI,UACF,cAAa,KAAK,eAAe,UAAU;aAClC,OAAO,SAAS,IAAI,CAG7B,cAAa,EAAE;SACV;KACL,MAAM,kBAAkB,KAAK,iBAAiB,OAAO;AACrD,kBAAa,gBAAgB;AAE7B,SACE,KAAK,QAAQ,kBACZ,CAAC,gBAAgB,cACf,gBAAgB,WAAW,SAAS,OACnC,gBAAgB,YAAY,OAEhC,cAAa,CAAC,GAAG,YAAY,KAAK,QAAQ,cAAc;;AAK5D,QAAI,WAAW,UAAU,QAAQ,WAAW,CAC1C,MAAK,MAAM,SAAS,YAAY;KAC9B,MAAM,KACJ,MAAM,QAAQ,QAAQ,aAAa,MAAM,QAAQ;AACnD,SAAI,GACF,KAAI;AACF,aAAO,OAAO,YAAY,GAAG,WAAW,CAAC;aACnC;;IAWd,MAAM,eAAe,KAAK,cAEtB,SACA,WACE,gBAAgB;KACd,MAAM;KACN,QAAQ;KACR,SAAS,KAAK;KACd,QAAQ,KAAK;KACd,CAAC,CAAC,iBACJ,CAAC;AAEN,QAAA,QAAA,IAAA,aAC2B,gBACzB,aACA,CAAC,KAAK,YAEN,KAAI;AAEF,SADkB,KAAK,iBAAiB,aAAa,CACvC,YAAY,OAAO,UAAU,GACzC,SAAQ,KACN,mBAAmB,aAAa,eAAe,UAAU,GAAG,wDAC7D;YAEG;IAOV,IAAI,aAAa;AACjB,QAAI,KAAK,0BAA0B,KAAK,QAAQ,QAAQ,QAAQ;KAC9D,MAAM,kBAAkB,EAAE;AAC1B,gBAAW,SAAS,UAAU;AAC5B,UAAI,MAAM,QAAQ,eAChB,KAAI;AACF,cAAO,OACL,iBACA,eAAe,MAAM,QAAQ,gBAAgB;QAC3C,GAAG;QACH,GAAG;QACJ,CAAC,CACH;cACK;OAIV;AACF,kBAAa;;AAGf,iBAAa,sBAAsB;KACjC,QAAQ;KACR;KACA;KACA,wBAAwB,KAAK;KAC9B,CAAC;AAGF,iBAAa,qBAAqB,YAAY,WAAW;IAGzD,MAAM,YAAY,KAAK,QAAQ,gBAAgB,WAAW;IAG1D,MAAM,OACJ,KAAK,SAAS,OACV,gBAAgB,OAChB,KAAK,OACH,iBAAiB,KAAK,MAAM,gBAAgB,KAAK,GACjD,KAAA;IAGR,MAAM,UAAU,OAAO,IAAI,SAAS;IAGpC,IAAI,YACF,KAAK,UAAU,OACX,gBAAgB,QAChB,KAAK,QACH,iBAAiB,KAAK,OAAO,gBAAgB,MAAM,GACnD,EAAE;AAGV,gBAAY,iBAAiB,gBAAgB,OAAO,UAAU;IAG9D,MAAM,WAAW,GAAG,eAAe,YAAY;IAG/C,IAAI;IACJ,IAAI;IACJ,IAAI,WAAW;AAEf,QAAI,KAAK,SAAS;KAEhB,MAAM,MAAM,IAAI,IAAI,UAAU,KAAK,OAAO;KAC1C,MAAM,eAAe,qBAAqB,KAAK,SAAS,IAAI;AAC5D,YAAO,IAAI,KAAK,QAAQ,IAAI,QAAQ,GAAG;AAGvC,SAAI,aAAa,WAAW,KAAK,QAAQ;AACvC,mBAAa,aAAa;AAC1B,iBAAW;WAEX,cACE,aAAa,WAAW,aAAa,SAAS,aAAa;WAE1D;AAKL,YAAO,kBAAkB,SAAS;AAClC,kBAAa;;AAGf,WAAO;KACL;KACA;KACA,UAAU;KACV,QAAQ;KACR;KACA,OAAO;KACP,MAAM,QAAQ;KACd;KACA,gBAAgB,KAAK;KACtB;;GAGH,MAAM,oBACJ,OAAyB,EAAE,EAC3B,eACG;IACH,MAAM,OAAO,MAAM,KAAK;IAExB,IAAI,aAAa,aAAa,MAAM,WAAW,GAAG,KAAA;AAElD,QAAI,CAAC,YAAY;KACf,MAAM,SAAS,OAAO,OAAO,KAAK;AAElC,SAAI,KAAK,QAAQ,YAAY;MAC3B,MAAM,QAAQ,cACZ,KAAK,UACL,KAAK,cACN;AACD,UAAI,OAAO;AACT,cAAO,OAAO,QAAQ,MAAM,UAAU;OACtC,MAAM,EACJ,MAAM,OACN,QAAQ,YACR,GAAG,cACD,MAAM;OAIV,MAAM,aACJ,eAAe,SAAS,eAAe,OACnC,OAAO,OAAO,KAAK,IAClB,cAAc,UAAU,OACvB,SACA,OAAO,OAAO,QAAQ,iBAAiB,YAAY,OAAO,CAAC;AAEnE,oBAAa;QACX,MAAM,KAAK;QACX,GAAG;QACH,QAAQ;QACT;AACD,oBAAa,MAAM,WAAW;;;;AAKpC,QAAI,WACF,MAAK,iBAAiB;AAGxB,WAAO;;AAGT,OAAI,KAAK,KACP,QAAO,iBAAiB,MAAM;IAC5B,MAAM,KAAK;IACX,GAAG,KAAK;IACT,CAAC;AAGJ,UAAO,iBAAiB,KAAK;;wBASI,OAAO,EACxC,gBACA,eACA,GAAG,WACC;GACJ,MAAM,oBAAoB;IAIxB,MAAM,eAAe;KACnB;KACA;KACA;KACA;KACD;AACD,iBAAa,SAAS,SAAS;AAC3B,UAAK,MAAc,QAAQ,KAAK,eAAe,MAAM;MACvD;IACF,MAAM,UAAU,UAAU,KAAK,OAAO,KAAK,eAAe,MAAM;AAChE,iBAAa,SAAS,SAAS;AAC7B,YAAO,KAAK,MAAM;MAClB;AACF,WAAO;;GAGT,MAAM,YACJ,cAAc,KAAK,eAAe,KAAK,KAAK,cAAc,KAAK,KAAK;GAEtE,IAAI,wBAAwB,KAAK;AACjC,QAAK,wBAAwB,8BAAoC;AAC/D,2BAAuB,SAAS;AAChC,4BAAwB,KAAA;KACxB;AAGF,OAAI,aAAa,aAAa,CAC5B,MAAK,MAAM;QACN;IACL,IAAI,EAEF,gBAEA,oBACA,GAAG,gBACD;AAEJ,QAAI,gBAAgB;AAClB,mBAAc;MACZ,GAAG;MACH,OAAO;OACL,GAAG,eAAe;OAClB,WAAW,KAAA;OACX,gBAAgB;QACd,GAAG;QACH,QAAQ,YAAY;QACpB,OAAO;SACL,GAAG,YAAY;SACf,WAAW,KAAA;SACX,gBAAgB,KAAA;SAChB,WAAW,KAAA;SACX,KAAK,KAAA;SACN;QACF;OACF;MACF;AAED,SACE,YAAY,kBACZ,KAAK,QAAQ,kBACb,MAEA,aAAY,MAAM,YAAY,KAAK;;AAIvC,gBAAY,MAAM,8BAChB,sBAAsB,KAAK,QAAQ,6BAA6B;AAElE,SAAK,uBAAuB;AAE5B,SAAK,QAAQ,KAAK,UAAU,YAAY,QACtC,YAAY,YACZ,YAAY,OACZ,EAAE,eAAe,CAClB;;AAGH,QAAK,kBAAkB,KAAK,eAAe;AAE3C,OAAI,CAAC,KAAK,QAAQ,YAAY,KAC5B,MAAK,MAAM;AAGb,UAAO,KAAK;;iCAIY,EACxB,SACA,aACA,oBACA,gBACA,eACA,MACA,GAAG,SACyC,EAAE,KAAK;AACnD,OAAI,MAAM;IACR,MAAM,eAAe,KAAK,QAAQ,SAAS,MAAM;IAEjD,MAAM,SAAS,UAAU,MAAM,EAC7B,aAAa,UAAU,eAAe,eAAe,GACtD,CAAC;IAKF,MAAM,UAAU,IAAI,IAAI,OAAO,UAAU,KAAK,OAAO;AAGrD,SAAK,KAFgB,oBAAoB,KAAK,SAAS,QAAQ,CAExC;AACvB,SAAK,SAAS,KAAK,QAAQ,YAAY,OAAO,OAAO;AAErD,SAAK,OAAO,OAAO,KAAK,MAAM,EAAE;;GAGlC,MAAM,WAAW,KAAK,cAAc;IAClC,GAAI;IACJ,wBAAwB;IACzB,CAAC;AAEF,QAAK,uBAAuB;GAI5B,MAAM,gBAAgB,KAAK,eAAe;IACxC,GAAG;IACH;IACA;IACA;IACA;IACA;IACD,CAAC;AAIF,WAAQ,SAAS,CAAC,WAAW;AAC3B,QAAI,KAAK,yBAAyB,SAChC,MAAK,uBAAuB,KAAA;KAE9B;AAEF,UAAO;;kBAUc,OAAO,EAC5B,IACA,gBACA,MACA,YACA,GAAG,WACC;GACJ,IAAI,YAAY;AAEhB,OAAI,KACF,KAAI;AACF,QAAI,IAAI,GAAG,OAAO;AAClB,gBAAY;WACN;AAGV,OAAI,aAAa,CAAC,eAChB,kBAAiB;AAGnB,OAAI,gBAAgB;AAKlB,QAAI,OAAO,KAAA,KAAa,CAAC,MAAM;KAC7B,MAAM,WAAW,KAAK,cAAc;MAAE;MAAI,GAAG;MAAM,CAAQ;AAE3D,YAAO,QAAQ,SAAS;AACxB,kBAAa,cAAc,SAAS;;IAKtC,MAAM,aAAa,CAAC,aAAa,aAAa,aAAa;AAI3D,QAAI,oBAAoB,YAAY,KAAK,kBAAkB,EAAE;AAC3D,SAAA,QAAA,IAAA,aAA6B,aAC3B,SAAQ,KACN,6CAA6C,aAC9C;AAEH,YAAO,QAAQ,SAAS;;AAI1B,QAAI,CAAC,KAAK,eAAe;KAGvB,MAAM,WADsB,KAAK,QACI,eAAe,IAAI,EAAE;AAC1D,UAAK,MAAM,WAAW,SACpB,KAAI,SAAS;UACS,MAAM,QAAQ,UAAU;OAC1C,iBAAiB,KAAK;OACtB,cAAc,KAAK;OACnB,QAAQ;OACT,CAAC,CAEA,QAAO,QAAQ,SAAS;;;AAMhC,QAAI,KAAK,QACP,QAAO,SAAS,QAAQ,WAAW;QAEnC,QAAO,SAAS,OAAO;AAEzB,WAAO,QAAQ,SAAS;;AAG1B,UAAO,KAAK,uBAAuB;IACjC,GAAG;IACH;IACI;IACJ,aAAa;IACd,CAAC;;0BAKe;AAEjB,QAAK,eAAe;AACpB,QAAK,sBAAsB;AAE3B,OAAI,YAAY,KAAK,UAAU;IAE7B,MAAM,eAAe,KAAK,cAAc;KACtC,IAAI,KAAK,eAAe;KACxB,QAAQ;KACR,QAAQ;KACR,MAAM;KACN,OAAO;KACP,wBAAwB;KACzB,CAAC;AAIF,QAAI,KAAK,eAAe,eAAe,aAAa,YAAY;KAC9D,MAAM,OAAO,KAAK,sBAAsB,aAAa;AACrD,SAAI,aAAa,SACf,OAAM,SAAS,EAAE,MAAM,CAAC;SAExB,OAAM,SAAS;MAAE;MAAM,gBAAgB;MAAc,CAAC;;;GAM5D,MAAM,iBAAiB,KAAK,YAAY,KAAK,eAAe;GAE5D,MAAM,oBAAoB,KAAK,OAAO,cACnC,KAAK,CACL,QAAQ,MAAM,CAAC,eAAe,MAAM,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC;AAG5D,QAAK,YAAY;AACf,SAAK,OAAO,OAAO,IAAI,UAAU;AACjC,SAAK,OAAO,WAAW,IAAI,IAAI;AAC/B,SAAK,OAAO,UAAU,IAAI,KAAK;AAC/B,SAAK,OAAO,SAAS,IAAI,KAAK,eAAe;AAC7C,SAAK,OAAO,WAAW,eAAe;AAEtC,SAAK,OAAO,UAAU,kBAAkB;KACxC;;cAGW,OAAO,SAA6C;GACjE,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM,mBACJ,KAAK,OAAO,iBAAiB,KAAK,IAAI,KAAK,OAAO,SAAS,KAAK;AAGlE,iBAAc,IAAI,SAAe,YAAY;AAC3C,SAAK,gBAAgB,YAAY;AAC/B,SAAI;AACF,WAAK,YAAY;MACjB,MAAM,OAAO,KAAK;MAElB,MAAM,qBAAqB,sBAAsB,MAD5B,KAAK,OAAO,iBAAiB,KAAK,CACa;AAEpE,UAAI,CAAC,KAAK,OAAO,SAAS,KAAK,CAC7B,MAAK,KAAK;OACR,MAAM;OACN,GAAG;OACJ,CAAC;AAGJ,WAAK,KAAK;OACR,MAAM;OACN,GAAG;OACJ,CAAC;AAEF,YAAM,YAAY;OAChB,QAAQ;OACR,MAAM,MAAM;OACZ,kBAAkB,iBAAiB,SAAS,KAAK;OACjD,SAAS,KAAK,OAAO,eAAe,KAAK;OACzC,UAAU;OACV,aAAa,KAAK;OAElB,SAAS,YAAY;AAEnB,aAAK,sBAAsB;AACzB,cAAK,oBAAoB,YAAY;UAQnC,IAAI,iBAA8C;UAIlD,IAAI,qBAAkD;UACtD,IAAI,sBAAmD;UACvD,IAAI,qBAAkD;AAEtD,eAAK,YAAY;WACf,MAAM,iBAAiB,KAAK,OAAO,eAAe,KAAK;WACvD,MAAM,eAAe,eAAe;WACpC,MAAM,iBAAiB,KAAK,OAAO,QAAQ,KAAK;AAEhD,4BAAiB,eACb,eAAe,QACZ,UACC,CAAC,KAAK,OAAO,mBAAmB,IAAI,MAAM,GAAG,CAChD,GACD;WAIJ,MAAM,kCAAkB,IAAI,KAAa;AACzC,gBAAK,MAAM,KAAK,KAAK,OAAO,mBAAmB,QAAQ,CACrD,KAAI,EAAE,QAAS,iBAAgB,IAAI,EAAE,QAAQ;WAE/C,MAAM,iCAAiB,IAAI,KAAa;AACxC,gBAAK,MAAM,KAAK,KAAK,OAAO,YAAY,QAAQ,CAC9C,KAAI,EAAE,QAAS,gBAAe,IAAI,EAAE,QAAQ;AAG9C,gCAAqB,eACjB,eAAe,QACZ,UAAU,CAAC,gBAAgB,IAAI,MAAM,QAAQ,CAC/C,GACD;AACJ,iCAAsB,eAClB,eAAe,QACZ,UAAU,CAAC,eAAe,IAAI,MAAM,QAAQ,CAC9C,GACD;AACJ,gCAAqB,eACjB,eAAe,QAAQ,UACrB,eAAe,IAAI,MAAM,QAAQ,CAClC,GACD;AAEJ,gBAAK,OAAO,UAAU,IAAI,MAAM;AAChC,gBAAK,OAAO,SAAS,IAAI,KAAK,KAAK,CAAC;;;;;;;AAOpC,eAAI,cAAc;AAChB,iBAAK,OAAO,WAAW,eAAe;AACtC,iBAAK,OAAO,WAAW,EAAE,CAAC;AAC1B,iBAAK,OAAO,UAAU,CACpB,GAAG,KAAK,OAAO,cAAc,KAAK,EAClC,GAAG,eAAgB,QAChB,MACC,EAAE,WAAW,WACb,EAAE,WAAW,cACb,EAAE,WAAW,aAChB,CACF,CAAC;AACF,iBAAK,mBAAmB;;YAE1B;AAGF,eAAK,MAAM,CAAC,SAAS,SAAS;WAC5B,CAAC,oBAAoB,UAAU;WAC/B,CAAC,qBAAqB,UAAU;WAChC,CAAC,oBAAoB,SAAS;WAC/B,EAAW;AACV,eAAI,CAAC,QAAS;AACd,gBAAK,MAAM,SAAS,QAClB,MAAK,gBAAgB,MAAM,SAAU,QAAQ,QAC3C,MACD;;WAGL;UACF;;OAEL,CAAC;cACK,KAAK;AACZ,UAAI,WAAW,IAAI,EAAE;AACnB,kBAAW;AACX,WAAI,EAAE,YAAY,KAAK,UACrB,MAAK,SAAS;QACZ,GAAG,SAAS;QACZ,SAAS;QACT,eAAe;QAChB,CAAC;iBAEK,WAAW,IAAI,CACxB,YAAW;MAGb,MAAM,iBAAiB,WACnB,SAAS,SACT,WACE,MACA,KAAK,OAAO,QAAQ,KAAK,CAAC,MAAM,MAAM,EAAE,WAAW,QAAQ,GACzD,MACA;AAER,WAAK,YAAY;AACf,YAAK,OAAO,WAAW,IAAI,eAAe;AAC1C,YAAK,OAAO,SAAS,IAAI,SAAS;QAClC;;AAGJ,SAAI,KAAK,sBAAsB,aAAa;AAC1C,WAAK,uBAAuB,SAAS;AACrC,WAAK,oBAAoB,KAAA;AACzB,WAAK,wBAAwB,KAAA;;AAG/B,cAAS;MACT;KACF;AAEF,QAAK,oBAAoB;AAEzB,SAAM;AAEN,UACG,KAAK,qBACN,gBAAgB,KAAK,kBAErB,OAAM,KAAK;GAGb,IAAI,gBAAoC,KAAA;AACxC,OAAI,KAAK,kBAAkB,CACzB,iBAAgB;YACP,KAAK,OAAO,QAAQ,KAAK,CAAC,MAAM,MAAM,EAAE,WAAW,QAAQ,CACpE,iBAAgB;AAElB,OAAI,kBAAkB,KAAA,EACpB,MAAK,OAAO,WAAW,IAAI,cAAc;;8BAItB,OAA4B;GAGjD,MAAM,uBACJ,KAAK,wBAAwB,KAAK,QAAQ;AAG5C,QAAK,uBAAuB,KAAA;AAG5B,OACE,wBACA,OAAO,aAAa,eACpB,yBAAyB,YACzB,OAAO,SAAS,wBAAwB,YACxC;IAGA,IAAI;AAEJ,QACE,OAAO,yBAAyB,YAChC,KAAK,gCACL;KACA,MAAM,OAAO,KAAK;KAClB,MAAM,eAAe,KAAK,OAAO,iBAAiB,KAAK;KAEvD,MAAM,8BACJ,OAAO,qBAAqB,UAAU,aAClC,qBAAqB,MACnB,sBAAsB,MAAM,aAAa,CAC1C,GACD,qBAAqB;AAE3B,SAAI,gCAAgC,OAAO;AACzC,UAAI;AACJ;;AAGF,iCAA4B;MAC1B,QAAQ;MACR,OAAO;MACR;UAED,6BAA4B;AAG9B,aAAS,oBAAoB,0BAA0B;SAEvD,KAAI;;sBAIsB,IAAI,YAAY;AAC5C,QAAK,sBAAsB;IACzB,MAAM,eAAe,KAAK,OAAO,mBAAmB,IAAI,GAAG;AAC3D,QAAI,cAAc;AAChB,kBAAa,IAAI,QAAQ;AACzB;;IAGF,MAAM,cAAc,KAAK,OAAO,YAAY,IAAI,GAAG;AACnD,QAAI,aAAa;AACf,iBAAY,IAAI,QAAQ;AACxB;;IAGF,MAAM,cAAc,KAAK,OAAO,kBAAkB,IAAI,GAAG;AACzD,QAAI,aAAa;KACf,MAAM,OAAO,QAAQ,YAAY,KAAK,CAAC;AACvC,SAAI,KAAK,WAAW;UACF,KAAK,OAAO,kBAAkB,OAAO,GAAG,CAEtD,MAAK,OAAO,UAAU,KAAK,SACzB,KAAK,QAAQ,YAAY,YAAY,GAAG,CACzC;WAGH,aAAY,IAAI,KAAK;;KAGzB;;mBAGoB,YAA+C;AACrE,UACE,KAAK,OAAO,kBAAkB,IAAI,QAAQ,EAAE,KAAK,IACjD,KAAK,OAAO,mBAAmB,IAAI,QAAQ,EAAE,KAAK,IAClD,KAAK,OAAO,YAAY,IAAI,QAAQ,EAAE,KAAK;;qBAoB1C,SAAS;GACZ,MAAM,cAAc,MAAkC;AACpD,QAAI,MAAM,SAAS,EAA+B,IAAI,KACpD,QAAO;KACL,GAAG;KACH,SAAS;KACT,GAAI,MAAM,gBACV,EAAE,WAAW,WACb,EAAE,WAAW,aACR;MAAE,QAAQ;MAAW,OAAO,KAAA;MAAW,GACxC,KAAA;KACL;AAEH,WAAO;;AAGT,QAAK,YAAY;AACf,SAAK,OAAO,WAAW,KAAK,OAAO,QAAQ,KAAK,CAAC,IAAI,WAAW,CAAC;AACjE,SAAK,OAAO,UAAU,KAAK,OAAO,cAAc,KAAK,CAAC,IAAI,WAAW,CAAC;AACtE,SAAK,OAAO,WAAW,KAAK,OAAO,eAAe,KAAK,CAAC,IAAI,WAAW,CAAC;KACxE;AAEF,QAAK,uBAAuB;AAC5B,UAAO,KAAK,KAAK,EAAE,MAAM,MAAM,MAAM,CAAC;;gCAGf,aAA6B;AAGpD,UAAO,SAAS,cAAc;;0BAGb,aAAuC;GACxD,MAAM,iBAAiB,SAAS,QAAQ,IAAI,WAAW;AAEvD,OAAI,CAAC,SAAS,QAAQ,QAAQ,SAAS,QAAQ,gBAAgB;IAC7D,MAAM,WACJ,SAAS,QAAQ,kBAAkB,KAAK,cAAc,SAAS,QAAQ;IACzE,MAAM,OAAO,KAAK,sBAAsB,SAAS;AACjD,aAAS,QAAQ,OAAO;AACxB,aAAS,QAAQ,IAAI,YAAY,KAAK;cAC7B,eACT,KAAI;IACF,MAAM,MAAM,IAAI,IAAI,eAAe;AACnC,QAAI,KAAK,UAAU,IAAI,WAAW,KAAK,QAAQ;KAC7C,MAAM,OAAO,IAAI,WAAW,IAAI,SAAS,IAAI;AAC7C,cAAS,QAAQ,OAAO;AACxB,cAAS,QAAQ,IAAI,YAAY,KAAK;;WAElC;AAKV,OACE,SAAS,QAAQ,QACjB,CAAC,SAAS,QAAQ,kBAElB,oBAAoB,SAAS,QAAQ,MAAM,KAAK,kBAAkB,CAElE,OAAM,IAAI,MAAA,QAAA,IAAA,aACiB,eACrB,8CAA8C,SAAS,QAAQ,KAAK,wBAAwB,MAAM,KAAK,KAAK,kBAAkB,CAAC,KAAK,KAAK,CAAC,KAC1I,oCACL;AAGH,OAAI,CAAC,SAAS,QAAQ,IAAI,WAAW,CACnC,UAAS,QAAQ,IAAI,YAAY,SAAS,QAAQ,KAAK;AAGzD,UAAO;;qBAGyB,SAAS;GACzC,MAAM,SAAS,MAAM;AACrB,OAAI,WAAW,KAAA,EACb,MAAK,OAAO,UACV,KAAK,OAAO,cACT,KAAK,CACL,QAAQ,MAAM,CAAC,OAAO,EAA+B,CAAC,CAC1D;OAED,MAAK,OAAO,UAAU,EAAE,CAAC;;iCAIH;GACxB,MAAM,MAAM,KAAK,KAAK;GAEtB,MAAM,UAAU,MAAkC;IAChD,MAAM,QAAQ,KAAK,gBAAgB,EAAE;AAErC,QAAI,CAAC,MAAM,QAAQ,OACjB,QAAO;IAKT,MAAM,UACH,EAAE,UACE,MAAM,QAAQ,iBAAiB,KAAK,QAAQ,uBAC5C,MAAM,QAAQ,UAAU,KAAK,QAAQ,kBAC1C,MAAS;AAGX,QADgB,EAAE,WAAW,QAChB,QAAO;AAGpB,WADmB,MAAM,EAAE,aAAa;;AAG1C,QAAK,WAAW,EAAE,QAAQ,CAAC;;wBAGZ;sBAOb,OAAO,SAAS;GAClB,MAAM,OAAO,KAAK,kBAAkB,KAAK,cAAc,KAAY;GAEnE,IAAI,UAAU,KAAK,YAAY,MAAM;IACnC,cAAc;IACd,SAAS;IACT,MAAM;IACP,CAAC;GAEF,MAAM,iBAAiB,IAAI,IAAI,CAC7B,GAAG,KAAK,OAAO,UAAU,KAAK,EAC9B,GAAG,KAAK,OAAO,WAAW,KAAK,CAChC,CAAC;GAEF,MAAM,iBAAiB,IAAI,IAAI,CAC7B,GAAG,gBACH,GAAG,KAAK,OAAO,UAAU,KAAK,CAC/B,CAAC;GAGF,MAAM,iBAAiB,QAAQ,QAC5B,UAAU,CAAC,eAAe,IAAI,MAAM,GAAG,CACzC;AACD,OAAI,eAAe,QAAQ;IACzB,MAAM,gBAAgB,KAAK,OAAO,cAAc,KAAK;AACrD,SAAK,OAAO,UAAU,CAAC,GAAG,eAAe,GAAG,eAAe,CAAC;;AAG9D,OAAI;AACF,cAAU,MAAM,YAAY;KAC1B,QAAQ;KACR;KACA,UAAU;KACV,SAAS;KACT,cAAc,IAAI,YAAY;AAE5B,UAAI,eAAe,IAAI,GAAG,CACxB,WAAU,QAAQ,KAAK,MAAO,EAAE,OAAO,KAAK,QAAQ,EAAE,GAAG,EAAG;UAE5D,MAAK,YAAY,IAAI,QAAQ;;KAGlC,CAAC;AAEF,WAAO;YACA,KAAK;AACZ,QAAI,WAAW,IAAI,EAAE;AACnB,SAAI,IAAI,QAAQ,eACd;AAGF,YAAO,MAAM,KAAK,aAAa;MAC7B,GAAG,IAAI;MACP,eAAe;MAChB,CAAC;;AAEJ,QAAI,CAAC,WAAW,IAAI,CAElB,SAAQ,MAAM,IAAI;AAEpB;;;qBASC,UAAU,SAAS;GACtB,MAAM,gBAAgB;IACpB,GAAG;IACH,IAAI,SAAS,KACT,KAAK,oBAAoB,SAAS,QAAQ,IAAI,SAAS,GAAa,GACpE,KAAA;IACJ,QAAQ,SAAS,UAAU,EAAE;IAC7B,aAAa;IACd;GACD,MAAM,OAAO,KAAK,cAAc,cAAqB;AAErD,OAAI,MAAM,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK,UAChD,QAAO;GAMT,MAAM,gBAFJ,MAAM,YAAY,KAAA,IAAY,CAAC,KAAK,OAAO,UAAU,KAAK,GAAG,KAAK,WAGhE,KAAK,iBACL,KAAK,OAAO,iBAAiB,KAAK,IAAI,KAAK,OAAO,SAAS,KAAK;GAEpE,MAAM,QAAQ,gBACZ,KAAK,UACL,MAAM,iBAAiB,OACvB,MAAM,SAAS,OACf,aAAa,UACb,KAAK,cACN;AAED,OAAI,CAAC,MACH,QAAO;AAGT,OAAI,SAAS;QACP,CAAC,UAAU,MAAM,WAAW,SAAS,QAAQ,EAAE,SAAS,MAAM,CAAC,CACjE,QAAO;;AAIX,OAAI,MAAM,iBAAiB,KACzB,QAAO,UAAU,aAAa,QAAQ,KAAK,QAAQ,EAAE,SAAS,MAAM,CAAC,GACjE,MAAM,YACN;AAGN,UAAO,MAAM;;gCASU;AACvB,UAAO,KAAK,OAAO,QAChB,KAAK,CACL,MAAM,MAAM,EAAE,WAAW,cAAc,EAAE,eAAe;;AA56D3D,OAAK,iBAAiB;AAEtB,OAAK,OAAO;GACV,qBAAqB;GACrB,kBAAkB;GAClB,qBAAqB;GACrB,SAAS,KAAA;GACT,GAAG;GACH,eAAe,QAAQ,iBAAiB;GACxC,cAAc,QAAQ,gBAAgB;GACtC,iBAAiB,QAAQ,mBAAmB;GAC5C,aAAa,QAAQ,eAAe;GACpC,mBACE,QAAQ,qBAAqB;GAChC,CAAC;AAEF,MAAI,OAAO,aAAa,YACtB,MAAK,iBAAiB;;CAS1B,UAAU;AACR,SAAO,CAAC,CAAC,KAAK,QAAQ;;CAGxB,iBAAiB;AACf,SAAO,CAAC,CAAC,KAAK,QAAQ;;CAmKxB,IAAI,QAAiC;AACnC,SAAO,KAAK,OAAO,QAAQ,KAAK;;CA2BlC,UAAU,EACR,YACA,cACA,iBACqC;AACrC,OAAK,aAAa;AAClB,OAAK,eAAe;AACpB,OAAK,gBAAgB;EAErB,MAAM,gBAAgB,KAAK,QAAQ;AAEnC,MAAI,eAAe;AACjB,iBAAc,KAAK,EACjB,eAAe,aAChB,CAAC;AACF,QAAK,WAAW,cAAc,MAAM;;;CA+HxC,eAAuB,OAAiB;EACtC,IAAI,SAAS,KAAK,iBAAiB,IAAI,MAAM;AAC7C,MAAI,CAAC,QAAQ;AACX,YAAS,iBAAiB,MAAM;AAChC,QAAK,iBAAiB,IAAI,OAAO,OAAO;;AAE1C,SAAO;;CAGT,IAAI,kBAAkB;AACpB,SAAO,KAAK;;CAqBd,iBAAyB,aAA6B;AAOpD,SAJsB,CAFA,aAAa,KAG7B,KAAK,QAAQ,WAAmB,KAAA,IACjC,YAAY,WAAW,KAAK,QAAQ,WAAW,KAAA;;CAKtD,oBACE,MACA,MACsB;EACtB,MAAM,sBAAsB,KAAK,iBAAiB,KAAK,SAAS;EAChE,MAAM,EAAE,YAAY,gBAAgB;EACpC,IAAI,EAAE,kBAAkB;EACxB,IAAI,mBAAmB;AAGvB,MAEE,aACI,WAAW,SAAS,OAAO,YAAY,QAEvC,cAAc,KAAK,SAAS,CAGhC,KAAI,KAAK,QAAQ,cACf,iBAAgB,CAAC,GAAG,eAAe,KAAK,QAAQ,cAAc;MAG9D,oBAAmB;EAIvB,MAAM,wBAAwB,mBAC1B,0BAA0B,KAAK,QAAQ,cAAc,cAAc,GACnE,KAAA;EAEJ,MAAM,UAAU,IAAI,MAAqB,cAAc,OAAO;EAG9D,MAAM,iDAAiC,IAAI,KAA4B;AACvE,OAAK,MAAM,SAAS,KAAK,OAAO,YAAY,QAAQ,CAClD,KAAI,MAAM,QACR,gCAA+B,IAAI,MAAM,SAAS,MAAM,KAAK,CAAC;AAIlE,OAAK,IAAI,QAAQ,GAAG,QAAQ,cAAc,QAAQ,SAAS;GACzD,MAAM,QAAQ,cAAc;GAQ5B,MAAM,cAAc,QAAQ,QAAQ;GAEpC,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ;IAEE,MAAM,eAAe,aAAa,UAAU,KAAK;IACjD,MAAM,qBAAqB,aAAa,iBAAiB,KAAA;AAEzD,QAAI;KACF,MAAM,eACJ,eAAe,MAAM,QAAQ,gBAAgB,EAAE,GAAG,cAAc,CAAC,IACjE,KAAA;AAEF,sBAAiB;MACf,GAAG;MACH,GAAG;MACJ;AACD,yBAAoB;MAAE,GAAG;MAAoB,GAAG;MAAc;AAC9D,mBAAc,KAAA;aACP,KAAU;KACjB,IAAI,mBAAmB;AACvB,SAAI,EAAE,eAAe,kBACnB,oBAAmB,IAAI,iBAAiB,IAAI,SAAS,EACnD,OAAO,KACR,CAAC;AAGJ,SAAI,MAAM,aACR,OAAM;AAGR,sBAAiB;AACjB,yBAAoB,EAAE;AACtB,mBAAc;;;GASlB,MAAM,aACJ,MAAM,QAAQ,aAAa,EACzB,QAAQ,gBACT,CAAC,IAAI;GAER,MAAM,iBAAiB,aAAa,KAAK,UAAU,WAAW,GAAG;GAEjE,MAAM,EAAE,kBAAkB,eAAe,gBAAgB;IACvD,MAAM,MAAM;IACZ,QAAQ;IACR,SAAS,KAAK;IACd,QAAQ,KAAK;IACd,CAAC;GAQF,MAAM,UAEJ,MAAM,KAEN,mBAEA;GAEF,MAAM,gBAAgB,KAAK,SAAS,QAAQ;GAE5C,MAAM,gBAAgB,+BAA+B,IAAI,MAAM,GAAG;GAElE,MAAM,eAAe,eAAe,iBAAiB;GAErD,IAAI,cAAuB,KAAA;AAE3B,OAAI,CAAC,cACH,KAAI;AACF,wBAAoB,OAAO,aAAa;YACjC,KAAU;AACjB,QAAI,WAAW,IAAI,IAAI,WAAW,IAAI,CACpC,eAAc;QAEd,eAAc,IAAI,eAAe,IAAI,SAAS,EAC5C,OAAO,KACR,CAAC;AAGJ,QAAI,MAAM,aACR,OAAM;;AAKZ,UAAO,OAAO,aAAa,aAAa;GAExC,MAAM,QAAQ,gBAAgB,SAAS;GAEvC,IAAI;AAEJ,OAAI,cACF,SAAQ;IACN,GAAG;IACH;IACA,QAAQ,eAAe,UAAU;IACjC,eAAe;IACf,QAAQ,gBACJ,qBAAqB,cAAc,QAAQ,eAAe,GAC1D,qBAAqB,cAAc,QAAQ,eAAe;IAC9D,eAAe;IAChB;QACI;IACL,MAAM,SACJ,MAAM,QAAQ,UACd,MAAM,QAAQ,cACd,MAAM,UACN,kBAAkB,MAAM,GACpB,YACA;AAEN,YAAQ;KACN,IAAI;KACJ,KAAM,YAAY,KAAK,WAAY,KAAA,IAAY,MAAM,QAAQ;KAC7D;KACA,SAAS,MAAM;KACf,QAAQ,eAAe,UAAU;KACjC,eAAe;KACf,UAAU;KACV,WAAW,KAAK,KAAK;KACrB,QAAQ,gBACJ,qBAAqB,cAAc,QAAQ,eAAe,GAC1D;KACJ,eAAe;KACf,aAAa,KAAA;KACb;KACA,YAAY;KACZ,OAAO,KAAA;KACP;KACA,gBAAgB,KAAA;KAChB,cAAc,EACZ,aAAa,yBAAyB,EACvC;KACD,qBAAqB,KAAA;KACrB,SAAS,EAAE;KACX,iBAAiB,IAAI,iBAAiB;KACtC,YAAY;KACZ;KACA,YAAY,gBACR,iBAAiB,cAAc,YAAY,WAAW,GACtD;KACJ,SAAS;KACT,SAAS;KACT,OAAO,KAAA;KACP,SAAS,KAAA;KACT,aAAa,KAAA;KACb,MAAM,KAAA;KACN,YAAY,MAAM,QAAQ,cAAc,EAAE;KAC1C,UAAU,MAAM;KACjB;;AAGH,OAAI,CAAC,MAAM,QAET,OAAM,iBAAiB,0BAA0B,MAAM;AAIzD,SAAM,cAAc;GAEpB,MAAM,gBAAgB,KAAK,iBAAiB,YAAY;AAExD,SAAM,UAAU;IACd,GAAG;IACH,GAAG,MAAM;IACT,GAAG,MAAM;IACV;AAED,WAAQ,SAAS;;AAGnB,OAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS;GACnD,MAAM,QAAQ,QAAQ;GACtB,MAAM,QAAQ,KAAK,gBAAgB,MAAM;GACzC,MAAM,gBAAgB,KAAK,SAAS,MAAM,GAAG;GAG7C,MAAM,gBAAgB,+BAA+B,IAAI,MAAM,QAAQ;AACvE,SAAM,SAAS,gBACX,qBAAqB,cAAc,QAAQ,YAAY,GACvD;AAEJ,OAAI,CAAC,eAAe;IAClB,MAAM,cAAc,QAAQ,QAAQ;IACpC,MAAM,gBAAgB,KAAK,iBAAiB,YAAY;AAIxD,QAAI,MAAM,QAAQ,SAAS;KACzB,MAAM,mBACJ;MACE,MAAM,MAAM;MACZ,QAAQ,MAAM;MACd,SAAS,iBAAiB,EAAE;MAC5B,UAAU;MACV,WAAW,SACT,KAAK,SAAS;OAAE,GAAG;OAAM,eAAe;OAAM,CAAC;MACjD,eAAe,KAAK;MACpB,OAAO,MAAM;MACb,iBAAiB,MAAM;MACvB,SAAS,CAAC,CAAC,MAAM;MACjB;MACA,SAAS,MAAM;MAChB;AAEH,WAAM,iBACJ,MAAM,QAAQ,QAAQ,iBAAiB,IAAI,KAAA;;AAG/C,UAAM,UAAU;KACd,GAAG;KACH,GAAG,MAAM;KACT,GAAG,MAAM;KACV;;;AAIL,SAAO;;;;;;;CAgBT,uBAA+B,UAK7B;EACA,MAAM,EAAE,eAAe,gBAAgB,KAAK,iBAC1C,SAAS,SACV;EACD,MAAM,YAAY,KAAK,cAAc;EAYrC,MAAM,oBAAoB,EAAE,GAAG,SAAS,QAAQ;AAChD,OAAK,MAAM,SAAS,cAClB,KAAI;AACF,UAAO,OACL,mBACA,eAAe,MAAM,QAAQ,gBAAgB,kBAAkB,CAChE;UACK;EAMV,MAAM,mBAAmB,KAAK,KAAK,OAAO,UAAU,KAAK,CAAC;EAC1D,MAAM,iBACJ,oBAAoB,KAAK,OAAO,YAAY,IAAI,iBAAiB,EAAE,KAAK;EAC1E,MAAM,iBACJ,kBACA,eAAe,YAAY,UAAU,MACrC,eAAe,aAAa,SAAS;EAEvC,IAAI;AACJ,MAAI,eACF,UAAS,eAAe;OACnB;GAEL,MAAM,eAAwC,OAAO,OACnD,OAAO,OAAO,KAAK,EACnB,YACD;AACD,QAAK,MAAM,SAAS,cAClB,KAAI;AACF,wBAAoB,OAAO,aAAa;WAClC;AAIV,YAAS;;AAGX,SAAO;GACL;GACA,UAAU,UAAU;GACpB,QAAQ;GACR;GACD;;;;AAmrCL,IAAa,mBAAb,cAAsC,MAAM;;AAG5C,IAAa,iBAAb,cAAoC,MAAM;AAE1C,MAAM,aAAa,QACjB,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,MAAM,GAAG,GAAG,GAAG;AAC3D,SAAS,aAAa,GAAW,GAAW;AAC1C,QAAO,UAAU,EAAE,KAAK,UAAU,EAAE;;;;;;AAOtC,SAAgB,OAGd,IAAsB,KAAY;AAClC,QAAO,OACL,GAAG,SACuC;AAE1C,UADiB,MAAM,IAAI,EACX,OAAO,WAAW,GAAG,KAAK;;;;AAK9C,SAAgB,sBACd,UACkB;AAClB,QAAO;EACL,UAAU;EACV,WAAW;EACX,iBAAiB;EACjB,QAAQ;EACR,kBAAkB,KAAA;EAClB;EACA,SAAS,EAAE;EACX,YAAY;EACb;;AAGH,SAAS,eAAe,gBAA8B,OAAyB;AAC7E,KAAI,kBAAkB,KAAM,QAAO,EAAE;AAErC,KAAI,eAAe,gBAAgB;EACjC,MAAM,SAAS,eAAe,aAAa,SAAS,MAAM;AAE1D,MAAI,kBAAkB,QACpB,OAAM,IAAI,iBAAiB,iCAAiC;AAE9D,MAAI,OAAO,OACT,OAAM,IAAI,iBAAiB,KAAK,UAAU,OAAO,QAAQ,KAAA,GAAW,EAAE,EAAE,EACtE,OAAO,QACR,CAAC;AAEJ,SAAO,OAAO;;AAGhB,KAAI,WAAW,eACb,QAAO,eAAe,MAAM,MAAM;AAGpC,KAAI,OAAO,mBAAmB,WAC5B,QAAO,eAAe,MAAM;AAG9B,QAAO,EAAE;;;;;;AAOX,SAAgB,iBAA+C,EAC7D,UACA,YACA,iBAKC;CACD,MAAM,cAAsC,OAAO,OAAO,KAAK;CAC/D,MAAM,cAAc,cAAc,SAAS;CAE3C,IAAI,aAAqC,KAAA;CACzC,MAAM,QAAQ,eAA2B,aAAa,eAAe,KAAK;AAC1E,KAAI,OAAO;AACT,eAAa,MAAM;AACnB,SAAO,OAAO,aAAa,MAAM,UAAU;;AAK7C,QAAO;EAAE,eAFa,OAAO,UAAU,CAAC,WAAA,YAAyB;EAEzC;EAAa;EAAY;;;;;;AAOnD,SAAS,sBAAsB,EAC7B,QACA,MACA,YACA,0BAMC;AAED,QADmB,qBAAqB,WAAW,CACjC,QAAQ,MAAM,0BAA0B,MAAM;;AAGlE,SAAS,qBAAqB,YAAqC;CACjE,MAAM,UAAU;EACd,MAAM;EACN,wBAAwB;EACxB,aAAa,EAAE;EAChB;AAED,MAAK,MAAM,SAAS,YAAY;AAC9B,MAAI,YAAY,MAAM;OAChB,MAAM,QAAQ,QAAQ,YACxB,SAAQ,YAAY,KAAK,GAAG,MAAM,QAAQ,OAAO,YAAY;aAK/D,MAAM,QAAQ,oBACd,MAAM,QAAQ,mBACd;GACA,MAAM,oBAA2C,EAAE,QAAQ,WAAW;IACpE,IAAI,aAAa;AAEjB,QACE,sBAAsB,MAAM,WAC5B,MAAM,QAAQ,iBAEd,cAAa,MAAM,QAAQ,iBAAiB,QACzC,MAAM,SAAS,KAAK,KAAK,EAC1B,OACD;IAGH,MAAM,SAAS,KAAK,WAAW;AAE/B,QACE,uBAAuB,MAAM,WAC7B,MAAM,QAAQ,kBAEd,QAAO,MAAM,QAAQ,kBAAkB,QACpC,MAAM,SAAS,KAAK,KAAK,EAC1B,OACD;AAGH,WAAO;;AAET,WAAQ,YAAY,KAAK,iBAAiB;;AAG5C,MAAI,MAAM,QAAQ,gBAAgB;GAChC,MAAM,YAAmC,EAAE,QAAQ,WAAW;IAC5D,MAAM,SAAS,KAAK,OAAO;AAC3B,QAAI,CAAC,QAAQ,uBAAwB,QAAO;AAC5C,QAAI;AAMF,YALwB;MACtB,GAAG;MACH,GAAI,eAAe,MAAM,QAAQ,gBAAgB,OAAO,IACtD,KAAA;MACH;YAEK;AAEN,YAAO;;;AAIX,WAAQ,YAAY,KAAK,SAAS;;;CAKtC,MAAM,SAAgC,EAAE,aAAa;EACnD,MAAM,OAAO,QAAQ;AACrB,MAAI,CAAC,KAAK,OACR,QAAO,EAAE;AAEX,MAAI,KAAK,WAAW,KAClB,QAAO;AAET,SAAO,iBAAiB,KAAK,QAAQ,OAAO;;AAG9C,SAAQ,YAAY,KAAK,MAAM;CAE/B,MAAM,aACJ,OACA,eACA,gBACQ;AAER,MAAI,SAAS,YAAY,OACvB,QAAO;EAGT,MAAM,aAAa,YAAY;EAE/B,MAAM,QAAQ,cAAwB;AACpC,UAAO,UAAU,QAAQ,GAAG,WAAW,YAAY;;AAGrD,SAAO,WAAW;GAAE,QAAQ;GAAe;GAAM,CAAC;;AAGpD,QAAO,SAAS,WACd,QACA,MACA,wBACA;AACA,UAAQ,OAAO;AACf,UAAQ,yBAAyB;AACjC,SAAO,UAAU,GAAG,QAAQ,QAAQ,YAAY;;;AAIpD,SAAS,0BACP,cACA,QACA;AACA,KAAI,iBAAiB,OACnB,MAAK,IAAI,IAAI,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;EAC3C,MAAM,QAAQ,OAAO;AACrB,MAAI,MAAM,SACR,QAAO,MAAM;;AAInB,QAAO;;AAGT,SAAS,oBACP,OACA,mBACA;CACA,MAAM,cAAc,MAAM,QAAQ,QAAQ,SAAS,MAAM,QAAQ;AACjE,KAAI,aAAa;EACf,MAAM,SAAS,YAAY,kBAA4C;AACvE,MAAI,WAAW,MACb,OAAM,IAAI,MAAM,wDAAwD;AAE1E,SAAO,OAAO,mBAAmB,OAAO"}