{"version":3,"file":"new-process-route-tree.cjs","names":[],"sources":["../../src/new-process-route-tree.ts"],"sourcesContent":["import { invariant } from './invariant'\nimport { createLRUCache } from './lru-cache'\nimport { last } from './utils'\nimport type { LRUCache } from './lru-cache'\n\nexport const SEGMENT_TYPE_PATHNAME = 0\nexport const SEGMENT_TYPE_PARAM = 1\nexport const SEGMENT_TYPE_WILDCARD = 2\nexport const SEGMENT_TYPE_OPTIONAL_PARAM = 3\nconst SEGMENT_TYPE_INDEX = 4\nconst SEGMENT_TYPE_PATHLESS = 5 // only used in matching to represent pathless routes that need to carry more information\n\n/**\n * All the kinds of segments that can be present in a route path.\n */\nexport type SegmentKind =\n  | typeof SEGMENT_TYPE_PATHNAME\n  | typeof SEGMENT_TYPE_PARAM\n  | typeof SEGMENT_TYPE_WILDCARD\n  | typeof SEGMENT_TYPE_OPTIONAL_PARAM\n\n/**\n * All the kinds of segments that can be present in the segment tree.\n */\ntype ExtendedSegmentKind =\n  | SegmentKind\n  | typeof SEGMENT_TYPE_INDEX\n  | typeof SEGMENT_TYPE_PATHLESS\n\nfunction getOpenAndCloseBraces(\n  part: string,\n): [openBrace: number, closeBrace: number] | null {\n  const openBrace = part.indexOf('{')\n  if (openBrace === -1) return null\n  const closeBrace = part.indexOf('}', openBrace)\n  if (closeBrace === -1) return null\n  const afterOpen = openBrace + 1\n  if (afterOpen >= part.length) return null\n  return [openBrace, closeBrace]\n}\n\ntype ParsedSegment = Uint16Array & {\n  /** segment type (0 = pathname, 1 = param, 2 = wildcard, 3 = optional param) */\n  0: SegmentKind\n  /** index of the end of the prefix */\n  1: number\n  /** index of the start of the value */\n  2: number\n  /** index of the end of the value */\n  3: number\n  /** index of the start of the suffix */\n  4: number\n  /** index of the end of the segment */\n  5: number\n}\n\n/**\n * Populates the `output` array with the parsed representation of the given `segment` string.\n *\n * Usage:\n * ```ts\n * let output\n * let cursor = 0\n * while (cursor < path.length) {\n *   output = parseSegment(path, cursor, output)\n *   const end = output[5]\n *   cursor = end + 1\n * ```\n *\n * `output` is stored outside to avoid allocations during repeated calls. It doesn't need to be typed\n * or initialized, it will be done automatically.\n */\nexport function parseSegment(\n  /** The full path string containing the segment. */\n  path: string,\n  /** The starting index of the segment within the path. */\n  start: number,\n  /** A Uint16Array (length: 6) to populate with the parsed segment data. */\n  output: Uint16Array = new Uint16Array(6),\n): ParsedSegment {\n  const next = path.indexOf('/', start)\n  const end = next === -1 ? path.length : next\n  const part = path.substring(start, end)\n\n  if (!part || !part.includes('$')) {\n    // early escape for static pathname\n    output[0] = SEGMENT_TYPE_PATHNAME\n    output[1] = start\n    output[2] = start\n    output[3] = end\n    output[4] = end\n    output[5] = end\n    return output as ParsedSegment\n  }\n\n  // $ (wildcard)\n  if (part === '$') {\n    const total = path.length\n    output[0] = SEGMENT_TYPE_WILDCARD\n    output[1] = start\n    output[2] = start\n    output[3] = total\n    output[4] = total\n    output[5] = total\n    return output as ParsedSegment\n  }\n\n  // $paramName\n  if (part.charCodeAt(0) === 36) {\n    output[0] = SEGMENT_TYPE_PARAM\n    output[1] = start\n    output[2] = start + 1 // skip '$'\n    output[3] = end\n    output[4] = end\n    output[5] = end\n    return output as ParsedSegment\n  }\n\n  const braces = getOpenAndCloseBraces(part)\n  if (braces) {\n    const [openBrace, closeBrace] = braces\n    const firstChar = part.charCodeAt(openBrace + 1)\n\n    // Check for {-$...} (optional param)\n    // prefix{-$paramName}suffix\n    // /^([^{]*)\\{-\\$([a-zA-Z_$][a-zA-Z0-9_$]*)\\}([^}]*)$/\n    if (firstChar === 45) {\n      // '-'\n      if (\n        openBrace + 2 < part.length &&\n        part.charCodeAt(openBrace + 2) === 36 // '$'\n      ) {\n        const paramStart = openBrace + 3\n        const paramEnd = closeBrace\n        // Validate param name exists\n        if (paramStart < paramEnd) {\n          output[0] = SEGMENT_TYPE_OPTIONAL_PARAM\n          output[1] = start + openBrace\n          output[2] = start + paramStart\n          output[3] = start + paramEnd\n          output[4] = start + closeBrace + 1\n          output[5] = end\n          return output as ParsedSegment\n        }\n      }\n    } else if (firstChar === 36) {\n      // '$'\n      const dollarPos = openBrace + 1\n      const afterDollar = openBrace + 2\n      // Check for {$} (wildcard)\n      if (afterDollar === closeBrace) {\n        // For wildcard, value should be '$' (from dollarPos to afterDollar)\n        // prefix{$}suffix\n        // /^([^{]*)\\{\\$\\}([^}]*)$/\n        output[0] = SEGMENT_TYPE_WILDCARD\n        output[1] = start + openBrace\n        output[2] = start + dollarPos\n        output[3] = start + afterDollar\n        output[4] = start + closeBrace + 1\n        output[5] = path.length\n        return output as ParsedSegment\n      }\n      // Regular param {$paramName} - value is the param name (after $)\n      // prefix{$paramName}suffix\n      // /^([^{]*)\\{\\$([a-zA-Z_$][a-zA-Z0-9_$]*)\\}([^}]*)$/\n      output[0] = SEGMENT_TYPE_PARAM\n      output[1] = start + openBrace\n      output[2] = start + afterDollar\n      output[3] = start + closeBrace\n      output[4] = start + closeBrace + 1\n      output[5] = end\n      return output as ParsedSegment\n    }\n  }\n\n  // fallback to static pathname (should never happen)\n  output[0] = SEGMENT_TYPE_PATHNAME\n  output[1] = start\n  output[2] = start\n  output[3] = end\n  output[4] = end\n  output[5] = end\n  return output as ParsedSegment\n}\n\n/**\n * Recursively parses the segments of the given route tree and populates a segment trie.\n *\n * @param data A reusable Uint16Array for parsing segments. (non important, we're just avoiding allocations)\n * @param route The current route to parse.\n * @param start The starting index for parsing within the route's full path.\n * @param node The current segment node in the trie to populate.\n * @param onRoute Callback invoked for each route processed.\n */\nfunction parseSegments<TRouteLike extends RouteLike>(\n  defaultCaseSensitive: boolean,\n  data: Uint16Array,\n  route: TRouteLike,\n  start: number,\n  node: AnySegmentNode<TRouteLike>,\n  depth: number,\n  onRoute?: (route: TRouteLike) => void,\n) {\n  onRoute?.(route)\n  let cursor = start\n  {\n    const path = route.fullPath ?? route.from\n    const length = path.length\n    const caseSensitive = route.options?.caseSensitive ?? defaultCaseSensitive\n    const skipOnParamError = !!(\n      route.options?.params?.parse &&\n      route.options?.skipRouteOnParseError?.params\n    )\n    while (cursor < length) {\n      const segment = parseSegment(path, cursor, data)\n      let nextNode: AnySegmentNode<TRouteLike>\n      const start = cursor\n      const end = segment[5]\n      cursor = end + 1\n      depth++\n      const kind = segment[0]\n      switch (kind) {\n        case SEGMENT_TYPE_PATHNAME: {\n          const value = path.substring(segment[2], segment[3])\n          if (caseSensitive) {\n            const existingNode = node.static?.get(value)\n            if (existingNode) {\n              nextNode = existingNode\n            } else {\n              node.static ??= new Map()\n              const next = createStaticNode<TRouteLike>(\n                route.fullPath ?? route.from,\n              )\n              next.parent = node\n              next.depth = depth\n              nextNode = next\n              node.static.set(value, next)\n            }\n          } else {\n            const name = value.toLowerCase()\n            const existingNode = node.staticInsensitive?.get(name)\n            if (existingNode) {\n              nextNode = existingNode\n            } else {\n              node.staticInsensitive ??= new Map()\n              const next = createStaticNode<TRouteLike>(\n                route.fullPath ?? route.from,\n              )\n              next.parent = node\n              next.depth = depth\n              nextNode = next\n              node.staticInsensitive.set(name, next)\n            }\n          }\n          break\n        }\n        case SEGMENT_TYPE_PARAM: {\n          const prefix_raw = path.substring(start, segment[1])\n          const suffix_raw = path.substring(segment[4], end)\n          const actuallyCaseSensitive =\n            caseSensitive && !!(prefix_raw || suffix_raw)\n          const prefix = !prefix_raw\n            ? undefined\n            : actuallyCaseSensitive\n              ? prefix_raw\n              : prefix_raw.toLowerCase()\n          const suffix = !suffix_raw\n            ? undefined\n            : actuallyCaseSensitive\n              ? suffix_raw\n              : suffix_raw.toLowerCase()\n          const existingNode =\n            !skipOnParamError &&\n            node.dynamic?.find(\n              (s) =>\n                !s.skipOnParamError &&\n                s.caseSensitive === actuallyCaseSensitive &&\n                s.prefix === prefix &&\n                s.suffix === suffix,\n            )\n          if (existingNode) {\n            nextNode = existingNode\n          } else {\n            const next = createDynamicNode<TRouteLike>(\n              SEGMENT_TYPE_PARAM,\n              route.fullPath ?? route.from,\n              actuallyCaseSensitive,\n              prefix,\n              suffix,\n            )\n            nextNode = next\n            next.depth = depth\n            next.parent = node\n            node.dynamic ??= []\n            node.dynamic.push(next)\n          }\n          break\n        }\n        case SEGMENT_TYPE_OPTIONAL_PARAM: {\n          const prefix_raw = path.substring(start, segment[1])\n          const suffix_raw = path.substring(segment[4], end)\n          const actuallyCaseSensitive =\n            caseSensitive && !!(prefix_raw || suffix_raw)\n          const prefix = !prefix_raw\n            ? undefined\n            : actuallyCaseSensitive\n              ? prefix_raw\n              : prefix_raw.toLowerCase()\n          const suffix = !suffix_raw\n            ? undefined\n            : actuallyCaseSensitive\n              ? suffix_raw\n              : suffix_raw.toLowerCase()\n          const existingNode =\n            !skipOnParamError &&\n            node.optional?.find(\n              (s) =>\n                !s.skipOnParamError &&\n                s.caseSensitive === actuallyCaseSensitive &&\n                s.prefix === prefix &&\n                s.suffix === suffix,\n            )\n          if (existingNode) {\n            nextNode = existingNode\n          } else {\n            const next = createDynamicNode<TRouteLike>(\n              SEGMENT_TYPE_OPTIONAL_PARAM,\n              route.fullPath ?? route.from,\n              actuallyCaseSensitive,\n              prefix,\n              suffix,\n            )\n            nextNode = next\n            next.parent = node\n            next.depth = depth\n            node.optional ??= []\n            node.optional.push(next)\n          }\n          break\n        }\n        case SEGMENT_TYPE_WILDCARD: {\n          const prefix_raw = path.substring(start, segment[1])\n          const suffix_raw = path.substring(segment[4], end)\n          const actuallyCaseSensitive =\n            caseSensitive && !!(prefix_raw || suffix_raw)\n          const prefix = !prefix_raw\n            ? undefined\n            : actuallyCaseSensitive\n              ? prefix_raw\n              : prefix_raw.toLowerCase()\n          const suffix = !suffix_raw\n            ? undefined\n            : actuallyCaseSensitive\n              ? suffix_raw\n              : suffix_raw.toLowerCase()\n          const next = createDynamicNode<TRouteLike>(\n            SEGMENT_TYPE_WILDCARD,\n            route.fullPath ?? route.from,\n            actuallyCaseSensitive,\n            prefix,\n            suffix,\n          )\n          nextNode = next\n          next.parent = node\n          next.depth = depth\n          node.wildcard ??= []\n          node.wildcard.push(next)\n        }\n      }\n      node = nextNode\n    }\n\n    // create pathless node\n    if (\n      skipOnParamError &&\n      route.children &&\n      !route.isRoot &&\n      route.id &&\n      route.id.charCodeAt(route.id.lastIndexOf('/') + 1) === 95 /* '_' */\n    ) {\n      const pathlessNode = createStaticNode<TRouteLike>(\n        route.fullPath ?? route.from,\n      )\n      pathlessNode.kind = SEGMENT_TYPE_PATHLESS\n      pathlessNode.parent = node\n      depth++\n      pathlessNode.depth = depth\n      node.pathless ??= []\n      node.pathless.push(pathlessNode)\n      node = pathlessNode\n    }\n\n    const isLeaf = (route.path || !route.children) && !route.isRoot\n    // create index node\n    if (isLeaf && path.endsWith('/')) {\n      const indexNode = createStaticNode<TRouteLike>(\n        route.fullPath ?? route.from,\n      )\n      indexNode.kind = SEGMENT_TYPE_INDEX\n      indexNode.parent = node\n      depth++\n      indexNode.depth = depth\n      node.index = indexNode\n      node = indexNode\n    }\n\n    node.parse = route.options?.params?.parse ?? null\n    node.skipOnParamError = skipOnParamError\n    node.parsingPriority = route.options?.skipRouteOnParseError?.priority ?? 0\n\n    // make node \"matchable\"\n    if (isLeaf && !node.route) {\n      node.route = route\n      node.fullPath = route.fullPath ?? route.from\n    }\n  }\n  if (route.children)\n    for (const child of route.children) {\n      parseSegments(\n        defaultCaseSensitive,\n        data,\n        child as TRouteLike,\n        cursor,\n        node,\n        depth,\n        onRoute,\n      )\n    }\n}\n\nfunction sortDynamic(\n  a: {\n    prefix?: string\n    suffix?: string\n    caseSensitive: boolean\n    skipOnParamError: boolean\n    parsingPriority: number\n  },\n  b: {\n    prefix?: string\n    suffix?: string\n    caseSensitive: boolean\n    skipOnParamError: boolean\n    parsingPriority: number\n  },\n) {\n  if (a.skipOnParamError && !b.skipOnParamError) return -1\n  if (!a.skipOnParamError && b.skipOnParamError) return 1\n  if (\n    a.skipOnParamError &&\n    b.skipOnParamError &&\n    (a.parsingPriority || b.parsingPriority)\n  )\n    return b.parsingPriority - a.parsingPriority\n  if (a.prefix && b.prefix && a.prefix !== b.prefix) {\n    if (a.prefix.startsWith(b.prefix)) return -1\n    if (b.prefix.startsWith(a.prefix)) return 1\n  }\n  if (a.suffix && b.suffix && a.suffix !== b.suffix) {\n    if (a.suffix.endsWith(b.suffix)) return -1\n    if (b.suffix.endsWith(a.suffix)) return 1\n  }\n  if (a.prefix && !b.prefix) return -1\n  if (!a.prefix && b.prefix) return 1\n  if (a.suffix && !b.suffix) return -1\n  if (!a.suffix && b.suffix) return 1\n  if (a.caseSensitive && !b.caseSensitive) return -1\n  if (!a.caseSensitive && b.caseSensitive) return 1\n\n  // we don't need a tiebreaker here\n  // at this point the 2 nodes cannot conflict during matching\n  return 0\n}\n\nfunction sortTreeNodes(node: SegmentNode<RouteLike>) {\n  if (node.pathless) {\n    for (const child of node.pathless) {\n      sortTreeNodes(child)\n    }\n  }\n  if (node.static) {\n    for (const child of node.static.values()) {\n      sortTreeNodes(child)\n    }\n  }\n  if (node.staticInsensitive) {\n    for (const child of node.staticInsensitive.values()) {\n      sortTreeNodes(child)\n    }\n  }\n  if (node.dynamic?.length) {\n    node.dynamic.sort(sortDynamic)\n    for (const child of node.dynamic) {\n      sortTreeNodes(child)\n    }\n  }\n  if (node.optional?.length) {\n    node.optional.sort(sortDynamic)\n    for (const child of node.optional) {\n      sortTreeNodes(child)\n    }\n  }\n  if (node.wildcard?.length) {\n    node.wildcard.sort(sortDynamic)\n    for (const child of node.wildcard) {\n      sortTreeNodes(child)\n    }\n  }\n}\n\nfunction createStaticNode<T extends RouteLike>(\n  fullPath: string,\n): StaticSegmentNode<T> {\n  return {\n    kind: SEGMENT_TYPE_PATHNAME,\n    depth: 0,\n    pathless: null,\n    index: null,\n    static: null,\n    staticInsensitive: null,\n    dynamic: null,\n    optional: null,\n    wildcard: null,\n    route: null,\n    fullPath,\n    parent: null,\n    parse: null,\n    skipOnParamError: false,\n    parsingPriority: 0,\n  }\n}\n\n/**\n * Keys must be declared in the same order as in `SegmentNode` type,\n * to ensure they are represented as the same object class in the engine.\n */\nfunction createDynamicNode<T extends RouteLike>(\n  kind:\n    | typeof SEGMENT_TYPE_PARAM\n    | typeof SEGMENT_TYPE_WILDCARD\n    | typeof SEGMENT_TYPE_OPTIONAL_PARAM,\n  fullPath: string,\n  caseSensitive: boolean,\n  prefix?: string,\n  suffix?: string,\n): DynamicSegmentNode<T> {\n  return {\n    kind,\n    depth: 0,\n    pathless: null,\n    index: null,\n    static: null,\n    staticInsensitive: null,\n    dynamic: null,\n    optional: null,\n    wildcard: null,\n    route: null,\n    fullPath,\n    parent: null,\n    parse: null,\n    skipOnParamError: false,\n    parsingPriority: 0,\n    caseSensitive,\n    prefix,\n    suffix,\n  }\n}\n\ntype StaticSegmentNode<T extends RouteLike> = SegmentNode<T> & {\n  kind:\n    | typeof SEGMENT_TYPE_PATHNAME\n    | typeof SEGMENT_TYPE_PATHLESS\n    | typeof SEGMENT_TYPE_INDEX\n}\n\ntype DynamicSegmentNode<T extends RouteLike> = SegmentNode<T> & {\n  kind:\n    | typeof SEGMENT_TYPE_PARAM\n    | typeof SEGMENT_TYPE_WILDCARD\n    | typeof SEGMENT_TYPE_OPTIONAL_PARAM\n  prefix?: string\n  suffix?: string\n  caseSensitive: boolean\n}\n\ntype AnySegmentNode<T extends RouteLike> =\n  | StaticSegmentNode<T>\n  | DynamicSegmentNode<T>\n\ntype SegmentNode<T extends RouteLike> = {\n  kind: ExtendedSegmentKind\n\n  pathless: Array<StaticSegmentNode<T>> | null\n\n  /** Exact index segment (highest priority) */\n  index: StaticSegmentNode<T> | null\n\n  /** Static segments (2nd priority) */\n  static: Map<string, StaticSegmentNode<T>> | null\n\n  /** Case insensitive static segments (3rd highest priority) */\n  staticInsensitive: Map<string, StaticSegmentNode<T>> | null\n\n  /** Dynamic segments ($param) */\n  dynamic: Array<DynamicSegmentNode<T>> | null\n\n  /** Optional dynamic segments ({-$param}) */\n  optional: Array<DynamicSegmentNode<T>> | null\n\n  /** Wildcard segments ($ - lowest priority) */\n  wildcard: Array<DynamicSegmentNode<T>> | null\n\n  /** Terminal route (if this path can end here) */\n  route: T | null\n\n  /** The full path for this segment node (will only be valid on leaf nodes) */\n  fullPath: string\n\n  parent: AnySegmentNode<T> | null\n\n  depth: number\n\n  /** route.options.params.parse function, set on the last node of the route */\n  parse: null | ((params: Record<string, string>) => any)\n\n  /** options.skipRouteOnParseError.params ?? false */\n  skipOnParamError: boolean\n\n  /** options.skipRouteOnParseError.priority ?? 0 */\n  parsingPriority: number\n}\n\ntype RouteLike = {\n  id?: string\n  path?: string // relative path from the parent,\n  children?: Array<RouteLike> // child routes,\n  parentRoute?: RouteLike // parent route,\n  isRoot?: boolean\n  options?: {\n    skipRouteOnParseError?: {\n      params?: boolean\n      priority?: number\n    }\n    caseSensitive?: boolean\n    params?: {\n      parse?: (params: Record<string, string>) => any\n    }\n  }\n} &\n  // router tree\n  (| { fullPath: string; from?: never } // full path from the root\n    // flat route masks list\n    | { fullPath?: never; from: string } // full path from the root\n  )\n\nexport type ProcessedTree<\n  TTree extends Extract<RouteLike, { fullPath: string }>,\n  TFlat extends Extract<RouteLike, { from: string }>,\n  TSingle extends Extract<RouteLike, { from: string }>,\n> = {\n  /** a representation of the `routeTree` as a segment tree */\n  segmentTree: AnySegmentNode<TTree>\n  /** a mini route tree generated from the flat `routeMasks` list */\n  masksTree: AnySegmentNode<TFlat> | null\n  /** @deprecated keep until v2 so that `router.matchRoute` can keep not caring about the actual route tree */\n  singleCache: LRUCache<string, AnySegmentNode<TSingle>>\n  /** a cache of route matches from the `segmentTree` */\n  matchCache: LRUCache<string, RouteMatch<TTree> | null>\n  /** a cache of route matches from the `masksTree` */\n  flatCache: LRUCache<string, ReturnType<typeof findMatch<TFlat>>> | null\n}\n\nexport function processRouteMasks<\n  TRouteLike extends Extract<RouteLike, { from: string }>,\n>(\n  routeList: Array<TRouteLike>,\n  processedTree: ProcessedTree<any, TRouteLike, any>,\n) {\n  const segmentTree = createStaticNode<TRouteLike>('/')\n  const data = new Uint16Array(6)\n  for (const route of routeList) {\n    parseSegments(false, data, route, 1, segmentTree, 0)\n  }\n  sortTreeNodes(segmentTree)\n  processedTree.masksTree = segmentTree\n  processedTree.flatCache = createLRUCache<\n    string,\n    ReturnType<typeof findMatch<TRouteLike>>\n  >(1000)\n}\n\n/**\n * Take an arbitrary list of routes, create a tree from them (if it hasn't been created already), and match a path against it.\n */\nexport function findFlatMatch<T extends Extract<RouteLike, { from: string }>>(\n  /** The path to match. */\n  path: string,\n  /** The `processedTree` returned by the initial `processRouteTree` call. */\n  processedTree: ProcessedTree<any, T, any>,\n) {\n  path ||= '/'\n  const cached = processedTree.flatCache!.get(path)\n  if (cached) return cached\n  const result = findMatch(path, processedTree.masksTree!)\n  processedTree.flatCache!.set(path, result)\n  return result\n}\n\n/**\n * @deprecated keep until v2 so that `router.matchRoute` can keep not caring about the actual route tree\n */\nexport function findSingleMatch(\n  from: string,\n  caseSensitive: boolean,\n  fuzzy: boolean,\n  path: string,\n  processedTree: ProcessedTree<any, any, { from: string }>,\n) {\n  from ||= '/'\n  path ||= '/'\n  const key = caseSensitive ? `case\\0${from}` : from\n  let tree = processedTree.singleCache.get(key)\n  if (!tree) {\n    // single flat routes (router.matchRoute) are not eagerly processed,\n    // if we haven't seen this route before, process it now\n    tree = createStaticNode<{ from: string }>('/')\n    const data = new Uint16Array(6)\n    parseSegments(caseSensitive, data, { from }, 1, tree, 0)\n    processedTree.singleCache.set(key, tree)\n  }\n  return findMatch(path, tree, fuzzy)\n}\n\ntype RouteMatch<T extends Extract<RouteLike, { fullPath: string }>> = {\n  route: T\n  rawParams: Record<string, string>\n  parsedParams?: Record<string, unknown>\n  branch: ReadonlyArray<T>\n}\n\nexport function findRouteMatch<\n  T extends Extract<RouteLike, { fullPath: string }>,\n>(\n  /** The path to match against the route tree. */\n  path: string,\n  /** The `processedTree` returned by the initial `processRouteTree` call. */\n  processedTree: ProcessedTree<T, any, any>,\n  /** If `true`, allows fuzzy matching (partial matches), i.e. which node in the tree would have been an exact match if the `path` had been shorter? */\n  fuzzy = false,\n): RouteMatch<T> | null {\n  const key = fuzzy ? path : `nofuzz\\0${path}` // the main use for `findRouteMatch` is fuzzy:true, so we optimize for that case\n  const cached = processedTree.matchCache.get(key)\n  if (cached !== undefined) return cached\n  path ||= '/'\n  let result: RouteMatch<T> | null\n\n  try {\n    result = findMatch(\n      path,\n      processedTree.segmentTree,\n      fuzzy,\n    ) as RouteMatch<T> | null\n  } catch (err) {\n    if (err instanceof URIError) {\n      result = null\n    } else {\n      throw err\n    }\n  }\n\n  if (result) result.branch = buildRouteBranch(result.route)\n  processedTree.matchCache.set(key, result)\n  return result\n}\n\n/** Trim trailing slashes (except preserving root '/'). */\nexport function trimPathRight(path: string) {\n  return path === '/' ? path : path.replace(/\\/{1,}$/, '')\n}\n\nexport interface ProcessRouteTreeResult<\n  TRouteLike extends Extract<RouteLike, { fullPath: string }> & { id: string },\n> {\n  /** Should be considered a black box, needs to be provided to all matching functions in this module. */\n  processedTree: ProcessedTree<TRouteLike, any, any>\n  /** A lookup map of routes by their unique IDs. */\n  routesById: Record<string, TRouteLike>\n  /** A lookup map of routes by their trimmed full paths. */\n  routesByPath: Record<string, TRouteLike>\n}\n\n/**\n * Processes a route tree into a segment trie for efficient path matching.\n * Also builds lookup maps for routes by ID and by trimmed full path.\n */\nexport function processRouteTree<\n  TRouteLike extends Extract<RouteLike, { fullPath: string }> & { id: string },\n>(\n  /** The root of the route tree to process. */\n  routeTree: TRouteLike,\n  /** Whether matching should be case sensitive by default (overridden by individual route options). */\n  caseSensitive: boolean = false,\n  /** Optional callback invoked for each route during processing. */\n  initRoute?: (route: TRouteLike, index: number) => void,\n): ProcessRouteTreeResult<TRouteLike> {\n  const segmentTree = createStaticNode<TRouteLike>(routeTree.fullPath)\n  const data = new Uint16Array(6)\n  const routesById = {} as Record<string, TRouteLike>\n  const routesByPath = {} as Record<string, TRouteLike>\n  let index = 0\n  parseSegments(caseSensitive, data, routeTree, 1, segmentTree, 0, (route) => {\n    initRoute?.(route, index)\n\n    if (route.id in routesById) {\n      if (process.env.NODE_ENV !== 'production') {\n        throw new Error(\n          `Invariant failed: Duplicate routes found with id: ${String(route.id)}`,\n        )\n      }\n\n      invariant()\n    }\n\n    routesById[route.id] = route\n\n    if (index !== 0 && route.path) {\n      const trimmedFullPath = trimPathRight(route.fullPath)\n      if (!routesByPath[trimmedFullPath] || route.fullPath.endsWith('/')) {\n        routesByPath[trimmedFullPath] = route\n      }\n    }\n\n    index++\n  })\n  sortTreeNodes(segmentTree)\n  const processedTree: ProcessedTree<TRouteLike, any, any> = {\n    segmentTree,\n    singleCache: createLRUCache<string, AnySegmentNode<any>>(1000),\n    matchCache: createLRUCache<string, RouteMatch<TRouteLike> | null>(1000),\n    flatCache: null,\n    masksTree: null,\n  }\n  return {\n    processedTree,\n    routesById,\n    routesByPath,\n  }\n}\n\nfunction findMatch<T extends RouteLike>(\n  path: string,\n  segmentTree: AnySegmentNode<T>,\n  fuzzy = false,\n): {\n  route: T\n  /**\n   * The raw (unparsed) params extracted from the path.\n   * This will be the exhaustive list of all params defined in the route's path.\n   */\n  rawParams: Record<string, string>\n  /**\n   * The accumlulated parsed params of each route in the branch that had `skipRouteOnParseError` enabled.\n   * Will not contain all params defined in the route's path. Those w/ a `params.parse` but no `skipRouteOnParseError` will need to be parsed separately.\n   */\n  parsedParams?: Record<string, unknown>\n} | null {\n  const parts = path.split('/')\n  const leaf = getNodeMatch(path, parts, segmentTree, fuzzy)\n  if (!leaf) return null\n  const [rawParams] = extractParams(path, parts, leaf)\n  return {\n    route: leaf.node.route!,\n    rawParams,\n    parsedParams: leaf.parsedParams,\n  }\n}\n\ntype ParamExtractionState = {\n  part: number\n  node: number\n  path: number\n  segment: number\n}\n\n/**\n * This function is \"resumable\":\n * - the `leaf` input can contain `extract` and `rawParams` properties from a previous `extractParams` call\n * - the returned `state` can be passed back as `extract` in a future call to continue extracting params from where we left off\n *\n * Inputs are *not* mutated.\n */\nfunction extractParams<T extends RouteLike>(\n  path: string,\n  parts: Array<string>,\n  leaf: {\n    node: AnySegmentNode<T>\n    skipped: number\n    extract?: ParamExtractionState\n    rawParams?: Record<string, string>\n  },\n): [rawParams: Record<string, string>, state: ParamExtractionState] {\n  const list = buildBranch(leaf.node)\n  let nodeParts: Array<string> | null = null\n  const rawParams: Record<string, string> = Object.create(null)\n  /** which segment of the path we're currently processing */\n  let partIndex = leaf.extract?.part ?? 0\n  /** which node of the route tree branch we're currently processing */\n  let nodeIndex = leaf.extract?.node ?? 0\n  /** index of the 1st character of the segment we're processing in the path string */\n  let pathIndex = leaf.extract?.path ?? 0\n  /** which fullPath segment we're currently processing */\n  let segmentCount = leaf.extract?.segment ?? 0\n  for (\n    ;\n    nodeIndex < list.length;\n    partIndex++, nodeIndex++, pathIndex++, segmentCount++\n  ) {\n    const node = list[nodeIndex]!\n    // index nodes are terminating nodes, nothing to extract, just leave\n    if (node.kind === SEGMENT_TYPE_INDEX) break\n    // pathless nodes do not consume a path segment\n    if (node.kind === SEGMENT_TYPE_PATHLESS) {\n      segmentCount--\n      partIndex--\n      pathIndex--\n      continue\n    }\n    const part = parts[partIndex]\n    const currentPathIndex = pathIndex\n    if (part) pathIndex += part.length\n    if (node.kind === SEGMENT_TYPE_PARAM) {\n      nodeParts ??= leaf.node.fullPath.split('/')\n      const nodePart = nodeParts[segmentCount]!\n      const preLength = node.prefix?.length ?? 0\n      // we can't rely on the presence of prefix/suffix to know whether it's curly-braced or not, because `/{$param}/` is valid, but has no prefix/suffix\n      const isCurlyBraced = nodePart.charCodeAt(preLength) === 123 // '{'\n      // param name is extracted at match-time so that tree nodes that are identical except for param name can share the same node\n      if (isCurlyBraced) {\n        const sufLength = node.suffix?.length ?? 0\n        const name = nodePart.substring(\n          preLength + 2,\n          nodePart.length - sufLength - 1,\n        )\n        const value = part!.substring(preLength, part!.length - sufLength)\n        rawParams[name] = decodeURIComponent(value)\n      } else {\n        const name = nodePart.substring(1)\n        rawParams[name] = decodeURIComponent(part!)\n      }\n    } else if (node.kind === SEGMENT_TYPE_OPTIONAL_PARAM) {\n      if (leaf.skipped & (1 << nodeIndex)) {\n        partIndex-- // stay on the same part\n        pathIndex = currentPathIndex - 1 // undo pathIndex advancement; -1 to account for loop increment\n        continue\n      }\n      nodeParts ??= leaf.node.fullPath.split('/')\n      const nodePart = nodeParts[segmentCount]!\n      const preLength = node.prefix?.length ?? 0\n      const sufLength = node.suffix?.length ?? 0\n      const name = nodePart.substring(\n        preLength + 3,\n        nodePart.length - sufLength - 1,\n      )\n      const value =\n        node.suffix || node.prefix\n          ? part!.substring(preLength, part!.length - sufLength)\n          : part\n      if (value) rawParams[name] = decodeURIComponent(value)\n    } else if (node.kind === SEGMENT_TYPE_WILDCARD) {\n      const n = node\n      const value = path.substring(\n        currentPathIndex + (n.prefix?.length ?? 0),\n        path.length - (n.suffix?.length ?? 0),\n      )\n      const splat = decodeURIComponent(value)\n      // TODO: Deprecate *\n      rawParams['*'] = splat\n      rawParams._splat = splat\n      break\n    }\n  }\n  if (leaf.rawParams) Object.assign(rawParams, leaf.rawParams)\n  return [\n    rawParams,\n    {\n      part: partIndex,\n      node: nodeIndex,\n      path: pathIndex,\n      segment: segmentCount,\n    },\n  ]\n}\n\nfunction buildRouteBranch<T extends RouteLike>(route: T) {\n  const list = [route]\n  while (route.parentRoute) {\n    route = route.parentRoute as T\n    list.push(route)\n  }\n  list.reverse()\n  return list\n}\n\nfunction buildBranch<T extends RouteLike>(node: AnySegmentNode<T>) {\n  const list: Array<AnySegmentNode<T>> = Array(node.depth + 1)\n  do {\n    list[node.depth] = node\n    node = node.parent!\n  } while (node)\n  return list\n}\n\ntype MatchStackFrame<T extends RouteLike> = {\n  node: AnySegmentNode<T>\n  /** index of the segment of path */\n  index: number\n  /** how many nodes between `node` and the root of the segment tree */\n  depth: number\n  /**\n   * Bitmask of skipped optional segments.\n   *\n   * This is a very performant way of storing an \"array of booleans\", but it means beyond 32 segments we can't track skipped optionals.\n   * If we really really need to support more than 32 segments we can switch to using a `BigInt` here. It's about 2x slower in worst case scenarios.\n   */\n  skipped: number\n  statics: number\n  dynamics: number\n  optionals: number\n  /** intermediary state for param extraction */\n  extract?: ParamExtractionState\n  /** intermediary params from param extraction */\n  rawParams?: Record<string, string>\n  parsedParams?: Record<string, unknown>\n}\n\nfunction getNodeMatch<T extends RouteLike>(\n  path: string,\n  parts: Array<string>,\n  segmentTree: AnySegmentNode<T>,\n  fuzzy: boolean,\n) {\n  // quick check for root index\n  // this is an optimization, algorithm should work correctly without this block\n  if (path === '/' && segmentTree.index)\n    return { node: segmentTree.index, skipped: 0 } as Pick<\n      Frame,\n      'node' | 'skipped' | 'parsedParams'\n    >\n\n  const trailingSlash = !last(parts)\n  const pathIsIndex = trailingSlash && path !== '/'\n  const partsLength = parts.length - (trailingSlash ? 1 : 0)\n\n  type Frame = MatchStackFrame<T>\n\n  // use a stack to explore all possible paths (params cause branching)\n  // iterate \"backwards\" (low priority first) so that we can push() each candidate, and pop() the highest priority candidate first\n  // - pros: it is depth-first, so we find full matches faster\n  // - cons: we cannot short-circuit, because highest priority matches are at the end of the loop (for loop with i--) (but we have no good short-circuiting anyway)\n  // other possible approaches:\n  // - shift instead of pop (measure performance difference), this allows iterating \"forwards\" (effectively breadth-first)\n  // - never remove from the stack, keep a cursor instead. Then we can push \"forwards\" and avoid reversing the order of candidates (effectively breadth-first)\n  const stack: Array<Frame> = [\n    {\n      node: segmentTree,\n      index: 1,\n      skipped: 0,\n      depth: 1,\n      statics: 1,\n      dynamics: 0,\n      optionals: 0,\n    },\n  ]\n\n  let wildcardMatch: Frame | null = null\n  let bestFuzzy: Frame | null = null\n  let bestMatch: Frame | null = null\n\n  while (stack.length) {\n    const frame = stack.pop()!\n    const { node, index, skipped, depth, statics, dynamics, optionals } = frame\n    let { extract, rawParams, parsedParams } = frame\n\n    if (node.skipOnParamError) {\n      const result = validateMatchParams(path, parts, frame)\n      if (!result) continue\n      rawParams = frame.rawParams\n      extract = frame.extract\n      parsedParams = frame.parsedParams\n    }\n\n    // In fuzzy mode, track the best partial match we've found so far\n    if (\n      fuzzy &&\n      node.route &&\n      node.kind !== SEGMENT_TYPE_INDEX &&\n      isFrameMoreSpecific(bestFuzzy, frame)\n    ) {\n      bestFuzzy = frame\n    }\n\n    const isBeyondPath = index === partsLength\n    if (isBeyondPath) {\n      if (node.route && !pathIsIndex && isFrameMoreSpecific(bestMatch, frame)) {\n        bestMatch = frame\n      }\n      // beyond the length of the path parts, only some segment types can match\n      if (!node.optional && !node.wildcard && !node.index && !node.pathless)\n        continue\n    }\n\n    const part = isBeyondPath ? undefined : parts[index]!\n    let lowerPart: string\n\n    // 0. Try index match\n    if (isBeyondPath && node.index) {\n      const indexFrame = {\n        node: node.index,\n        index,\n        skipped,\n        depth: depth + 1,\n        statics,\n        dynamics,\n        optionals,\n        extract,\n        rawParams,\n        parsedParams,\n      }\n      let indexValid = true\n      if (node.index.skipOnParamError) {\n        const result = validateMatchParams(path, parts, indexFrame)\n        if (!result) indexValid = false\n      }\n      if (indexValid) {\n        // perfect match, no need to continue\n        // this is an optimization, algorithm should work correctly without this block\n        if (statics === partsLength && !dynamics && !optionals && !skipped) {\n          return indexFrame\n        }\n        if (isFrameMoreSpecific(bestMatch, indexFrame)) {\n          // index matches skip the stack because they cannot have children\n          bestMatch = indexFrame\n        }\n      }\n    }\n\n    // 5. Try wildcard match\n    if (node.wildcard && isFrameMoreSpecific(wildcardMatch, frame)) {\n      for (const segment of node.wildcard) {\n        const { prefix, suffix } = segment\n        if (prefix) {\n          if (isBeyondPath) continue\n          const casePart = segment.caseSensitive\n            ? part\n            : (lowerPart ??= part!.toLowerCase())\n          if (!casePart!.startsWith(prefix)) continue\n        }\n        if (suffix) {\n          if (isBeyondPath) continue\n          const end = parts.slice(index).join('/').slice(-suffix.length)\n          const casePart = segment.caseSensitive ? end : end.toLowerCase()\n          if (casePart !== suffix) continue\n        }\n        // the first wildcard match is the highest priority one\n        // wildcard matches skip the stack because they cannot have children\n        const frame = {\n          node: segment,\n          index: partsLength,\n          skipped,\n          depth,\n          statics,\n          dynamics,\n          optionals,\n          extract,\n          rawParams,\n          parsedParams,\n        }\n        if (segment.skipOnParamError) {\n          const result = validateMatchParams(path, parts, frame)\n          if (!result) continue\n        }\n        wildcardMatch = frame\n        break\n      }\n    }\n\n    // 4. Try optional match\n    if (node.optional) {\n      const nextSkipped = skipped | (1 << depth)\n      const nextDepth = depth + 1\n      for (let i = node.optional.length - 1; i >= 0; i--) {\n        const segment = node.optional[i]!\n        // when skipping, node and depth advance by 1, but index doesn't\n        stack.push({\n          node: segment,\n          index,\n          skipped: nextSkipped,\n          depth: nextDepth,\n          statics,\n          dynamics,\n          optionals,\n          extract,\n          rawParams,\n          parsedParams,\n        }) // enqueue skipping the optional\n      }\n      if (!isBeyondPath) {\n        for (let i = node.optional.length - 1; i >= 0; i--) {\n          const segment = node.optional[i]!\n          const { prefix, suffix } = segment\n          if (prefix || suffix) {\n            const casePart = segment.caseSensitive\n              ? part!\n              : (lowerPart ??= part!.toLowerCase())\n            if (prefix && !casePart.startsWith(prefix)) continue\n            if (suffix && !casePart.endsWith(suffix)) continue\n          }\n          stack.push({\n            node: segment,\n            index: index + 1,\n            skipped,\n            depth: nextDepth,\n            statics,\n            dynamics,\n            optionals: optionals + 1,\n            extract,\n            rawParams,\n            parsedParams,\n          })\n        }\n      }\n    }\n\n    // 3. Try dynamic match\n    if (!isBeyondPath && node.dynamic && part) {\n      for (let i = node.dynamic.length - 1; i >= 0; i--) {\n        const segment = node.dynamic[i]!\n        const { prefix, suffix } = segment\n        if (prefix || suffix) {\n          const casePart = segment.caseSensitive\n            ? part\n            : (lowerPart ??= part.toLowerCase())\n          if (prefix && !casePart.startsWith(prefix)) continue\n          if (suffix && !casePart.endsWith(suffix)) continue\n        }\n        stack.push({\n          node: segment,\n          index: index + 1,\n          skipped,\n          depth: depth + 1,\n          statics,\n          dynamics: dynamics + 1,\n          optionals,\n          extract,\n          rawParams,\n          parsedParams,\n        })\n      }\n    }\n\n    // 2. Try case insensitive static match\n    if (!isBeyondPath && node.staticInsensitive) {\n      const match = node.staticInsensitive.get(\n        (lowerPart ??= part!.toLowerCase()),\n      )\n      if (match) {\n        stack.push({\n          node: match,\n          index: index + 1,\n          skipped,\n          depth: depth + 1,\n          statics: statics + 1,\n          dynamics,\n          optionals,\n          extract,\n          rawParams,\n          parsedParams,\n        })\n      }\n    }\n\n    // 1. Try static match\n    if (!isBeyondPath && node.static) {\n      const match = node.static.get(part!)\n      if (match) {\n        stack.push({\n          node: match,\n          index: index + 1,\n          skipped,\n          depth: depth + 1,\n          statics: statics + 1,\n          dynamics,\n          optionals,\n          extract,\n          rawParams,\n          parsedParams,\n        })\n      }\n    }\n\n    // 0. Try pathless match\n    if (node.pathless) {\n      const nextDepth = depth + 1\n      for (let i = node.pathless.length - 1; i >= 0; i--) {\n        const segment = node.pathless[i]!\n        stack.push({\n          node: segment,\n          index,\n          skipped,\n          depth: nextDepth,\n          statics,\n          dynamics,\n          optionals,\n          extract,\n          rawParams,\n          parsedParams,\n        })\n      }\n    }\n  }\n\n  if (bestMatch && wildcardMatch) {\n    return isFrameMoreSpecific(wildcardMatch, bestMatch)\n      ? bestMatch\n      : wildcardMatch\n  }\n\n  if (bestMatch) return bestMatch\n\n  if (wildcardMatch) return wildcardMatch\n\n  if (fuzzy && bestFuzzy) {\n    let sliceIndex = bestFuzzy.index\n    for (let i = 0; i < bestFuzzy.index; i++) {\n      sliceIndex += parts[i]!.length\n    }\n    const splat = sliceIndex === path.length ? '/' : path.slice(sliceIndex)\n    bestFuzzy.rawParams ??= Object.create(null)\n    bestFuzzy.rawParams!['**'] = decodeURIComponent(splat)\n    return bestFuzzy\n  }\n\n  return null\n}\n\nfunction validateMatchParams<T extends RouteLike>(\n  path: string,\n  parts: Array<string>,\n  frame: MatchStackFrame<T>,\n) {\n  try {\n    const [rawParams, state] = extractParams(path, parts, frame)\n    frame.rawParams = rawParams\n    frame.extract = state\n    const parsed = frame.node.parse!(rawParams)\n    frame.parsedParams = Object.assign(\n      Object.create(null),\n      frame.parsedParams,\n      parsed,\n    )\n    return true\n  } catch {\n    return null\n  }\n}\n\nfunction isFrameMoreSpecific(\n  // the stack frame previously saved as \"best match\"\n  prev: MatchStackFrame<any> | null,\n  // the candidate stack frame\n  next: MatchStackFrame<any>,\n): boolean {\n  if (!prev) return true\n  return (\n    next.statics > prev.statics ||\n    (next.statics === prev.statics &&\n      (next.dynamics > prev.dynamics ||\n        (next.dynamics === prev.dynamics &&\n          (next.optionals > prev.optionals ||\n            (next.optionals === prev.optionals &&\n              ((next.node.kind === SEGMENT_TYPE_INDEX) >\n                (prev.node.kind === SEGMENT_TYPE_INDEX) ||\n                ((next.node.kind === SEGMENT_TYPE_INDEX) ===\n                  (prev.node.kind === SEGMENT_TYPE_INDEX) &&\n                  next.depth > prev.depth)))))))\n  )\n}\n"],"mappings":"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"}