/opt/canhelp/node_modules/next/dist/client/components/segment-cache-impl
NameSizeModeActions
cache-key.d.ts5090644editdlrm
cache-key.js8770644editdlrm
cache-key.js.map14070644editdlrm
cache.d.ts92220644editdlrm
cache.js757180644editdlrm
cache.js.map1189340644editdlrm
lru.d.ts3490644editdlrm
lru.js40920644editdlrm
lru.js.map61180644editdlrm
navigation.d.ts16140644editdlrm
navigation.js178550644editdlrm
navigation.js.map286640644editdlrm
prefetch.d.ts16380644editdlrm
prefetch.js11990644editdlrm
prefetch.js.map28400644editdlrm
scheduler.d.ts55640644editdlrm
scheduler.js469350644editdlrm
scheduler.js.map736450644editdlrm
tuple-map.d.ts8580644editdlrm
tuple-map.js55220644editdlrm
tuple-map.js.map85030644editdlrm
Edit: /opt/canhelp/node_modules/next/dist/client/components/segment-cache-impl/cache.js.map (118934B)
{"version":3,"sources":["../../../../src/client/components/segment-cache-impl/cache.ts"],"sourcesContent":["import type {\n TreePrefetch,\n RootTreePrefetch,\n SegmentPrefetch,\n} from '../../../server/app-render/collect-segment-data'\nimport type {\n HeadData,\n LoadingModuleData,\n} from '../../../shared/lib/app-router-context.shared-runtime'\nimport type {\n CacheNodeSeedData,\n DynamicParamTypesShort,\n Segment as FlightRouterStateSegment,\n} from '../../../server/app-render/types'\nimport { HasLoadingBoundary } from '../../../server/app-render/types'\nimport {\n NEXT_DID_POSTPONE_HEADER,\n NEXT_ROUTER_PREFETCH_HEADER,\n NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,\n NEXT_ROUTER_STALE_TIME_HEADER,\n NEXT_ROUTER_STATE_TREE_HEADER,\n NEXT_URL,\n RSC_CONTENT_TYPE_HEADER,\n RSC_HEADER,\n} from '../app-router-headers'\nimport {\n createFetch,\n createFromNextReadableStream,\n type RSCResponse,\n type RequestHeaders,\n} from '../router-reducer/fetch-server-response'\nimport {\n pingPrefetchTask,\n isPrefetchTaskDirty,\n type PrefetchTask,\n type PrefetchSubtaskResult,\n} from './scheduler'\nimport { getAppBuildId } from '../../app-build-id'\nimport { createHrefFromUrl } from '../router-reducer/create-href-from-url'\nimport type {\n NormalizedHref,\n NormalizedNextUrl,\n NormalizedSearch,\n RouteCacheKey,\n} from './cache-key'\n// TODO: Rename this module to avoid confusion with other types of cache keys\nimport { createCacheKey as createPrefetchRequestKey } from './cache-key'\nimport {\n doesStaticSegmentAppearInURL,\n getCacheKeyForDynamicParam,\n getParamValueFromCacheKey,\n getRenderedPathname,\n getRenderedSearch,\n parseDynamicParamFromURLPart,\n type RouteParam,\n} from '../../route-params'\nimport { createTupleMap, type TupleMap, type Prefix } from './tuple-map'\nimport { createLRU } from './lru'\nimport {\n appendSegmentCacheKeyPart,\n appendSegmentRequestKeyPart,\n convertSegmentPathToStaticExportFilename,\n createSegmentCacheKeyPart,\n createSegmentRequestKeyPart,\n ROOT_SEGMENT_CACHE_KEY,\n ROOT_SEGMENT_REQUEST_KEY,\n type SegmentCacheKey,\n type SegmentRequestKey,\n} from '../../../shared/lib/segment-cache/segment-value-encoding'\nimport type {\n FlightRouterState,\n NavigationFlightResponse,\n} from '../../../server/app-render/types'\nimport { normalizeFlightData } from '../../flight-data-helpers'\nimport { STATIC_STALETIME_MS } from '../router-reducer/prefetch-cache-utils'\nimport { pingVisibleLinks } from '../links'\nimport { PAGE_SEGMENT_KEY } from '../../../shared/lib/segment'\nimport {\n DOC_PREFETCH_RANGE_HEADER_VALUE,\n doesExportedHtmlMatchBuildId,\n} from '../../../shared/lib/segment-cache/output-export-prefetch-encoding'\nimport { FetchStrategy } from '../segment-cache'\nimport { createPromiseWithResolvers } from '../../../shared/lib/promise-with-resolvers'\n\n// A note on async/await when working in the prefetch cache:\n//\n// Most async operations in the prefetch cache should *not* use async/await,\n// Instead, spawn a subtask that writes the results to a cache entry, and attach\n// a \"ping\" listener to notify the prefetch queue to try again.\n//\n// The reason is we need to be able to access the segment cache and traverse its\n// data structures synchronously. For example, if there's a synchronous update\n// we can take an immediate snapshot of the cache to produce something we can\n// render. Limiting the use of async/await also makes it easier to avoid race\n// conditions, which is especially important because is cache is mutable.\n//\n// Another reason is that while we're performing async work, it's possible for\n// existing entries to become stale, or for Link prefetches to be removed from\n// the queue. For optimal scheduling, we need to be able to \"cancel\" subtasks\n// that are no longer needed. So, when a segment is received from the server, we\n// restart from the root of the tree that's being prefetched, to confirm all the\n// parent segments are still cached. If the segment is no longer reachable from\n// the root, then it's effectively canceled. This is similar to the design of\n// Rust Futures, or React Suspense.\n\nexport type RouteTree = {\n cacheKey: SegmentCacheKey\n requestKey: SegmentRequestKey\n // TODO: Remove the `segment` field, now that it can be reconstructed\n // from `param`.\n segment: FlightRouterStateSegment\n param: RouteParam | null\n slots: null | {\n [parallelRouteKey: string]: RouteTree\n }\n isRootLayout: boolean\n\n // If this is a dynamic route, indicates whether there is a loading boundary\n // somewhere in the tree. If not, we can skip the prefetch for the data,\n // because we know it would be an empty response. (For a static/PPR route,\n // this value is disregarded, because in that model `loading.tsx` is treated\n // like any other Suspense boundary.)\n hasLoadingBoundary: HasLoadingBoundary\n}\n\ntype RouteCacheEntryShared = {\n staleAt: number\n // This is false only if we're certain the route cannot be intercepted. It's\n // true in all other cases, including on initialization when we haven't yet\n // received a response from the server.\n couldBeIntercepted: boolean\n\n // See comment in scheduler.ts for context\n TODO_metadataStatus: EntryStatus.Empty | EntryStatus.Fulfilled\n TODO_isHeadDynamic: boolean\n\n // LRU-related fields\n keypath: null | Prefix\n next: null | RouteCacheEntry\n prev: null | RouteCacheEntry\n size: number\n}\n\n/**\n * Tracks the status of a cache entry as it progresses from no data (Empty),\n * waiting for server data (Pending), and finished (either Fulfilled or\n * Rejected depending on the response from the server.\n */\nexport const enum EntryStatus {\n Empty,\n Pending,\n Fulfilled,\n Rejected,\n}\n\ntype PendingRouteCacheEntry = RouteCacheEntryShared & {\n status: EntryStatus.Empty | EntryStatus.Pending\n blockedTasks: Set | null\n canonicalUrl: null\n renderedSearch: null\n tree: null\n head: HeadData | null\n isHeadPartial: true\n isPPREnabled: false\n}\n\ntype RejectedRouteCacheEntry = RouteCacheEntryShared & {\n status: EntryStatus.Rejected\n blockedTasks: Set | null\n canonicalUrl: null\n renderedSearch: null\n tree: null\n head: null\n isHeadPartial: true\n isPPREnabled: boolean\n}\n\nexport type FulfilledRouteCacheEntry = RouteCacheEntryShared & {\n status: EntryStatus.Fulfilled\n blockedTasks: null\n canonicalUrl: string\n renderedSearch: NormalizedSearch\n tree: RouteTree\n head: HeadData\n isHeadPartial: boolean\n isPPREnabled: boolean\n}\n\nexport type RouteCacheEntry =\n | PendingRouteCacheEntry\n | FulfilledRouteCacheEntry\n | RejectedRouteCacheEntry\n\ntype SegmentCacheEntryShared = {\n staleAt: number\n fetchStrategy: FetchStrategy\n revalidating: SegmentCacheEntry | null\n\n // LRU-related fields\n keypath: null | Prefix\n next: null | SegmentCacheEntry\n prev: null | SegmentCacheEntry\n size: number\n}\n\nexport type EmptySegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Empty\n rsc: null\n loading: null\n isPartial: true\n promise: null\n}\n\nexport type PendingSegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Pending\n rsc: null\n loading: null\n isPartial: true\n promise: null | PromiseWithResolvers\n}\n\ntype RejectedSegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Rejected\n rsc: null\n loading: null\n isPartial: true\n promise: null\n}\n\nexport type FulfilledSegmentCacheEntry = SegmentCacheEntryShared & {\n status: EntryStatus.Fulfilled\n rsc: React.ReactNode | null\n loading: LoadingModuleData | Promise\n isPartial: boolean\n promise: null\n}\n\nexport type SegmentCacheEntry =\n | EmptySegmentCacheEntry\n | PendingSegmentCacheEntry\n | RejectedSegmentCacheEntry\n | FulfilledSegmentCacheEntry\n\nexport type NonEmptySegmentCacheEntry = Exclude<\n SegmentCacheEntry,\n EmptySegmentCacheEntry\n>\n\nconst isOutputExportMode =\n process.env.NODE_ENV === 'production' &&\n process.env.__NEXT_CONFIG_OUTPUT === 'export'\n\n/**\n * Ensures a minimum stale time of 30s to avoid issues where the server sends a too\n * short-lived stale time, which would prevent anything from being prefetched.\n */\nfunction getStaleTimeMs(staleTimeSeconds: number): number {\n return Math.max(staleTimeSeconds, 30) * 1000\n}\n\n// Route cache entries vary on multiple keys: the href and the Next-Url. Each of\n// these parts needs to be included in the internal cache key. Rather than\n// concatenate the keys into a single key, we use a multi-level map, where the\n// first level is keyed by href, the second level is keyed by Next-Url, and so\n// on (if were to add more levels).\ntype RouteCacheKeypath = [NormalizedHref, NormalizedNextUrl]\nlet routeCacheMap: TupleMap =\n createTupleMap()\n\n// We use an LRU for memory management. We must update this whenever we add or\n// remove a new cache entry, or when an entry changes size.\n// TODO: I chose the max size somewhat arbitrarily. Consider setting this based\n// on navigator.deviceMemory, or some other heuristic. We should make this\n// customizable via the Next.js config, too.\nconst maxRouteLruSize = 10 * 1024 * 1024 // 10 MB\nlet routeCacheLru = createLRU(\n maxRouteLruSize,\n onRouteLRUEviction\n)\n\ntype SegmentCacheKeypath = [string, NormalizedSearch]\nlet segmentCacheMap: TupleMap =\n createTupleMap()\n// NOTE: Segments and Route entries are managed by separate LRUs. We could\n// combine them into a single LRU, but because they are separate types, we'd\n// need to wrap each one in an extra LRU node (to maintain monomorphism, at the\n// cost of additional memory).\nconst maxSegmentLruSize = 50 * 1024 * 1024 // 50 MB\nlet segmentCacheLru = createLRU(\n maxSegmentLruSize,\n onSegmentLRUEviction\n)\n\n// All invalidation listeners for the whole cache are tracked in single set.\n// Since we don't yet support tag or path-based invalidation, there's no point\n// tracking them any more granularly than this. Once we add granular\n// invalidation, that may change, though generally the model is to just notify\n// the listeners and allow the caller to poll the prefetch cache with a new\n// prefetch task if desired.\nlet invalidationListeners: Set | null = null\n\n// Incrementing counter used to track cache invalidations.\nlet currentCacheVersion = 0\n\nexport function getCurrentCacheVersion(): number {\n return currentCacheVersion\n}\n\n/**\n * Used to clear the client prefetch cache when a server action calls\n * revalidatePath or revalidateTag. Eventually we will support only clearing the\n * segments that were actually affected, but there's more work to be done on the\n * server before the client is able to do this correctly.\n */\nexport function revalidateEntireCache(\n nextUrl: string | null,\n tree: FlightRouterState\n) {\n currentCacheVersion++\n\n // Clearing the cache also effectively rejects any pending requests, because\n // when the response is received, it gets written into a cache entry that is\n // no longer reachable.\n // TODO: There's an exception to this case that we don't currently handle\n // correctly: background revalidations. See note in `upsertSegmentEntry`.\n routeCacheMap = createTupleMap()\n routeCacheLru = createLRU(maxRouteLruSize, onRouteLRUEviction)\n segmentCacheMap = createTupleMap()\n segmentCacheLru = createLRU(maxSegmentLruSize, onSegmentLRUEviction)\n\n // Prefetch all the currently visible links again, to re-fill the cache.\n pingVisibleLinks(nextUrl, tree)\n\n // Similarly, notify all invalidation listeners (i.e. those passed to\n // `router.prefetch(onInvalidate)`), so they can trigger a new prefetch\n // if needed.\n pingInvalidationListeners(nextUrl, tree)\n}\n\nfunction attachInvalidationListener(task: PrefetchTask): void {\n // This function is called whenever a prefetch task reads a cache entry. If\n // the task has an onInvalidate function associated with it — i.e. the one\n // optionally passed to router.prefetch(onInvalidate) — then we attach that\n // listener to the every cache entry that the task reads. Then, if an entry\n // is invalidated, we call the function.\n if (task.onInvalidate !== null) {\n if (invalidationListeners === null) {\n invalidationListeners = new Set([task])\n } else {\n invalidationListeners.add(task)\n }\n }\n}\n\nfunction notifyInvalidationListener(task: PrefetchTask): void {\n const onInvalidate = task.onInvalidate\n if (onInvalidate !== null) {\n // Clear the callback from the task object to guarantee it's not called more\n // than once.\n task.onInvalidate = null\n\n // This is a user-space function, so we must wrap in try/catch.\n try {\n onInvalidate()\n } catch (error) {\n if (typeof reportError === 'function') {\n reportError(error)\n } else {\n console.error(error)\n }\n }\n }\n}\n\nexport function pingInvalidationListeners(\n nextUrl: string | null,\n tree: FlightRouterState\n): void {\n // The rough equivalent of pingVisibleLinks, but for onInvalidate callbacks.\n // This is called when the Next-Url or the base tree changes, since those\n // may affect the result of a prefetch task. It's also called after a\n // cache invalidation.\n if (invalidationListeners !== null) {\n const tasks = invalidationListeners\n invalidationListeners = null\n for (const task of tasks) {\n if (isPrefetchTaskDirty(task, nextUrl, tree)) {\n notifyInvalidationListener(task)\n }\n }\n }\n}\n\nexport function readExactRouteCacheEntry(\n now: number,\n href: NormalizedHref,\n nextUrl: NormalizedNextUrl | null\n): RouteCacheEntry | null {\n const keypath: Prefix =\n nextUrl === null ? [href] : [href, nextUrl]\n const existingEntry = routeCacheMap.get(keypath)\n if (existingEntry !== null) {\n // Check if the entry is stale\n if (existingEntry.staleAt > now) {\n // Reuse the existing entry.\n\n // Since this is an access, move the entry to the front of the LRU.\n routeCacheLru.put(existingEntry)\n\n return existingEntry\n } else {\n // Evict the stale entry from the cache.\n deleteRouteFromCache(existingEntry, keypath)\n }\n }\n return null\n}\n\nexport function readRouteCacheEntry(\n now: number,\n key: RouteCacheKey\n): RouteCacheEntry | null {\n // First check if there's a non-intercepted entry. Most routes cannot be\n // intercepted, so this is the common case.\n const nonInterceptedEntry = readExactRouteCacheEntry(now, key.href, null)\n if (nonInterceptedEntry !== null && !nonInterceptedEntry.couldBeIntercepted) {\n // Found a match, and the route cannot be intercepted. We can reuse it.\n return nonInterceptedEntry\n }\n // There was no match. Check again but include the Next-Url this time.\n return readExactRouteCacheEntry(now, key.href, key.nextUrl)\n}\n\nexport function getSegmentKeypathForTask(\n task: PrefetchTask,\n route: FulfilledRouteCacheEntry,\n cacheKey: SegmentCacheKey\n): Prefix {\n // When a prefetch includes dynamic data, the search params are included\n // in the result, so we must include the search string in the segment\n // cache key. (Note that this is true even if the search string is empty.)\n //\n // If we're fetching using PPR, we do not need to include the search params in\n // the cache key, because the search params are treated as dynamic data. The\n // cache entry is valid for all possible search param values.\n const isDynamicTask =\n task.fetchStrategy === FetchStrategy.Full ||\n task.fetchStrategy === FetchStrategy.PPRRuntime ||\n !route.isPPREnabled\n return isDynamicTask && cacheKey.endsWith('/' + PAGE_SEGMENT_KEY)\n ? [cacheKey, route.renderedSearch]\n : [cacheKey]\n}\n\nexport function readSegmentCacheEntry(\n now: number,\n route: FulfilledRouteCacheEntry,\n cacheKey: SegmentCacheKey\n): SegmentCacheEntry | null {\n if (!cacheKey.endsWith('/' + PAGE_SEGMENT_KEY)) {\n // Fast path. Search params only exist on page segments.\n return readExactSegmentCacheEntry(now, [cacheKey])\n }\n\n const renderedSearch = route.renderedSearch\n if (renderedSearch !== null) {\n // Page segments may or may not contain search params. If they were prefetched\n // using a dynamic request, then we will have an entry with search params.\n // Check for that case first.\n const entryWithSearchParams = readExactSegmentCacheEntry(now, [\n cacheKey,\n renderedSearch,\n ])\n if (entryWithSearchParams !== null) {\n return entryWithSearchParams\n }\n }\n\n // If we did not find an entry with the given search params, check for a\n // \"fallback\" entry, where the search params are treated as dynamic data. This\n // is the common case because PPR/static prerenders always treat search params\n // as dynamic.\n //\n // See corresponding logic in `getSegmentKeypathForTask`.\n const entryWithoutSearchParams = readExactSegmentCacheEntry(now, [cacheKey])\n return entryWithoutSearchParams\n}\n\nfunction readExactSegmentCacheEntry(\n now: number,\n keypath: Prefix\n): SegmentCacheEntry | null {\n const existingEntry = segmentCacheMap.get(keypath)\n if (existingEntry !== null) {\n // Check if the entry is stale\n if (existingEntry.staleAt > now) {\n // Reuse the existing entry.\n\n // Since this is an access, move the entry to the front of the LRU.\n segmentCacheLru.put(existingEntry)\n\n return existingEntry\n } else {\n // This is a stale entry.\n const revalidatingEntry = existingEntry.revalidating\n if (revalidatingEntry !== null) {\n // There's a revalidation in progress. Upsert it.\n const upsertedEntry = upsertSegmentEntry(\n now,\n keypath,\n revalidatingEntry\n )\n if (upsertedEntry !== null && upsertedEntry.staleAt > now) {\n // We can use the upserted revalidation entry.\n return upsertedEntry\n }\n } else {\n // Evict the stale entry from the cache.\n deleteSegmentFromCache(existingEntry, keypath)\n }\n }\n }\n return null\n}\n\nfunction readRevalidatingSegmentCacheEntry(\n now: number,\n owner: SegmentCacheEntry\n): SegmentCacheEntry | null {\n const existingRevalidation = owner.revalidating\n if (existingRevalidation !== null) {\n if (existingRevalidation.staleAt > now) {\n // There's already a revalidation in progress. Or a previous revalidation\n // failed and it has not yet expired.\n return existingRevalidation\n } else {\n // Clear the stale revalidation from its owner.\n clearRevalidatingSegmentFromOwner(owner)\n }\n }\n return null\n}\n\nexport function waitForSegmentCacheEntry(\n pendingEntry: PendingSegmentCacheEntry\n): Promise {\n // Because the entry is pending, there's already a in-progress request.\n // Attach a promise to the entry that will resolve when the server responds.\n let promiseWithResolvers = pendingEntry.promise\n if (promiseWithResolvers === null) {\n promiseWithResolvers = pendingEntry.promise =\n createPromiseWithResolvers()\n } else {\n // There's already a promise we can use\n }\n return promiseWithResolvers.promise\n}\n\n/**\n * Checks if an entry for a route exists in the cache. If so, it returns the\n * entry, If not, it adds an empty entry to the cache and returns it.\n */\nexport function readOrCreateRouteCacheEntry(\n now: number,\n task: PrefetchTask\n): RouteCacheEntry {\n attachInvalidationListener(task)\n\n const key = task.key\n const existingEntry = readRouteCacheEntry(now, key)\n if (existingEntry !== null) {\n return existingEntry\n }\n // Create a pending entry and add it to the cache.\n const pendingEntry: PendingRouteCacheEntry = {\n canonicalUrl: null,\n status: EntryStatus.Empty,\n blockedTasks: null,\n tree: null,\n head: null,\n isHeadPartial: true,\n // Since this is an empty entry, there's no reason to ever evict it. It will\n // be updated when the data is populated.\n staleAt: Infinity,\n // This is initialized to true because we don't know yet whether the route\n // could be intercepted. It's only set to false once we receive a response\n // from the server.\n couldBeIntercepted: true,\n // Similarly, we don't yet know if the route supports PPR.\n isPPREnabled: false,\n renderedSearch: null,\n\n TODO_metadataStatus: EntryStatus.Empty,\n TODO_isHeadDynamic: false,\n\n // LRU-related fields\n keypath: null,\n next: null,\n prev: null,\n size: 0,\n }\n const keypath: Prefix =\n key.nextUrl === null ? [key.href] : [key.href, key.nextUrl]\n routeCacheMap.set(keypath, pendingEntry)\n // Stash the keypath on the entry so we know how to remove it from the map\n // if it gets evicted from the LRU.\n pendingEntry.keypath = keypath\n routeCacheLru.put(pendingEntry)\n return pendingEntry\n}\n\nexport function requestOptimisticRouteCacheEntry(\n now: number,\n requestedUrl: URL,\n nextUrl: string | null\n): FulfilledRouteCacheEntry | null {\n // This function is called during a navigation when there was no matching\n // route tree in the prefetch cache. Before de-opting to a blocking,\n // unprefetched navigation, we will first attempt to construct an \"optimistic\"\n // route tree by checking the cache for similar routes.\n //\n // Check if there's a route with the same pathname, but with different\n // search params. We can then base our optimistic route tree on this entry.\n //\n // Conceptually, we are simulating what would happen if we did perform a\n // prefetch the requested URL, under the assumption that the server will\n // not redirect or rewrite the request in a different manner than the\n // base route tree. This assumption might not hold, in which case we'll have\n // to recover when we perform the dynamic navigation request. However, this\n // is what would happen if a route were dynamically rewritten/redirected\n // in between the prefetch and the navigation. So the logic needs to exist\n // to handle this case regardless.\n\n // Look for a route with the same pathname, but with an empty search string.\n // TODO: There's nothing inherently special about the empty search string;\n // it's chosen somewhat arbitrarily, with the rationale that it's the most\n // likely one to exist. But we should update this to match _any_ search\n // string. The plan is to generalize this logic alongside other improvements\n // related to \"fallback\" cache entries.\n const requestedSearch = requestedUrl.search as NormalizedSearch\n if (requestedSearch === '') {\n // The caller would have already checked if a route with an empty search\n // string is in the cache. So we can bail out here.\n return null\n }\n const routeWithNoSearchParams = readRouteCacheEntry(\n now,\n createPrefetchRequestKey(\n requestedUrl.origin + requestedUrl.pathname,\n nextUrl\n )\n )\n\n if (\n routeWithNoSearchParams === null ||\n routeWithNoSearchParams.status !== EntryStatus.Fulfilled ||\n // There's no point constructing an optimistic route tree if the metadata\n // isn't fully available, because we'll have to do a blocking\n // navigation anyway.\n routeWithNoSearchParams.isHeadPartial ||\n // We cannot reuse this route if it has dynamic metadata.\n // TODO: Move the metadata out of the route cache entry so the route\n // tree is reusable separately from the metadata. Then we can remove\n // these checks.\n routeWithNoSearchParams.TODO_metadataStatus !== EntryStatus.Empty ||\n routeWithNoSearchParams.TODO_isHeadDynamic\n ) {\n // Bail out of constructing an optimistic route tree. This will result in\n // a blocking, unprefetched navigation.\n return null\n }\n\n // Now we have a base route tree we can \"patch\" with our optimistic values.\n\n // Optimistically assume that redirects for the requested pathname do\n // not vary on the search string. Therefore, if the base route was\n // redirected to a different search string, then the optimistic route\n // should be redirected to the same search string. Otherwise, we use\n // the requested search string.\n const canonicalUrlForRouteWithNoSearchParams = new URL(\n routeWithNoSearchParams.canonicalUrl,\n requestedUrl.origin\n )\n const optimisticCanonicalSearch =\n canonicalUrlForRouteWithNoSearchParams.search !== ''\n ? // Base route was redirected. Reuse the same redirected search string.\n canonicalUrlForRouteWithNoSearchParams.search\n : requestedSearch\n\n // Similarly, optimistically assume that rewrites for the requested\n // pathname do not vary on the search string. Therefore, if the base\n // route was rewritten to a different search string, then the optimistic\n // route should be rewritten to the same search string. Otherwise, we use\n // the requested search string.\n const optimisticRenderedSearch =\n routeWithNoSearchParams.renderedSearch !== ''\n ? // Base route was rewritten. Reuse the same rewritten search string.\n routeWithNoSearchParams.renderedSearch\n : requestedSearch\n\n const optimisticUrl = new URL(\n routeWithNoSearchParams.canonicalUrl,\n location.origin\n )\n optimisticUrl.search = optimisticCanonicalSearch\n const optimisticCanonicalUrl = createHrefFromUrl(optimisticUrl)\n\n // Clone the base route tree, and override the relevant fields with our\n // optimistic values.\n const optimisticEntry: FulfilledRouteCacheEntry = {\n canonicalUrl: optimisticCanonicalUrl,\n\n status: EntryStatus.Fulfilled,\n // This isn't cloned because it's instance-specific\n blockedTasks: null,\n tree: routeWithNoSearchParams.tree,\n head: routeWithNoSearchParams.head,\n isHeadPartial: routeWithNoSearchParams.isHeadPartial,\n staleAt: routeWithNoSearchParams.staleAt,\n couldBeIntercepted: routeWithNoSearchParams.couldBeIntercepted,\n isPPREnabled: routeWithNoSearchParams.isPPREnabled,\n\n // Override the rendered search with the optimistic value.\n renderedSearch: optimisticRenderedSearch,\n\n TODO_metadataStatus: routeWithNoSearchParams.TODO_metadataStatus,\n TODO_isHeadDynamic: routeWithNoSearchParams.TODO_isHeadDynamic,\n\n // LRU-related fields\n keypath: null,\n next: null,\n prev: null,\n size: 0,\n }\n\n // Do not insert this entry into the cache. It only exists so we can\n // perform the current navigation. Just return it to the caller.\n return optimisticEntry\n}\n\n/**\n * Checks if an entry for a segment exists in the cache. If so, it returns the\n * entry, If not, it adds an empty entry to the cache and returns it.\n */\nexport function readOrCreateSegmentCacheEntry(\n now: number,\n task: PrefetchTask,\n route: FulfilledRouteCacheEntry,\n cacheKey: SegmentCacheKey\n): SegmentCacheEntry {\n const keypath = getSegmentKeypathForTask(task, route, cacheKey)\n const existingEntry = readExactSegmentCacheEntry(now, keypath)\n if (existingEntry !== null) {\n return existingEntry\n }\n // Create a pending entry and add it to the cache.\n const pendingEntry = createDetachedSegmentCacheEntry(route.staleAt)\n segmentCacheMap.set(keypath, pendingEntry)\n // Stash the keypath on the entry so we know how to remove it from the map\n // if it gets evicted from the LRU.\n pendingEntry.keypath = keypath\n segmentCacheLru.put(pendingEntry)\n return pendingEntry\n}\n\nexport function readOrCreateRevalidatingSegmentEntry(\n now: number,\n prevEntry: SegmentCacheEntry\n): SegmentCacheEntry {\n const existingRevalidation = readRevalidatingSegmentCacheEntry(now, prevEntry)\n if (existingRevalidation !== null) {\n return existingRevalidation\n }\n const pendingEntry = createDetachedSegmentCacheEntry(prevEntry.staleAt)\n\n // Background revalidations are not stored directly in the cache map or LRU;\n // they're stashed on the entry that they will (potentially) replace.\n //\n // Note that we don't actually ever clear this field, except when the entry\n // expires. When the revalidation finishes, one of two things will happen:\n //\n // 1) the revalidation is successful, `prevEntry` is removed from the cache\n // and garbage collected (so there's no point clearing any of its fields)\n // 2) the revalidation fails, and we'll use the `revalidating` field to\n // prevent subsequent revalidation attempts, until it expires.\n prevEntry.revalidating = pendingEntry\n\n return pendingEntry\n}\n\nexport function upsertSegmentEntry(\n now: number,\n keypath: Prefix,\n candidateEntry: SegmentCacheEntry\n): SegmentCacheEntry | null {\n // We have a new entry that has not yet been inserted into the cache. Before\n // we do so, we need to confirm whether it takes precedence over the existing\n // entry (if one exists).\n // TODO: We should not upsert an entry if its key was invalidated in the time\n // since the request was made. We can do that by passing the \"owner\" entry to\n // this function and confirming it's the same as `existingEntry`.\n const existingEntry = readExactSegmentCacheEntry(now, keypath)\n if (existingEntry !== null) {\n // Don't replace a more specific segment with a less-specific one. A case where this\n // might happen is if the existing segment was fetched via\n // ``.\n if (\n // We fetched the new segment using a different, less specific fetch strategy\n // than the segment we already have in the cache, so it can't have more content.\n (candidateEntry.fetchStrategy !== existingEntry.fetchStrategy &&\n !canNewFetchStrategyProvideMoreContent(\n existingEntry.fetchStrategy,\n candidateEntry.fetchStrategy\n )) ||\n // The existing entry isn't partial, but the new one is.\n // (TODO: can this be true if `candidateEntry.fetchStrategy >= existingEntry.fetchStrategy`?)\n (!existingEntry.isPartial && candidateEntry.isPartial)\n ) {\n // We're going to leave the entry on the owner's `revalidating` field\n // so that it doesn't get revalidated again unnecessarily. Downgrade the\n // Fulfilled entry to Rejected and null out the data so it can be garbage\n // collected. We leave `staleAt` intact to prevent subsequent revalidation\n // attempts only until the entry expires.\n const rejectedEntry: RejectedSegmentCacheEntry = candidateEntry as any\n rejectedEntry.status = EntryStatus.Rejected\n rejectedEntry.loading = null\n rejectedEntry.rsc = null\n return null\n }\n\n // Evict the existing entry from the cache.\n deleteSegmentFromCache(existingEntry, keypath)\n }\n segmentCacheMap.set(keypath, candidateEntry)\n // Stash the keypath on the entry so we know how to remove it from the map\n // if it gets evicted from the LRU.\n candidateEntry.keypath = keypath\n segmentCacheLru.put(candidateEntry)\n return candidateEntry\n}\n\nexport function createDetachedSegmentCacheEntry(\n staleAt: number\n): EmptySegmentCacheEntry {\n const emptyEntry: EmptySegmentCacheEntry = {\n status: EntryStatus.Empty,\n // Default to assuming the fetch strategy will be PPR. This will be updated\n // when a fetch is actually initiated.\n fetchStrategy: FetchStrategy.PPR,\n revalidating: null,\n rsc: null,\n loading: null,\n staleAt,\n isPartial: true,\n promise: null,\n\n // LRU-related fields\n keypath: null,\n next: null,\n prev: null,\n size: 0,\n }\n return emptyEntry\n}\n\nexport function upgradeToPendingSegment(\n emptyEntry: EmptySegmentCacheEntry,\n fetchStrategy: FetchStrategy\n): PendingSegmentCacheEntry {\n const pendingEntry: PendingSegmentCacheEntry = emptyEntry as any\n pendingEntry.status = EntryStatus.Pending\n pendingEntry.fetchStrategy = fetchStrategy\n return pendingEntry\n}\n\nfunction deleteRouteFromCache(\n entry: RouteCacheEntry,\n keypath: Prefix\n): void {\n pingBlockedTasks(entry)\n routeCacheMap.delete(keypath)\n routeCacheLru.delete(entry)\n}\n\nfunction deleteSegmentFromCache(\n entry: SegmentCacheEntry,\n keypath: Prefix\n): void {\n cancelEntryListeners(entry)\n segmentCacheMap.delete(keypath)\n segmentCacheLru.delete(entry)\n clearRevalidatingSegmentFromOwner(entry)\n}\n\nfunction clearRevalidatingSegmentFromOwner(owner: SegmentCacheEntry): void {\n // Revalidating segments are not stored in the cache directly; they're\n // stored as a field on the entry that they will (potentially) replace. So\n // to dispose of an existing revalidation, we just need to null out the field\n // on the owner.\n const revalidatingSegment = owner.revalidating\n if (revalidatingSegment !== null) {\n cancelEntryListeners(revalidatingSegment)\n owner.revalidating = null\n }\n}\n\nexport function resetRevalidatingSegmentEntry(\n owner: SegmentCacheEntry\n): EmptySegmentCacheEntry {\n clearRevalidatingSegmentFromOwner(owner)\n const emptyEntry = createDetachedSegmentCacheEntry(owner.staleAt)\n owner.revalidating = emptyEntry\n return emptyEntry\n}\n\nfunction onRouteLRUEviction(entry: RouteCacheEntry): void {\n // The LRU evicted this entry. Remove it from the map.\n const keypath = entry.keypath\n if (keypath !== null) {\n entry.keypath = null\n pingBlockedTasks(entry)\n routeCacheMap.delete(keypath)\n }\n}\n\nfunction onSegmentLRUEviction(entry: SegmentCacheEntry): void {\n // The LRU evicted this entry. Remove it from the map.\n const keypath = entry.keypath\n if (keypath !== null) {\n entry.keypath = null\n cancelEntryListeners(entry)\n segmentCacheMap.delete(keypath)\n }\n}\n\nfunction cancelEntryListeners(entry: SegmentCacheEntry): void {\n if (entry.status === EntryStatus.Pending && entry.promise !== null) {\n // There were listeners for this entry. Resolve them with `null` to indicate\n // that the prefetch failed. It's up to the listener to decide how to handle\n // this case.\n // NOTE: We don't currently propagate the reason the prefetch was canceled\n // but we could by accepting a `reason` argument.\n entry.promise.resolve(null)\n entry.promise = null\n }\n}\n\nfunction pingBlockedTasks(entry: {\n blockedTasks: Set | null\n}): void {\n const blockedTasks = entry.blockedTasks\n if (blockedTasks !== null) {\n for (const task of blockedTasks) {\n pingPrefetchTask(task)\n }\n entry.blockedTasks = null\n }\n}\n\nfunction fulfillRouteCacheEntry(\n entry: RouteCacheEntry,\n tree: RouteTree,\n head: HeadData,\n isHeadPartial: boolean,\n staleAt: number,\n couldBeIntercepted: boolean,\n canonicalUrl: string,\n renderedSearch: NormalizedSearch,\n isPPREnabled: boolean,\n isHeadDynamic: boolean\n): FulfilledRouteCacheEntry {\n const fulfilledEntry: FulfilledRouteCacheEntry = entry as any\n fulfilledEntry.status = EntryStatus.Fulfilled\n fulfilledEntry.tree = tree\n fulfilledEntry.head = head\n fulfilledEntry.isHeadPartial = isHeadPartial\n fulfilledEntry.staleAt = staleAt\n fulfilledEntry.couldBeIntercepted = couldBeIntercepted\n fulfilledEntry.canonicalUrl = canonicalUrl\n fulfilledEntry.renderedSearch = renderedSearch\n fulfilledEntry.isPPREnabled = isPPREnabled\n fulfilledEntry.TODO_isHeadDynamic = isHeadDynamic\n pingBlockedTasks(entry)\n return fulfilledEntry\n}\n\nfunction fulfillSegmentCacheEntry(\n segmentCacheEntry: PendingSegmentCacheEntry,\n rsc: React.ReactNode,\n loading: LoadingModuleData | Promise,\n staleAt: number,\n isPartial: boolean\n): FulfilledSegmentCacheEntry {\n const fulfilledEntry: FulfilledSegmentCacheEntry = segmentCacheEntry as any\n fulfilledEntry.status = EntryStatus.Fulfilled\n fulfilledEntry.rsc = rsc\n fulfilledEntry.loading = loading\n fulfilledEntry.staleAt = staleAt\n fulfilledEntry.isPartial = isPartial\n // Resolve any listeners that were waiting for this data.\n if (segmentCacheEntry.promise !== null) {\n segmentCacheEntry.promise.resolve(fulfilledEntry)\n // Free the promise for garbage collection.\n fulfilledEntry.promise = null\n }\n return fulfilledEntry\n}\n\nfunction rejectRouteCacheEntry(\n entry: PendingRouteCacheEntry,\n staleAt: number\n): void {\n const rejectedEntry: RejectedRouteCacheEntry = entry as any\n rejectedEntry.status = EntryStatus.Rejected\n rejectedEntry.staleAt = staleAt\n pingBlockedTasks(entry)\n}\n\nfunction rejectSegmentCacheEntry(\n entry: PendingSegmentCacheEntry,\n staleAt: number\n): void {\n const rejectedEntry: RejectedSegmentCacheEntry = entry as any\n rejectedEntry.status = EntryStatus.Rejected\n rejectedEntry.staleAt = staleAt\n if (entry.promise !== null) {\n // NOTE: We don't currently propagate the reason the prefetch was canceled\n // but we could by accepting a `reason` argument.\n entry.promise.resolve(null)\n entry.promise = null\n }\n}\n\nfunction convertRootTreePrefetchToRouteTree(\n rootTree: RootTreePrefetch,\n renderedPathname: string\n) {\n // Remove trailing and leading slashes\n const pathnameParts = renderedPathname.split('/').filter((p) => p !== '')\n const index = 0\n const rootSegment = ROOT_SEGMENT_CACHE_KEY\n return convertTreePrefetchToRouteTree(\n rootTree.tree,\n rootSegment,\n null,\n ROOT_SEGMENT_REQUEST_KEY,\n ROOT_SEGMENT_CACHE_KEY,\n pathnameParts,\n index\n )\n}\n\nfunction convertTreePrefetchToRouteTree(\n prefetch: TreePrefetch,\n segment: FlightRouterStateSegment,\n param: RouteParam | null,\n requestKey: SegmentRequestKey,\n cacheKey: SegmentCacheKey,\n pathnameParts: Array,\n pathnamePartsIndex: number\n): RouteTree {\n // Converts the route tree sent by the server into the format used by the\n // cache. The cached version of the tree includes additional fields, such as a\n // cache key for each segment. Since this is frequently accessed, we compute\n // it once instead of on every access. This same cache key is also used to\n // request the segment from the server.\n\n let slots: { [parallelRouteKey: string]: RouteTree } | null = null\n const prefetchSlots = prefetch.slots\n if (prefetchSlots !== null) {\n slots = {}\n for (let parallelRouteKey in prefetchSlots) {\n const childPrefetch = prefetchSlots[parallelRouteKey]\n const childParamName = childPrefetch.name\n const childParamType = childPrefetch.paramType\n const childServerSentParamKey = childPrefetch.paramKey\n\n let childDoesAppearInURL: boolean\n let childParam: RouteParam | null = null\n let childSegment: FlightRouterStateSegment\n if (childParamType !== null) {\n // This segment is parameterized. Get the param from the pathname.\n const childParamValue = parseDynamicParamFromURLPart(\n childParamType,\n pathnameParts,\n pathnamePartsIndex\n )\n\n // Assign a cache key to the segment, based on the param value. In the\n // pre-Segment Cache implementation, the server computes this and sends\n // it in the body of the response. In the Segment Cache implementation,\n // the server sends an empty string and we fill it in here.\n\n // TODO: We're intentionally not adding the search param to page\n // segments here; it's tracked separately and added back during a read.\n // This would clearer if we waited to construct the segment until it's\n // read from the cache, since that's effectively what we're\n // doing anyway.\n const renderedSearch = '' as NormalizedSearch\n const childParamKey =\n // The server omits this field from the prefetch response when\n // clientParamParsing is enabled. The flag only exists while we're\n // testing the feature, in case there's a bug and we need to revert.\n // TODO: Remove once clientParamParsing is enabled everywhere.\n childServerSentParamKey !== null\n ? childServerSentParamKey\n : // If no param key was sent, use the value parsed on the client.\n getCacheKeyForDynamicParam(childParamValue, renderedSearch)\n\n childParam = {\n name: childParamName,\n value: childParamValue,\n type: childParamType,\n }\n childSegment = [childParamName, childParamKey, childParamType]\n childDoesAppearInURL = true\n } else {\n childSegment = childParamName\n childDoesAppearInURL = doesStaticSegmentAppearInURL(childParamName)\n }\n\n // Only increment the index if the segment appears in the URL. If it's a\n // \"virtual\" segment, like a route group, it remains the same.\n const childPathnamePartsIndex = childDoesAppearInURL\n ? pathnamePartsIndex + 1\n : pathnamePartsIndex\n\n const childRequestKeyPart = createSegmentRequestKeyPart(childSegment)\n const childRequestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n childRequestKeyPart\n )\n const childCacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(childRequestKeyPart, childSegment)\n )\n slots[parallelRouteKey] = convertTreePrefetchToRouteTree(\n childPrefetch,\n childSegment,\n childParam,\n childRequestKey,\n childCacheKey,\n pathnameParts,\n childPathnamePartsIndex\n )\n }\n }\n\n return {\n cacheKey,\n requestKey,\n segment,\n param,\n slots,\n isRootLayout: prefetch.isRootLayout,\n // This field is only relevant to dynamic routes. For a PPR/static route,\n // there's always some partial loading state we can fetch.\n hasLoadingBoundary: HasLoadingBoundary.SegmentHasLoadingBoundary,\n }\n}\n\nfunction convertRootFlightRouterStateToRouteTree(\n flightRouterState: FlightRouterState\n): RouteTree {\n return convertFlightRouterStateToRouteTree(\n flightRouterState,\n ROOT_SEGMENT_CACHE_KEY,\n ROOT_SEGMENT_REQUEST_KEY\n )\n}\n\nfunction convertFlightRouterStateToRouteTree(\n flightRouterState: FlightRouterState,\n cacheKey: SegmentCacheKey,\n requestKey: SegmentRequestKey\n): RouteTree {\n let slots: { [parallelRouteKey: string]: RouteTree } | null = null\n\n const parallelRoutes = flightRouterState[1]\n for (let parallelRouteKey in parallelRoutes) {\n const childRouterState = parallelRoutes[parallelRouteKey]\n const childSegment = childRouterState[0]\n // TODO: Eventually, the param values will not be included in the response\n // from the server. We'll instead fill them in on the client by parsing\n // the URL. This is where we'll do that.\n const childRequestKeyPart = createSegmentRequestKeyPart(childSegment)\n const childRequestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n childRequestKeyPart\n )\n const childCacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(childRequestKeyPart, childSegment)\n )\n const childTree = convertFlightRouterStateToRouteTree(\n childRouterState,\n childCacheKey,\n childRequestKey\n )\n if (slots === null) {\n slots = {\n [parallelRouteKey]: childTree,\n }\n } else {\n slots[parallelRouteKey] = childTree\n }\n }\n const originalSegment = flightRouterState[0]\n\n let segment: FlightRouterStateSegment\n let param: RouteParam | null = null\n if (Array.isArray(originalSegment)) {\n const paramCacheKey = originalSegment[1]\n const paramType = originalSegment[2]\n const paramValue = getParamValueFromCacheKey(paramCacheKey, paramType)\n param = {\n name: originalSegment[0],\n value: paramValue === undefined ? null : paramValue,\n type: originalSegment[2] as DynamicParamTypesShort,\n }\n segment = originalSegment\n } else {\n // The navigation implementation expects the search params to be included\n // in the segment. However, in the case of a static response, the search\n // params are omitted. So the client needs to add them back in when reading\n // from the Segment Cache.\n //\n // For consistency, we'll do this for dynamic responses, too.\n //\n // TODO: We should move search params out of FlightRouterState and handle\n // them entirely on the client, similar to our plan for dynamic params.\n segment =\n typeof originalSegment === 'string' &&\n originalSegment.startsWith(PAGE_SEGMENT_KEY)\n ? PAGE_SEGMENT_KEY\n : originalSegment\n }\n\n return {\n cacheKey,\n requestKey,\n segment,\n param,\n slots,\n isRootLayout: flightRouterState[4] === true,\n hasLoadingBoundary:\n flightRouterState[5] !== undefined\n ? flightRouterState[5]\n : HasLoadingBoundary.SubtreeHasNoLoadingBoundary,\n }\n}\n\nexport function convertRouteTreeToFlightRouterState(\n routeTree: RouteTree\n): FlightRouterState {\n const parallelRoutes: Record = {}\n if (routeTree.slots !== null) {\n for (const parallelRouteKey in routeTree.slots) {\n parallelRoutes[parallelRouteKey] = convertRouteTreeToFlightRouterState(\n routeTree.slots[parallelRouteKey]\n )\n }\n }\n const flightRouterState: FlightRouterState = [\n routeTree.segment,\n parallelRoutes,\n null,\n null,\n routeTree.isRootLayout,\n ]\n return flightRouterState\n}\n\nexport async function fetchRouteOnCacheMiss(\n entry: PendingRouteCacheEntry,\n task: PrefetchTask\n): Promise | null> {\n // This function is allowed to use async/await because it contains the actual\n // fetch that gets issued on a cache miss. Notice it writes the result to the\n // cache entry directly, rather than return data that is then written by\n // the caller.\n const key = task.key\n const href = key.href\n const nextUrl = key.nextUrl\n const segmentPath = '/_tree' as SegmentRequestKey\n\n const headers: RequestHeaders = {\n [RSC_HEADER]: '1',\n [NEXT_ROUTER_PREFETCH_HEADER]: '1',\n [NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: segmentPath,\n }\n if (nextUrl !== null) {\n headers[NEXT_URL] = nextUrl\n }\n\n try {\n let response\n let urlAfterRedirects\n if (isOutputExportMode) {\n // In output: \"export\" mode, we can't use headers to request a particular\n // segment. Instead, we encode the extra request information into the URL.\n // This is not part of the \"public\" interface of the app; it's an internal\n // Next.js implementation detail that the app developer should not need to\n // concern themselves with.\n //\n // For example, to request a segment:\n //\n // Path passed to : /path/to/page\n // Path passed to fetch: /path/to/page/__next-segments/_tree\n //\n // (This is not the exact protocol, just an illustration.)\n //\n // Before we do that, though, we need to account for redirects. Even in\n // output: \"export\" mode, a proxy might redirect the page to a different\n // location, but we shouldn't assume or expect that they also redirect all\n // the segment files, too.\n //\n // To check whether the page is redirected, we perform a range request of\n // the first N bytes of the HTML document. The canonical URL is determined\n // from the response.\n //\n // Then we can use the canonical URL to request the route tree.\n //\n // NOTE: We could embed the route tree into the HTML document, to avoid\n // a second request. We're not doing that currently because it would make\n // the HTML document larger and affect normal page loads.\n const url = new URL(href)\n const htmlResponse = await fetch(href, {\n headers: {\n Range: DOC_PREFETCH_RANGE_HEADER_VALUE,\n },\n })\n const partialHtml = await htmlResponse.text()\n if (!doesExportedHtmlMatchBuildId(partialHtml, getAppBuildId())) {\n // The target page is not part of this app, or it belongs to a\n // different build.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n urlAfterRedirects = htmlResponse.redirected\n ? new URL(htmlResponse.url)\n : url\n response = await fetchPrefetchResponse(\n addSegmentPathToUrlInOutputExportMode(urlAfterRedirects, segmentPath),\n headers\n )\n } else {\n // \"Server\" mode. We can use request headers instead of the pathname.\n // TODO: The eventual plan is to get rid of our custom request headers and\n // encode everything into the URL, using a similar strategy to the\n // \"output: export\" block above.\n const url = new URL(href)\n response = await fetchPrefetchResponse(url, headers)\n urlAfterRedirects =\n response !== null && response.redirected ? new URL(response.url) : url\n }\n\n if (\n !response ||\n !response.ok ||\n // 204 is a Cache miss. Though theoretically this shouldn't happen when\n // PPR is enabled, because we always respond to route tree requests, even\n // if it needs to be blockingly generated on demand.\n response.status === 204 ||\n !response.body\n ) {\n // Server responded with an error, or with a miss. We should still cache\n // the response, but we can try again after 10 seconds.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n\n // TODO: The canonical URL is the href without the origin. I think\n // historically the reason for this is because the initial canonical URL\n // gets passed as a prop to the top-level React component, which means it\n // needs to be computed during SSR. If it were to include the origin, it\n // would need to always be same as location.origin on the client, to prevent\n // a hydration mismatch. To sidestep this complexity, we omit the origin.\n //\n // However, since this is neither a native URL object nor a fully qualified\n // URL string, we need to be careful about how we use it. To prevent subtle\n // mistakes, we should create a special type for it, instead of just string.\n // Or, we should just use a (readonly) URL object instead. The type of the\n // prop that we pass to seed the initial state does not need to be the same\n // type as the state itself.\n const canonicalUrl = createHrefFromUrl(urlAfterRedirects)\n\n // Check whether the response varies based on the Next-Url header.\n const varyHeader = response.headers.get('vary')\n const couldBeIntercepted =\n varyHeader !== null && varyHeader.includes(NEXT_URL)\n\n // Track when the network connection closes.\n const closed = createPromiseWithResolvers()\n\n // This checks whether the response was served from the per-segment cache,\n // rather than the old prefetching flow. If it fails, it implies that PPR\n // is disabled on this route.\n const routeIsPPREnabled =\n response.headers.get(NEXT_DID_POSTPONE_HEADER) === '2' ||\n // In output: \"export\" mode, we can't rely on response headers. But if we\n // receive a well-formed response, we can assume it's a static response,\n // because all data is static in this mode.\n isOutputExportMode\n\n // Regardless of the type of response, we will never receive dynamic\n // metadata as part of this prefetch request.\n const isHeadDynamic = false\n\n if (routeIsPPREnabled) {\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(size) {\n routeCacheLru.updateSize(entry, size)\n }\n )\n const serverData = await (createFromNextReadableStream(\n prefetchStream\n ) as Promise)\n if (serverData.buildId !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n // TODO: We should cache the fact that this is an MPA navigation.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n\n // Get the params that were used to render the target page. These may\n // be different from the params in the request URL, if the page\n // was rewritten.\n const renderedPathname = getRenderedPathname(response)\n const renderedSearch = getRenderedSearch(response)\n\n const routeTree = convertRootTreePrefetchToRouteTree(\n serverData,\n renderedPathname\n )\n\n const staleTimeMs = getStaleTimeMs(serverData.staleTime)\n fulfillRouteCacheEntry(\n entry,\n routeTree,\n serverData.head,\n serverData.isHeadPartial,\n Date.now() + staleTimeMs,\n couldBeIntercepted,\n canonicalUrl,\n renderedSearch,\n routeIsPPREnabled,\n isHeadDynamic\n )\n } else {\n // PPR is not enabled for this route. The server responds with a\n // different format (FlightRouterState) that we need to convert.\n // TODO: We will unify the responses eventually. I'm keeping the types\n // separate for now because FlightRouterState has so many\n // overloaded concerns.\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(size) {\n routeCacheLru.updateSize(entry, size)\n }\n )\n const serverData = await (createFromNextReadableStream(\n prefetchStream\n ) as Promise)\n if (serverData.b !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n // TODO: We should cache the fact that this is an MPA navigation.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n\n writeDynamicTreeResponseIntoCache(\n Date.now(),\n task,\n // The non-PPR response format is what we'd get if we prefetched these segments\n // using the LoadingBoundary fetch strategy, so mark their cache entries accordingly.\n FetchStrategy.LoadingBoundary,\n response,\n serverData,\n entry,\n couldBeIntercepted,\n canonicalUrl,\n routeIsPPREnabled\n )\n }\n\n if (!couldBeIntercepted && nextUrl !== null) {\n // This route will never be intercepted. So we can use this entry for all\n // requests to this route, regardless of the Next-Url header. This works\n // because when reading the cache we always check for a valid\n // non-intercepted entry first.\n //\n // Re-key the entry. Since we're in an async task, we must first confirm\n // that the entry hasn't been concurrently modified by a different task.\n const currentKeypath: Prefix = [href, nextUrl]\n const expectedEntry = routeCacheMap.get(currentKeypath)\n if (expectedEntry === entry) {\n routeCacheMap.delete(currentKeypath)\n const newKeypath: Prefix = [href]\n routeCacheMap.set(newKeypath, entry)\n // We don't need to update the LRU because the entry is already in it.\n // But since we changed the keypath, we do need to update that, so we\n // know how to remove it from the map if it gets evicted from the LRU.\n entry.keypath = newKeypath\n } else {\n // Something else modified this entry already. Since the re-keying is\n // just a performance optimization, we can safely skip it.\n }\n }\n // Return a promise that resolves when the network connection closes, so\n // the scheduler can track the number of concurrent network connections.\n return { value: null, closed: closed.promise }\n } catch (error) {\n // Either the connection itself failed, or something bad happened while\n // decoding the response.\n rejectRouteCacheEntry(entry, Date.now() + 10 * 1000)\n return null\n }\n}\n\nexport async function fetchSegmentOnCacheMiss(\n route: FulfilledRouteCacheEntry,\n segmentCacheEntry: PendingSegmentCacheEntry,\n routeKey: RouteCacheKey,\n tree: RouteTree\n): Promise | null> {\n // This function is allowed to use async/await because it contains the actual\n // fetch that gets issued on a cache miss. Notice it writes the result to the\n // cache entry directly, rather than return data that is then written by\n // the caller.\n //\n // Segment fetches are non-blocking so we don't need to ping the scheduler\n // on completion.\n\n // Use the canonical URL to request the segment, not the original URL. These\n // are usually the same, but the canonical URL will be different if the route\n // tree response was redirected. To avoid an extra waterfall on every segment\n // request, we pass the redirected URL instead of the original one.\n const url = new URL(route.canonicalUrl, routeKey.href)\n const nextUrl = routeKey.nextUrl\n\n const requestKey = tree.requestKey\n const normalizedRequestKey =\n requestKey === ROOT_SEGMENT_REQUEST_KEY\n ? // The root segment is a special case. To simplify the server-side\n // handling of these requests, we encode the root segment path as\n // `_index` instead of as an empty string. This should be treated as\n // an implementation detail and not as a stable part of the protocol.\n // It just needs to match the equivalent logic that happens when\n // prerendering the responses. It should not leak outside of Next.js.\n ('/_index' as SegmentRequestKey)\n : requestKey\n\n const headers: RequestHeaders = {\n [RSC_HEADER]: '1',\n [NEXT_ROUTER_PREFETCH_HEADER]: '1',\n [NEXT_ROUTER_SEGMENT_PREFETCH_HEADER]: normalizedRequestKey,\n }\n if (nextUrl !== null) {\n headers[NEXT_URL] = nextUrl\n }\n\n const requestUrl = isOutputExportMode\n ? // In output: \"export\" mode, we need to add the segment path to the URL.\n addSegmentPathToUrlInOutputExportMode(url, normalizedRequestKey)\n : url\n try {\n const response = await fetchPrefetchResponse(requestUrl, headers)\n if (\n !response ||\n !response.ok ||\n response.status === 204 || // Cache miss\n // This checks whether the response was served from the per-segment cache,\n // rather than the old prefetching flow. If it fails, it implies that PPR\n // is disabled on this route. Theoretically this should never happen\n // because we only issue requests for segments once we've verified that\n // the route supports PPR.\n (response.headers.get(NEXT_DID_POSTPONE_HEADER) !== '2' &&\n // In output: \"export\" mode, we can't rely on response headers. But if\n // we receive a well-formed response, we can assume it's a static\n // response, because all data is static in this mode.\n !isOutputExportMode) ||\n !response.body\n ) {\n // Server responded with an error, or with a miss. We should still cache\n // the response, but we can try again after 10 seconds.\n rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000)\n return null\n }\n\n // Track when the network connection closes.\n const closed = createPromiseWithResolvers()\n\n // Wrap the original stream in a new stream that never closes. That way the\n // Flight client doesn't error if there's a hanging promise.\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(size) {\n segmentCacheLru.updateSize(segmentCacheEntry, size)\n }\n )\n const serverData = await (createFromNextReadableStream(\n prefetchStream\n ) as Promise)\n if (serverData.buildId !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000)\n return null\n }\n return {\n value: fulfillSegmentCacheEntry(\n segmentCacheEntry,\n serverData.rsc,\n serverData.loading,\n // TODO: The server does not currently provide per-segment stale time.\n // So we use the stale time of the route.\n route.staleAt,\n serverData.isPartial\n ),\n // Return a promise that resolves when the network connection closes, so\n // the scheduler can track the number of concurrent network connections.\n closed: closed.promise,\n }\n } catch (error) {\n // Either the connection itself failed, or something bad happened while\n // decoding the response.\n rejectSegmentCacheEntry(segmentCacheEntry, Date.now() + 10 * 1000)\n return null\n }\n}\n\nexport async function fetchSegmentPrefetchesUsingDynamicRequest(\n task: PrefetchTask,\n route: FulfilledRouteCacheEntry,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n dynamicRequestTree: FlightRouterState,\n spawnedEntries: Map\n): Promise | null> {\n const url = new URL(route.canonicalUrl, task.key.href)\n const nextUrl = task.key.nextUrl\n const headers: RequestHeaders = {\n [RSC_HEADER]: '1',\n [NEXT_ROUTER_STATE_TREE_HEADER]: encodeURIComponent(\n JSON.stringify(dynamicRequestTree)\n ),\n }\n if (nextUrl !== null) {\n headers[NEXT_URL] = nextUrl\n }\n switch (fetchStrategy) {\n case FetchStrategy.Full: {\n // We omit the prefetch header from a full prefetch because it's essentially\n // just a navigation request that happens ahead of time — it should include\n // all the same data in the response.\n break\n }\n case FetchStrategy.PPRRuntime: {\n headers[NEXT_ROUTER_PREFETCH_HEADER] = '2'\n break\n }\n case FetchStrategy.LoadingBoundary: {\n headers[NEXT_ROUTER_PREFETCH_HEADER] = '1'\n break\n }\n default: {\n fetchStrategy satisfies never\n }\n }\n\n try {\n const response = await fetchPrefetchResponse(url, headers)\n if (!response || !response.ok || !response.body) {\n // Server responded with an error, or with a miss. We should still cache\n // the response, but we can try again after 10 seconds.\n rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000)\n return null\n }\n\n const renderedSearch = getRenderedSearch(response)\n if (renderedSearch !== route.renderedSearch) {\n // The search params that were used to render the target page are\n // different from the search params in the request URL. This only happens\n // when there's a dynamic rewrite in between the tree prefetch and the\n // data prefetch.\n // TODO: For now, since this is an edge case, we reject the prefetch, but\n // the proper way to handle this is to evict the stale route tree entry\n // then fill the cache with the new response.\n rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000)\n return null\n }\n\n // Track when the network connection closes.\n const closed = createPromiseWithResolvers()\n\n let fulfilledEntries: Array | null = null\n const prefetchStream = createPrefetchResponseStream(\n response.body,\n closed.resolve,\n function onResponseSizeUpdate(totalBytesReceivedSoFar) {\n // When processing a dynamic response, we don't know how large each\n // individual segment is, so approximate by assiging each segment\n // the average of the total response size.\n if (fulfilledEntries === null) {\n // Haven't received enough data yet to know which segments\n // were included.\n return\n }\n const averageSize = totalBytesReceivedSoFar / fulfilledEntries.length\n for (const entry of fulfilledEntries) {\n segmentCacheLru.updateSize(entry, averageSize)\n }\n }\n )\n const serverData = await (createFromNextReadableStream(\n prefetchStream\n ) as Promise)\n\n const isResponsePartial =\n fetchStrategy === FetchStrategy.PPRRuntime\n ? // A runtime prefetch may have holes.\n !!response.headers.get(NEXT_DID_POSTPONE_HEADER)\n : // Full and LoadingBoundary prefetches cannot have holes.\n // (even if we did set the prefetch header, we only use this codepath for non-PPR-enabled routes)\n false\n\n // Aside from writing the data into the cache, this function also returns\n // the entries that were fulfilled, so we can streamingly update their sizes\n // in the LRU as more data comes in.\n fulfilledEntries = writeDynamicRenderResponseIntoCache(\n Date.now(),\n task,\n fetchStrategy,\n response,\n serverData,\n isResponsePartial,\n route,\n spawnedEntries\n )\n\n // Return a promise that resolves when the network connection closes, so\n // the scheduler can track the number of concurrent network connections.\n return { value: null, closed: closed.promise }\n } catch (error) {\n rejectSegmentEntriesIfStillPending(spawnedEntries, Date.now() + 10 * 1000)\n return null\n }\n}\n\nfunction writeDynamicTreeResponseIntoCache(\n now: number,\n task: PrefetchTask,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n response: RSCResponse,\n serverData: NavigationFlightResponse,\n entry: PendingRouteCacheEntry,\n couldBeIntercepted: boolean,\n canonicalUrl: string,\n routeIsPPREnabled: boolean\n) {\n // Get the URL that was used to render the target page. This may be different\n // from the URL in the request URL, if the page was rewritten.\n const renderedSearch = getRenderedSearch(response)\n\n const normalizedFlightDataResult = normalizeFlightData(serverData.f)\n if (\n // A string result means navigating to this route will result in an\n // MPA navigation.\n typeof normalizedFlightDataResult === 'string' ||\n normalizedFlightDataResult.length !== 1\n ) {\n rejectRouteCacheEntry(entry, now + 10 * 1000)\n return\n }\n const flightData = normalizedFlightDataResult[0]\n if (!flightData.isRootRender) {\n // Unexpected response format.\n rejectRouteCacheEntry(entry, now + 10 * 1000)\n return\n }\n\n const flightRouterState = flightData.tree\n // TODO: Extract to function\n const staleTimeHeaderSeconds = response.headers.get(\n NEXT_ROUTER_STALE_TIME_HEADER\n )\n const staleTimeMs =\n staleTimeHeaderSeconds !== null\n ? getStaleTimeMs(parseInt(staleTimeHeaderSeconds, 10))\n : STATIC_STALETIME_MS\n\n // If the response contains dynamic holes, then we must conservatively assume\n // that any individual segment might contain dynamic holes, and also the\n // head. If it did not contain dynamic holes, then we can assume every segment\n // and the head is completely static.\n const isResponsePartial =\n response.headers.get(NEXT_DID_POSTPONE_HEADER) === '1'\n\n // Since this is a dynamic response, we must conservatively assume that the\n // head responded with dynamic data.\n const isHeadDynamic = true\n\n const fulfilledEntry = fulfillRouteCacheEntry(\n entry,\n convertRootFlightRouterStateToRouteTree(flightRouterState),\n flightData.head,\n flightData.isHeadPartial,\n now + staleTimeMs,\n couldBeIntercepted,\n canonicalUrl,\n renderedSearch,\n routeIsPPREnabled,\n isHeadDynamic\n )\n\n // If the server sent segment data as part of the response, we should write\n // it into the cache to prevent a second, redundant prefetch request.\n //\n // TODO: When `clientSegmentCache` is enabled, the server does not include\n // segment data when responding to a route tree prefetch request. However,\n // when `clientSegmentCache` is set to \"client-only\", and PPR is enabled (or\n // the page is fully static), the normal check is bypassed and the server\n // responds with the full page. This is a temporary situation until we can\n // remove the \"client-only\" option. Then, we can delete this function call.\n writeDynamicRenderResponseIntoCache(\n now,\n task,\n fetchStrategy,\n response,\n serverData,\n isResponsePartial,\n fulfilledEntry,\n null\n )\n}\n\nfunction rejectSegmentEntriesIfStillPending(\n entries: Map,\n staleAt: number\n): Array {\n const fulfilledEntries = []\n for (const entry of entries.values()) {\n if (entry.status === EntryStatus.Pending) {\n rejectSegmentCacheEntry(entry, staleAt)\n } else if (entry.status === EntryStatus.Fulfilled) {\n fulfilledEntries.push(entry)\n }\n }\n return fulfilledEntries\n}\n\nfunction writeDynamicRenderResponseIntoCache(\n now: number,\n task: PrefetchTask,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n response: RSCResponse,\n serverData: NavigationFlightResponse,\n isResponsePartial: boolean,\n route: FulfilledRouteCacheEntry,\n spawnedEntries: Map | null\n): Array | null {\n if (serverData.b !== getAppBuildId()) {\n // The server build does not match the client. Treat as a 404. During\n // an actual navigation, the router will trigger an MPA navigation.\n // TODO: Consider moving the build ID to a response header so we can check\n // it before decoding the response, and so there's one way of checking\n // across all response types.\n if (spawnedEntries !== null) {\n rejectSegmentEntriesIfStillPending(spawnedEntries, now + 10 * 1000)\n }\n return null\n }\n\n const flightDatas = normalizeFlightData(serverData.f)\n if (typeof flightDatas === 'string') {\n // This means navigating to this route will result in an MPA navigation.\n // TODO: We should cache this, too, so that the MPA navigation is immediate.\n return null\n }\n\n const staleTimeHeaderSeconds = response.headers.get(\n NEXT_ROUTER_STALE_TIME_HEADER\n )\n const staleTimeMs =\n staleTimeHeaderSeconds !== null\n ? getStaleTimeMs(parseInt(staleTimeHeaderSeconds, 10))\n : STATIC_STALETIME_MS\n const staleAt = now + staleTimeMs\n\n for (const flightData of flightDatas) {\n const seedData = flightData.seedData\n if (seedData !== null) {\n // The data sent by the server represents only a subtree of the app. We\n // need to find the part of the task tree that matches the response.\n //\n // segmentPath represents the parent path of subtree. It's a repeating\n // pattern of parallel route key and segment:\n //\n // [string, Segment, string, Segment, string, Segment, ...]\n const segmentPath = flightData.segmentPath\n let requestKey = ROOT_SEGMENT_REQUEST_KEY\n let cacheKey = ROOT_SEGMENT_CACHE_KEY\n for (let i = 0; i < segmentPath.length; i += 2) {\n const parallelRouteKey: string = segmentPath[i]\n const segment: FlightRouterStateSegment = segmentPath[i + 1]\n const requestKeyPart = createSegmentRequestKeyPart(segment)\n requestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n requestKeyPart\n )\n cacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(requestKeyPart, segment)\n )\n }\n\n writeSeedDataIntoCache(\n now,\n task,\n fetchStrategy,\n route,\n staleAt,\n seedData,\n isResponsePartial,\n cacheKey,\n requestKey,\n spawnedEntries\n )\n }\n\n // During a dynamic request, the server sends back new head data for the\n // page. Overwrite the existing head with the new one. Note that we're\n // intentionally not taking into account whether the existing head is\n // already complete, even though the incoming head might not have finished\n // streaming in yet. This is to prioritize consistency of the head with\n // the segment data (though it's still not a guarantee, since some of the\n // segment data may be reused from a previous request).\n route.head = flightData.head\n route.isHeadPartial = flightData.isHeadPartial\n route.TODO_isHeadDynamic = true\n\n // TODO: Currently the stale time of the route tree represents the\n // stale time of both the route tree *and* all the segment data. So we\n // can't just overwrite this field; we have to use whichever value is\n // lower. In the future, though, the plan is to track segment lifetimes\n // separately from the route tree lifetime.\n if (staleAt < route.staleAt) {\n route.staleAt = staleAt\n }\n }\n // Any entry that's still pending was intentionally not rendered by the\n // server, because it was inside the loading boundary. Mark them as rejected\n // so we know not to fetch them again.\n // TODO: If PPR is enabled on some routes but not others, then it's possible\n // that a different page is able to do a per-segment prefetch of one of the\n // segments we're marking as rejected here. We should mark on the segment\n // somehow that the reason for the rejection is because of a non-PPR prefetch.\n // That way a per-segment prefetch knows to disregard the rejection.\n if (spawnedEntries !== null) {\n const fulfilledEntries = rejectSegmentEntriesIfStillPending(\n spawnedEntries,\n now + 10 * 1000\n )\n return fulfilledEntries\n }\n return null\n}\n\nfunction writeSeedDataIntoCache(\n now: number,\n task: PrefetchTask,\n fetchStrategy:\n | FetchStrategy.LoadingBoundary\n | FetchStrategy.PPRRuntime\n | FetchStrategy.Full,\n route: FulfilledRouteCacheEntry,\n staleAt: number,\n seedData: CacheNodeSeedData,\n isResponsePartial: boolean,\n cacheKey: SegmentCacheKey,\n requestKey: SegmentRequestKey,\n entriesOwnedByCurrentTask: Map<\n SegmentCacheKey,\n PendingSegmentCacheEntry\n > | null\n) {\n // This function is used to write the result of a dynamic server request\n // (CacheNodeSeedData) into the prefetch cache. It's used in cases where we\n // want to treat a dynamic response as if it were static. The two examples\n // where this happens are (which implicitly opts\n // dynamic data into being static) and when prefetching a PPR-disabled route\n const rsc = seedData[1]\n const loading = seedData[3]\n const isPartial = rsc === null || isResponsePartial\n\n // We should only write into cache entries that are owned by us. Or create\n // a new one and write into that. We must never write over an entry that was\n // created by a different task, because that causes data races.\n const ownedEntry =\n entriesOwnedByCurrentTask !== null\n ? entriesOwnedByCurrentTask.get(cacheKey)\n : undefined\n if (ownedEntry !== undefined) {\n fulfillSegmentCacheEntry(ownedEntry, rsc, loading, staleAt, isPartial)\n } else {\n // There's no matching entry. Attempt to create a new one.\n const possiblyNewEntry = readOrCreateSegmentCacheEntry(\n now,\n task,\n route,\n cacheKey\n )\n if (possiblyNewEntry.status === EntryStatus.Empty) {\n // Confirmed this is a new entry. We can fulfill it.\n const newEntry = possiblyNewEntry\n fulfillSegmentCacheEntry(\n upgradeToPendingSegment(newEntry, fetchStrategy),\n rsc,\n loading,\n staleAt,\n isPartial\n )\n } else {\n // There was already an entry in the cache. But we may be able to\n // replace it with the new one from the server.\n const newEntry = fulfillSegmentCacheEntry(\n upgradeToPendingSegment(\n createDetachedSegmentCacheEntry(staleAt),\n fetchStrategy\n ),\n rsc,\n loading,\n staleAt,\n isPartial\n )\n upsertSegmentEntry(\n now,\n getSegmentKeypathForTask(task, route, cacheKey),\n newEntry\n )\n }\n }\n // Recursively write the child data into the cache.\n const seedDataChildren = seedData[2]\n if (seedDataChildren !== null) {\n for (const parallelRouteKey in seedDataChildren) {\n const childSeedData = seedDataChildren[parallelRouteKey]\n if (childSeedData !== null) {\n const childSegment = childSeedData[0]\n const childRequestKeyPart = createSegmentRequestKeyPart(childSegment)\n const childRequestKey = appendSegmentRequestKeyPart(\n requestKey,\n parallelRouteKey,\n childRequestKeyPart\n )\n const childCacheKey = appendSegmentCacheKeyPart(\n cacheKey,\n parallelRouteKey,\n createSegmentCacheKeyPart(childRequestKeyPart, childSegment)\n )\n writeSeedDataIntoCache(\n now,\n task,\n fetchStrategy,\n route,\n staleAt,\n childSeedData,\n isResponsePartial,\n childCacheKey,\n childRequestKey,\n entriesOwnedByCurrentTask\n )\n }\n }\n }\n}\n\nasync function fetchPrefetchResponse(\n url: URL,\n headers: RequestHeaders\n): Promise {\n const fetchPriority = 'low'\n const response = await createFetch(url, headers, fetchPriority)\n if (!response.ok) {\n return null\n }\n\n // Check the content type\n if (isOutputExportMode) {\n // In output: \"export\" mode, we relaxed about the content type, since it's\n // not Next.js that's serving the response. If the status is OK, assume the\n // response is valid. If it's not a valid response, the Flight client won't\n // be able to decode it, and we'll treat it as a miss.\n } else {\n const contentType = response.headers.get('content-type')\n const isFlightResponse =\n contentType && contentType.startsWith(RSC_CONTENT_TYPE_HEADER)\n if (!isFlightResponse) {\n return null\n }\n }\n return response\n}\n\nfunction createPrefetchResponseStream(\n originalFlightStream: ReadableStream,\n onStreamClose: () => void,\n onResponseSizeUpdate: (size: number) => void\n): ReadableStream {\n // When PPR is enabled, prefetch streams may contain references that never\n // resolve, because that's how we encode dynamic data access. In the decoded\n // object returned by the Flight client, these are reified into hanging\n // promises that suspend during render, which is effectively what we want.\n // The UI resolves when it switches to the dynamic data stream\n // (via useDeferredValue(dynamic, static)).\n //\n // However, the Flight implementation currently errors if the server closes\n // the response before all the references are resolved. As a cheat to work\n // around this, we wrap the original stream in a new stream that never closes,\n // and therefore doesn't error.\n //\n // While processing the original stream, we also incrementally update the size\n // of the cache entry in the LRU.\n let totalByteLength = 0\n const reader = originalFlightStream.getReader()\n return new ReadableStream({\n async pull(controller) {\n while (true) {\n const { done, value } = await reader.read()\n if (!done) {\n // Pass to the target stream and keep consuming the Flight response\n // from the server.\n controller.enqueue(value)\n\n // Incrementally update the size of the cache entry in the LRU.\n // NOTE: Since prefetch responses are delivered in a single chunk,\n // it's not really necessary to do this streamingly, but I'm doing it\n // anyway in case this changes in the future.\n totalByteLength += value.byteLength\n onResponseSizeUpdate(totalByteLength)\n continue\n }\n // The server stream has closed. Exit, but intentionally do not close\n // the target stream. We do notify the caller, though.\n onStreamClose()\n return\n }\n },\n })\n}\n\nfunction addSegmentPathToUrlInOutputExportMode(\n url: URL,\n segmentPath: SegmentRequestKey\n): URL {\n if (isOutputExportMode) {\n // In output: \"export\" mode, we cannot use a header to encode the segment\n // path. Instead, we append it to the end of the pathname.\n const staticUrl = new URL(url)\n const routeDir = staticUrl.pathname.endsWith('/')\n ? staticUrl.pathname.substring(0, -1)\n : staticUrl.pathname\n const staticExportFilename =\n convertSegmentPathToStaticExportFilename(segmentPath)\n staticUrl.pathname = `${routeDir}/${staticExportFilename}`\n return staticUrl\n }\n return url\n}\n\n/**\n * Checks whether the new fetch strategy is likely to provide more content than the old one.\n *\n * Generally, when an app uses dynamic data, a \"more specific\" fetch strategy is expected to provide more content:\n * - `LoadingBoundary` only provides static layouts\n * - `PPR` can provide shells for each segment (even for segments that use dynamic data)\n * - `PPRRuntime` can additionally include content that uses searchParams, params, or cookies\n * - `Full` includes all the content, even if it uses dynamic data\n *\n * However, it's possible that a more specific fetch strategy *won't* give us more content if:\n * - a segment is fully static\n * (then, `PPR`/`PPRRuntime`/`Full` will all yield equivalent results)\n * - providing searchParams/params/cookies doesn't reveal any more content, e.g. because of an `await connection()`\n * (then, `PPR` and `PPRRuntime` will yield equivalent results, only `Full` will give us more)\n * Because of this, when comparing two segments, we should also check if the existing segment is partial.\n * If it's not partial, then there's no need to prefetch it again, even using a \"more specific\" strategy.\n * There's currently no way to know if `PPRRuntime` will yield more data that `PPR`, so we have to assume it will.\n *\n * Also note that, in practice, we don't expect to be comparing `LoadingBoundary` to `PPR`/`PPRRuntime`,\n * because a non-PPR-enabled route wouldn't ever use the latter strategies. It might however use `Full`.\n */\nexport function canNewFetchStrategyProvideMoreContent(\n currentStrategy: FetchStrategy,\n newStrategy: FetchStrategy\n): boolean {\n return currentStrategy < newStrategy\n}\n"],"names":["EntryStatus","canNewFetchStrategyProvideMoreContent","convertRouteTreeToFlightRouterState","createDetachedSegmentCacheEntry","fetchRouteOnCacheMiss","fetchSegmentOnCacheMiss","fetchSegmentPrefetchesUsingDynamicRequest","getCurrentCacheVersion","getSegmentKeypathForTask","pingInvalidationListeners","readExactRouteCacheEntry","readOrCreateRevalidatingSegmentEntry","readOrCreateRouteCacheEntry","readOrCreateSegmentCacheEntry","readRouteCacheEntry","readSegmentCacheEntry","requestOptimisticRouteCacheEntry","resetRevalidatingSegmentEntry","revalidateEntireCache","upgradeToPendingSegment","upsertSegmentEntry","waitForSegmentCacheEntry","isOutputExportMode","process","env","NODE_ENV","__NEXT_CONFIG_OUTPUT","getStaleTimeMs","staleTimeSeconds","Math","max","routeCacheMap","createTupleMap","maxRouteLruSize","routeCacheLru","createLRU","onRouteLRUEviction","segmentCacheMap","maxSegmentLruSize","segmentCacheLru","onSegmentLRUEviction","invalidationListeners","currentCacheVersion","nextUrl","tree","pingVisibleLinks","attachInvalidationListener","task","onInvalidate","Set","add","notifyInvalidationListener","error","reportError","console","tasks","isPrefetchTaskDirty","now","href","keypath","existingEntry","get","staleAt","put","deleteRouteFromCache","key","nonInterceptedEntry","couldBeIntercepted","route","cacheKey","isDynamicTask","fetchStrategy","FetchStrategy","Full","PPRRuntime","isPPREnabled","endsWith","PAGE_SEGMENT_KEY","renderedSearch","readExactSegmentCacheEntry","entryWithSearchParams","entryWithoutSearchParams","revalidatingEntry","revalidating","upsertedEntry","deleteSegmentFromCache","readRevalidatingSegmentCacheEntry","owner","existingRevalidation","clearRevalidatingSegmentFromOwner","pendingEntry","promiseWithResolvers","promise","createPromiseWithResolvers","canonicalUrl","status","blockedTasks","head","isHeadPartial","Infinity","TODO_metadataStatus","TODO_isHeadDynamic","next","prev","size","set","requestedUrl","requestedSearch","search","routeWithNoSearchParams","createPrefetchRequestKey","origin","pathname","canonicalUrlForRouteWithNoSearchParams","URL","optimisticCanonicalSearch","optimisticRenderedSearch","optimisticUrl","location","optimisticCanonicalUrl","createHrefFromUrl","optimisticEntry","prevEntry","candidateEntry","isPartial","rejectedEntry","loading","rsc","emptyEntry","PPR","entry","pingBlockedTasks","delete","cancelEntryListeners","revalidatingSegment","resolve","pingPrefetchTask","fulfillRouteCacheEntry","isHeadDynamic","fulfilledEntry","fulfillSegmentCacheEntry","segmentCacheEntry","rejectRouteCacheEntry","rejectSegmentCacheEntry","convertRootTreePrefetchToRouteTree","rootTree","renderedPathname","pathnameParts","split","filter","p","index","rootSegment","ROOT_SEGMENT_CACHE_KEY","convertTreePrefetchToRouteTree","ROOT_SEGMENT_REQUEST_KEY","prefetch","segment","param","requestKey","pathnamePartsIndex","slots","prefetchSlots","parallelRouteKey","childPrefetch","childParamName","name","childParamType","paramType","childServerSentParamKey","paramKey","childDoesAppearInURL","childParam","childSegment","childParamValue","parseDynamicParamFromURLPart","childParamKey","getCacheKeyForDynamicParam","value","type","doesStaticSegmentAppearInURL","childPathnamePartsIndex","childRequestKeyPart","createSegmentRequestKeyPart","childRequestKey","appendSegmentRequestKeyPart","childCacheKey","appendSegmentCacheKeyPart","createSegmentCacheKeyPart","isRootLayout","hasLoadingBoundary","HasLoadingBoundary","SegmentHasLoadingBoundary","convertRootFlightRouterStateToRouteTree","flightRouterState","convertFlightRouterStateToRouteTree","parallelRoutes","childRouterState","childTree","originalSegment","Array","isArray","paramCacheKey","paramValue","getParamValueFromCacheKey","undefined","startsWith","SubtreeHasNoLoadingBoundary","routeTree","segmentPath","headers","RSC_HEADER","NEXT_ROUTER_PREFETCH_HEADER","NEXT_ROUTER_SEGMENT_PREFETCH_HEADER","NEXT_URL","response","urlAfterRedirects","url","htmlResponse","fetch","Range","DOC_PREFETCH_RANGE_HEADER_VALUE","partialHtml","text","doesExportedHtmlMatchBuildId","getAppBuildId","Date","redirected","fetchPrefetchResponse","addSegmentPathToUrlInOutputExportMode","ok","body","varyHeader","includes","closed","routeIsPPREnabled","NEXT_DID_POSTPONE_HEADER","prefetchStream","createPrefetchResponseStream","onResponseSizeUpdate","updateSize","serverData","createFromNextReadableStream","buildId","getRenderedPathname","getRenderedSearch","staleTimeMs","staleTime","b","writeDynamicTreeResponseIntoCache","LoadingBoundary","currentKeypath","expectedEntry","newKeypath","routeKey","normalizedRequestKey","requestUrl","dynamicRequestTree","spawnedEntries","NEXT_ROUTER_STATE_TREE_HEADER","encodeURIComponent","JSON","stringify","rejectSegmentEntriesIfStillPending","fulfilledEntries","totalBytesReceivedSoFar","averageSize","length","isResponsePartial","writeDynamicRenderResponseIntoCache","normalizedFlightDataResult","normalizeFlightData","f","flightData","isRootRender","staleTimeHeaderSeconds","NEXT_ROUTER_STALE_TIME_HEADER","parseInt","STATIC_STALETIME_MS","entries","values","push","flightDatas","seedData","i","requestKeyPart","writeSeedDataIntoCache","entriesOwnedByCurrentTask","ownedEntry","possiblyNewEntry","newEntry","seedDataChildren","childSeedData","fetchPriority","createFetch","contentType","isFlightResponse","RSC_CONTENT_TYPE_HEADER","originalFlightStream","onStreamClose","totalByteLength","reader","getReader","ReadableStream","pull","controller","done","read","enqueue","byteLength","staticUrl","routeDir","substring","staticExportFilename","convertSegmentPathToStaticExportFilename","currentStrategy","newStrategy"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAoJkBA,WAAW;eAAXA;;IAyhEFC,qCAAqC;eAArCA;;IAr8BAC,mCAAmC;eAAnCA;;IA/ZAC,+BAA+B;eAA/BA;;IAobMC,qBAAqB;eAArBA;;IAkQAC,uBAAuB;eAAvBA;;IAoHAC,yCAAyC;eAAzCA;;IAn0CNC,sBAAsB;eAAtBA;;IAiIAC,wBAAwB;eAAxBA;;IA3DAC,yBAAyB;eAAzBA;;IAmBAC,wBAAwB;eAAxBA;;IAoXAC,oCAAoC;eAApCA;;IA3MAC,2BAA2B;eAA3BA;;IAsLAC,6BAA6B;eAA7BA;;IAtUAC,mBAAmB;eAAnBA;;IAoCAC,qBAAqB;eAArBA;;IA6JAC,gCAAgC;eAAhCA;;IAuSAC,6BAA6B;eAA7BA;;IAhlBAC,qBAAqB;eAArBA;;IAuiBAC,uBAAuB;eAAvBA;;IA3EAC,kBAAkB;eAAlBA;;IAvPAC,wBAAwB;eAAxBA;;;uBAjhBmB;kCAU5B;qCAMA;2BAMA;4BACuB;mCACI;0BAQyB;6BASpD;0BACoD;qBACjC;sCAWnB;mCAK6B;oCACA;uBACH;yBACA;8CAI1B;8BACuB;sCACa;AAkEpC,IAAA,AAAWrB,qCAAAA;;;;;WAAAA;;AAoGlB,MAAMsB,qBACJC,QAAQC,GAAG,CAACC,QAAQ,KAAK,gBACzBF,QAAQC,GAAG,CAACE,oBAAoB,KAAK;AAEvC;;;CAGC,GACD,SAASC,eAAeC,gBAAwB;IAC9C,OAAOC,KAAKC,GAAG,CAACF,kBAAkB,MAAM;AAC1C;AAQA,IAAIG,gBACFC,IAAAA,wBAAc;AAEhB,8EAA8E;AAC9E,2DAA2D;AAC3D,+EAA+E;AAC/E,0EAA0E;AAC1E,4CAA4C;AAC5C,MAAMC,kBAAkB,KAAK,OAAO,KAAK,QAAQ;;AACjD,IAAIC,gBAAgBC,IAAAA,cAAS,EAC3BF,iBACAG;AAIF,IAAIC,kBACFL,IAAAA,wBAAc;AAChB,0EAA0E;AAC1E,4EAA4E;AAC5E,+EAA+E;AAC/E,8BAA8B;AAC9B,MAAMM,oBAAoB,KAAK,OAAO,KAAK,QAAQ;;AACnD,IAAIC,kBAAkBJ,IAAAA,cAAS,EAC7BG,mBACAE;AAGF,4EAA4E;AAC5E,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAC9E,2EAA2E;AAC3E,4BAA4B;AAC5B,IAAIC,wBAAkD;AAEtD,0DAA0D;AAC1D,IAAIC,sBAAsB;AAEnB,SAASnC;IACd,OAAOmC;AACT;AAQO,SAASxB,sBACdyB,OAAsB,EACtBC,IAAuB;IAEvBF;IAEA,4EAA4E;IAC5E,4EAA4E;IAC5E,uBAAuB;IACvB,yEAAyE;IACzE,yEAAyE;IACzEX,gBAAgBC,IAAAA,wBAAc;IAC9BE,gBAAgBC,IAAAA,cAAS,EAACF,iBAAiBG;IAC3CC,kBAAkBL,IAAAA,wBAAc;IAChCO,kBAAkBJ,IAAAA,cAAS,EAACG,mBAAmBE;IAE/C,wEAAwE;IACxEK,IAAAA,uBAAgB,EAACF,SAASC;IAE1B,qEAAqE;IACrE,uEAAuE;IACvE,aAAa;IACbnC,0BAA0BkC,SAASC;AACrC;AAEA,SAASE,2BAA2BC,IAAkB;IACpD,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,wCAAwC;IACxC,IAAIA,KAAKC,YAAY,KAAK,MAAM;QAC9B,IAAIP,0BAA0B,MAAM;YAClCA,wBAAwB,IAAIQ,IAAI;gBAACF;aAAK;QACxC,OAAO;YACLN,sBAAsBS,GAAG,CAACH;QAC5B;IACF;AACF;AAEA,SAASI,2BAA2BJ,IAAkB;IACpD,MAAMC,eAAeD,KAAKC,YAAY;IACtC,IAAIA,iBAAiB,MAAM;QACzB,4EAA4E;QAC5E,aAAa;QACbD,KAAKC,YAAY,GAAG;QAEpB,+DAA+D;QAC/D,IAAI;YACFA;QACF,EAAE,OAAOI,OAAO;YACd,IAAI,OAAOC,gBAAgB,YAAY;gBACrCA,YAAYD;YACd,OAAO;gBACLE,QAAQF,KAAK,CAACA;YAChB;QACF;IACF;AACF;AAEO,SAAS3C,0BACdkC,OAAsB,EACtBC,IAAuB;IAEvB,4EAA4E;IAC5E,yEAAyE;IACzE,qEAAqE;IACrE,sBAAsB;IACtB,IAAIH,0BAA0B,MAAM;QAClC,MAAMc,QAAQd;QACdA,wBAAwB;QACxB,KAAK,MAAMM,QAAQQ,MAAO;YACxB,IAAIC,IAAAA,8BAAmB,EAACT,MAAMJ,SAASC,OAAO;gBAC5CO,2BAA2BJ;YAC7B;QACF;IACF;AACF;AAEO,SAASrC,yBACd+C,GAAW,EACXC,IAAoB,EACpBf,OAAiC;IAEjC,MAAMgB,UACJhB,YAAY,OAAO;QAACe;KAAK,GAAG;QAACA;QAAMf;KAAQ;IAC7C,MAAMiB,gBAAgB7B,cAAc8B,GAAG,CAACF;IACxC,IAAIC,kBAAkB,MAAM;QAC1B,8BAA8B;QAC9B,IAAIA,cAAcE,OAAO,GAAGL,KAAK;YAC/B,4BAA4B;YAE5B,mEAAmE;YACnEvB,cAAc6B,GAAG,CAACH;YAElB,OAAOA;QACT,OAAO;YACL,wCAAwC;YACxCI,qBAAqBJ,eAAeD;QACtC;IACF;IACA,OAAO;AACT;AAEO,SAAS7C,oBACd2C,GAAW,EACXQ,GAAkB;IAElB,wEAAwE;IACxE,2CAA2C;IAC3C,MAAMC,sBAAsBxD,yBAAyB+C,KAAKQ,IAAIP,IAAI,EAAE;IACpE,IAAIQ,wBAAwB,QAAQ,CAACA,oBAAoBC,kBAAkB,EAAE;QAC3E,uEAAuE;QACvE,OAAOD;IACT;IACA,sEAAsE;IACtE,OAAOxD,yBAAyB+C,KAAKQ,IAAIP,IAAI,EAAEO,IAAItB,OAAO;AAC5D;AAEO,SAASnC,yBACduC,IAAkB,EAClBqB,KAA+B,EAC/BC,QAAyB;IAEzB,wEAAwE;IACxE,qEAAqE;IACrE,0EAA0E;IAC1E,EAAE;IACF,8EAA8E;IAC9E,4EAA4E;IAC5E,6DAA6D;IAC7D,MAAMC,gBACJvB,KAAKwB,aAAa,KAAKC,2BAAa,CAACC,IAAI,IACzC1B,KAAKwB,aAAa,KAAKC,2BAAa,CAACE,UAAU,IAC/C,CAACN,MAAMO,YAAY;IACrB,OAAOL,iBAAiBD,SAASO,QAAQ,CAAC,MAAMC,yBAAgB,IAC5D;QAACR;QAAUD,MAAMU,cAAc;KAAC,GAChC;QAACT;KAAS;AAChB;AAEO,SAAStD,sBACd0C,GAAW,EACXW,KAA+B,EAC/BC,QAAyB;IAEzB,IAAI,CAACA,SAASO,QAAQ,CAAC,MAAMC,yBAAgB,GAAG;QAC9C,wDAAwD;QACxD,OAAOE,2BAA2BtB,KAAK;YAACY;SAAS;IACnD;IAEA,MAAMS,iBAAiBV,MAAMU,cAAc;IAC3C,IAAIA,mBAAmB,MAAM;QAC3B,8EAA8E;QAC9E,0EAA0E;QAC1E,6BAA6B;QAC7B,MAAME,wBAAwBD,2BAA2BtB,KAAK;YAC5DY;YACAS;SACD;QACD,IAAIE,0BAA0B,MAAM;YAClC,OAAOA;QACT;IACF;IAEA,wEAAwE;IACxE,8EAA8E;IAC9E,8EAA8E;IAC9E,cAAc;IACd,EAAE;IACF,yDAAyD;IACzD,MAAMC,2BAA2BF,2BAA2BtB,KAAK;QAACY;KAAS;IAC3E,OAAOY;AACT;AAEA,SAASF,2BACPtB,GAAW,EACXE,OAAoC;IAEpC,MAAMC,gBAAgBvB,gBAAgBwB,GAAG,CAACF;IAC1C,IAAIC,kBAAkB,MAAM;QAC1B,8BAA8B;QAC9B,IAAIA,cAAcE,OAAO,GAAGL,KAAK;YAC/B,4BAA4B;YAE5B,mEAAmE;YACnElB,gBAAgBwB,GAAG,CAACH;YAEpB,OAAOA;QACT,OAAO;YACL,yBAAyB;YACzB,MAAMsB,oBAAoBtB,cAAcuB,YAAY;YACpD,IAAID,sBAAsB,MAAM;gBAC9B,iDAAiD;gBACjD,MAAME,gBAAgBhE,mBACpBqC,KACAE,SACAuB;gBAEF,IAAIE,kBAAkB,QAAQA,cAActB,OAAO,GAAGL,KAAK;oBACzD,8CAA8C;oBAC9C,OAAO2B;gBACT;YACF,OAAO;gBACL,wCAAwC;gBACxCC,uBAAuBzB,eAAeD;YACxC;QACF;IACF;IACA,OAAO;AACT;AAEA,SAAS2B,kCACP7B,GAAW,EACX8B,KAAwB;IAExB,MAAMC,uBAAuBD,MAAMJ,YAAY;IAC/C,IAAIK,yBAAyB,MAAM;QACjC,IAAIA,qBAAqB1B,OAAO,GAAGL,KAAK;YACtC,yEAAyE;YACzE,qCAAqC;YACrC,OAAO+B;QACT,OAAO;YACL,+CAA+C;YAC/CC,kCAAkCF;QACpC;IACF;IACA,OAAO;AACT;AAEO,SAASlE,yBACdqE,YAAsC;IAEtC,uEAAuE;IACvE,4EAA4E;IAC5E,IAAIC,uBAAuBD,aAAaE,OAAO;IAC/C,IAAID,yBAAyB,MAAM;QACjCA,uBAAuBD,aAAaE,OAAO,GACzCC,IAAAA,gDAA0B;IAC9B,OAAO;IACL,uCAAuC;IACzC;IACA,OAAOF,qBAAqBC,OAAO;AACrC;AAMO,SAAShF,4BACd6C,GAAW,EACXV,IAAkB;IAElBD,2BAA2BC;IAE3B,MAAMkB,MAAMlB,KAAKkB,GAAG;IACpB,MAAML,gBAAgB9C,oBAAoB2C,KAAKQ;IAC/C,IAAIL,kBAAkB,MAAM;QAC1B,OAAOA;IACT;IACA,kDAAkD;IAClD,MAAM8B,eAAuC;QAC3CI,cAAc;QACdC,MAAM;QACNC,cAAc;QACdpD,MAAM;QACNqD,MAAM;QACNC,eAAe;QACf,4EAA4E;QAC5E,yCAAyC;QACzCpC,SAASqC;QACT,0EAA0E;QAC1E,0EAA0E;QAC1E,mBAAmB;QACnBhC,oBAAoB;QACpB,0DAA0D;QAC1DQ,cAAc;QACdG,gBAAgB;QAEhBsB,mBAAmB;QACnBC,oBAAoB;QAEpB,qBAAqB;QACrB1C,SAAS;QACT2C,MAAM;QACNC,MAAM;QACNC,MAAM;IACR;IACA,MAAM7C,UACJM,IAAItB,OAAO,KAAK,OAAO;QAACsB,IAAIP,IAAI;KAAC,GAAG;QAACO,IAAIP,IAAI;QAAEO,IAAItB,OAAO;KAAC;IAC7DZ,cAAc0E,GAAG,CAAC9C,SAAS+B;IAC3B,0EAA0E;IAC1E,mCAAmC;IACnCA,aAAa/B,OAAO,GAAGA;IACvBzB,cAAc6B,GAAG,CAAC2B;IAClB,OAAOA;AACT;AAEO,SAAS1E,iCACdyC,GAAW,EACXiD,YAAiB,EACjB/D,OAAsB;IAEtB,yEAAyE;IACzE,oEAAoE;IACpE,8EAA8E;IAC9E,uDAAuD;IACvD,EAAE;IACF,sEAAsE;IACtE,2EAA2E;IAC3E,EAAE;IACF,wEAAwE;IACxE,wEAAwE;IACxE,qEAAqE;IACrE,4EAA4E;IAC5E,2EAA2E;IAC3E,wEAAwE;IACxE,0EAA0E;IAC1E,kCAAkC;IAElC,4EAA4E;IAC5E,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,4EAA4E;IAC5E,uCAAuC;IACvC,MAAMgE,kBAAkBD,aAAaE,MAAM;IAC3C,IAAID,oBAAoB,IAAI;QAC1B,wEAAwE;QACxE,mDAAmD;QACnD,OAAO;IACT;IACA,MAAME,0BAA0B/F,oBAC9B2C,KACAqD,IAAAA,wBAAwB,EACtBJ,aAAaK,MAAM,GAAGL,aAAaM,QAAQ,EAC3CrE;IAIJ,IACEkE,4BAA4B,QAC5BA,wBAAwBd,MAAM,UAC9B,yEAAyE;IACzE,6DAA6D;IAC7D,qBAAqB;IACrBc,wBAAwBX,aAAa,IACrC,yDAAyD;IACzD,oEAAoE;IACpE,oEAAoE;IACpE,gBAAgB;IAChBW,wBAAwBT,mBAAmB,UAC3CS,wBAAwBR,kBAAkB,EAC1C;QACA,yEAAyE;QACzE,uCAAuC;QACvC,OAAO;IACT;IAEA,2EAA2E;IAE3E,qEAAqE;IACrE,kEAAkE;IAClE,qEAAqE;IACrE,oEAAoE;IACpE,+BAA+B;IAC/B,MAAMY,yCAAyC,IAAIC,IACjDL,wBAAwBf,YAAY,EACpCY,aAAaK,MAAM;IAErB,MAAMI,4BACJF,uCAAuCL,MAAM,KAAK,KAE9CK,uCAAuCL,MAAM,GAC7CD;IAEN,mEAAmE;IACnE,oEAAoE;IACpE,wEAAwE;IACxE,yEAAyE;IACzE,+BAA+B;IAC/B,MAAMS,2BACJP,wBAAwB/B,cAAc,KAAK,KAEvC+B,wBAAwB/B,cAAc,GACtC6B;IAEN,MAAMU,gBAAgB,IAAIH,IACxBL,wBAAwBf,YAAY,EACpCwB,SAASP,MAAM;IAEjBM,cAAcT,MAAM,GAAGO;IACvB,MAAMI,yBAAyBC,IAAAA,oCAAiB,EAACH;IAEjD,uEAAuE;IACvE,qBAAqB;IACrB,MAAMI,kBAA4C;QAChD3B,cAAcyB;QAEdxB,MAAM;QACN,mDAAmD;QACnDC,cAAc;QACdpD,MAAMiE,wBAAwBjE,IAAI;QAClCqD,MAAMY,wBAAwBZ,IAAI;QAClCC,eAAeW,wBAAwBX,aAAa;QACpDpC,SAAS+C,wBAAwB/C,OAAO;QACxCK,oBAAoB0C,wBAAwB1C,kBAAkB;QAC9DQ,cAAckC,wBAAwBlC,YAAY;QAElD,0DAA0D;QAC1DG,gBAAgBsC;QAEhBhB,qBAAqBS,wBAAwBT,mBAAmB;QAChEC,oBAAoBQ,wBAAwBR,kBAAkB;QAE9D,qBAAqB;QACrB1C,SAAS;QACT2C,MAAM;QACNC,MAAM;QACNC,MAAM;IACR;IAEA,oEAAoE;IACpE,gEAAgE;IAChE,OAAOiB;AACT;AAMO,SAAS5G,8BACd4C,GAAW,EACXV,IAAkB,EAClBqB,KAA+B,EAC/BC,QAAyB;IAEzB,MAAMV,UAAUnD,yBAAyBuC,MAAMqB,OAAOC;IACtD,MAAMT,gBAAgBmB,2BAA2BtB,KAAKE;IACtD,IAAIC,kBAAkB,MAAM;QAC1B,OAAOA;IACT;IACA,kDAAkD;IAClD,MAAM8B,eAAevF,gCAAgCiE,MAAMN,OAAO;IAClEzB,gBAAgBoE,GAAG,CAAC9C,SAAS+B;IAC7B,0EAA0E;IAC1E,mCAAmC;IACnCA,aAAa/B,OAAO,GAAGA;IACvBpB,gBAAgBwB,GAAG,CAAC2B;IACpB,OAAOA;AACT;AAEO,SAAS/E,qCACd8C,GAAW,EACXiE,SAA4B;IAE5B,MAAMlC,uBAAuBF,kCAAkC7B,KAAKiE;IACpE,IAAIlC,yBAAyB,MAAM;QACjC,OAAOA;IACT;IACA,MAAME,eAAevF,gCAAgCuH,UAAU5D,OAAO;IAEtE,4EAA4E;IAC5E,qEAAqE;IACrE,EAAE;IACF,2EAA2E;IAC3E,0EAA0E;IAC1E,EAAE;IACF,4EAA4E;IAC5E,6EAA6E;IAC7E,wEAAwE;IACxE,kEAAkE;IAClE4D,UAAUvC,YAAY,GAAGO;IAEzB,OAAOA;AACT;AAEO,SAAStE,mBACdqC,GAAW,EACXE,OAAoC,EACpCgE,cAAiC;IAEjC,4EAA4E;IAC5E,6EAA6E;IAC7E,yBAAyB;IACzB,6EAA6E;IAC7E,6EAA6E;IAC7E,iEAAiE;IACjE,MAAM/D,gBAAgBmB,2BAA2BtB,KAAKE;IACtD,IAAIC,kBAAkB,MAAM;QAC1B,oFAAoF;QACpF,0DAA0D;QAC1D,4BAA4B;QAC5B,IAGE,AAFA,6EAA6E;QAC7E,gFAAgF;QAC/E+D,eAAepD,aAAa,KAAKX,cAAcW,aAAa,IAC3D,CAACtE,sCACC2D,cAAcW,aAAa,EAC3BoD,eAAepD,aAAa,KAEhC,wDAAwD;QACxD,6FAA6F;QAC5F,CAACX,cAAcgE,SAAS,IAAID,eAAeC,SAAS,EACrD;YACA,qEAAqE;YACrE,wEAAwE;YACxE,yEAAyE;YACzE,0EAA0E;YAC1E,yCAAyC;YACzC,MAAMC,gBAA2CF;YACjDE,cAAc9B,MAAM;YACpB8B,cAAcC,OAAO,GAAG;YACxBD,cAAcE,GAAG,GAAG;YACpB,OAAO;QACT;QAEA,2CAA2C;QAC3C1C,uBAAuBzB,eAAeD;IACxC;IACAtB,gBAAgBoE,GAAG,CAAC9C,SAASgE;IAC7B,0EAA0E;IAC1E,mCAAmC;IACnCA,eAAehE,OAAO,GAAGA;IACzBpB,gBAAgBwB,GAAG,CAAC4D;IACpB,OAAOA;AACT;AAEO,SAASxH,gCACd2D,OAAe;IAEf,MAAMkE,aAAqC;QACzCjC,MAAM;QACN,2EAA2E;QAC3E,sCAAsC;QACtCxB,eAAeC,2BAAa,CAACyD,GAAG;QAChC9C,cAAc;QACd4C,KAAK;QACLD,SAAS;QACThE;QACA8D,WAAW;QACXhC,SAAS;QAET,qBAAqB;QACrBjC,SAAS;QACT2C,MAAM;QACNC,MAAM;QACNC,MAAM;IACR;IACA,OAAOwB;AACT;AAEO,SAAS7G,wBACd6G,UAAkC,EAClCzD,aAA4B;IAE5B,MAAMmB,eAAyCsC;IAC/CtC,aAAaK,MAAM;IACnBL,aAAanB,aAAa,GAAGA;IAC7B,OAAOmB;AACT;AAEA,SAAS1B,qBACPkE,KAAsB,EACtBvE,OAAkC;IAElCwE,iBAAiBD;IACjBnG,cAAcqG,MAAM,CAACzE;IACrBzB,cAAckG,MAAM,CAACF;AACvB;AAEA,SAAS7C,uBACP6C,KAAwB,EACxBvE,OAAoC;IAEpC0E,qBAAqBH;IACrB7F,gBAAgB+F,MAAM,CAACzE;IACvBpB,gBAAgB6F,MAAM,CAACF;IACvBzC,kCAAkCyC;AACpC;AAEA,SAASzC,kCAAkCF,KAAwB;IACjE,sEAAsE;IACtE,0EAA0E;IAC1E,6EAA6E;IAC7E,gBAAgB;IAChB,MAAM+C,sBAAsB/C,MAAMJ,YAAY;IAC9C,IAAImD,wBAAwB,MAAM;QAChCD,qBAAqBC;QACrB/C,MAAMJ,YAAY,GAAG;IACvB;AACF;AAEO,SAASlE,8BACdsE,KAAwB;IAExBE,kCAAkCF;IAClC,MAAMyC,aAAa7H,gCAAgCoF,MAAMzB,OAAO;IAChEyB,MAAMJ,YAAY,GAAG6C;IACrB,OAAOA;AACT;AAEA,SAAS5F,mBAAmB8F,KAAsB;IAChD,sDAAsD;IACtD,MAAMvE,UAAUuE,MAAMvE,OAAO;IAC7B,IAAIA,YAAY,MAAM;QACpBuE,MAAMvE,OAAO,GAAG;QAChBwE,iBAAiBD;QACjBnG,cAAcqG,MAAM,CAACzE;IACvB;AACF;AAEA,SAASnB,qBAAqB0F,KAAwB;IACpD,sDAAsD;IACtD,MAAMvE,UAAUuE,MAAMvE,OAAO;IAC7B,IAAIA,YAAY,MAAM;QACpBuE,MAAMvE,OAAO,GAAG;QAChB0E,qBAAqBH;QACrB7F,gBAAgB+F,MAAM,CAACzE;IACzB;AACF;AAEA,SAAS0E,qBAAqBH,KAAwB;IACpD,IAAIA,MAAMnC,MAAM,UAA4BmC,MAAMtC,OAAO,KAAK,MAAM;QAClE,4EAA4E;QAC5E,4EAA4E;QAC5E,aAAa;QACb,0EAA0E;QAC1E,iDAAiD;QACjDsC,MAAMtC,OAAO,CAAC2C,OAAO,CAAC;QACtBL,MAAMtC,OAAO,GAAG;IAClB;AACF;AAEA,SAASuC,iBAAiBD,KAEzB;IACC,MAAMlC,eAAekC,MAAMlC,YAAY;IACvC,IAAIA,iBAAiB,MAAM;QACzB,KAAK,MAAMjD,QAAQiD,aAAc;YAC/BwC,IAAAA,2BAAgB,EAACzF;QACnB;QACAmF,MAAMlC,YAAY,GAAG;IACvB;AACF;AAEA,SAASyC,uBACPP,KAAsB,EACtBtF,IAAe,EACfqD,IAAc,EACdC,aAAsB,EACtBpC,OAAe,EACfK,kBAA2B,EAC3B2B,YAAoB,EACpBhB,cAAgC,EAChCH,YAAqB,EACrB+D,aAAsB;IAEtB,MAAMC,iBAA2CT;IACjDS,eAAe5C,MAAM;IACrB4C,eAAe/F,IAAI,GAAGA;IACtB+F,eAAe1C,IAAI,GAAGA;IACtB0C,eAAezC,aAAa,GAAGA;IAC/ByC,eAAe7E,OAAO,GAAGA;IACzB6E,eAAexE,kBAAkB,GAAGA;IACpCwE,eAAe7C,YAAY,GAAGA;IAC9B6C,eAAe7D,cAAc,GAAGA;IAChC6D,eAAehE,YAAY,GAAGA;IAC9BgE,eAAetC,kBAAkB,GAAGqC;IACpCP,iBAAiBD;IACjB,OAAOS;AACT;AAEA,SAASC,yBACPC,iBAA2C,EAC3Cd,GAAoB,EACpBD,OAAuD,EACvDhE,OAAe,EACf8D,SAAkB;IAElB,MAAMe,iBAA6CE;IACnDF,eAAe5C,MAAM;IACrB4C,eAAeZ,GAAG,GAAGA;IACrBY,eAAeb,OAAO,GAAGA;IACzBa,eAAe7E,OAAO,GAAGA;IACzB6E,eAAef,SAAS,GAAGA;IAC3B,yDAAyD;IACzD,IAAIiB,kBAAkBjD,OAAO,KAAK,MAAM;QACtCiD,kBAAkBjD,OAAO,CAAC2C,OAAO,CAACI;QAClC,2CAA2C;QAC3CA,eAAe/C,OAAO,GAAG;IAC3B;IACA,OAAO+C;AACT;AAEA,SAASG,sBACPZ,KAA6B,EAC7BpE,OAAe;IAEf,MAAM+D,gBAAyCK;IAC/CL,cAAc9B,MAAM;IACpB8B,cAAc/D,OAAO,GAAGA;IACxBqE,iBAAiBD;AACnB;AAEA,SAASa,wBACPb,KAA+B,EAC/BpE,OAAe;IAEf,MAAM+D,gBAA2CK;IACjDL,cAAc9B,MAAM;IACpB8B,cAAc/D,OAAO,GAAGA;IACxB,IAAIoE,MAAMtC,OAAO,KAAK,MAAM;QAC1B,0EAA0E;QAC1E,iDAAiD;QACjDsC,MAAMtC,OAAO,CAAC2C,OAAO,CAAC;QACtBL,MAAMtC,OAAO,GAAG;IAClB;AACF;AAEA,SAASoD,mCACPC,QAA0B,EAC1BC,gBAAwB;IAExB,sCAAsC;IACtC,MAAMC,gBAAgBD,iBAAiBE,KAAK,CAAC,KAAKC,MAAM,CAAC,CAACC,IAAMA,MAAM;IACtE,MAAMC,QAAQ;IACd,MAAMC,cAAcC,4CAAsB;IAC1C,OAAOC,+BACLT,SAASrG,IAAI,EACb4G,aACA,MACAG,8CAAwB,EACxBF,4CAAsB,EACtBN,eACAI;AAEJ;AAEA,SAASG,+BACPE,QAAsB,EACtBC,OAAiC,EACjCC,KAAwB,EACxBC,UAA6B,EAC7B1F,QAAyB,EACzB8E,aAA4B,EAC5Ba,kBAA0B;IAE1B,yEAAyE;IACzE,8EAA8E;IAC9E,4EAA4E;IAC5E,0EAA0E;IAC1E,uCAAuC;IAEvC,IAAIC,QAA0D;IAC9D,MAAMC,gBAAgBN,SAASK,KAAK;IACpC,IAAIC,kBAAkB,MAAM;QAC1BD,QAAQ,CAAC;QACT,IAAK,IAAIE,oBAAoBD,cAAe;YAC1C,MAAME,gBAAgBF,aAAa,CAACC,iBAAiB;YACrD,MAAME,iBAAiBD,cAAcE,IAAI;YACzC,MAAMC,iBAAiBH,cAAcI,SAAS;YAC9C,MAAMC,0BAA0BL,cAAcM,QAAQ;YAEtD,IAAIC;YACJ,IAAIC,aAAgC;YACpC,IAAIC;YACJ,IAAIN,mBAAmB,MAAM;gBAC3B,kEAAkE;gBAClE,MAAMO,kBAAkBC,IAAAA,yCAA4B,EAClDR,gBACApB,eACAa;gBAGF,sEAAsE;gBACtE,uEAAuE;gBACvE,uEAAuE;gBACvE,2DAA2D;gBAE3D,gEAAgE;gBAChE,uEAAuE;gBACvE,sEAAsE;gBACtE,2DAA2D;gBAC3D,gBAAgB;gBAChB,MAAMlF,iBAAiB;gBACvB,MAAMkG,gBACJ,8DAA8D;gBAC9D,kEAAkE;gBAClE,oEAAoE;gBACpE,8DAA8D;gBAC9DP,4BAA4B,OACxBA,0BAEAQ,IAAAA,uCAA0B,EAACH,iBAAiBhG;gBAElD8F,aAAa;oBACXN,MAAMD;oBACNa,OAAOJ;oBACPK,MAAMZ;gBACR;gBACAM,eAAe;oBAACR;oBAAgBW;oBAAeT;iBAAe;gBAC9DI,uBAAuB;YACzB,OAAO;gBACLE,eAAeR;gBACfM,uBAAuBS,IAAAA,yCAA4B,EAACf;YACtD;YAEA,wEAAwE;YACxE,8DAA8D;YAC9D,MAAMgB,0BAA0BV,uBAC5BX,qBAAqB,IACrBA;YAEJ,MAAMsB,sBAAsBC,IAAAA,iDAA2B,EAACV;YACxD,MAAMW,kBAAkBC,IAAAA,iDAA2B,EACjD1B,YACAI,kBACAmB;YAEF,MAAMI,gBAAgBC,IAAAA,+CAAyB,EAC7CtH,UACA8F,kBACAyB,IAAAA,+CAAyB,EAACN,qBAAqBT;YAEjDZ,KAAK,CAACE,iBAAiB,GAAGT,+BACxBU,eACAS,cACAD,YACAY,iBACAE,eACAvC,eACAkC;QAEJ;IACF;IAEA,OAAO;QACLhH;QACA0F;QACAF;QACAC;QACAG;QACA4B,cAAcjC,SAASiC,YAAY;QACnC,yEAAyE;QACzE,0DAA0D;QAC1DC,oBAAoBC,yBAAkB,CAACC,yBAAyB;IAClE;AACF;AAEA,SAASC,wCACPC,iBAAoC;IAEpC,OAAOC,oCACLD,mBACAzC,4CAAsB,EACtBE,8CAAwB;AAE5B;AAEA,SAASwC,oCACPD,iBAAoC,EACpC7H,QAAyB,EACzB0F,UAA6B;IAE7B,IAAIE,QAA0D;IAE9D,MAAMmC,iBAAiBF,iBAAiB,CAAC,EAAE;IAC3C,IAAK,IAAI/B,oBAAoBiC,eAAgB;QAC3C,MAAMC,mBAAmBD,cAAc,CAACjC,iBAAiB;QACzD,MAAMU,eAAewB,gBAAgB,CAAC,EAAE;QACxC,0EAA0E;QAC1E,uEAAuE;QACvE,wCAAwC;QACxC,MAAMf,sBAAsBC,IAAAA,iDAA2B,EAACV;QACxD,MAAMW,kBAAkBC,IAAAA,iDAA2B,EACjD1B,YACAI,kBACAmB;QAEF,MAAMI,gBAAgBC,IAAAA,+CAAyB,EAC7CtH,UACA8F,kBACAyB,IAAAA,+CAAyB,EAACN,qBAAqBT;QAEjD,MAAMyB,YAAYH,oCAChBE,kBACAX,eACAF;QAEF,IAAIvB,UAAU,MAAM;YAClBA,QAAQ;gBACN,CAACE,iBAAiB,EAAEmC;YACtB;QACF,OAAO;YACLrC,KAAK,CAACE,iBAAiB,GAAGmC;QAC5B;IACF;IACA,MAAMC,kBAAkBL,iBAAiB,CAAC,EAAE;IAE5C,IAAIrC;IACJ,IAAIC,QAA2B;IAC/B,IAAI0C,MAAMC,OAAO,CAACF,kBAAkB;QAClC,MAAMG,gBAAgBH,eAAe,CAAC,EAAE;QACxC,MAAM/B,YAAY+B,eAAe,CAAC,EAAE;QACpC,MAAMI,aAAaC,IAAAA,sCAAyB,EAACF,eAAelC;QAC5DV,QAAQ;YACNQ,MAAMiC,eAAe,CAAC,EAAE;YACxBrB,OAAOyB,eAAeE,YAAY,OAAOF;YACzCxB,MAAMoB,eAAe,CAAC,EAAE;QAC1B;QACA1C,UAAU0C;IACZ,OAAO;QACL,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,0BAA0B;QAC1B,EAAE;QACF,6DAA6D;QAC7D,EAAE;QACF,yEAAyE;QACzE,uEAAuE;QACvE1C,UACE,OAAO0C,oBAAoB,YAC3BA,gBAAgBO,UAAU,CAACjI,yBAAgB,IACvCA,yBAAgB,GAChB0H;IACR;IAEA,OAAO;QACLlI;QACA0F;QACAF;QACAC;QACAG;QACA4B,cAAcK,iBAAiB,CAAC,EAAE,KAAK;QACvCJ,oBACEI,iBAAiB,CAAC,EAAE,KAAKW,YACrBX,iBAAiB,CAAC,EAAE,GACpBH,yBAAkB,CAACgB,2BAA2B;IACtD;AACF;AAEO,SAAS7M,oCACd8M,SAAoB;IAEpB,MAAMZ,iBAAoD,CAAC;IAC3D,IAAIY,UAAU/C,KAAK,KAAK,MAAM;QAC5B,IAAK,MAAME,oBAAoB6C,UAAU/C,KAAK,CAAE;YAC9CmC,cAAc,CAACjC,iBAAiB,GAAGjK,oCACjC8M,UAAU/C,KAAK,CAACE,iBAAiB;QAErC;IACF;IACA,MAAM+B,oBAAuC;QAC3Cc,UAAUnD,OAAO;QACjBuC;QACA;QACA;QACAY,UAAUnB,YAAY;KACvB;IACD,OAAOK;AACT;AAEO,eAAe9L,sBACpB8H,KAA6B,EAC7BnF,IAAkB;IAElB,6EAA6E;IAC7E,6EAA6E;IAC7E,wEAAwE;IACxE,cAAc;IACd,MAAMkB,MAAMlB,KAAKkB,GAAG;IACpB,MAAMP,OAAOO,IAAIP,IAAI;IACrB,MAAMf,UAAUsB,IAAItB,OAAO;IAC3B,MAAMsK,cAAc;IAEpB,MAAMC,UAA0B;QAC9B,CAACC,4BAAU,CAAC,EAAE;QACd,CAACC,6CAA2B,CAAC,EAAE;QAC/B,CAACC,qDAAmC,CAAC,EAAEJ;IACzC;IACA,IAAItK,YAAY,MAAM;QACpBuK,OAAO,CAACI,0BAAQ,CAAC,GAAG3K;IACtB;IAEA,IAAI;QACF,IAAI4K;QACJ,IAAIC;QACJ,IAAIlM,oBAAoB;YACtB,yEAAyE;YACzE,0EAA0E;YAC1E,0EAA0E;YAC1E,0EAA0E;YAC1E,2BAA2B;YAC3B,EAAE;YACF,qCAAqC;YACrC,EAAE;YACF,2CAA2C;YAC3C,iEAAiE;YACjE,EAAE;YACF,4DAA4D;YAC5D,EAAE;YACF,uEAAuE;YACvE,wEAAwE;YACxE,0EAA0E;YAC1E,0BAA0B;YAC1B,EAAE;YACF,yEAAyE;YACzE,0EAA0E;YAC1E,qBAAqB;YACrB,EAAE;YACF,+DAA+D;YAC/D,EAAE;YACF,uEAAuE;YACvE,yEAAyE;YACzE,yDAAyD;YACzD,MAAMmM,MAAM,IAAIvG,IAAIxD;YACpB,MAAMgK,eAAe,MAAMC,MAAMjK,MAAM;gBACrCwJ,SAAS;oBACPU,OAAOC,6DAA+B;gBACxC;YACF;YACA,MAAMC,cAAc,MAAMJ,aAAaK,IAAI;YAC3C,IAAI,CAACC,IAAAA,0DAA4B,EAACF,aAAaG,IAAAA,yBAAa,MAAK;gBAC/D,8DAA8D;gBAC9D,mBAAmB;gBACnBnF,sBAAsBZ,OAAOgG,KAAKzK,GAAG,KAAK,KAAK;gBAC/C,OAAO;YACT;YACA+J,oBAAoBE,aAAaS,UAAU,GACvC,IAAIjH,IAAIwG,aAAaD,GAAG,IACxBA;YACJF,WAAW,MAAMa,sBACfC,sCAAsCb,mBAAmBP,cACzDC;QAEJ,OAAO;YACL,qEAAqE;YACrE,0EAA0E;YAC1E,kEAAkE;YAClE,gCAAgC;YAChC,MAAMO,MAAM,IAAIvG,IAAIxD;YACpB6J,WAAW,MAAMa,sBAAsBX,KAAKP;YAC5CM,oBACED,aAAa,QAAQA,SAASY,UAAU,GAAG,IAAIjH,IAAIqG,SAASE,GAAG,IAAIA;QACvE;QAEA,IACE,CAACF,YACD,CAACA,SAASe,EAAE,IACZ,uEAAuE;QACvE,yEAAyE;QACzE,oDAAoD;QACpDf,SAASxH,MAAM,KAAK,OACpB,CAACwH,SAASgB,IAAI,EACd;YACA,wEAAwE;YACxE,uDAAuD;YACvDzF,sBAAsBZ,OAAOgG,KAAKzK,GAAG,KAAK,KAAK;YAC/C,OAAO;QACT;QAEA,kEAAkE;QAClE,wEAAwE;QACxE,yEAAyE;QACzE,wEAAwE;QACxE,4EAA4E;QAC5E,yEAAyE;QACzE,EAAE;QACF,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,0EAA0E;QAC1E,2EAA2E;QAC3E,4BAA4B;QAC5B,MAAMqC,eAAe0B,IAAAA,oCAAiB,EAACgG;QAEvC,kEAAkE;QAClE,MAAMgB,aAAajB,SAASL,OAAO,CAACrJ,GAAG,CAAC;QACxC,MAAMM,qBACJqK,eAAe,QAAQA,WAAWC,QAAQ,CAACnB,0BAAQ;QAErD,4CAA4C;QAC5C,MAAMoB,SAAS7I,IAAAA,gDAA0B;QAEzC,0EAA0E;QAC1E,yEAAyE;QACzE,6BAA6B;QAC7B,MAAM8I,oBACJpB,SAASL,OAAO,CAACrJ,GAAG,CAAC+K,0CAAwB,MAAM,OACnD,yEAAyE;QACzE,wEAAwE;QACxE,2CAA2C;QAC3CtN;QAEF,oEAAoE;QACpE,6CAA6C;QAC7C,MAAMoH,gBAAgB;QAEtB,IAAIiG,mBAAmB;YACrB,MAAME,iBAAiBC,6BACrBvB,SAASgB,IAAI,EACbG,OAAOnG,OAAO,EACd,SAASwG,qBAAqBvI,IAAI;gBAChCtE,cAAc8M,UAAU,CAAC9G,OAAO1B;YAClC;YAEF,MAAMyI,aAAa,MAAOC,IAAAA,iDAA4B,EACpDL;YAEF,IAAII,WAAWE,OAAO,KAAKlB,IAAAA,yBAAa,KAAI;gBAC1C,qEAAqE;gBACrE,mEAAmE;gBACnE,0EAA0E;gBAC1E,sEAAsE;gBACtE,6BAA6B;gBAC7B,iEAAiE;gBACjEnF,sBAAsBZ,OAAOgG,KAAKzK,GAAG,KAAK,KAAK;gBAC/C,OAAO;YACT;YAEA,qEAAqE;YACrE,+DAA+D;YAC/D,iBAAiB;YACjB,MAAMyF,mBAAmBkG,IAAAA,gCAAmB,EAAC7B;YAC7C,MAAMzI,iBAAiBuK,IAAAA,8BAAiB,EAAC9B;YAEzC,MAAMP,YAAYhE,mCAChBiG,YACA/F;YAGF,MAAMoG,cAAc3N,eAAesN,WAAWM,SAAS;YACvD9G,uBACEP,OACA8E,WACAiC,WAAWhJ,IAAI,EACfgJ,WAAW/I,aAAa,EACxBgI,KAAKzK,GAAG,KAAK6L,aACbnL,oBACA2B,cACAhB,gBACA6J,mBACAjG;QAEJ,OAAO;YACL,gEAAgE;YAChE,gEAAgE;YAChE,sEAAsE;YACtE,yDAAyD;YACzD,uBAAuB;YACvB,MAAMmG,iBAAiBC,6BACrBvB,SAASgB,IAAI,EACbG,OAAOnG,OAAO,EACd,SAASwG,qBAAqBvI,IAAI;gBAChCtE,cAAc8M,UAAU,CAAC9G,OAAO1B;YAClC;YAEF,MAAMyI,aAAa,MAAOC,IAAAA,iDAA4B,EACpDL;YAEF,IAAII,WAAWO,CAAC,KAAKvB,IAAAA,yBAAa,KAAI;gBACpC,qEAAqE;gBACrE,mEAAmE;gBACnE,0EAA0E;gBAC1E,sEAAsE;gBACtE,6BAA6B;gBAC7B,iEAAiE;gBACjEnF,sBAAsBZ,OAAOgG,KAAKzK,GAAG,KAAK,KAAK;gBAC/C,OAAO;YACT;YAEAgM,kCACEvB,KAAKzK,GAAG,IACRV,MACA,+EAA+E;YAC/E,qFAAqF;YACrFyB,2BAAa,CAACkL,eAAe,EAC7BnC,UACA0B,YACA/G,OACA/D,oBACA2B,cACA6I;QAEJ;QAEA,IAAI,CAACxK,sBAAsBxB,YAAY,MAAM;YAC3C,yEAAyE;YACzE,wEAAwE;YACxE,6DAA6D;YAC7D,+BAA+B;YAC/B,EAAE;YACF,wEAAwE;YACxE,wEAAwE;YACxE,MAAMgN,iBAA4C;gBAACjM;gBAAMf;aAAQ;YACjE,MAAMiN,gBAAgB7N,cAAc8B,GAAG,CAAC8L;YACxC,IAAIC,kBAAkB1H,OAAO;gBAC3BnG,cAAcqG,MAAM,CAACuH;gBACrB,MAAME,aAAwC;oBAACnM;iBAAK;gBACpD3B,cAAc0E,GAAG,CAACoJ,YAAY3H;gBAC9B,sEAAsE;gBACtE,qEAAqE;gBACrE,sEAAsE;gBACtEA,MAAMvE,OAAO,GAAGkM;YAClB,OAAO;YACL,qEAAqE;YACrE,0DAA0D;YAC5D;QACF;QACA,wEAAwE;QACxE,wEAAwE;QACxE,OAAO;YAAE3E,OAAO;YAAMwD,QAAQA,OAAO9I,OAAO;QAAC;IAC/C,EAAE,OAAOxC,OAAO;QACd,uEAAuE;QACvE,yBAAyB;QACzB0F,sBAAsBZ,OAAOgG,KAAKzK,GAAG,KAAK,KAAK;QAC/C,OAAO;IACT;AACF;AAEO,eAAepD,wBACpB+D,KAA+B,EAC/ByE,iBAA2C,EAC3CiH,QAAuB,EACvBlN,IAAe;IAEf,6EAA6E;IAC7E,6EAA6E;IAC7E,wEAAwE;IACxE,cAAc;IACd,EAAE;IACF,0EAA0E;IAC1E,iBAAiB;IAEjB,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,mEAAmE;IACnE,MAAM6K,MAAM,IAAIvG,IAAI9C,MAAM0B,YAAY,EAAEgK,SAASpM,IAAI;IACrD,MAAMf,UAAUmN,SAASnN,OAAO;IAEhC,MAAMoH,aAAanH,KAAKmH,UAAU;IAClC,MAAMgG,uBACJhG,eAAeJ,8CAAwB,GAEnC,iEAAiE;IACjE,oEAAoE;IACpE,qEAAqE;IACrE,gEAAgE;IAChE,qEAAqE;IACpE,YACDI;IAEN,MAAMmD,UAA0B;QAC9B,CAACC,4BAAU,CAAC,EAAE;QACd,CAACC,6CAA2B,CAAC,EAAE;QAC/B,CAACC,qDAAmC,CAAC,EAAE0C;IACzC;IACA,IAAIpN,YAAY,MAAM;QACpBuK,OAAO,CAACI,0BAAQ,CAAC,GAAG3K;IACtB;IAEA,MAAMqN,aAAa1O,qBAEf+M,sCAAsCZ,KAAKsC,wBAC3CtC;IACJ,IAAI;QACF,MAAMF,WAAW,MAAMa,sBAAsB4B,YAAY9C;QACzD,IACE,CAACK,YACD,CAACA,SAASe,EAAE,IACZf,SAASxH,MAAM,KAAK,OAAO,aAAa;QACxC,0EAA0E;QAC1E,yEAAyE;QACzE,oEAAoE;QACpE,uEAAuE;QACvE,0BAA0B;QACzBwH,SAASL,OAAO,CAACrJ,GAAG,CAAC+K,0CAAwB,MAAM,OAClD,sEAAsE;QACtE,iEAAiE;QACjE,qDAAqD;QACrD,CAACtN,sBACH,CAACiM,SAASgB,IAAI,EACd;YACA,wEAAwE;YACxE,uDAAuD;YACvDxF,wBAAwBF,mBAAmBqF,KAAKzK,GAAG,KAAK,KAAK;YAC7D,OAAO;QACT;QAEA,4CAA4C;QAC5C,MAAMiL,SAAS7I,IAAAA,gDAA0B;QAEzC,2EAA2E;QAC3E,4DAA4D;QAC5D,MAAMgJ,iBAAiBC,6BACrBvB,SAASgB,IAAI,EACbG,OAAOnG,OAAO,EACd,SAASwG,qBAAqBvI,IAAI;YAChCjE,gBAAgByM,UAAU,CAACnG,mBAAmBrC;QAChD;QAEF,MAAMyI,aAAa,MAAOC,IAAAA,iDAA4B,EACpDL;QAEF,IAAII,WAAWE,OAAO,KAAKlB,IAAAA,yBAAa,KAAI;YAC1C,qEAAqE;YACrE,mEAAmE;YACnE,0EAA0E;YAC1E,sEAAsE;YACtE,6BAA6B;YAC7BlF,wBAAwBF,mBAAmBqF,KAAKzK,GAAG,KAAK,KAAK;YAC7D,OAAO;QACT;QACA,OAAO;YACLyH,OAAOtC,yBACLC,mBACAoG,WAAWlH,GAAG,EACdkH,WAAWnH,OAAO,EAClB,sEAAsE;YACtE,yCAAyC;YACzC1D,MAAMN,OAAO,EACbmL,WAAWrH,SAAS;YAEtB,wEAAwE;YACxE,wEAAwE;YACxE8G,QAAQA,OAAO9I,OAAO;QACxB;IACF,EAAE,OAAOxC,OAAO;QACd,uEAAuE;QACvE,yBAAyB;QACzB2F,wBAAwBF,mBAAmBqF,KAAKzK,GAAG,KAAK,KAAK;QAC7D,OAAO;IACT;AACF;AAEO,eAAenD,0CACpByC,IAAkB,EAClBqB,KAA+B,EAC/BG,aAGsB,EACtB0L,kBAAqC,EACrCC,cAA8D;IAE9D,MAAMzC,MAAM,IAAIvG,IAAI9C,MAAM0B,YAAY,EAAE/C,KAAKkB,GAAG,CAACP,IAAI;IACrD,MAAMf,UAAUI,KAAKkB,GAAG,CAACtB,OAAO;IAChC,MAAMuK,UAA0B;QAC9B,CAACC,4BAAU,CAAC,EAAE;QACd,CAACgD,+CAA6B,CAAC,EAAEC,mBAC/BC,KAAKC,SAAS,CAACL;IAEnB;IACA,IAAItN,YAAY,MAAM;QACpBuK,OAAO,CAACI,0BAAQ,CAAC,GAAG3K;IACtB;IACA,OAAQ4B;QACN,KAAKC,2BAAa,CAACC,IAAI;YAAE;gBAIvB;YACF;QACA,KAAKD,2BAAa,CAACE,UAAU;YAAE;gBAC7BwI,OAAO,CAACE,6CAA2B,CAAC,GAAG;gBACvC;YACF;QACA,KAAK5I,2BAAa,CAACkL,eAAe;YAAE;gBAClCxC,OAAO,CAACE,6CAA2B,CAAC,GAAG;gBACvC;YACF;QACA;YAAS;gBACP7I;YACF;IACF;IAEA,IAAI;QACF,MAAMgJ,WAAW,MAAMa,sBAAsBX,KAAKP;QAClD,IAAI,CAACK,YAAY,CAACA,SAASe,EAAE,IAAI,CAACf,SAASgB,IAAI,EAAE;YAC/C,wEAAwE;YACxE,uDAAuD;YACvDgC,mCAAmCL,gBAAgBhC,KAAKzK,GAAG,KAAK,KAAK;YACrE,OAAO;QACT;QAEA,MAAMqB,iBAAiBuK,IAAAA,8BAAiB,EAAC9B;QACzC,IAAIzI,mBAAmBV,MAAMU,cAAc,EAAE;YAC3C,iEAAiE;YACjE,yEAAyE;YACzE,sEAAsE;YACtE,iBAAiB;YACjB,yEAAyE;YACzE,uEAAuE;YACvE,6CAA6C;YAC7CyL,mCAAmCL,gBAAgBhC,KAAKzK,GAAG,KAAK,KAAK;YACrE,OAAO;QACT;QAEA,4CAA4C;QAC5C,MAAMiL,SAAS7I,IAAAA,gDAA0B;QAEzC,IAAI2K,mBAA6D;QACjE,MAAM3B,iBAAiBC,6BACrBvB,SAASgB,IAAI,EACbG,OAAOnG,OAAO,EACd,SAASwG,qBAAqB0B,uBAAuB;YACnD,mEAAmE;YACnE,iEAAiE;YACjE,0CAA0C;YAC1C,IAAID,qBAAqB,MAAM;gBAC7B,0DAA0D;gBAC1D,iBAAiB;gBACjB;YACF;YACA,MAAME,cAAcD,0BAA0BD,iBAAiBG,MAAM;YACrE,KAAK,MAAMzI,SAASsI,iBAAkB;gBACpCjO,gBAAgByM,UAAU,CAAC9G,OAAOwI;YACpC;QACF;QAEF,MAAMzB,aAAa,MAAOC,IAAAA,iDAA4B,EACpDL;QAGF,MAAM+B,oBACJrM,kBAAkBC,2BAAa,CAACE,UAAU,GAEtC,CAAC,CAAC6I,SAASL,OAAO,CAACrJ,GAAG,CAAC+K,0CAAwB,IAE/C,iGAAiG;QACjG;QAEN,yEAAyE;QACzE,4EAA4E;QAC5E,oCAAoC;QACpC4B,mBAAmBK,oCACjB3C,KAAKzK,GAAG,IACRV,MACAwB,eACAgJ,UACA0B,YACA2B,mBACAxM,OACA8L;QAGF,wEAAwE;QACxE,wEAAwE;QACxE,OAAO;YAAEhF,OAAO;YAAMwD,QAAQA,OAAO9I,OAAO;QAAC;IAC/C,EAAE,OAAOxC,OAAO;QACdmN,mCAAmCL,gBAAgBhC,KAAKzK,GAAG,KAAK,KAAK;QACrE,OAAO;IACT;AACF;AAEA,SAASgM,kCACPhM,GAAW,EACXV,IAAkB,EAClBwB,aAGsB,EACtBgJ,QAAqB,EACrB0B,UAAoC,EACpC/G,KAA6B,EAC7B/D,kBAA2B,EAC3B2B,YAAoB,EACpB6I,iBAA0B;IAE1B,6EAA6E;IAC7E,8DAA8D;IAC9D,MAAM7J,iBAAiBuK,IAAAA,8BAAiB,EAAC9B;IAEzC,MAAMuD,6BAA6BC,IAAAA,sCAAmB,EAAC9B,WAAW+B,CAAC;IACnE,IACE,mEAAmE;IACnE,kBAAkB;IAClB,OAAOF,+BAA+B,YACtCA,2BAA2BH,MAAM,KAAK,GACtC;QACA7H,sBAAsBZ,OAAOzE,MAAM,KAAK;QACxC;IACF;IACA,MAAMwN,aAAaH,0BAA0B,CAAC,EAAE;IAChD,IAAI,CAACG,WAAWC,YAAY,EAAE;QAC5B,8BAA8B;QAC9BpI,sBAAsBZ,OAAOzE,MAAM,KAAK;QACxC;IACF;IAEA,MAAMyI,oBAAoB+E,WAAWrO,IAAI;IACzC,4BAA4B;IAC5B,MAAMuO,yBAAyB5D,SAASL,OAAO,CAACrJ,GAAG,CACjDuN,+CAA6B;IAE/B,MAAM9B,cACJ6B,2BAA2B,OACvBxP,eAAe0P,SAASF,wBAAwB,OAChDG,uCAAmB;IAEzB,6EAA6E;IAC7E,wEAAwE;IACxE,8EAA8E;IAC9E,qCAAqC;IACrC,MAAMV,oBACJrD,SAASL,OAAO,CAACrJ,GAAG,CAAC+K,0CAAwB,MAAM;IAErD,2EAA2E;IAC3E,oCAAoC;IACpC,MAAMlG,gBAAgB;IAEtB,MAAMC,iBAAiBF,uBACrBP,OACA+D,wCAAwCC,oBACxC+E,WAAWhL,IAAI,EACfgL,WAAW/K,aAAa,EACxBzC,MAAM6L,aACNnL,oBACA2B,cACAhB,gBACA6J,mBACAjG;IAGF,2EAA2E;IAC3E,qEAAqE;IACrE,EAAE;IACF,0EAA0E;IAC1E,0EAA0E;IAC1E,4EAA4E;IAC5E,yEAAyE;IACzE,0EAA0E;IAC1E,2EAA2E;IAC3EmI,oCACEpN,KACAV,MACAwB,eACAgJ,UACA0B,YACA2B,mBACAjI,gBACA;AAEJ;AAEA,SAAS4H,mCACPgB,OAAgD,EAChDzN,OAAe;IAEf,MAAM0M,mBAAmB,EAAE;IAC3B,KAAK,MAAMtI,SAASqJ,QAAQC,MAAM,GAAI;QACpC,IAAItJ,MAAMnC,MAAM,QAA0B;YACxCgD,wBAAwBb,OAAOpE;QACjC,OAAO,IAAIoE,MAAMnC,MAAM,QAA4B;YACjDyK,iBAAiBiB,IAAI,CAACvJ;QACxB;IACF;IACA,OAAOsI;AACT;AAEA,SAASK,oCACPpN,GAAW,EACXV,IAAkB,EAClBwB,aAGsB,EACtBgJ,QAAqB,EACrB0B,UAAoC,EACpC2B,iBAA0B,EAC1BxM,KAA+B,EAC/B8L,cAAqE;IAErE,IAAIjB,WAAWO,CAAC,KAAKvB,IAAAA,yBAAa,KAAI;QACpC,qEAAqE;QACrE,mEAAmE;QACnE,0EAA0E;QAC1E,sEAAsE;QACtE,6BAA6B;QAC7B,IAAIiC,mBAAmB,MAAM;YAC3BK,mCAAmCL,gBAAgBzM,MAAM,KAAK;QAChE;QACA,OAAO;IACT;IAEA,MAAMiO,cAAcX,IAAAA,sCAAmB,EAAC9B,WAAW+B,CAAC;IACpD,IAAI,OAAOU,gBAAgB,UAAU;QACnC,wEAAwE;QACxE,4EAA4E;QAC5E,OAAO;IACT;IAEA,MAAMP,yBAAyB5D,SAASL,OAAO,CAACrJ,GAAG,CACjDuN,+CAA6B;IAE/B,MAAM9B,cACJ6B,2BAA2B,OACvBxP,eAAe0P,SAASF,wBAAwB,OAChDG,uCAAmB;IACzB,MAAMxN,UAAUL,MAAM6L;IAEtB,KAAK,MAAM2B,cAAcS,YAAa;QACpC,MAAMC,WAAWV,WAAWU,QAAQ;QACpC,IAAIA,aAAa,MAAM;YACrB,uEAAuE;YACvE,oEAAoE;YACpE,EAAE;YACF,sEAAsE;YACtE,6CAA6C;YAC7C,EAAE;YACF,6DAA6D;YAC7D,MAAM1E,cAAcgE,WAAWhE,WAAW;YAC1C,IAAIlD,aAAaJ,8CAAwB;YACzC,IAAItF,WAAWoF,4CAAsB;YACrC,IAAK,IAAImI,IAAI,GAAGA,IAAI3E,YAAY0D,MAAM,EAAEiB,KAAK,EAAG;gBAC9C,MAAMzH,mBAA2B8C,WAAW,CAAC2E,EAAE;gBAC/C,MAAM/H,UAAoCoD,WAAW,CAAC2E,IAAI,EAAE;gBAC5D,MAAMC,iBAAiBtG,IAAAA,iDAA2B,EAAC1B;gBACnDE,aAAa0B,IAAAA,iDAA2B,EACtC1B,YACAI,kBACA0H;gBAEFxN,WAAWsH,IAAAA,+CAAyB,EAClCtH,UACA8F,kBACAyB,IAAAA,+CAAyB,EAACiG,gBAAgBhI;YAE9C;YAEAiI,uBACErO,KACAV,MACAwB,eACAH,OACAN,SACA6N,UACAf,mBACAvM,UACA0F,YACAmG;QAEJ;QAEA,wEAAwE;QACxE,sEAAsE;QACtE,qEAAqE;QACrE,0EAA0E;QAC1E,uEAAuE;QACvE,yEAAyE;QACzE,uDAAuD;QACvD9L,MAAM6B,IAAI,GAAGgL,WAAWhL,IAAI;QAC5B7B,MAAM8B,aAAa,GAAG+K,WAAW/K,aAAa;QAC9C9B,MAAMiC,kBAAkB,GAAG;QAE3B,kEAAkE;QAClE,sEAAsE;QACtE,qEAAqE;QACrE,uEAAuE;QACvE,2CAA2C;QAC3C,IAAIvC,UAAUM,MAAMN,OAAO,EAAE;YAC3BM,MAAMN,OAAO,GAAGA;QAClB;IACF;IACA,uEAAuE;IACvE,4EAA4E;IAC5E,sCAAsC;IACtC,4EAA4E;IAC5E,2EAA2E;IAC3E,yEAAyE;IACzE,8EAA8E;IAC9E,oEAAoE;IACpE,IAAIoM,mBAAmB,MAAM;QAC3B,MAAMM,mBAAmBD,mCACvBL,gBACAzM,MAAM,KAAK;QAEb,OAAO+M;IACT;IACA,OAAO;AACT;AAEA,SAASsB,uBACPrO,GAAW,EACXV,IAAkB,EAClBwB,aAGsB,EACtBH,KAA+B,EAC/BN,OAAe,EACf6N,QAA2B,EAC3Bf,iBAA0B,EAC1BvM,QAAyB,EACzB0F,UAA6B,EAC7BgI,yBAGQ;IAER,wEAAwE;IACxE,2EAA2E;IAC3E,0EAA0E;IAC1E,uEAAuE;IACvE,4EAA4E;IAC5E,MAAMhK,MAAM4J,QAAQ,CAAC,EAAE;IACvB,MAAM7J,UAAU6J,QAAQ,CAAC,EAAE;IAC3B,MAAM/J,YAAYG,QAAQ,QAAQ6I;IAElC,0EAA0E;IAC1E,4EAA4E;IAC5E,+DAA+D;IAC/D,MAAMoB,aACJD,8BAA8B,OAC1BA,0BAA0BlO,GAAG,CAACQ,YAC9BwI;IACN,IAAImF,eAAenF,WAAW;QAC5BjE,yBAAyBoJ,YAAYjK,KAAKD,SAAShE,SAAS8D;IAC9D,OAAO;QACL,0DAA0D;QAC1D,MAAMqK,mBAAmBpR,8BACvB4C,KACAV,MACAqB,OACAC;QAEF,IAAI4N,iBAAiBlM,MAAM,QAAwB;YACjD,oDAAoD;YACpD,MAAMmM,WAAWD;YACjBrJ,yBACEzH,wBAAwB+Q,UAAU3N,gBAClCwD,KACAD,SACAhE,SACA8D;QAEJ,OAAO;YACL,iEAAiE;YACjE,+CAA+C;YAC/C,MAAMsK,WAAWtJ,yBACfzH,wBACEhB,gCAAgC2D,UAChCS,gBAEFwD,KACAD,SACAhE,SACA8D;YAEFxG,mBACEqC,KACAjD,yBAAyBuC,MAAMqB,OAAOC,WACtC6N;QAEJ;IACF;IACA,mDAAmD;IACnD,MAAMC,mBAAmBR,QAAQ,CAAC,EAAE;IACpC,IAAIQ,qBAAqB,MAAM;QAC7B,IAAK,MAAMhI,oBAAoBgI,iBAAkB;YAC/C,MAAMC,gBAAgBD,gBAAgB,CAAChI,iBAAiB;YACxD,IAAIiI,kBAAkB,MAAM;gBAC1B,MAAMvH,eAAeuH,aAAa,CAAC,EAAE;gBACrC,MAAM9G,sBAAsBC,IAAAA,iDAA2B,EAACV;gBACxD,MAAMW,kBAAkBC,IAAAA,iDAA2B,EACjD1B,YACAI,kBACAmB;gBAEF,MAAMI,gBAAgBC,IAAAA,+CAAyB,EAC7CtH,UACA8F,kBACAyB,IAAAA,+CAAyB,EAACN,qBAAqBT;gBAEjDiH,uBACErO,KACAV,MACAwB,eACAH,OACAN,SACAsO,eACAxB,mBACAlF,eACAF,iBACAuG;YAEJ;QACF;IACF;AACF;AAEA,eAAe3D,sBACbX,GAAQ,EACRP,OAAuB;IAEvB,MAAMmF,gBAAgB;IACtB,MAAM9E,WAAW,MAAM+E,IAAAA,gCAAW,EAAC7E,KAAKP,SAASmF;IACjD,IAAI,CAAC9E,SAASe,EAAE,EAAE;QAChB,OAAO;IACT;IAEA,yBAAyB;IACzB,IAAIhN,oBAAoB;IACtB,0EAA0E;IAC1E,2EAA2E;IAC3E,2EAA2E;IAC3E,sDAAsD;IACxD,OAAO;QACL,MAAMiR,cAAchF,SAASL,OAAO,CAACrJ,GAAG,CAAC;QACzC,MAAM2O,mBACJD,eAAeA,YAAYzF,UAAU,CAAC2F,yCAAuB;QAC/D,IAAI,CAACD,kBAAkB;YACrB,OAAO;QACT;IACF;IACA,OAAOjF;AACT;AAEA,SAASuB,6BACP4D,oBAAgD,EAChDC,aAAyB,EACzB5D,oBAA4C;IAE5C,0EAA0E;IAC1E,4EAA4E;IAC5E,uEAAuE;IACvE,0EAA0E;IAC1E,8DAA8D;IAC9D,2CAA2C;IAC3C,EAAE;IACF,2EAA2E;IAC3E,0EAA0E;IAC1E,8EAA8E;IAC9E,+BAA+B;IAC/B,EAAE;IACF,8EAA8E;IAC9E,iCAAiC;IACjC,IAAI6D,kBAAkB;IACtB,MAAMC,SAASH,qBAAqBI,SAAS;IAC7C,OAAO,IAAIC,eAAe;QACxB,MAAMC,MAAKC,UAAU;YACnB,MAAO,KAAM;gBACX,MAAM,EAAEC,IAAI,EAAEhI,KAAK,EAAE,GAAG,MAAM2H,OAAOM,IAAI;gBACzC,IAAI,CAACD,MAAM;oBACT,mEAAmE;oBACnE,mBAAmB;oBACnBD,WAAWG,OAAO,CAAClI;oBAEnB,+DAA+D;oBAC/D,kEAAkE;oBAClE,qEAAqE;oBACrE,6CAA6C;oBAC7C0H,mBAAmB1H,MAAMmI,UAAU;oBACnCtE,qBAAqB6D;oBACrB;gBACF;gBACA,qEAAqE;gBACrE,sDAAsD;gBACtDD;gBACA;YACF;QACF;IACF;AACF;AAEA,SAAStE,sCACPZ,GAAQ,EACRR,WAA8B;IAE9B,IAAI3L,oBAAoB;QACtB,yEAAyE;QACzE,0DAA0D;QAC1D,MAAMgS,YAAY,IAAIpM,IAAIuG;QAC1B,MAAM8F,WAAWD,UAAUtM,QAAQ,CAACpC,QAAQ,CAAC,OACzC0O,UAAUtM,QAAQ,CAACwM,SAAS,CAAC,GAAG,CAAC,KACjCF,UAAUtM,QAAQ;QACtB,MAAMyM,uBACJC,IAAAA,8DAAwC,EAACzG;QAC3CqG,UAAUtM,QAAQ,GAAG,AAAGuM,WAAS,MAAGE;QACpC,OAAOH;IACT;IACA,OAAO7F;AACT;AAuBO,SAASxN,sCACd0T,eAA8B,EAC9BC,WAA0B;IAE1B,OAAOD,kBAAkBC;AAC3B","ignoreList":[0]}