{"version":3,"sources":["../../modules/react/components/index.ts","../../modules/react/components/Image/index.tsx","../../modules/react/cache/client-data-cache/index.ts","../../modules/react/components/Link/index.tsx"],"sourcesContent":["export { Image } from \"./Image\";\r\nexport { Link } from \"./Link\";","import React from 'react';\r\n\r\ninterface ImageProps\r\n  extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, \"src\" | \"alt\" | \"width\" | \"height\"> {\r\n  src: string;\r\n  alt: string;\r\n  width?: number;\r\n  height?: number;\r\n  priority?: boolean;\r\n  fill?: boolean;\r\n  sizes?: string;\r\n  placeholder?: 'blur' | 'empty';\r\n  blurDataURL?: string;\r\n  quality?: number;\r\n  format?: 'webp' | 'avif' | 'auto';\r\n  className?: string;\r\n  // Device sizes for srcset generation (defaults if not provided)\r\n  deviceSizes?: number[];\r\n  // Image sizes for srcset generation (defaults if not provided)\r\n  imageSizes?: number[];\r\n}\r\n\r\n/**\r\n * Generates an optimized image URL.\r\n */\r\nfunction getOptimizedImageUrl(\r\n  src: string,\r\n  width?: number,\r\n  height?: number,\r\n  quality?: number,\r\n  format?: 'webp' | 'avif' | 'auto'\r\n): string {\r\n  const params = new URLSearchParams();\r\n  params.set('src', src);\r\n  \r\n  if (width) params.set('w', width.toString());\r\n  if (height) params.set('h', height.toString());\r\n  if (quality) params.set('q', quality.toString());\r\n  if (format && format !== 'auto') params.set('format', format);\r\n  \r\n  return `/_loly/image?${params.toString()}`;\r\n}\r\n\r\n/**\r\n * Generates srcset for responsive images.\r\n */\r\nfunction generateSrcSet(\r\n  src: string,\r\n  sizes: number[],\r\n  height?: number,\r\n  quality?: number,\r\n  format?: 'webp' | 'avif' | 'auto'\r\n): string {\r\n  return sizes\r\n    .map((size) => {\r\n      const url = getOptimizedImageUrl(src, size, height, quality, format);\r\n      return `${url} ${size}w`;\r\n    })\r\n    .join(', ');\r\n}\r\n\r\n/**\r\n * Image component with automatic optimization, lazy loading, and responsive images.\r\n *\r\n * Features:\r\n * - Automatic image optimization via /_loly/image endpoint\r\n * - Lazy loading by default (unless priority is true)\r\n * - Responsive images with srcset\r\n * - Placeholder support (blur)\r\n * - Fill mode for container-filling images\r\n *\r\n * @param props - Image component props\r\n * @returns Image element\r\n */\r\nexport function Image({\r\n  src,\r\n  alt,\r\n  width,\r\n  height,\r\n  priority = false,\r\n  fill = false,\r\n  sizes,\r\n  placeholder,\r\n  blurDataURL,\r\n  quality,\r\n  format,\r\n  className,\r\n  deviceSizes,\r\n  imageSizes,\r\n  style,\r\n  ...rest\r\n}: ImageProps) {\r\n  // Default device sizes (matching Next.js defaults)\r\n  const defaultDeviceSizes = deviceSizes || [640, 750, 828, 1080, 1200, 1920, 2048, 3840];\r\n  const defaultImageSizes = imageSizes || [16, 32, 48, 64, 96, 128, 256, 384];\r\n  \r\n  // Validate props\r\n  if (!fill && (!width || !height)) {\r\n    if (process.env.NODE_ENV === 'development') {\r\n      console.warn(\r\n        '[Image] width and height are required when fill is false. ' +\r\n        'This helps prevent layout shift (CLS).'\r\n      );\r\n    }\r\n  }\r\n  \r\n  // Generate optimized image URL\r\n  const optimizedSrc = getOptimizedImageUrl(src, width, height, quality, format);\r\n  \r\n  // Generate srcset for responsive images\r\n  // Use deviceSizes if width is provided, otherwise use imageSizes\r\n  const srcSetSizes = width ? defaultDeviceSizes.filter(s => s <= (width * 2)) : defaultImageSizes;\r\n  const srcSet = srcSetSizes.length > 0 ? generateSrcSet(src, srcSetSizes, height, quality, format) : undefined;\r\n  \r\n  // Build styles\r\n  const imageStyle: React.CSSProperties = {\r\n    ...style,\r\n  };\r\n  \r\n  if (fill) {\r\n    imageStyle.position = 'absolute';\r\n    imageStyle.height = '100%';\r\n    imageStyle.width = '100%';\r\n    imageStyle.objectFit = 'cover';\r\n    imageStyle.objectPosition = 'center';\r\n  } else {\r\n    if (width) imageStyle.width = width;\r\n    if (height) imageStyle.height = height;\r\n  }\r\n  \r\n  // Aspect ratio container to prevent CLS (only if width and height are provided)\r\n  if (!fill && width && height) {\r\n    const aspectRatio = (height / width) * 100;\r\n    return (\r\n      <span\r\n        style={{\r\n          display: 'block',\r\n          position: 'relative',\r\n          width: width,\r\n          maxWidth: '100%',\r\n        }}\r\n        className={className}\r\n      >\r\n        <span\r\n          style={{\r\n            display: 'block',\r\n            paddingBottom: `${aspectRatio}%`,\r\n          }}\r\n        />\r\n        {placeholder === 'blur' && blurDataURL && (\r\n          <img\r\n            src={blurDataURL}\r\n            alt=\"\"\r\n            aria-hidden=\"true\"\r\n            style={{\r\n              position: 'absolute',\r\n              top: 0,\r\n              left: 0,\r\n              width: '100%',\r\n              height: '100%',\r\n              objectFit: 'cover',\r\n              filter: 'blur(20px)',\r\n              transform: 'scale(1.1)',\r\n            }}\r\n          />\r\n        )}\r\n        <img\r\n          src={optimizedSrc}\r\n          alt={alt}\r\n          width={width}\r\n          height={height}\r\n          srcSet={srcSet}\r\n          sizes={sizes}\r\n          loading={priority ? 'eager' : 'lazy'}\r\n          decoding=\"async\"\r\n          style={{\r\n            ...imageStyle,\r\n            position: 'absolute',\r\n            top: 0,\r\n            left: 0,\r\n            height: '100%',\r\n            width: '100%',\r\n          }}\r\n          {...rest}\r\n        />\r\n      </span>\r\n    );\r\n  }\r\n  \r\n  // Simple case without aspect ratio container\r\n  return (\r\n    <img\r\n      src={optimizedSrc}\r\n      alt={alt}\r\n      width={width}\r\n      height={height}\r\n      srcSet={srcSet}\r\n      sizes={sizes}\r\n      loading={priority ? 'eager' : 'lazy'}\r\n      decoding=\"async\"\r\n      className={className}\r\n      style={imageStyle}\r\n      {...rest}\r\n    />\r\n  );\r\n}\r\n","import type { PageMetadata } from \"@router/index\";\n\n/**\n * Response data structure from server for route data requests\n */\nexport type RouteDataResponse = {\n  /** Combined props (layout + page) - kept for backward compatibility */\n  props?: Record<string, unknown>;\n  /** Layout props (from layout.server.hook.ts) - only present when layout hooks were executed */\n  layoutProps?: Record<string, unknown>;\n  /** Page props (from page.server.hook.ts) - always present in data requests */\n  pageProps?: Record<string, unknown>;\n  metadata?: PageMetadata | null;\n  theme?: string;\n  redirect?: { destination: string; permanent?: boolean };\n  notFound?: boolean;\n  error?: boolean;\n  message?: string;\n  params?: Record<string, string>;\n  /** Pathname after rewrite (for client-side route matching) */\n  pathname?: string;\n};\n\ntype RouteData = {\n  ok: boolean;\n  status: number;\n  json: RouteDataResponse;\n};\n\ntype CacheEntry =\n  | { status: \"pending\"; promise: Promise<RouteData> }\n  | { status: \"fulfilled\"; value: RouteData }\n  | { status: \"rejected\"; error: any };\n\n// Use window to guarantee a single shared cache instance\n// across all bundles/modules\nconst CACHE_KEY = \"__FW_DATA_CACHE__\";\n\n// Maximum number of entries in the cache (LRU)\nconst MAX_CACHE_SIZE = 100;\n\ntype CacheStore = {\n  data: Map<string, CacheEntry>;\n  index: Map<string, Set<string>>; // pathBase -> Set of keys\n  lru: string[]; // Ordered list: most recent at end, oldest at start\n};\n\nfunction getCacheStore(): CacheStore {\n  if (typeof window !== \"undefined\") {\n    if (!(window as any)[CACHE_KEY]) {\n      (window as any)[CACHE_KEY] = {\n        data: new Map<string, CacheEntry>(),\n        index: new Map<string, Set<string>>(),\n        lru: [],\n      };\n    }\n    return (window as any)[CACHE_KEY];\n  }\n  // Fallback for SSR (though this shouldn't be used on the client)\n  return {\n    data: new Map<string, CacheEntry>(),\n    index: new Map<string, Set<string>>(),\n    lru: [],\n  };\n}\n\nconst cacheStore = getCacheStore();\nconst dataCache = cacheStore.data;\nconst pathIndex = cacheStore.index;\nconst lru = cacheStore.lru;\n\n// Helper functions for cache management\n\n/**\n * Extract base path from a cache key (removes query params)\n */\nfunction extractPathBase(key: string): string {\n  return key.split(\"?\")[0];\n}\n\n/**\n * Add key to path index\n */\nfunction addToIndex(key: string): void {\n  const pathBase = extractPathBase(key);\n  if (!pathIndex.has(pathBase)) {\n    pathIndex.set(pathBase, new Set());\n  }\n  pathIndex.get(pathBase)!.add(key);\n}\n\n/**\n * Remove key from path index\n */\nfunction removeFromIndex(key: string): void {\n  const pathBase = extractPathBase(key);\n  const keys = pathIndex.get(pathBase);\n  if (keys) {\n    keys.delete(key);\n    if (keys.size === 0) {\n      pathIndex.delete(pathBase);\n    }\n  }\n}\n\n/**\n * Update LRU order - move key to end (most recent)\n */\nfunction updateLRU(key: string): void {\n  const index = lru.indexOf(key);\n  if (index !== -1) {\n    lru.splice(index, 1);\n  }\n  lru.push(key);\n}\n\n/**\n * Remove oldest entries if cache exceeds MAX_CACHE_SIZE\n */\nfunction evictOldest(): void {\n  while (lru.length >= MAX_CACHE_SIZE && lru.length > 0) {\n    const oldestKey = lru.shift()!;\n    dataCache.delete(oldestKey);\n    removeFromIndex(oldestKey);\n  }\n}\n\n/**\n * Set cache entry and maintain indexes\n */\nfunction setCacheEntry(key: string, entry: CacheEntry): void {\n  const existingEntry = dataCache.get(key);\n  const wasFulfilled = existingEntry?.status === \"fulfilled\";\n  \n  dataCache.set(key, entry);\n  \n  // Only track fulfilled entries in LRU and index (not pending/rejected)\n  if (entry.status === \"fulfilled\") {\n    // Add to index if it wasn't already fulfilled (new entry or transition from pending/rejected)\n    if (!wasFulfilled) {\n      addToIndex(key);\n    }\n    updateLRU(key);\n    evictOldest();\n  } else if (wasFulfilled) {\n    // If entry was fulfilled and now isn't (transitioning to pending/rejected), remove from index\n    removeFromIndex(key);\n  }\n}\n\n/**\n * Delete cache entry and clean up indexes\n */\nfunction deleteCacheEntry(key: string): void {\n  if (dataCache.has(key)) {\n    dataCache.delete(key);\n    removeFromIndex(key);\n    const lruIndex = lru.indexOf(key);\n    if (lruIndex !== -1) {\n      lru.splice(lruIndex, 1);\n    }\n  }\n}\n\nfunction buildDataUrl(url: string): string {\n  return url + (url.includes(\"?\") ? \"&\" : \"?\") + \"__fw_data=1\";\n}\n\nasync function fetchRouteDataOnce(\n  url: string,\n  skipLayoutHooks: boolean = true\n): Promise<RouteData> {\n  const dataUrl = buildDataUrl(url);\n\n  const headers: Record<string, string> = {\n    \"x-fw-data\": \"1\",\n    Accept: \"application/json\",\n  };\n\n  // Send header to skip layout hooks execution in SPA navigation\n  // Only skip if skipLayoutHooks is true (normal SPA navigation)\n  // If false (revalidate), don't send header to force execution of all hooks\n  if (skipLayoutHooks) {\n    headers[\"x-skip-layout-hooks\"] = \"true\";\n  }\n\n  const res = await fetch(dataUrl, { headers });\n\n  let json: any = {};\n\n  try {\n    const text = await res.text();\n    if (text) {\n      json = JSON.parse(text);\n    }\n  } catch (parseError) {\n    console.error(\n      \"[client][cache] Failed to parse response as JSON:\",\n      parseError\n    );\n  }\n\n  const result: RouteData = {\n    ok: res.ok,\n    status: res.status,\n    json,\n  };\n\n  return result;\n}\n\n/**\n * Revalidates route data by removing it from the cache.\n * The next time you navigate to this route, fresh data will be fetched from the server.\n * This is a client-side function and does not require a server-side revalidation.\n *\n * @param path - The route path to revalidate (e.g., '/posts/1' or '/posts/1?page=2')\n *               If query params are not included, revalidates all variants of that route.\n *\n * @example\n * ```ts\n * // After saving something to the DB, revalidate the route\n * await saveToDatabase(data);\n * revalidatePath('/posts');\n * \n * // Revalidate a specific route with query params\n * revalidatePath('/posts?page=2');\n * ```\n */\nexport function revalidatePath(path: string, skipAutoRevalidate: boolean = false): void {\n  // Normalize the base path (without query params)\n  const normalizedPath = path.split(\"?\")[0];\n  const hasQueryParams = path.includes(\"?\");\n  \n  // Get all keys for this path base from index (O(1) lookup)\n  const keysForPath = pathIndex.get(normalizedPath);\n  \n  if (!keysForPath || keysForPath.size === 0) {\n    return; // No entries to revalidate\n  }\n  \n  // If the path includes specific query params, extract them\n  let specificQueryParams: string | undefined;\n  if (hasQueryParams) {\n    const queryPart = path.split(\"?\")[1];\n    // Sort query params for consistent comparison\n    specificQueryParams = queryPart\n      .split(\"&\")\n      .filter((p) => !p.startsWith(\"__fw_data=\"))\n      .sort()\n      .join(\"&\");\n  }\n  \n  // Iterate only over keys for this path (much smaller set)\n  const keysToDelete: string[] = [];\n  for (const key of keysForPath) {\n    // If specific query params were specified, check if they match\n    if (hasQueryParams && specificQueryParams) {\n      const [, keyQuery = \"\"] = key.split(\"?\");\n      const keyQueryParams = keyQuery\n        .split(\"&\")\n        .filter((p) => !p.startsWith(\"__fw_data=\"))\n        .sort()\n        .join(\"&\");\n      \n      if (keyQueryParams === specificQueryParams) {\n        keysToDelete.push(key);\n      }\n    } else {\n      // If no specific query params, revalidate all variants\n      keysToDelete.push(key);\n    }\n  }\n  \n  // Delete matching entries\n  keysToDelete.forEach((key) => {\n    deleteCacheEntry(key);\n  });\n  \n  // If the revalidated path matches the current route, automatically refresh data\n  // UNLESS skipAutoRevalidate is true (to prevent recursive calls from revalidate())\n  if (!skipAutoRevalidate && typeof window !== \"undefined\") {\n    const currentPathname = window.location.pathname;\n    const currentSearch = window.location.search;\n    const matchesCurrentPath = normalizedPath === currentPathname;\n    \n    if (matchesCurrentPath) {\n      if (hasQueryParams && specificQueryParams) {\n        const currentQueryParams = currentSearch\n          .replace(\"?\", \"\")\n          .split(\"&\")\n          .filter((p) => !p.startsWith(\"__fw_data=\"))\n          .sort()\n          .join(\"&\");\n        \n        if (currentQueryParams === specificQueryParams) {\n          revalidate().catch((err) => {\n            console.error(\n              \"[client][cache] Error revalidating current route:\",\n              err\n            );\n          });\n        }\n      } else {\n        revalidate().catch((err) => {\n          console.error(\n            \"[client][cache] Error revalidating current route:\",\n            err\n          );\n        });\n      }\n    }\n  }\n}\n\n/**\n * Revalidates and refreshes the current page data.\n * Similar to Next.js's `router.refresh()`.\n * \n * This function:\n * 1. Removes the current route from cache\n * 2. Fetches fresh data from the server\n * 3. Updates window.__FW_DATA__ with the new data\n * 4. Dispatches a 'fw-data-refresh' event for components to listen to\n * \n * @returns Promise that resolves with the fresh route data\n * \n * @example\n * ```ts\n * // Refresh current page data after a mutation\n * await revalidate();\n * ```\n */\n// Flag to prevent recursive calls to revalidate()\nlet isRevalidating = false;\n\nexport async function revalidate(): Promise<RouteData> {\n  if (typeof window === \"undefined\") {\n    throw new Error(\"revalidate() can only be called on the client\");\n  }\n\n  // Prevent multiple simultaneous revalidations\n  if (isRevalidating) {\n    // Wait for the current revalidation to complete\n    const key = buildDataUrl(window.location.pathname + window.location.search);\n    const entry = dataCache.get(key);\n    if (entry && entry.status === \"pending\") {\n      return entry.promise;\n    }\n    // If no pending entry, something went wrong, allow the call\n  }\n\n  isRevalidating = true;\n  try {\n    const pathname = window.location.pathname + window.location.search;\n    \n    // Revalidate the path (remove from cache)\n    // Pass a flag to prevent revalidatePath from calling revalidate() again (recursive call)\n    revalidatePath(pathname, true); // true = skip auto-revalidate\n    \n    // Fetch fresh data\n    const freshData = await getRouteData(pathname, { revalidate: true });\n    \n    // Update window.__FW_DATA__ if it exists\n    if ((window as any).__FW_DATA__ && freshData.ok && freshData.json) {\n      const currentData = (window as any).__FW_DATA__;\n      \n      // Update preserved layout props if new ones were returned\n      if (freshData.json.layoutProps !== undefined && freshData.json.layoutProps !== null) {\n        (window as any).__FW_LAYOUT_PROPS__ = freshData.json.layoutProps;\n      }\n      \n      // Combine layout props (new or preserved) + page props\n      let combinedProps = currentData.props || {};\n      if (freshData.json.layoutProps !== undefined && freshData.json.layoutProps !== null) {\n        // Use new layout props\n        combinedProps = {\n          ...freshData.json.layoutProps,\n          ...(freshData.json.pageProps ?? freshData.json.props ?? {}),\n        };\n      } else if (freshData.json.pageProps !== undefined) {\n        // Use preserved layout props + new page props\n        const preservedLayoutProps = (window as any).__FW_LAYOUT_PROPS__ || {};\n        combinedProps = {\n          ...preservedLayoutProps,\n          ...freshData.json.pageProps,\n        };\n      } else if (freshData.json.props) {\n        // Fallback to combined props\n        combinedProps = freshData.json.props;\n      }\n      \n      (window as any).__FW_DATA__ = {\n        ...currentData,\n        pathname: pathname.split(\"?\")[0],\n        params: freshData.json.params || currentData.params || {},\n        props: combinedProps,\n        metadata: freshData.json.metadata ?? currentData.metadata ?? null,\n        notFound: freshData.json.notFound ?? false,\n        error: freshData.json.error ?? false,\n      };\n      \n      // Dispatch event for components to listen to\n      window.dispatchEvent(new CustomEvent(\"fw-data-refresh\", {\n        detail: { data: freshData },\n      }));\n    }\n    \n    return freshData;\n  } finally {\n    isRevalidating = false;\n  }\n}\n\n/**\n * @deprecated Use `revalidatePath()` instead. This function is kept for backwards compatibility.\n */\nexport function revalidateRouteData(url: string): void {\n  revalidatePath(url);\n}\n\nexport function prefetchRouteData(url: string): void {\n  const key = buildDataUrl(url);\n\n  const cached = dataCache.get(key);\n\n  if (cached && cached.status !== \"rejected\") {\n    // Update LRU if it exists and is fulfilled\n    if (cached.status === \"fulfilled\") {\n      updateLRU(key);\n    }\n    return;\n  }\n\n  // Prefetch uses skipLayoutHooks: true (normal navigation behavior)\n  const promise = fetchRouteDataOnce(url, true)\n    .then((value) => {\n      setCacheEntry(key, { status: \"fulfilled\", value });\n      return value;\n    })\n    .catch((error) => {\n      console.error(\"[client][cache] Error prefetching route data:\", error);\n      dataCache.set(key, { status: \"rejected\", error });\n      throw error;\n    });\n\n  dataCache.set(key, { status: \"pending\", promise });\n}\n\nexport type GetRouteDataOptions = {\n  /**\n   * If true, forces revalidation of route data,\n   * ignoring the cache and fetching fresh data from the server.\n   * Similar to Next.js's `router.refresh()` behavior.\n   */\n  revalidate?: boolean;\n};\n\nexport async function getRouteData(\n  url: string,\n  options?: GetRouteDataOptions\n): Promise<RouteData> {\n  const key = buildDataUrl(url);\n\n  // If revalidation is requested, remove the entry from cache\n  // This ensures we don't reuse pending or fulfilled entries\n  if (options?.revalidate) {\n    deleteCacheEntry(key);\n  }\n\n  const entry = dataCache.get(key);\n\n  if (entry && !options?.revalidate) {\n    // Only use cached entry if not revalidating\n    if (entry.status === \"fulfilled\") {\n      // Update LRU: mark as recently used\n      updateLRU(key);\n      return entry.value;\n    }\n    if (entry.status === \"pending\") {\n      // Return existing pending promise to avoid duplicate requests\n      return entry.promise;\n    }\n  }\n\n  // No entry in cache (or revalidating), fetch it\n  // skipLayoutHooks: true for normal SPA navigation, false when revalidating\n  const skipLayoutHooks = !options?.revalidate;\n  \n  // Check again if an entry was added while we were processing (race condition)\n  const currentEntry = dataCache.get(key);\n  if (currentEntry && !options?.revalidate) {\n    if (currentEntry.status === \"fulfilled\") {\n      updateLRU(key);\n      return currentEntry.value;\n    }\n    if (currentEntry.status === \"pending\") {\n      return currentEntry.promise;\n    }\n  }\n  \n  // Create a new promise for this fetch\n  const promise = fetchRouteDataOnce(url, skipLayoutHooks)\n    .then((value) => {\n      // Only set cache entry if this is still the current fetch for this key\n      // This prevents race conditions where multiple revalidations happen simultaneously\n      const entryAfterFetch = dataCache.get(key);\n      if (!entryAfterFetch || entryAfterFetch.status === \"pending\") {\n        setCacheEntry(key, { status: \"fulfilled\", value });\n      }\n      return value;\n    })\n    .catch((error) => {\n      console.error(\"[client][cache] Error fetching route data:\", error);\n      const entryAfterFetch = dataCache.get(key);\n      if (!entryAfterFetch || entryAfterFetch.status === \"pending\") {\n        dataCache.set(key, { status: \"rejected\", error });\n      }\n      throw error;\n    });\n\n  // Set pending entry - if revalidating, we already deleted it, so this is safe\n  dataCache.set(key, { status: \"pending\", promise });\n  \n  return promise;\n}\n","import React from \"react\";\r\nimport { prefetchRouteData } from \"../../cache/index\";\r\n\r\ninterface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\r\n  href: string;\r\n  children: React.ReactNode;\r\n  prefetch?: boolean;\r\n}\r\n\r\nimport { useEffect, useRef } from \"react\"; \r\n\r\nfunction isExternal(href: string) {\r\n  try {\r\n    const url = new URL(href, window.location.href);\r\n    return url.origin !== window.location.origin;\r\n  } catch {\r\n    return false;\r\n  }\r\n}\r\n\r\nexport function Link({\r\n  href,\r\n  prefetch = true,\r\n  children,\r\n  ...rest\r\n}: React.PropsWithChildren<{\r\n  href: string;\r\n  prefetch?: boolean;\r\n}> &\r\n  React.AnchorHTMLAttributes<HTMLAnchorElement>) {\r\n  const ref = useRef<HTMLAnchorElement | null>(null);\r\n\r\n  useEffect(() => {\r\n    if (!prefetch || !ref.current || isExternal(href)) return;\r\n\r\n    const el = ref.current;\r\n    let prefetched = false;\r\n\r\n    const io = new IntersectionObserver(([entry]) => {\r\n      if (entry.isIntersecting && !prefetched) {\r\n        prefetched = true;\r\n        prefetchRouteData(href);\r\n      }\r\n    });\r\n\r\n    io.observe(el);\r\n    return () => io.disconnect();\r\n  }, [href, prefetch]);\r\n\r\n  return (\r\n    <a ref={ref} href={href} {...rest}>\r\n      {children}\r\n    </a>\r\n  );\r\n}\r\n"],"mappings":"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","names":["import_jsx_runtime"]}