{"version":3,"sources":["../../../../src/client/components/router-reducer/prefetch-cache-utils.ts"],"sourcesContent":["import {\n  fetchServerResponse,\n  type FetchServerResponseResult,\n} from './fetch-server-response'\nimport {\n  PrefetchCacheEntryStatus,\n  type PrefetchCacheEntry,\n  PrefetchKind,\n  type ReadonlyReducerState,\n} from './router-reducer-types'\nimport { prefetchQueue } from './reducers/prefetch-reducer'\n\nconst INTERCEPTION_CACHE_KEY_MARKER = '%'\n\nexport type AliasedPrefetchCacheEntry = PrefetchCacheEntry & {\n  /** This is a special property that indicates a prefetch entry associated with a different URL\n   * was returned rather than the requested URL. This signals to the router that it should only\n   * apply the part that doesn't depend on searchParams (specifically the loading state).\n   */\n  aliased?: boolean\n}\n\n/**\n * Creates a cache key for the router prefetch cache\n *\n * @param url - The URL being navigated to\n * @param nextUrl - an internal URL, primarily used for handling rewrites. Defaults to '/'.\n * @return The generated prefetch cache key.\n */\nfunction createPrefetchCacheKeyImpl(\n  url: URL,\n  includeSearchParams: boolean,\n  prefix?: string | null\n) {\n  // Initially we only use the pathname as the cache key. We don't want to include\n  // search params so that multiple URLs with the same search parameter can re-use\n  // loading states.\n  let pathnameFromUrl = url.pathname\n\n  // RSC responses can differ based on search params, specifically in the case where we aren't\n  // returning a partial response (ie with `PrefetchKind.AUTO`).\n  // In the auto case, since loading.js & layout.js won't have access to search params,\n  // we can safely re-use that cache entry. But for full prefetches, we should not\n  // re-use the cache entry as the response may differ.\n  if (includeSearchParams) {\n    // if we have a full prefetch, we can include the search param in the key,\n    // as we'll be getting back a full response. The server might have read the search\n    // params when generating the full response.\n    pathnameFromUrl += url.search\n  }\n\n  if (prefix) {\n    return `${prefix}${INTERCEPTION_CACHE_KEY_MARKER}${pathnameFromUrl}`\n  }\n\n  return pathnameFromUrl\n}\n\nfunction createPrefetchCacheKey(\n  url: URL,\n  kind: PrefetchKind | undefined,\n  nextUrl?: string | null\n) {\n  return createPrefetchCacheKeyImpl(url, kind === PrefetchKind.FULL, nextUrl)\n}\n\nfunction getExistingCacheEntry(\n  url: URL,\n  kind: PrefetchKind = PrefetchKind.TEMPORARY,\n  nextUrl: string | null,\n  prefetchCache: Map<string, PrefetchCacheEntry>,\n  allowAliasing: boolean\n): AliasedPrefetchCacheEntry | undefined {\n  // We first check if there's a more specific interception route prefetch entry\n  // This is because when we detect a prefetch that corresponds with an interception route, we prefix it with nextUrl (see `createPrefetchCacheKey`)\n  // to avoid conflicts with other pages that may have the same URL but render different things depending on the `Next-URL` header.\n  for (const maybeNextUrl of [nextUrl, null]) {\n    const cacheKeyWithParams = createPrefetchCacheKeyImpl(\n      url,\n      true,\n      maybeNextUrl\n    )\n    const cacheKeyWithoutParams = createPrefetchCacheKeyImpl(\n      url,\n      false,\n      maybeNextUrl\n    )\n\n    // First, we check if we have a cache entry that exactly matches the URL\n    const cacheKeyToUse = url.search\n      ? cacheKeyWithParams\n      : cacheKeyWithoutParams\n\n    const existingEntry = prefetchCache.get(cacheKeyToUse)\n    if (existingEntry && allowAliasing) {\n      // We know we're returning an aliased entry when the pathname matches but the search params don't,\n      const isAliased =\n        existingEntry.url.pathname === url.pathname &&\n        existingEntry.url.search !== url.search\n\n      if (isAliased) {\n        return {\n          ...existingEntry,\n          aliased: true,\n        }\n      }\n\n      return existingEntry\n    }\n\n    // If the request contains search params, and we're not doing a full prefetch, we can return the\n    // param-less entry if it exists.\n    // This is technically covered by the check at the bottom of this function, which iterates over cache entries,\n    // but lets us arrive there quicker in the param-full case.\n    const entryWithoutParams = prefetchCache.get(cacheKeyWithoutParams)\n    if (\n      process.env.NODE_ENV !== 'development' &&\n      allowAliasing &&\n      url.search &&\n      kind !== PrefetchKind.FULL &&\n      entryWithoutParams &&\n      // We shouldn't return the aliased entry if it was relocated to a new cache key.\n      // Since it's rewritten, it could respond with a completely different loading state.\n      !entryWithoutParams.key.includes(INTERCEPTION_CACHE_KEY_MARKER)\n    ) {\n      return { ...entryWithoutParams, aliased: true }\n    }\n  }\n\n  // If we've gotten to this point, we didn't find a specific cache entry that matched\n  // the request URL.\n  // We attempt a partial match by checking if there's a cache entry with the same pathname.\n  // Regardless of what we find, since it doesn't correspond with the requested URL, we'll mark it \"aliased\".\n  // This will signal to the router that it should only apply the loading state on the prefetched data.\n  if (\n    process.env.NODE_ENV !== 'development' &&\n    kind !== PrefetchKind.FULL &&\n    allowAliasing\n  ) {\n    for (const cacheEntry of prefetchCache.values()) {\n      if (\n        cacheEntry.url.pathname === url.pathname &&\n        // We shouldn't return the aliased entry if it was relocated to a new cache key.\n        // Since it's rewritten, it could respond with a completely different loading state.\n        !cacheEntry.key.includes(INTERCEPTION_CACHE_KEY_MARKER)\n      ) {\n        return { ...cacheEntry, aliased: true }\n      }\n    }\n  }\n\n  return undefined\n}\n\n/**\n * Returns a prefetch cache entry if one exists. Otherwise creates a new one and enqueues a fetch request\n * to retrieve the prefetch data from the server.\n */\nexport function getOrCreatePrefetchCacheEntry({\n  url,\n  nextUrl,\n  tree,\n  prefetchCache,\n  kind,\n  allowAliasing = true,\n}: Pick<ReadonlyReducerState, 'nextUrl' | 'prefetchCache' | 'tree'> & {\n  url: URL\n  kind?: PrefetchKind\n  allowAliasing: boolean\n}): AliasedPrefetchCacheEntry {\n  const existingCacheEntry = getExistingCacheEntry(\n    url,\n    kind,\n    nextUrl,\n    prefetchCache,\n    allowAliasing\n  )\n\n  if (existingCacheEntry) {\n    // Grab the latest status of the cache entry and update it\n    existingCacheEntry.status = getPrefetchEntryCacheStatus(existingCacheEntry)\n\n    // when `kind` is provided, an explicit prefetch was requested.\n    // if the requested prefetch is \"full\" and the current cache entry wasn't, we want to re-prefetch with the new intent\n    const switchedToFullPrefetch =\n      existingCacheEntry.kind !== PrefetchKind.FULL &&\n      kind === PrefetchKind.FULL\n\n    if (switchedToFullPrefetch) {\n      // If we switched to a full prefetch, validate that the existing cache entry contained partial data.\n      // It's possible that the cache entry was seeded with full data but has a cache type of \"auto\" (ie when cache entries\n      // are seeded but without a prefetch intent)\n      existingCacheEntry.data.then((prefetchResponse) => {\n        const isFullPrefetch =\n          Array.isArray(prefetchResponse.flightData) &&\n          prefetchResponse.flightData.some((flightData) => {\n            // If we started rendering from the root and we returned RSC data (seedData), we already had a full prefetch.\n            return flightData.isRootRender && flightData.seedData !== null\n          })\n\n        if (!isFullPrefetch) {\n          return createLazyPrefetchEntry({\n            tree,\n            url,\n            nextUrl,\n            prefetchCache,\n            // If we didn't get an explicit prefetch kind, we want to set a temporary kind\n            // rather than assuming the same intent as the previous entry, to be consistent with how we\n            // lazily create prefetch entries when intent is left unspecified.\n            kind: kind ?? PrefetchKind.TEMPORARY,\n          })\n        }\n      })\n    }\n\n    // If the existing cache entry was marked as temporary, it means it was lazily created when attempting to get an entry,\n    // where we didn't have the prefetch intent. Now that we have the intent (in `kind`), we want to update the entry to the more accurate kind.\n    if (kind && existingCacheEntry.kind === PrefetchKind.TEMPORARY) {\n      existingCacheEntry.kind = kind\n    }\n\n    // We've determined that the existing entry we found is still valid, so we return it.\n    return existingCacheEntry\n  }\n\n  // If we didn't return an entry, create a new one.\n  return createLazyPrefetchEntry({\n    tree,\n    url,\n    nextUrl,\n    prefetchCache,\n    kind: kind || PrefetchKind.TEMPORARY,\n  })\n}\n\n/*\n * Used to take an existing cache entry and prefix it with the nextUrl, if it exists.\n * This ensures that we don't have conflicting cache entries for the same URL (as is the case with route interception).\n */\nfunction prefixExistingPrefetchCacheEntry({\n  url,\n  nextUrl,\n  prefetchCache,\n  existingCacheKey,\n}: Pick<ReadonlyReducerState, 'nextUrl' | 'prefetchCache'> & {\n  url: URL\n  existingCacheKey: string\n}) {\n  const existingCacheEntry = prefetchCache.get(existingCacheKey)\n  if (!existingCacheEntry) {\n    // no-op -- there wasn't an entry to move\n    return\n  }\n\n  const newCacheKey = createPrefetchCacheKey(\n    url,\n    existingCacheEntry.kind,\n    nextUrl\n  )\n  prefetchCache.set(newCacheKey, { ...existingCacheEntry, key: newCacheKey })\n  prefetchCache.delete(existingCacheKey)\n\n  return newCacheKey\n}\n\n/**\n * Use to seed the prefetch cache with data that has already been fetched.\n */\nexport function createSeededPrefetchCacheEntry({\n  nextUrl,\n  tree,\n  prefetchCache,\n  url,\n  data,\n  kind,\n}: Pick<ReadonlyReducerState, 'nextUrl' | 'tree' | 'prefetchCache'> & {\n  url: URL\n  data: FetchServerResponseResult\n  kind: PrefetchKind\n}) {\n  // The initial cache entry technically includes full data, but it isn't explicitly prefetched -- we just seed the\n  // prefetch cache so that we can skip an extra prefetch request later, since we already have the data.\n  // if the prefetch corresponds with an interception route, we use the nextUrl to prefix the cache key\n  const prefetchCacheKey = data.couldBeIntercepted\n    ? createPrefetchCacheKey(url, kind, nextUrl)\n    : createPrefetchCacheKey(url, kind)\n\n  const prefetchEntry = {\n    treeAtTimeOfPrefetch: tree,\n    data: Promise.resolve(data),\n    kind,\n    prefetchTime: Date.now(),\n    lastUsedTime: Date.now(),\n    staleTime: data.staleTime,\n    key: prefetchCacheKey,\n    status: PrefetchCacheEntryStatus.fresh,\n    url,\n  } satisfies PrefetchCacheEntry\n\n  prefetchCache.set(prefetchCacheKey, prefetchEntry)\n\n  return prefetchEntry\n}\n\n/**\n * Creates a prefetch entry entry and enqueues a fetch request to retrieve the data.\n */\nfunction createLazyPrefetchEntry({\n  url,\n  kind,\n  tree,\n  nextUrl,\n  prefetchCache,\n}: Pick<ReadonlyReducerState, 'nextUrl' | 'tree' | 'prefetchCache'> & {\n  url: URL\n  kind: PrefetchKind\n}): PrefetchCacheEntry {\n  const prefetchCacheKey = createPrefetchCacheKey(url, kind)\n\n  // initiates the fetch request for the prefetch and attaches a listener\n  // to the promise to update the prefetch cache entry when the promise resolves (if necessary)\n  const data = prefetchQueue.enqueue(() =>\n    fetchServerResponse(url, {\n      flightRouterState: tree,\n      nextUrl,\n      prefetchKind: kind,\n    }).then((prefetchResponse) => {\n      // TODO: `fetchServerResponse` should be more tighly coupled to these prefetch cache operations\n      // to avoid drift between this cache key prefixing logic\n      // (which is currently directly influenced by the server response)\n      let newCacheKey\n\n      if (prefetchResponse.couldBeIntercepted) {\n        // Determine if we need to prefix the cache key with the nextUrl\n        newCacheKey = prefixExistingPrefetchCacheEntry({\n          url,\n          existingCacheKey: prefetchCacheKey,\n          nextUrl,\n          prefetchCache,\n        })\n      }\n\n      // If the prefetch was a cache hit, we want to update the existing cache entry to reflect that it was a full prefetch.\n      // This is because we know that a static response will contain the full RSC payload, and can be updated to respect the `static`\n      // staleTime.\n      if (prefetchResponse.prerendered) {\n        const existingCacheEntry = prefetchCache.get(\n          // if we prefixed the cache key due to route interception, we want to use the new key. Otherwise we use the original key\n          newCacheKey ?? prefetchCacheKey\n        )\n        if (existingCacheEntry) {\n          existingCacheEntry.kind = PrefetchKind.FULL\n          if (prefetchResponse.staleTime !== -1) {\n            // This is the stale time that was collected by the server during\n            // static generation. Use this in place of the default stale time.\n            existingCacheEntry.staleTime = prefetchResponse.staleTime\n          }\n        }\n      }\n\n      return prefetchResponse\n    })\n  )\n\n  const prefetchEntry = {\n    treeAtTimeOfPrefetch: tree,\n    data,\n    kind,\n    prefetchTime: Date.now(),\n    lastUsedTime: null,\n    staleTime: -1,\n    key: prefetchCacheKey,\n    status: PrefetchCacheEntryStatus.fresh,\n    url,\n  }\n\n  prefetchCache.set(prefetchCacheKey, prefetchEntry)\n\n  return prefetchEntry\n}\n\nexport function prunePrefetchCache(\n  prefetchCache: ReadonlyReducerState['prefetchCache']\n) {\n  for (const [href, prefetchCacheEntry] of prefetchCache) {\n    if (\n      getPrefetchEntryCacheStatus(prefetchCacheEntry) ===\n      PrefetchCacheEntryStatus.expired\n    ) {\n      prefetchCache.delete(href)\n    }\n  }\n}\n\n// These values are set by `define-env-plugin` (based on `nextConfig.experimental.staleTimes`)\n// and default to 5 minutes (static) / 0 seconds (dynamic)\nexport const DYNAMIC_STALETIME_MS =\n  Number(process.env.__NEXT_CLIENT_ROUTER_DYNAMIC_STALETIME) * 1000\n\nexport const STATIC_STALETIME_MS =\n  Number(process.env.__NEXT_CLIENT_ROUTER_STATIC_STALETIME) * 1000\n\nfunction getPrefetchEntryCacheStatus({\n  kind,\n  prefetchTime,\n  lastUsedTime,\n}: PrefetchCacheEntry): PrefetchCacheEntryStatus {\n  // We will re-use the cache entry data for up to the `dynamic` staletime window.\n  if (Date.now() < (lastUsedTime ?? prefetchTime) + DYNAMIC_STALETIME_MS) {\n    return lastUsedTime\n      ? PrefetchCacheEntryStatus.reusable\n      : PrefetchCacheEntryStatus.fresh\n  }\n\n  // For \"auto\" prefetching, we'll re-use only the loading boundary for up to `static` staletime window.\n  // A stale entry will only re-use the `loading` boundary, not the full data.\n  // This will trigger a \"lazy fetch\" for the full data.\n  if (kind === PrefetchKind.AUTO) {\n    if (Date.now() < prefetchTime + STATIC_STALETIME_MS) {\n      return PrefetchCacheEntryStatus.stale\n    }\n  }\n\n  // for \"full\" prefetching, we'll re-use the cache entry data for up to `static` staletime window.\n  if (kind === PrefetchKind.FULL) {\n    if (Date.now() < prefetchTime + STATIC_STALETIME_MS) {\n      return PrefetchCacheEntryStatus.reusable\n    }\n  }\n\n  return PrefetchCacheEntryStatus.expired\n}\n"],"names":["DYNAMIC_STALETIME_MS","STATIC_STALETIME_MS","createSeededPrefetchCacheEntry","getOrCreatePrefetchCacheEntry","prunePrefetchCache","INTERCEPTION_CACHE_KEY_MARKER","createPrefetchCacheKeyImpl","url","includeSearchParams","prefix","pathnameFromUrl","pathname","search","createPrefetchCacheKey","kind","nextUrl","PrefetchKind","FULL","getExistingCacheEntry","prefetchCache","allowAliasing","TEMPORARY","maybeNextUrl","cacheKeyWithParams","cacheKeyWithoutParams","cacheKeyToUse","existingEntry","get","isAliased","aliased","entryWithoutParams","process","env","NODE_ENV","key","includes","cacheEntry","values","undefined","tree","existingCacheEntry","status","getPrefetchEntryCacheStatus","switchedToFullPrefetch","data","then","prefetchResponse","isFullPrefetch","Array","isArray","flightData","some","isRootRender","seedData","createLazyPrefetchEntry","prefixExistingPrefetchCacheEntry","existingCacheKey","newCacheKey","set","delete","prefetchCacheKey","couldBeIntercepted","prefetchEntry","treeAtTimeOfPrefetch","Promise","resolve","prefetchTime","Date","now","lastUsedTime","staleTime","PrefetchCacheEntryStatus","fresh","prefetchQueue","enqueue","fetchServerResponse","flightRouterState","prefetchKind","prerendered","href","prefetchCacheEntry","expired","Number","__NEXT_CLIENT_ROUTER_DYNAMIC_STALETIME","__NEXT_CLIENT_ROUTER_STATIC_STALETIME","reusable","AUTO","stale"],"mappings":";;;;;;;;;;;;;;;;;;IA4YaA,oBAAoB;eAApBA;;IAGAC,mBAAmB;eAAnBA;;IAnIGC,8BAA8B;eAA9BA;;IA9GAC,6BAA6B;eAA7BA;;IA+NAC,kBAAkB;eAAlBA;;;qCA1XT;oCAMA;iCACuB;AAE9B,MAAMC,gCAAgC;AAUtC;;;;;;CAMC,GACD,SAASC,2BACPC,GAAQ,EACRC,mBAA4B,EAC5BC,MAAsB;IAEtB,gFAAgF;IAChF,gFAAgF;IAChF,kBAAkB;IAClB,IAAIC,kBAAkBH,IAAII,QAAQ;IAElC,4FAA4F;IAC5F,8DAA8D;IAC9D,qFAAqF;IACrF,gFAAgF;IAChF,qDAAqD;IACrD,IAAIH,qBAAqB;QACvB,0EAA0E;QAC1E,kFAAkF;QAClF,4CAA4C;QAC5CE,mBAAmBH,IAAIK,MAAM;IAC/B;IAEA,IAAIH,QAAQ;QACV,OAAO,AAAC,KAAEA,SAASJ,gCAAgCK;IACrD;IAEA,OAAOA;AACT;AAEA,SAASG,uBACPN,GAAQ,EACRO,IAA8B,EAC9BC,OAAuB;IAEvB,OAAOT,2BAA2BC,KAAKO,SAASE,gCAAY,CAACC,IAAI,EAAEF;AACrE;AAEA,SAASG,sBACPX,GAAQ,EACRO,IAA2C,EAC3CC,OAAsB,EACtBI,aAA8C,EAC9CC,aAAsB;IAHtBN,IAAAA,iBAAAA,OAAqBE,gCAAY,CAACK,SAAS;IAK3C,8EAA8E;IAC9E,kJAAkJ;IAClJ,iIAAiI;IACjI,KAAK,MAAMC,gBAAgB;QAACP;QAAS;KAAK,CAAE;QAC1C,MAAMQ,qBAAqBjB,2BACzBC,KACA,MACAe;QAEF,MAAME,wBAAwBlB,2BAC5BC,KACA,OACAe;QAGF,wEAAwE;QACxE,MAAMG,gBAAgBlB,IAAIK,MAAM,GAC5BW,qBACAC;QAEJ,MAAME,gBAAgBP,cAAcQ,GAAG,CAACF;QACxC,IAAIC,iBAAiBN,eAAe;YAClC,kGAAkG;YAClG,MAAMQ,YACJF,cAAcnB,GAAG,CAACI,QAAQ,KAAKJ,IAAII,QAAQ,IAC3Ce,cAAcnB,GAAG,CAACK,MAAM,KAAKL,IAAIK,MAAM;YAEzC,IAAIgB,WAAW;gBACb,OAAO;oBACL,GAAGF,aAAa;oBAChBG,SAAS;gBACX;YACF;YAEA,OAAOH;QACT;QAEA,gGAAgG;QAChG,iCAAiC;QACjC,8GAA8G;QAC9G,2DAA2D;QAC3D,MAAMI,qBAAqBX,cAAcQ,GAAG,CAACH;QAC7C,IACEO,QAAQC,GAAG,CAACC,QAAQ,KAAK,iBACzBb,iBACAb,IAAIK,MAAM,IACVE,SAASE,gCAAY,CAACC,IAAI,IAC1Ba,sBACA,gFAAgF;QAChF,oFAAoF;QACpF,CAACA,mBAAmBI,GAAG,CAACC,QAAQ,CAAC9B,gCACjC;YACA,OAAO;gBAAE,GAAGyB,kBAAkB;gBAAED,SAAS;YAAK;QAChD;IACF;IAEA,oFAAoF;IACpF,mBAAmB;IACnB,0FAA0F;IAC1F,2GAA2G;IAC3G,qGAAqG;IACrG,IACEE,QAAQC,GAAG,CAACC,QAAQ,KAAK,iBACzBnB,SAASE,gCAAY,CAACC,IAAI,IAC1BG,eACA;QACA,KAAK,MAAMgB,cAAcjB,cAAckB,MAAM,GAAI;YAC/C,IACED,WAAW7B,GAAG,CAACI,QAAQ,KAAKJ,IAAII,QAAQ,IACxC,gFAAgF;YAChF,oFAAoF;YACpF,CAACyB,WAAWF,GAAG,CAACC,QAAQ,CAAC9B,gCACzB;gBACA,OAAO;oBAAE,GAAG+B,UAAU;oBAAEP,SAAS;gBAAK;YACxC;QACF;IACF;IAEA,OAAOS;AACT;AAMO,SAASnC,8BAA8B,KAW7C;IAX6C,IAAA,EAC5CI,GAAG,EACHQ,OAAO,EACPwB,IAAI,EACJpB,aAAa,EACbL,IAAI,EACJM,gBAAgB,IAAI,EAKrB,GAX6C;IAY5C,MAAMoB,qBAAqBtB,sBACzBX,KACAO,MACAC,SACAI,eACAC;IAGF,IAAIoB,oBAAoB;QACtB,0DAA0D;QAC1DA,mBAAmBC,MAAM,GAAGC,4BAA4BF;QAExD,+DAA+D;QAC/D,qHAAqH;QACrH,MAAMG,yBACJH,mBAAmB1B,IAAI,KAAKE,gCAAY,CAACC,IAAI,IAC7CH,SAASE,gCAAY,CAACC,IAAI;QAE5B,IAAI0B,wBAAwB;YAC1B,oGAAoG;YACpG,qHAAqH;YACrH,4CAA4C;YAC5CH,mBAAmBI,IAAI,CAACC,IAAI,CAAC,CAACC;gBAC5B,MAAMC,iBACJC,MAAMC,OAAO,CAACH,iBAAiBI,UAAU,KACzCJ,iBAAiBI,UAAU,CAACC,IAAI,CAAC,CAACD;oBAChC,6GAA6G;oBAC7G,OAAOA,WAAWE,YAAY,IAAIF,WAAWG,QAAQ,KAAK;gBAC5D;gBAEF,IAAI,CAACN,gBAAgB;oBACnB,OAAOO,wBAAwB;wBAC7Bf;wBACAhC;wBACAQ;wBACAI;wBACA,8EAA8E;wBAC9E,2FAA2F;wBAC3F,kEAAkE;wBAClEL,MAAMA,eAAAA,OAAQE,gCAAY,CAACK,SAAS;oBACtC;gBACF;YACF;QACF;QAEA,uHAAuH;QACvH,4IAA4I;QAC5I,IAAIP,QAAQ0B,mBAAmB1B,IAAI,KAAKE,gCAAY,CAACK,SAAS,EAAE;YAC9DmB,mBAAmB1B,IAAI,GAAGA;QAC5B;QAEA,qFAAqF;QACrF,OAAO0B;IACT;IAEA,kDAAkD;IAClD,OAAOc,wBAAwB;QAC7Bf;QACAhC;QACAQ;QACAI;QACAL,MAAMA,QAAQE,gCAAY,CAACK,SAAS;IACtC;AACF;AAEA;;;CAGC,GACD,SAASkC,iCAAiC,KAQzC;IARyC,IAAA,EACxChD,GAAG,EACHQ,OAAO,EACPI,aAAa,EACbqC,gBAAgB,EAIjB,GARyC;IASxC,MAAMhB,qBAAqBrB,cAAcQ,GAAG,CAAC6B;IAC7C,IAAI,CAAChB,oBAAoB;QACvB,yCAAyC;QACzC;IACF;IAEA,MAAMiB,cAAc5C,uBAClBN,KACAiC,mBAAmB1B,IAAI,EACvBC;IAEFI,cAAcuC,GAAG,CAACD,aAAa;QAAE,GAAGjB,kBAAkB;QAAEN,KAAKuB;IAAY;IACzEtC,cAAcwC,MAAM,CAACH;IAErB,OAAOC;AACT;AAKO,SAASvD,+BAA+B,KAW9C;IAX8C,IAAA,EAC7Ca,OAAO,EACPwB,IAAI,EACJpB,aAAa,EACbZ,GAAG,EACHqC,IAAI,EACJ9B,IAAI,EAKL,GAX8C;IAY7C,iHAAiH;IACjH,sGAAsG;IACtG,qGAAqG;IACrG,MAAM8C,mBAAmBhB,KAAKiB,kBAAkB,GAC5ChD,uBAAuBN,KAAKO,MAAMC,WAClCF,uBAAuBN,KAAKO;IAEhC,MAAMgD,gBAAgB;QACpBC,sBAAsBxB;QACtBK,MAAMoB,QAAQC,OAAO,CAACrB;QACtB9B;QACAoD,cAAcC,KAAKC,GAAG;QACtBC,cAAcF,KAAKC,GAAG;QACtBE,WAAW1B,KAAK0B,SAAS;QACzBpC,KAAK0B;QACLnB,QAAQ8B,4CAAwB,CAACC,KAAK;QACtCjE;IACF;IAEAY,cAAcuC,GAAG,CAACE,kBAAkBE;IAEpC,OAAOA;AACT;AAEA;;CAEC,GACD,SAASR,wBAAwB,KAShC;IATgC,IAAA,EAC/B/C,GAAG,EACHO,IAAI,EACJyB,IAAI,EACJxB,OAAO,EACPI,aAAa,EAId,GATgC;IAU/B,MAAMyC,mBAAmB/C,uBAAuBN,KAAKO;IAErD,uEAAuE;IACvE,6FAA6F;IAC7F,MAAM8B,OAAO6B,8BAAa,CAACC,OAAO,CAAC,IACjCC,IAAAA,wCAAmB,EAACpE,KAAK;YACvBqE,mBAAmBrC;YACnBxB;YACA8D,cAAc/D;QAChB,GAAG+B,IAAI,CAAC,CAACC;YACP,+FAA+F;YAC/F,wDAAwD;YACxD,kEAAkE;YAClE,IAAIW;YAEJ,IAAIX,iBAAiBe,kBAAkB,EAAE;gBACvC,gEAAgE;gBAChEJ,cAAcF,iCAAiC;oBAC7ChD;oBACAiD,kBAAkBI;oBAClB7C;oBACAI;gBACF;YACF;YAEA,sHAAsH;YACtH,+HAA+H;YAC/H,aAAa;YACb,IAAI2B,iBAAiBgC,WAAW,EAAE;gBAChC,MAAMtC,qBAAqBrB,cAAcQ,GAAG,CAC1C,wHAAwH;gBACxH8B,sBAAAA,cAAeG;gBAEjB,IAAIpB,oBAAoB;oBACtBA,mBAAmB1B,IAAI,GAAGE,gCAAY,CAACC,IAAI;oBAC3C,IAAI6B,iBAAiBwB,SAAS,KAAK,CAAC,GAAG;wBACrC,iEAAiE;wBACjE,kEAAkE;wBAClE9B,mBAAmB8B,SAAS,GAAGxB,iBAAiBwB,SAAS;oBAC3D;gBACF;YACF;YAEA,OAAOxB;QACT;IAGF,MAAMgB,gBAAgB;QACpBC,sBAAsBxB;QACtBK;QACA9B;QACAoD,cAAcC,KAAKC,GAAG;QACtBC,cAAc;QACdC,WAAW,CAAC;QACZpC,KAAK0B;QACLnB,QAAQ8B,4CAAwB,CAACC,KAAK;QACtCjE;IACF;IAEAY,cAAcuC,GAAG,CAACE,kBAAkBE;IAEpC,OAAOA;AACT;AAEO,SAAS1D,mBACde,aAAoD;IAEpD,KAAK,MAAM,CAAC4D,MAAMC,mBAAmB,IAAI7D,cAAe;QACtD,IACEuB,4BAA4BsC,wBAC5BT,4CAAwB,CAACU,OAAO,EAChC;YACA9D,cAAcwC,MAAM,CAACoB;QACvB;IACF;AACF;AAIO,MAAM/E,uBACXkF,OAAOnD,QAAQC,GAAG,CAACmD,sCAAsC,IAAI;AAExD,MAAMlF,sBACXiF,OAAOnD,QAAQC,GAAG,CAACoD,qCAAqC,IAAI;AAE9D,SAAS1C,4BAA4B,KAIhB;IAJgB,IAAA,EACnC5B,IAAI,EACJoD,YAAY,EACZG,YAAY,EACO,GAJgB;IAKnC,gFAAgF;IAChF,IAAIF,KAAKC,GAAG,KAAK,AAACC,CAAAA,uBAAAA,eAAgBH,YAAW,IAAKlE,sBAAsB;QACtE,OAAOqE,eACHE,4CAAwB,CAACc,QAAQ,GACjCd,4CAAwB,CAACC,KAAK;IACpC;IAEA,sGAAsG;IACtG,4EAA4E;IAC5E,sDAAsD;IACtD,IAAI1D,SAASE,gCAAY,CAACsE,IAAI,EAAE;QAC9B,IAAInB,KAAKC,GAAG,KAAKF,eAAejE,qBAAqB;YACnD,OAAOsE,4CAAwB,CAACgB,KAAK;QACvC;IACF;IAEA,iGAAiG;IACjG,IAAIzE,SAASE,gCAAY,CAACC,IAAI,EAAE;QAC9B,IAAIkD,KAAKC,GAAG,KAAKF,eAAejE,qBAAqB;YACnD,OAAOsE,4CAAwB,CAACc,QAAQ;QAC1C;IACF;IAEA,OAAOd,4CAAwB,CAACU,OAAO;AACzC","ignoreList":[0]}