{"version":3,"file":"entry.modern.mjs","sources":["../src/useTransition.ts","../src/useMutationObserver.ts","../src/useEventBus.ts","../src/useWrappedChildren.ts","../src/usePreferredTheme.ts","../src/useNetworkState.ts","../src/useClipboard.ts","../src/useRageClick.ts","../src/useThreadedWorker.ts","../src/indexedDB/openDB.ts","../src/indexedDB/requestToPromise.ts","../src/indexedDB/tableController.ts","../src/useIndexedDB.ts","../src/indexedDB/dbController.ts","../src/useWebRTCIP.ts","../src/useWasmCompute.ts","../src/useWorkerNotifications.ts"],"sourcesContent":["import { useState, useCallback } from \"preact/hooks\";\n\n/**\n * Mimics React's useTransition hook in Preact.\n * @returns [startTransition, isPending]\n */\nexport function useTransition(): [\n  startTransition: (callback: () => void) => void,\n  isPending: boolean,\n] {\n  const [isPending, setIsPending] = useState(false);\n\n  const startTransition = useCallback((callback: () => void) => {\n    setIsPending(true);\n    Promise.resolve().then(() => {\n      callback();\n      setIsPending(false);\n    });\n  }, []);\n\n  return [startTransition, isPending];\n}\n","import { RefObject } from \"preact\";\nimport { useEffect } from \"preact/hooks\";\n\nexport type UseMutationObserverOptions = MutationObserverInit;\n\n/**\n * A Preact hook to observe DOM mutations using MutationObserver.\n * @param target - The element to observe.\n * @param callback - Function to call on mutation.\n * @param options - MutationObserver options.\n */\nexport function useMutationObserver(\n  targetRef: RefObject<HTMLElement | null>,\n  callback: MutationCallback,\n  options: MutationObserverInit\n) {\n  useEffect(() => {\n    const node = targetRef.current;\n    if (!node) return;\n\n    const observer = new MutationObserver(callback);\n    observer.observe(node, options);\n\n    return () => observer.disconnect();\n  }, [targetRef, callback, options]);\n}\n","import { useCallback } from \"preact/hooks\";\n\ntype EventMap = Record<string, (...args: unknown[]) => void>;\n\nconst listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n/**\n * A Preact hook to publish and subscribe to custom events across components.\n * @returns An object with `emit` and `on` methods.\n */\nexport function useEventBus<T extends EventMap>() {\n  const emit = useCallback(\n    <K extends keyof T>(event: K, ...args: Parameters<T[K]>) => {\n      const handlers = listeners.get(event as string);\n      if (handlers) {\n        handlers.forEach((handler) => handler(...args));\n      }\n    },\n    []\n  );\n\n  const on = useCallback(<K extends keyof T>(event: K, handler: T[K]) => {\n    let handlers = listeners.get(event as string);\n    if (!handlers) {\n      handlers = new Set();\n      listeners.set(event as string, handlers);\n    }\n    handlers.add(handler);\n\n    return () => {\n      handlers!.delete(handler);\n      if (handlers!.size === 0) {\n        listeners.delete(event as string);\n      }\n    };\n  }, []);\n\n  return { emit, on };\n}\n","import { ComponentChildren, cloneElement, isValidElement, VNode } from \"preact\";\nimport { useMemo } from \"preact/hooks\";\n\nexport type InjectableProps = Record<string, unknown>;\n\ninterface PropsWithStyle {\n  style?: Record<string, string | number>;\n}\n\n/**\n * A Preact hook to wrap children components and inject additional props into them.\n * @param children - The children to wrap and enhance with props.\n * @param injectProps - The props to inject into each child component.\n * @param mergeStrategy - How to handle prop conflicts ('override' | 'preserve'). Defaults to 'preserve'.\n * @returns Enhanced children with injected props.\n */\nexport function useWrappedChildren(\n  children: ComponentChildren,\n  injectProps: InjectableProps,\n  mergeStrategy: \"override\" | \"preserve\" = \"preserve\"\n): ComponentChildren {\n  return useMemo(() => {\n    if (!children) return children;\n\n    const enhanceChild = (child: ComponentChildren): ComponentChildren => {\n      if (!isValidElement(child)) return child;\n\n      const existingProps = (child as VNode).props || {};\n\n      let mergedProps: InjectableProps;\n\n      if (mergeStrategy === \"override\") {\n        // Injected props override existing ones\n        mergedProps = { ...existingProps, ...injectProps };\n      } else {\n        // Existing props are preserved, injected props are added only if not present\n        mergedProps = { ...injectProps, ...existingProps };\n      }\n\n      // Special handling for style prop to merge style objects properly\n      const existingStyle = (existingProps as PropsWithStyle)?.style;\n      const injectStyle = (injectProps as PropsWithStyle)?.style;\n\n      if (\n        existingStyle &&\n        injectStyle &&\n        typeof existingStyle === \"object\" &&\n        typeof injectStyle === \"object\"\n      ) {\n        if (mergeStrategy === \"override\") {\n          (mergedProps as PropsWithStyle).style = {\n            ...existingStyle,\n            ...injectStyle,\n          };\n        } else {\n          (mergedProps as PropsWithStyle).style = {\n            ...injectStyle,\n            ...existingStyle,\n          };\n        }\n      }\n\n      return cloneElement(child, mergedProps);\n    };\n\n    if (Array.isArray(children)) {\n      return children.map(enhanceChild);\n    }\n\n    return enhanceChild(children);\n  }, [children, injectProps, mergeStrategy]);\n}\n","import { useEffect, useState } from \"preact/hooks\";\n\nexport type PreferredTheme = \"light\" | \"dark\" | \"no-preference\";\n\n/**\n * A Preact hook that returns the user's preferred color scheme based on the\n * `prefers-color-scheme` media query. Updates reactively when the user changes\n * their system or browser theme preference.\n *\n * @returns The preferred theme: 'light', 'dark', or 'no-preference'\n *\n * @example\n * ```tsx\n * function ThemeAwareComponent() {\n *   const theme = usePreferredTheme();\n *   return (\n *     <div data-theme={theme}>\n *       Current preference: {theme}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function usePreferredTheme(): PreferredTheme {\n  const [theme, setTheme] = useState<PreferredTheme>(() => {\n    if (typeof window === \"undefined\") return \"no-preference\";\n\n    const darkQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n    const lightQuery = window.matchMedia(\"(prefers-color-scheme: light)\");\n\n    if (darkQuery.matches) return \"dark\";\n    if (lightQuery.matches) return \"light\";\n    return \"no-preference\";\n  });\n\n  useEffect(() => {\n    if (typeof window === \"undefined\") return;\n\n    const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n    const handleChange = (e: MediaQueryListEvent) => {\n      setTheme(e.matches ? \"dark\" : \"light\");\n    };\n\n    // Re-check in case of no-preference (some browsers don't support light query)\n    const updateTheme = () => {\n      const darkQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n      const lightQuery = window.matchMedia(\"(prefers-color-scheme: light)\");\n\n      if (darkQuery.matches) setTheme(\"dark\");\n      else if (lightQuery.matches) setTheme(\"light\");\n      else setTheme(\"no-preference\");\n    };\n\n    mediaQuery.addEventListener(\"change\", handleChange);\n\n    // Fallback: some environments may not fire change, so we also listen for light\n    const lightQuery = window.matchMedia(\"(prefers-color-scheme: light)\");\n    lightQuery.addEventListener(\"change\", updateTheme);\n\n    return () => {\n      mediaQuery.removeEventListener(\"change\", handleChange);\n      lightQuery.removeEventListener(\"change\", updateTheme);\n    };\n  }, []);\n\n  return theme;\n}\n","import { useEffect, useState } from \"preact/hooks\";\n\n/** Network Information API (not in all browsers) */\ninterface NetworkInformation extends EventTarget {\n  effectiveType?: string;\n  downlink?: number;\n  rtt?: number;\n  saveData?: boolean;\n  type?: string;\n}\n\n/** Effective connection type from Network Information API */\nexport type EffectiveConnectionType = \"slow-2g\" | \"2g\" | \"3g\" | \"4g\";\n\n/** Network connection type (e.g., wifi, cellular) */\nexport type ConnectionType =\n  | \"bluetooth\"\n  | \"cellular\"\n  | \"ethernet\"\n  | \"mixed\"\n  | \"none\"\n  | \"other\"\n  | \"unknown\"\n  | \"wifi\";\n\nexport interface NetworkState {\n  /** Whether the browser is online */\n  online: boolean;\n  /** Effective connection type (when supported) */\n  effectiveType?: EffectiveConnectionType;\n  /** Estimated downlink speed in Mbps (when supported) */\n  downlink?: number;\n  /** Estimated round-trip time in ms (when supported) */\n  rtt?: number;\n  /** Whether the user has requested reduced data usage (when supported) */\n  saveData?: boolean;\n  /** Connection type (when supported) */\n  connectionType?: ConnectionType;\n}\n\nfunction getNetworkState(): NetworkState {\n  if (typeof navigator === \"undefined\") {\n    return { online: true };\n  }\n\n  const state: NetworkState = {\n    online: navigator.onLine,\n  };\n\n  const connection = (\n    navigator as Navigator & { connection?: NetworkInformation }\n  ).connection;\n\n  if (connection) {\n    if (connection.effectiveType !== undefined) {\n      state.effectiveType = connection.effectiveType as EffectiveConnectionType;\n    }\n    if (connection.downlink !== undefined) {\n      state.downlink = connection.downlink;\n    }\n    if (connection.rtt !== undefined) {\n      state.rtt = connection.rtt;\n    }\n    if (connection.saveData !== undefined) {\n      state.saveData = connection.saveData;\n    }\n    if (connection.type !== undefined) {\n      state.connectionType = connection.type as ConnectionType;\n    }\n  }\n\n  return state;\n}\n\n/**\n * A Preact hook that returns the current network state, including online/offline\n * status and (when supported) connection type, downlink, RTT, and save-data preference.\n * Updates reactively when the network state changes.\n *\n * @returns The current network state object\n *\n * @example\n * ```tsx\n * function NetworkStatus() {\n *   const { online, effectiveType, saveData } = useNetworkState();\n *   return (\n *     <div>\n *       Status: {online ? 'Online' : 'Offline'}\n *       {effectiveType && ` (${effectiveType})`}\n *       {saveData && ' - Reduced data mode'}\n *     </div>\n * );\n * }\n * ```\n */\nexport function useNetworkState(): NetworkState {\n  const [state, setState] = useState<NetworkState>(getNetworkState);\n\n  useEffect(() => {\n    if (typeof window === \"undefined\") return;\n\n    const updateState = () => setState(getNetworkState());\n\n    window.addEventListener(\"online\", updateState);\n    window.addEventListener(\"offline\", updateState);\n\n    const connection = (\n      navigator as Navigator & { connection?: NetworkInformation }\n    ).connection;\n    if (connection?.addEventListener) {\n      connection.addEventListener(\"change\", updateState);\n    }\n\n    return () => {\n      window.removeEventListener(\"online\", updateState);\n      window.removeEventListener(\"offline\", updateState);\n      if (connection?.removeEventListener) {\n        connection.removeEventListener(\"change\", updateState);\n      }\n    };\n  }, []);\n\n  return state;\n}\n","import { useCallback, useState } from \"preact/hooks\";\n\nexport interface UseClipboardOptions {\n  /** Duration in ms to keep `copied` true before resetting. Default: 2000 */\n  resetDelay?: number;\n}\n\nexport interface UseClipboardReturn {\n  /** Copy text to the clipboard. Returns true on success. */\n  copy: (text: string) => Promise<boolean>;\n  /** Read text from the clipboard. Returns empty string if denied or unavailable. */\n  paste: () => Promise<string>;\n  /** Whether the last copy operation succeeded (resets after resetDelay) */\n  copied: boolean;\n  /** Error from the last failed operation, or null */\n  error: Error | null;\n  /** Manually reset copied and error state */\n  reset: () => void;\n}\n\n/**\n * A Preact hook for reading and writing the clipboard. Uses the async\n * Clipboard API when available (requires secure context and user gesture).\n *\n * @param options - Optional configuration (e.g., resetDelay for copied state)\n * @returns Object with copy, paste, copied, error, and reset\n *\n * @example\n * ```tsx\n * function CopyButton() {\n *   const { copy, copied, error } = useClipboard();\n *   return (\n *     <button onClick={() => copy('Hello!')}>\n *       {copied ? 'Copied!' : 'Copy'}\n *     </button>\n *   );\n * }\n * ```\n */\nexport function useClipboard(\n  options: UseClipboardOptions = {}\n): UseClipboardReturn {\n  const { resetDelay = 2000 } = options;\n\n  const [copied, setCopied] = useState(false);\n  const [error, setError] = useState<Error | null>(null);\n\n  const reset = useCallback(() => {\n    setCopied(false);\n    setError(null);\n  }, []);\n\n  const copy = useCallback(\n    async (text: string): Promise<boolean> => {\n      setError(null);\n\n      if (typeof navigator === \"undefined\" || !navigator.clipboard) {\n        const err = new Error(\"Clipboard API is not available\");\n        setError(err);\n        return false;\n      }\n\n      try {\n        await navigator.clipboard.writeText(text);\n        setCopied(true);\n        if (resetDelay > 0) {\n          setTimeout(() => setCopied(false), resetDelay);\n        }\n        return true;\n      } catch (e) {\n        const err = e instanceof Error ? e : new Error(String(e));\n        setError(err);\n        return false;\n      }\n    },\n    [resetDelay]\n  );\n\n  const paste = useCallback(async (): Promise<string> => {\n    setError(null);\n\n    if (typeof navigator === \"undefined\" || !navigator.clipboard) {\n      const err = new Error(\"Clipboard API is not available\");\n      setError(err);\n      return \"\";\n    }\n\n    try {\n      const text = await navigator.clipboard.readText();\n      return text;\n    } catch (e) {\n      const err = e instanceof Error ? e : new Error(String(e));\n      setError(err);\n      return \"\";\n    }\n  }, []);\n\n  return { copy, paste, copied, error, reset };\n}\n","import type { RefObject } from \"preact\";\nimport { useEffect, useRef } from \"preact/hooks\";\n\nexport interface RageClickPayload {\n  /** Number of clicks that triggered the rage click */\n  count: number;\n  /** Last click event (e.g. for Sentry context) */\n  event: MouseEvent;\n}\n\nexport interface UseRageClickOptions {\n  /** Called when a rage click is detected. Use this to report to Sentry or your error tracker. */\n  onRageClick: (payload: RageClickPayload) => void;\n  /** Minimum number of clicks in the time window to count as rage click. Default: 5 (Sentry-style). */\n  threshold?: number;\n  /** Time window in ms. Default: 1000. */\n  timeWindow?: number;\n  /** Max distance in px between clicks to count as same spot. Default: 30. Set to Infinity to ignore distance. */\n  distanceThreshold?: number;\n}\n\ninterface ClickRecord {\n  time: number;\n  x: number;\n  y: number;\n}\n\nfunction distance(a: ClickRecord, b: ClickRecord): number {\n  return Math.hypot(b.x - a.x, b.y - a.y);\n}\n\n/**\n * Detects \"rage clicks\" (repeated rapid clicks in the same area), e.g. when the UI\n * is unresponsive. Use the callback to report to Sentry or similar tools to surface\n * rage click issues and lower rage-click-related support.\n *\n * @param targetRef - Ref of the element to monitor (e.g. a button or card).\n * @param options - onRageClick callback and optional threshold, timeWindow, distanceThreshold.\n *\n * @example\n * ```tsx\n * const ref = useRef<HTMLButtonElement>(null)\n * useRageClick(ref, {\n *   onRageClick: ({ count, event }) => {\n *     Sentry.captureMessage('Rage click detected', { extra: { count, target: event.target } })\n *   },\n * })\n * return <button ref={ref}>Submit</button>\n * ```\n */\nexport function useRageClick(\n  targetRef: RefObject<HTMLElement | null>,\n  options: UseRageClickOptions\n) {\n  const {\n    onRageClick,\n    threshold = 5,\n    timeWindow = 1000,\n    distanceThreshold = 30,\n  } = options;\n\n  const onRageClickRef = useRef(onRageClick);\n  onRageClickRef.current = onRageClick;\n\n  const clicksRef = useRef<ClickRecord[]>([]);\n\n  useEffect(() => {\n    const node = targetRef.current;\n    if (!node) return;\n\n    const handleClick = (e: MouseEvent) => {\n      const now = Date.now();\n      const record: ClickRecord = { time: now, x: e.clientX, y: e.clientY };\n\n      const clicks = clicksRef.current;\n      const cutoff = now - timeWindow;\n      const recent = clicks.filter((c) => c.time >= cutoff);\n      recent.push(record);\n\n      if (distanceThreshold !== Infinity) {\n        const inRange = recent.filter(\n          (c) => distance(c, record) <= distanceThreshold\n        );\n        if (inRange.length >= threshold) {\n          onRageClickRef.current({ count: inRange.length, event: e });\n          clicksRef.current = [];\n          return;\n        }\n      } else {\n        if (recent.length >= threshold) {\n          onRageClickRef.current({ count: recent.length, event: e });\n          clicksRef.current = [];\n          return;\n        }\n      }\n\n      clicksRef.current = recent;\n    };\n\n    node.addEventListener(\"click\", handleClick);\n    return () => node.removeEventListener(\"click\", handleClick);\n  }, [targetRef, threshold, timeWindow, distanceThreshold]);\n}\n","import { useState, useCallback, useRef, useEffect } from \"preact/hooks\";\n\n/** Lower number = higher priority. Default priority when not specified. */\nconst DEFAULT_PRIORITY = 1;\n\nexport type ThreadedWorkerMode = \"sequential\" | \"parallel\";\n\nexport interface UseThreadedWorkerOptions {\n  /** Sequential: single worker, priority-ordered. Parallel: worker pool. */\n  mode: ThreadedWorkerMode;\n  /** Max concurrent workers. Only used when mode is \"parallel\". Default 4. */\n  concurrency?: number;\n}\n\nexport interface RunOptions {\n  /** 1 = highest priority. Lower number runs first. FIFO within same priority. */\n  priority?: number;\n}\n\ninterface QueuedTask<TData, TResult> {\n  data: TData;\n  priority: number;\n  sequence: number;\n  resolve: (value: TResult) => void;\n  reject: (reason: unknown) => void;\n}\n\nexport interface UseThreadedWorkerReturn<TData, TResult> {\n  /** Enqueue work. Returns a Promise that resolves with the worker result. */\n  run: (data: TData, options?: RunOptions) => Promise<TResult>;\n  /** True while any task is queued or running. */\n  loading: boolean;\n  /** Result of the most recently completed successful task. */\n  result: TResult | undefined;\n  /** Error from the most recently failed task. */\n  error: unknown;\n  /** Number of tasks currently queued + running. */\n  queueSize: number;\n  /** Clear all pending (not yet started) tasks. Running tasks continue. */\n  clearQueue: () => void;\n  /** Stop accepting new work and clear pending queue. Running tasks finish. */\n  terminate: () => void;\n}\n\n/**\n * Production-grade hook to run async work in a queue with optional priority\n * and either sequential or parallel execution.\n *\n * @param workerFn - Async function to run for each task (e.g. API call, heavy compute).\n * @param options - mode: \"sequential\" | \"parallel\", concurrency (parallel only).\n * @returns run, loading, result, error, queueSize, clearQueue, terminate.\n */\nexport function useThreadedWorker<TData, TResult>(\n  workerFn: (data: TData) => Promise<TResult>,\n  options: UseThreadedWorkerOptions\n): UseThreadedWorkerReturn<TData, TResult> {\n  const { mode, concurrency = 4 } = options;\n  const maxConcurrent = mode === \"sequential\" ? 1 : Math.max(1, concurrency);\n\n  const [loading, setLoading] = useState(false);\n  const [result, setResult] = useState<TResult | undefined>(undefined);\n  const [error, setError] = useState<unknown>(undefined);\n  const [queueSize, setQueueSize] = useState(0);\n\n  const queueRef = useRef<QueuedTask<TData, TResult>[]>([]);\n  const sequenceRef = useRef(0);\n  const activeCountRef = useRef(0);\n  const terminatedRef = useRef(false);\n  const workerFnRef = useRef(workerFn);\n  workerFnRef.current = workerFn;\n\n  const updateQueueSize = useCallback(() => {\n    setQueueSize(queueRef.current.length + activeCountRef.current);\n  }, []);\n\n  const processNext = useCallback(() => {\n    if (terminatedRef.current) return;\n    if (activeCountRef.current >= maxConcurrent) return;\n    if (queueRef.current.length === 0) {\n      if (activeCountRef.current === 0) setLoading(false);\n      updateQueueSize();\n      return;\n    }\n\n    // Sort by priority (asc), then by sequence (FIFO within same priority).\n    queueRef.current.sort((a, b) => {\n      if (a.priority !== b.priority) return a.priority - b.priority;\n      return a.sequence - b.sequence;\n    });\n    const task = queueRef.current.shift()!;\n    activeCountRef.current += 1;\n    setLoading(true);\n    updateQueueSize();\n\n    const fn = workerFnRef.current;\n    fn(task.data)\n      .then((value) => {\n        setResult(value);\n        setError(undefined);\n        task.resolve(value);\n      })\n      .catch((err) => {\n        setError(err);\n        task.reject(err);\n      })\n      .finally(() => {\n        activeCountRef.current -= 1;\n        updateQueueSize();\n        processNext();\n      });\n\n    // Fill remaining slots (parallel mode).\n    if (queueRef.current.length > 0 && activeCountRef.current < maxConcurrent) {\n      processNext();\n    }\n  }, [maxConcurrent, updateQueueSize]);\n\n  const run = useCallback(\n    (data: TData, runOptions?: RunOptions): Promise<TResult> => {\n      if (terminatedRef.current) {\n        return Promise.reject(new Error(\"Worker is terminated\"));\n      }\n      const priority = runOptions?.priority ?? DEFAULT_PRIORITY;\n      const sequence = ++sequenceRef.current;\n      const promise = new Promise<TResult>((resolve, reject) => {\n        queueRef.current.push({ data, priority, sequence, resolve, reject });\n      });\n      updateQueueSize();\n      setLoading(true);\n      queueMicrotask(processNext);\n      return promise;\n    },\n    [processNext, updateQueueSize]\n  );\n\n  const clearQueue = useCallback(() => {\n    const pending = queueRef.current;\n    queueRef.current = [];\n    pending.forEach((t) => t.reject(new Error(\"Task cleared from queue\")));\n    updateQueueSize();\n    if (activeCountRef.current === 0) setLoading(false);\n  }, [updateQueueSize]);\n\n  const terminate = useCallback(() => {\n    terminatedRef.current = true;\n    clearQueue();\n  }, [clearQueue]);\n\n  // Reset terminated on unmount so the same hook instance can't be \"revived\" without options change.\n  useEffect(() => {\n    return () => {\n      terminatedRef.current = true;\n    };\n  }, []);\n\n  return {\n    run,\n    loading,\n    result,\n    error,\n    queueSize,\n    clearQueue,\n    terminate,\n  };\n}\n","/**\n * Opens IndexedDB and runs onupgradeneeded to create stores and indexes.\n * Singleton per (name, version).\n * @module indexedDB/openDB\n */\n\nimport type { IndexedDBConfig, TableSchema } from \"./types\";\n\nconst connectionCache = new Map<string, Promise<IDBDatabase>>();\n\n/**\n * Opens the database and creates/upgrades object stores and indexes from config.\n * Uses a singleton cache per (name, version); repeated calls with the same config reuse the same connection.\n */\nexport function openDB(config: IndexedDBConfig): Promise<IDBDatabase> {\n  const key = `${config.name}_v${config.version}`;\n  let promise = connectionCache.get(key);\n  if (promise) return promise;\n  promise = _openDB(config);\n  connectionCache.set(key, promise);\n  return promise;\n}\n\nfunction _openDB(config: IndexedDBConfig): Promise<IDBDatabase> {\n  return new Promise<IDBDatabase>((resolve, reject) => {\n    const request = indexedDB.open(config.name, config.version);\n    request.onerror = () =>\n      reject(request.error ?? new DOMException(\"Failed to open database\"));\n    request.onsuccess = () => resolve(request.result);\n    request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n      const db = (event.target as IDBOpenDBRequest).result;\n      const tables = config.tables;\n      for (const tableName of Object.keys(tables)) {\n        const schema = tables[tableName] as TableSchema;\n        if (!db.objectStoreNames.contains(tableName)) {\n          const store = db.createObjectStore(tableName, {\n            keyPath: schema.keyPath,\n            autoIncrement: schema.autoIncrement ?? false,\n          });\n          if (schema.indexes) {\n            for (const indexName of schema.indexes) {\n              store.createIndex(indexName, indexName, { unique: false });\n            }\n          }\n        }\n      }\n    };\n  });\n}\n","/**\n * Wraps an IDBRequest in a Promise.\n * @module indexedDB/requestToPromise\n */\n\n/**\n * Converts an IDBRequest to a Promise. Rejects with the request's error on failure.\n * @param request - Native IndexedDB request.\n * @returns Promise that resolves with the request result or rejects with DOMException.\n */\nexport function requestToPromise<T>(request: IDBRequest<T>): Promise<T> {\n  return new Promise<T>((resolve, reject) => {\n    request.onsuccess = () => resolve(request.result);\n    request.onerror = () =>\n      reject(request.error ?? new DOMException(\"Unknown IndexedDB error\"));\n  });\n}\n","/**\n * Table controller: insert, update, delete, exists, query, upsert, bulkInsert, clear, count.\n * Works in standalone mode (opens its own transaction per op) or bound to a transaction.\n * @module indexedDB/tableController\n */\n\nimport type { OperationCallbacks } from \"./types\";\nimport { requestToPromise } from \"./requestToPromise\";\n\n/** Runs optional callbacks and returns the result. */\nfunction withCallbacks<T>(\n  promise: Promise<T>,\n  options?: OperationCallbacks<T>\n): Promise<T> {\n  if (!options) return promise;\n  return promise\n    .then((result) => {\n      options.onSuccess?.(result);\n      return result;\n    })\n    .catch((err: DOMException) => {\n      options.onError?.(err);\n      throw err;\n    });\n}\n\n/**\n * Standalone table controller: opens a new transaction for each operation.\n */\nfunction createStandaloneController(\n  db: IDBDatabase,\n  tableName: string\n): ITableController {\n  function getStore(mode: IDBTransactionMode): IDBObjectStore {\n    const tx = db.transaction([tableName], mode);\n    return tx.objectStore(tableName);\n  }\n\n  return {\n    insert<T>(\n      data: T,\n      options?: OperationCallbacks<IDBValidKey>\n    ): Promise<IDBValidKey> {\n      const store = getStore(\"readwrite\");\n      return withCallbacks(requestToPromise(store.add(data)), options);\n    },\n\n    update<T>(\n      key: IDBValidKey,\n      updates: Partial<T>,\n      options?: OperationCallbacks<void>\n    ): Promise<void> {\n      const store = getStore(\"readwrite\");\n      const getReq = store.get(key);\n      return withCallbacks(\n        requestToPromise(getReq)\n          .then((existing) => {\n            if (existing === undefined) {\n              throw new DOMException(\"Key not found\", \"NotFoundError\");\n            }\n            const merged = { ...existing, ...updates } as T;\n            return requestToPromise(store.put(merged));\n          })\n          .then(() => undefined),\n        options\n      );\n    },\n\n    delete(\n      key: IDBValidKey,\n      options?: OperationCallbacks<void>\n    ): Promise<void> {\n      const store = getStore(\"readwrite\");\n      return withCallbacks(\n        requestToPromise(store.delete(key)).then(() => undefined),\n        options\n      );\n    },\n\n    exists(key: IDBValidKey): Promise<boolean> {\n      const store = getStore(\"readonly\");\n      return requestToPromise(store.getKey(key)).then((k) => k !== undefined);\n    },\n\n    query<T>(\n      filterFn: (item: T) => boolean,\n      options?: OperationCallbacks<T[]>\n    ): Promise<T[]> {\n      const store = getStore(\"readonly\");\n      const request = store.openCursor();\n      const results: T[] = [];\n      return withCallbacks(\n        new Promise<T[]>((resolve, reject) => {\n          request.onsuccess = () => {\n            const cursor = request.result;\n            if (cursor) {\n              if (filterFn(cursor.value as T)) results.push(cursor.value as T);\n              cursor.continue();\n            } else {\n              resolve(results);\n            }\n          };\n          request.onerror = () =>\n            reject(request.error ?? new DOMException(\"Unknown error\"));\n        }),\n        options\n      );\n    },\n\n    upsert<T>(\n      data: T,\n      options?: OperationCallbacks<IDBValidKey>\n    ): Promise<IDBValidKey> {\n      const store = getStore(\"readwrite\");\n      return withCallbacks(requestToPromise(store.put(data)), options);\n    },\n\n    bulkInsert<T>(\n      items: T[],\n      options?: OperationCallbacks<IDBValidKey[]>\n    ): Promise<IDBValidKey[]> {\n      const store = getStore(\"readwrite\");\n      const keys: IDBValidKey[] = [];\n      if (items.length === 0) {\n        return withCallbacks(Promise.resolve(keys), options);\n      }\n      let completed = 0;\n      const promise = new Promise<IDBValidKey[]>((resolve, reject) => {\n        const onDone = () => {\n          completed++;\n          if (completed === items.length) resolve(keys);\n        };\n        items.forEach((item, i) => {\n          const req = store.add(item);\n          req.onsuccess = () => {\n            keys[i] = req.result;\n            onDone();\n          };\n          req.onerror = () =>\n            reject(req.error ?? new DOMException(\"Unknown error\"));\n        });\n      });\n      return withCallbacks(promise, options);\n    },\n\n    clear(options?: OperationCallbacks<void>): Promise<void> {\n      const store = getStore(\"readwrite\");\n      return withCallbacks(\n        requestToPromise(store.clear()).then(() => undefined),\n        options\n      );\n    },\n\n    count(options?: OperationCallbacks<number>): Promise<number> {\n      const store = getStore(\"readonly\");\n      return withCallbacks(requestToPromise(store.count()), options ?? {});\n    },\n  };\n}\n\n/**\n * Transaction-scoped table controller: uses the given transaction (no new transaction).\n */\nfunction createTransactionController(\n  tx: IDBTransaction,\n  tableName: string\n): ITableController {\n  function getStore(): IDBObjectStore {\n    return tx.objectStore(tableName);\n  }\n\n  return {\n    insert<T>(\n      data: T,\n      options?: OperationCallbacks<IDBValidKey>\n    ): Promise<IDBValidKey> {\n      const store = getStore();\n      return withCallbacks(requestToPromise(store.add(data)), options);\n    },\n\n    update<T>(\n      key: IDBValidKey,\n      updates: Partial<T>,\n      options?: OperationCallbacks<void>\n    ): Promise<void> {\n      const store = getStore();\n      return withCallbacks(\n        requestToPromise(store.get(key))\n          .then((existing) => {\n            if (existing === undefined) {\n              throw new DOMException(\"Key not found\", \"NotFoundError\");\n            }\n            const merged = { ...existing, ...updates } as T;\n            return requestToPromise(store.put(merged));\n          })\n          .then(() => undefined),\n        options\n      );\n    },\n\n    delete(\n      key: IDBValidKey,\n      options?: OperationCallbacks<void>\n    ): Promise<void> {\n      const store = getStore();\n      return withCallbacks(\n        requestToPromise(store.delete(key)).then(() => undefined),\n        options\n      );\n    },\n\n    exists(key: IDBValidKey): Promise<boolean> {\n      const store = getStore();\n      return requestToPromise(store.getKey(key)).then((k) => k !== undefined);\n    },\n\n    query<T>(\n      filterFn: (item: T) => boolean,\n      options?: OperationCallbacks<T[]>\n    ): Promise<T[]> {\n      const store = getStore();\n      const request = store.openCursor();\n      const results: T[] = [];\n      return withCallbacks(\n        new Promise<T[]>((resolve, reject) => {\n          request.onsuccess = () => {\n            const cursor = request.result;\n            if (cursor) {\n              if (filterFn(cursor.value as T)) results.push(cursor.value as T);\n              cursor.continue();\n            } else {\n              resolve(results);\n            }\n          };\n          request.onerror = () =>\n            reject(request.error ?? new DOMException(\"Unknown error\"));\n        }),\n        options\n      );\n    },\n\n    upsert<T>(\n      data: T,\n      options?: OperationCallbacks<IDBValidKey>\n    ): Promise<IDBValidKey> {\n      const store = getStore();\n      return withCallbacks(requestToPromise(store.put(data)), options);\n    },\n\n    bulkInsert<T>(\n      items: T[],\n      options?: OperationCallbacks<IDBValidKey[]>\n    ): Promise<IDBValidKey[]> {\n      const store = getStore();\n      const keys: IDBValidKey[] = [];\n      if (items.length === 0) {\n        return withCallbacks(Promise.resolve(keys), options);\n      }\n      let completed = 0;\n      const promise = new Promise<IDBValidKey[]>((resolve, reject) => {\n        items.forEach((item, i) => {\n          const req = store.add(item);\n          req.onsuccess = () => {\n            keys[i] = req.result;\n            completed++;\n            if (completed === items.length) resolve(keys);\n          };\n          req.onerror = () =>\n            reject(req.error ?? new DOMException(\"Unknown error\"));\n        });\n      });\n      return withCallbacks(promise, options);\n    },\n\n    clear(options?: OperationCallbacks<void>): Promise<void> {\n      const store = getStore();\n      return withCallbacks(\n        requestToPromise(store.clear()).then(() => undefined),\n        options\n      );\n    },\n\n    count(options?: OperationCallbacks<number>): Promise<number> {\n      const store = getStore();\n      return withCallbacks(requestToPromise(store.count()), options ?? {});\n    },\n  };\n}\n\n/** Public interface for a table controller (standalone or transaction-scoped). */\nexport interface ITableController {\n  insert<T>(\n    data: T,\n    options?: OperationCallbacks<IDBValidKey>\n  ): Promise<IDBValidKey>;\n  update<T>(\n    key: IDBValidKey,\n    updates: Partial<T>,\n    options?: OperationCallbacks<void>\n  ): Promise<void>;\n  delete(key: IDBValidKey, options?: OperationCallbacks<void>): Promise<void>;\n  exists(key: IDBValidKey): Promise<boolean>;\n  query<T>(\n    filterFn: (item: T) => boolean,\n    options?: OperationCallbacks<T[]>\n  ): Promise<T[]>;\n  upsert<T>(\n    data: T,\n    options?: OperationCallbacks<IDBValidKey>\n  ): Promise<IDBValidKey>;\n  bulkInsert<T>(\n    items: T[],\n    options?: OperationCallbacks<IDBValidKey[]>\n  ): Promise<IDBValidKey[]>;\n  clear(options?: OperationCallbacks<void>): Promise<void>;\n  count(options?: OperationCallbacks<number>): Promise<number>;\n}\n\nexport function createTableController(\n  db: IDBDatabase,\n  tableName: string\n): ITableController {\n  return createStandaloneController(db, tableName);\n}\n\nexport function createTransactionTableController(\n  tx: IDBTransaction,\n  tableName: string\n): ITableController {\n  return createTransactionController(tx, tableName);\n}\n","/**\n * Preact hook for IndexedDB: open database, create stores/indexes, return a database controller.\n * Uses a singleton connection per (name, version).\n * @module useIndexedDB\n */\n\nimport { useState, useEffect, useRef } from \"preact/hooks\";\nimport type { IndexedDBConfig } from \"./indexedDB/types\";\nimport { openDB } from \"./indexedDB/openDB\";\nimport { createDBController } from \"./indexedDB/dbController\";\nimport type { IDBController } from \"./indexedDB/dbController\";\n\nexport type { IndexedDBConfig, IDBController } from \"./indexedDB\";\n\nexport interface UseIndexedDBReturn {\n  /** Database controller (table, transaction). Null until the database is open. */\n  db: IDBController | null;\n  /** True once the database is open and ready. */\n  isReady: boolean;\n  /** Error from opening the database, if any. */\n  error: DOMException | null;\n}\n\n/**\n * Opens an IndexedDB database and returns a controller for tables and transactions.\n * Handles onupgradeneeded: creates object stores and indexes from config.\n * Connection is a singleton per (config.name, config.version).\n *\n * @param config - Database name, version, and table schemas (keyPath, autoIncrement, indexes).\n * @returns { db, isReady, error }. Use db.table(name) and db.transaction(...) when isReady is true.\n *\n * @example\n * const { db, isReady, error } = useIndexedDB({\n *   name: 'my-db',\n *   version: 1,\n *   tables: {\n *     users: { keyPath: 'id', autoIncrement: true, indexes: ['email'] },\n *   },\n * })\n * if (isReady && db) {\n *   const users = db.table('users')\n *   await users.insert({ email: 'a@b.com' })\n *   await db.transaction(['users'], 'readwrite', (tx) => tx.table('users').insert({ email: 'b@b.com' }))\n * }\n */\nexport function useIndexedDB(config: IndexedDBConfig): UseIndexedDBReturn {\n  const [db, setDb] = useState<IDBController | null>(null);\n  const [error, setError] = useState<DOMException | null>(null);\n  const [isReady, setIsReady] = useState(false);\n  const configRef = useRef(config);\n  configRef.current = config;\n\n  useEffect(() => {\n    let cancelled = false;\n    setError(null);\n    setIsReady(false);\n    setDb(null);\n\n    const { name, version, tables } = configRef.current;\n    openDB({ name, version, tables })\n      .then((database) => {\n        if (cancelled) {\n          database.close();\n          return;\n        }\n        const controller = createDBController(database, configRef.current);\n        setDb(controller);\n        setIsReady(true);\n      })\n      .catch((err: DOMException) => {\n        if (!cancelled) setError(err);\n      });\n\n    return () => {\n      cancelled = true;\n    };\n  }, [config.name, config.version]);\n\n  return { db, isReady, error };\n}\n\n/*\n * Usage example:\n *\n * const { db, isReady, error } = useIndexedDB({\n *   name: 'my-app-db',\n *   version: 1,\n *   tables: {\n *     users: { keyPath: 'id', autoIncrement: true, indexes: ['email'] },\n *     settings: { keyPath: 'key' },\n *   },\n * })\n *\n * if (error) return <div>Failed to open database</div>\n * if (!isReady || !db) return <div>Loading...</div>\n *\n * const users = db.table('users')\n * await users.insert({ email: 'a@b.com', name: 'Alice' })\n * await users.update(1, { name: 'Alice Smith' })\n * const found = await users.query((u) => u.email.startsWith('a@'))\n * const n = await users.count()\n * await users.delete(1)\n * await users.upsert({ id: 2, email: 'b@b.com' })\n * await users.bulkInsert([{ email: 'c@b.com' }, { email: 'd@b.com' }])\n * await users.clear({ onSuccess: () => console.log('cleared') })\n *\n * await db.transaction(['users', 'settings'], 'readwrite', async (tx) => {\n *   await tx.table('users').insert({ email: 'e@b.com' })\n *   await tx.table('settings').upsert({ key: 'theme', value: 'dark' })\n * }, { onSuccess: () => console.log('transaction done') })\n */\n","/**\n * Database controller: table(name), transaction(storeNames, mode, callback, options).\n * @module indexedDB/dbController\n */\n\nimport type { IndexedDBConfig, TransactionOptions } from \"./types\";\nimport type { ITableController } from \"./tableController\";\nimport {\n  createTableController,\n  createTransactionTableController,\n} from \"./tableController\";\n\n/** Transaction context passed to the callback: provides table(name) bound to this transaction. */\nexport interface TransactionContext {\n  /** Returns a table controller bound to this transaction. Use for all ops inside the callback. */\n  table: (name: string) => ITableController;\n}\n\n/**\n * Database controller built from an open IDBDatabase.\n * Exposes table(name) and transaction(...).\n */\nexport interface IDBController {\n  /** Underlying IDBDatabase (read-only). */\n  readonly db: IDBDatabase;\n  /** Returns true if an object store with the given name exists. */\n  hasTable: (name: string) => boolean;\n  /** Returns a table controller for the given store (each op opens its own transaction). */\n  table: (name: string) => ITableController;\n  /**\n   * Runs a callback inside a single transaction. All operations in the callback use the same transaction.\n   * @param storeNames - Object store names to include in the transaction.\n   * @param mode - 'readonly' | 'readwrite'.\n   * @param callback - Async or sync function receiving { table(name) }. Return value is ignored; await all ops inside.\n   * @param options - Optional onSuccess/onError callbacks.\n   * @returns Promise that resolves when the transaction completes (after all requests and the callback).\n   */\n  transaction: <T = void>(\n    storeNames: string[],\n    mode: IDBTransactionMode,\n    callback: (tx: TransactionContext) => T | Promise<T>,\n    options?: TransactionOptions\n  ) => Promise<void>;\n}\n\nfunction withTransactionCallbacks(\n  promise: Promise<void>,\n  options?: TransactionOptions\n): Promise<void> {\n  if (!options) return promise;\n  return promise\n    .then(() => options.onSuccess?.())\n    .catch((err: DOMException) => {\n      options.onError?.(err);\n      throw err;\n    });\n}\n\n/**\n * Creates a database controller from an open IDBDatabase instance.\n */\nexport function createDBController(\n  db: IDBDatabase,\n  _config: IndexedDBConfig\n): IDBController {\n  void _config; // Reserved for future config options\n  return {\n    get db(): IDBDatabase {\n      return db;\n    },\n\n    hasTable(name: string): boolean {\n      return db.objectStoreNames.contains(name);\n    },\n\n    table(name: string): ITableController {\n      return createTableController(db, name);\n    },\n\n    transaction<T = void>(\n      storeNames: string[],\n      mode: IDBTransactionMode,\n      callback: (tx: TransactionContext) => T | Promise<T>,\n      options?: TransactionOptions\n    ): Promise<void> {\n      const tx = db.transaction(storeNames, mode);\n      const txContext: TransactionContext = {\n        table: (tableName: string) =>\n          createTransactionTableController(tx, tableName),\n      };\n      const txPromise = new Promise<void>((resolve, reject) => {\n        tx.oncomplete = () => resolve();\n        tx.onerror = () =>\n          reject(tx.error ?? new DOMException(\"Transaction failed\"));\n      });\n      const callbackResult = callback(txContext);\n      const promise = Promise.resolve(callbackResult).then(() => txPromise);\n      return withTransactionCallbacks(promise, options);\n    },\n  };\n}\n","/**\n * useWebRTCIP – detect local/public IPs via WebRTC ICE candidates and STUN.\n * Not highly reliable; use as first-priority hint and fall back to a public IP API (e.g. ipapi.co) if needed.\n * @module useWebRTCIP\n */\n\nimport { useEffect, useState, useRef } from \"preact/hooks\";\n\n/** IPv4 regex for ICE candidate strings (captures dotted-decimal). */\nconst IPV4_REGEX =\n  /\\b(?:25[0-5]|2[0-4]\\d|1?\\d{1,2})(?:\\.(?:25[0-5]|2[0-4]\\d|1?\\d{1,2})){3}\\b/g;\n\nconst DEFAULT_STUN_SERVERS: string[] = [\"stun:stun.l.google.com:19302\"];\nconst DEFAULT_TIMEOUT_MS = 3000;\n\nexport interface UseWebRTCIPOptions {\n  /** STUN server URLs (default: Google STUN). */\n  stunServers?: string[];\n  /** Stop gathering after this many ms (default: 3000). */\n  timeout?: number;\n  /** Called once per newly detected IP (no duplicates). */\n  onDetect?: (ip: string) => void;\n}\n\nexport interface UseWebRTCIPReturn {\n  /** Unique IPv4 addresses found from ICE candidates. */\n  ips: string[];\n  /** True while ICE gathering is in progress. */\n  loading: boolean;\n  /** Error message if WebRTC is unavailable or detection fails. */\n  error: string | null;\n}\n\nfunction isSSR(): boolean {\n  return typeof window === \"undefined\";\n}\n\nfunction isWebRTCAvailable(): boolean {\n  return typeof RTCPeerConnection !== \"undefined\";\n}\n\n/**\n * Extracts IPv4 addresses from an ICE candidate string.\n * Filters out common non-public/local patterns (e.g. 0.0.0.0) if desired; currently returns all matches.\n */\nfunction extractIPv4FromCandidate(candidate: string): string[] {\n  const matches = candidate.match(IPV4_REGEX);\n  return matches ? [...matches] : [];\n}\n\n/**\n * Attempts to detect client IP addresses using WebRTC ICE candidates and a STUN server.\n * Works frontend-only (no backend). Not guaranteed to return a public IP; use as a hint and\n * fall back to a public IP API (e.g. ipapi.co, ip-api.com) if you need reliability.\n *\n * @param options - Optional: stunServers, timeout (ms), onDetect(ip) callback.\n * @returns { ips, loading, error } – unique IPv4s, loading flag, and error message.\n *\n * @example\n * const { ips, loading, error } = useWebRTCIP({\n *   timeout: 5000,\n *   onDetect: (ip) => console.log('Detected:', ip),\n * })\n * // If ips is empty and error is set, fall back to: fetch('https://api.ipify.org?format=json')\n */\nexport function useWebRTCIP(\n  options: UseWebRTCIPOptions = {}\n): UseWebRTCIPReturn {\n  const {\n    stunServers = DEFAULT_STUN_SERVERS,\n    timeout: timeoutMs = DEFAULT_TIMEOUT_MS,\n    onDetect,\n  } = options;\n\n  const [ips, setIps] = useState<string[]>([]);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState<string | null>(null);\n\n  const pcRef = useRef<RTCPeerConnection | null>(null);\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n  const reportedRef = useRef<Set<string>>(new Set());\n  const onDetectRef = useRef(onDetect);\n  onDetectRef.current = onDetect;\n\n  useEffect(() => {\n    if (isSSR()) {\n      setLoading(false);\n      setError(\"WebRTC IP detection is not available during SSR\");\n      return;\n    }\n\n    if (!isWebRTCAvailable()) {\n      setLoading(false);\n      setError(\"RTCPeerConnection is not available\");\n      return;\n    }\n\n    const reported = new Set<string>();\n    reportedRef.current = reported;\n\n    const finish = () => {\n      if (timeoutRef.current) {\n        clearTimeout(timeoutRef.current);\n        timeoutRef.current = null;\n      }\n      if (pcRef.current) {\n        pcRef.current.close();\n        pcRef.current = null;\n      }\n      setLoading(false);\n    };\n\n    const addIP = (ip: string) => {\n      if (reported.has(ip)) return;\n      reported.add(ip);\n      setIps((prev) => {\n        const next = [...prev, ip];\n        return next;\n      });\n      onDetectRef.current?.(ip);\n    };\n\n    try {\n      const pc = new RTCPeerConnection({\n        iceServers: [{ urls: stunServers }],\n      });\n      pcRef.current = pc;\n\n      pc.onicecandidate = (event) => {\n        const c = event.candidate;\n        if (!c || !c.candidate) return;\n        const found = extractIPv4FromCandidate(c.candidate);\n        found.forEach(addIP);\n      };\n\n      pc.createDataChannel(\"\");\n\n      pc.createOffer()\n        .then((offer) => pc.setLocalDescription(offer))\n        .catch((err) => {\n          setError(\n            err instanceof Error ? err.message : \"Failed to create offer\"\n          );\n          finish();\n        });\n\n      timeoutRef.current = setTimeout(() => finish(), timeoutMs);\n    } catch (err) {\n      setError(err instanceof Error ? err.message : \"WebRTC setup failed\");\n      finish();\n    }\n\n    return () => {\n      finish();\n    };\n  }, [stunServers.join(\",\"), timeoutMs]);\n\n  return { ips, loading, error };\n}\n\n/*\n * Example usage (Preact component):\n *\n * function MyIPDisplay() {\n *   const { ips, loading, error } = useWebRTCIP({\n *     timeout: 4000,\n *     onDetect: (ip) => { / * optional: e.g. send to analytics * / },\n *   })\n *\n *   if (loading) return <p>Detecting IP…</p>\n *   if (error) return <p>WebRTC failed: {error}. Try fallback API.</p>\n *   return <p>IPs (WebRTC): {ips.join(', ') || 'None'}</p>\n * }\n *\n * Fallback to public IP API when WebRTC fails or returns empty:\n *   const [apiIP, setApiIP] = useState<string | null>(null)\n *   useEffect(() => {\n *     if (!loading && ips.length === 0 && error)\n *       fetch('https://api.ipify.org?format=json').then(r => r.json()).then(d => setApiIP(d.ip))\n *   }, [loading, ips.length, error])\n */\n","/**\n * useWasmCompute – run WebAssembly computation off the main thread via a Web Worker.\n * Flow: Preact Component → useWasmCompute() → Web Worker → WASM Module → Return result.\n * @module useWasmCompute\n */\n\nimport { useState, useCallback, useRef, useEffect } from \"preact/hooks\";\n\nconst WASM_WORKER_SCRIPT = `\nself.onmessage = async (e) => {\n  const d = e.data;\n  if (d.type === 'init') {\n    try {\n      const res = await fetch(d.wasmUrl);\n      const buf = await res.arrayBuffer();\n      const mod = await WebAssembly.instantiate(buf, d.importObject || {});\n      self.wasmInstance = mod.instance;\n      self.exportName = d.exportName || 'compute';\n      self.postMessage({ type: 'ready' });\n    } catch (err) {\n      self.postMessage({ type: 'error', error: (err && err.message) || String(err) });\n    }\n    return;\n  }\n  if (d.type === 'compute') {\n    try {\n      const fn = self.wasmInstance.exports[self.exportName];\n      if (typeof fn !== 'function') {\n        self.postMessage({ type: 'error', error: 'Export \"' + self.exportName + '\" is not a function' });\n        return;\n      }\n      const result = fn(d.input);\n      self.postMessage({ type: 'result', result: result });\n    } catch (err) {\n      self.postMessage({ type: 'error', error: (err && err.message) || String(err) });\n    }\n  }\n};\n`;\n\nexport interface UseWasmComputeOptions {\n  /** URL of the .wasm module to load in the worker. */\n  wasmUrl: string;\n  /** Name of the exported function to call for compute (default: 'compute'). */\n  exportName?: string;\n  /** Optional custom worker script URL. If provided, worker must handle init (wasmUrl, exportName) and compute(input) messages. */\n  workerUrl?: string;\n  /** Optional import object for WebAssembly.instantiate (only used when using default inline worker; must be serializable). */\n  importObject?: WebAssembly.Imports;\n}\n\nexport interface UseWasmComputeReturn<TInput = number, TResult = number> {\n  /** Invoke the WASM export with the given input. Resolves with the return value when ready. */\n  compute: (input: TInput) => Promise<TResult>;\n  /** Last result from a successful compute call. */\n  result: TResult | undefined;\n  /** True while WASM is loading or a compute is in progress. */\n  loading: boolean;\n  /** Error message if environment is unsupported, init failed, or compute failed. */\n  error: string | null;\n  /** True when the WASM module is loaded and compute can be called. */\n  ready: boolean;\n}\n\nfunction isSSR(): boolean {\n  return typeof window === \"undefined\";\n}\n\nfunction isWorkerSupported(): boolean {\n  return typeof Worker !== \"undefined\";\n}\n\nfunction isWebAssemblySupported(): boolean {\n  return (\n    typeof WebAssembly !== \"undefined\" &&\n    typeof WebAssembly.instantiate === \"function\"\n  );\n}\n\nfunction createWorker(workerUrl?: string): Worker {\n  if (workerUrl) {\n    return new Worker(workerUrl);\n  }\n  const blob = new Blob([WASM_WORKER_SCRIPT], {\n    type: \"application/javascript\",\n  });\n  const url = URL.createObjectURL(blob);\n  const w = new Worker(url);\n  URL.revokeObjectURL(url);\n  return w;\n}\n\n/**\n * Runs WebAssembly computation in a Web Worker. Validates environment (browser, Worker, WebAssembly)\n * and returns a stable compute function plus result/loading/error/ready state.\n *\n * @param options - wasmUrl, optional exportName, optional workerUrl, optional importObject.\n * @returns { compute, result, loading, error, ready }.\n *\n * @example\n * const { compute, result, loading, error, ready } = useWasmCompute({ wasmUrl: '/add.wasm', exportName: 'add' });\n * // When ready: compute(2).then(sum => ...); result will update with the last return value.\n */\nexport function useWasmCompute<TInput = number, TResult = number>(\n  options: UseWasmComputeOptions\n): UseWasmComputeReturn<TInput, TResult> {\n  const { wasmUrl, exportName = \"compute\", workerUrl, importObject } = options;\n\n  const [result, setResult] = useState<TResult | undefined>(undefined);\n  const [loading, setLoading] = useState(true);\n  const [error, setError] = useState<string | null>(null);\n  const [ready, setReady] = useState(false);\n\n  const workerRef = useRef<Worker | null>(null);\n  const pendingResolveRef = useRef<((value: TResult) => void) | null>(null);\n  const pendingRejectRef = useRef<((reason: Error) => void) | null>(null);\n\n  useEffect(() => {\n    if (isSSR()) {\n      setError(\"useWasmCompute is not available during SSR\");\n      setLoading(false);\n      return;\n    }\n    if (!isWorkerSupported()) {\n      setError(\"Worker is not supported in this environment\");\n      setLoading(false);\n      return;\n    }\n    if (!isWebAssemblySupported()) {\n      setError(\"WebAssembly is not supported in this environment\");\n      setLoading(false);\n      return;\n    }\n\n    setError(null);\n    setReady(false);\n    const worker = createWorker(workerUrl);\n    workerRef.current = worker;\n\n    const onMessage = (e: MessageEvent) => {\n      const { type, result: msgResult, error: msgError } = e.data ?? {};\n      if (type === \"ready\") {\n        setReady(true);\n        setLoading(false);\n        return;\n      }\n      if (type === \"error\") {\n        setError(msgError ?? \"Unknown error\");\n        setLoading(false);\n        if (pendingRejectRef.current) {\n          pendingRejectRef.current(new Error(msgError));\n          pendingResolveRef.current = null;\n          pendingRejectRef.current = null;\n        }\n        return;\n      }\n      if (type === \"result\") {\n        setResult(msgResult);\n        setLoading(false);\n        if (pendingResolveRef.current) {\n          pendingResolveRef.current(msgResult);\n          pendingResolveRef.current = null;\n          pendingRejectRef.current = null;\n        }\n      }\n    };\n\n    worker.addEventListener(\"message\", onMessage);\n    worker.postMessage({\n      type: \"init\",\n      wasmUrl,\n      exportName,\n      importObject: importObject ?? {},\n    });\n\n    return () => {\n      worker.removeEventListener(\"message\", onMessage);\n      worker.terminate();\n      workerRef.current = null;\n      if (pendingRejectRef.current) {\n        pendingRejectRef.current(new Error(\"Worker terminated\"));\n        pendingResolveRef.current = null;\n        pendingRejectRef.current = null;\n      }\n    };\n  }, [wasmUrl, exportName, workerUrl, importObject]);\n\n  const compute = useCallback(\n    (input: TInput): Promise<TResult> => {\n      return new Promise((resolve, reject) => {\n        if (!workerRef.current || !ready) {\n          reject(new Error(\"WASM not ready\"));\n          return;\n        }\n        if (error) {\n          reject(new Error(error));\n          return;\n        }\n        pendingResolveRef.current = resolve;\n        pendingRejectRef.current = reject;\n        setLoading(true);\n        workerRef.current.postMessage({ type: \"compute\", input });\n      });\n    },\n    [ready, error]\n  );\n\n  return { compute, result, loading, error, ready };\n}\n","/**\n * useWorkerNotifications – listen to worker messages and maintain running state, counts, history, and derived stats.\n * @module useWorkerNotifications\n */\n\nimport { useState, useRef, useEffect, useMemo } from \"preact/hooks\";\n\n/** Supported worker event types for tracking. Worker should postMessage with these shapes. */\nexport type WorkerEventType =\n  | \"task_start\"\n  | \"task_end\"\n  | \"task_fail\"\n  | \"queue_size\";\n\nexport interface WorkerNotificationEvent {\n  type: WorkerEventType;\n  taskId?: string;\n  duration?: number;\n  error?: string;\n  size?: number;\n  timestamp: number;\n}\n\nexport interface UseWorkerNotificationsOptions {\n  /** Max events to keep in history. Default 100. */\n  maxHistory?: number;\n  /** Window in ms for throughput calculation (completed per second). Default 1000. */\n  throughputWindowMs?: number;\n}\n\nexport interface UseWorkerNotificationsReturn {\n  /** Task IDs currently running (received task_start, not yet task_end/task_fail). */\n  runningTasks: string[];\n  /** Total tasks that completed successfully. */\n  completedCount: number;\n  /** Total tasks that failed. */\n  failedCount: number;\n  /** Recent events (oldest first), capped at maxHistory. */\n  eventHistory: WorkerNotificationEvent[];\n  /** Average task duration in ms (from task_end events that include duration). */\n  averageDurationMs: number;\n  /** Completed tasks per second over the throughput window. */\n  throughputPerSecond: number;\n  /** Last reported queue size (from queue_size events); 0 if never sent. */\n  currentQueueSize: number;\n  /** Default view: all active worker data and progress in one object. */\n  progress: {\n    runningTasks: string[];\n    completedCount: number;\n    failedCount: number;\n    averageDurationMs: number;\n    throughputPerSecond: number;\n    currentQueueSize: number;\n    totalProcessed: number;\n    recentEventCount: number;\n  };\n}\n\nfunction parseMessage(data: unknown): WorkerNotificationEvent | null {\n  if (data == null || typeof data !== \"object\") return null;\n  const d = data as Record<string, unknown>;\n  const type = d.type as string;\n  if (\n    type !== \"task_start\" &&\n    type !== \"task_end\" &&\n    type !== \"task_fail\" &&\n    type !== \"queue_size\"\n  ) {\n    return null;\n  }\n  const taskId = typeof d.taskId === \"string\" ? d.taskId : undefined;\n  const duration = typeof d.duration === \"number\" ? d.duration : undefined;\n  const error = typeof d.error === \"string\" ? d.error : undefined;\n  const size = typeof d.size === \"number\" ? d.size : undefined;\n  return {\n    type: type as WorkerEventType,\n    taskId,\n    duration,\n    error,\n    size,\n    timestamp: Date.now(),\n  };\n}\n\n/**\n * Listens to a Worker's messages and maintains state: running tasks, completed/failed counts,\n * event history, execution time per task, average duration, throughput per second, and queue size.\n * Worker should postMessage with: { type: 'task_start'|'task_end'|'task_fail'|'queue_size', taskId?, duration?, error?, size? }.\n *\n * @param worker - The Worker instance to listen to, or null/undefined to listen to nothing.\n * @param options - Optional maxHistory and throughputWindowMs.\n * @returns State and derived stats plus a default progress object.\n */\nexport function useWorkerNotifications(\n  worker: Worker | null | undefined,\n  options: UseWorkerNotificationsOptions = {}\n): UseWorkerNotificationsReturn {\n  const { maxHistory = 100, throughputWindowMs = 1000 } = options;\n\n  const [runningTasks, setRunningTasks] = useState<string[]>([]);\n  const [completedCount, setCompletedCount] = useState(0);\n  const [failedCount, setFailedCount] = useState(0);\n  const [eventHistory, setEventHistory] = useState<WorkerNotificationEvent[]>(\n    []\n  );\n  const [currentQueueSize, setCurrentQueueSize] = useState(0);\n\n  const completedTimestampsRef = useRef<number[]>([]);\n  const durationSumRef = useRef(0);\n  const durationCountRef = useRef(0);\n\n  useEffect(() => {\n    if (!worker) return;\n\n    const onMessage = (e: MessageEvent) => {\n      const ev = parseMessage(e.data);\n      if (!ev) return;\n\n      setEventHistory((prev) => {\n        const next = [...prev, ev].slice(-maxHistory);\n        return next;\n      });\n\n      if (ev.type === \"task_start\" && ev.taskId) {\n        setRunningTasks((prev) =>\n          prev.includes(ev.taskId!) ? prev : [...prev, ev.taskId!]\n        );\n      } else if (ev.type === \"task_end\") {\n        if (ev.taskId) {\n          setRunningTasks((prev) => prev.filter((id) => id !== ev.taskId));\n        }\n        setCompletedCount((c) => c + 1);\n        const cutoff = Date.now() - throughputWindowMs;\n        completedTimestampsRef.current = [\n          ...completedTimestampsRef.current.filter((t) => t >= cutoff),\n          ev.timestamp,\n        ];\n        if (typeof ev.duration === \"number\") {\n          durationSumRef.current += ev.duration;\n          durationCountRef.current += 1;\n        }\n      } else if (ev.type === \"task_fail\") {\n        if (ev.taskId) {\n          setRunningTasks((prev) => prev.filter((id) => id !== ev.taskId));\n        }\n        setFailedCount((c) => c + 1);\n      } else if (ev.type === \"queue_size\" && typeof ev.size === \"number\") {\n        setCurrentQueueSize(ev.size);\n      }\n    };\n\n    worker.addEventListener(\"message\", onMessage);\n    return () => worker.removeEventListener(\"message\", onMessage);\n  }, [worker, maxHistory]);\n\n  const averageDurationMs = useMemo(() => {\n    const count = durationCountRef.current;\n    const sum = durationSumRef.current;\n    return count > 0 ? sum / count : 0;\n  }, [eventHistory]);\n\n  const throughputPerSecond = useMemo(() => {\n    const now = Date.now();\n    const cutoff = now - throughputWindowMs;\n    const timestamps = completedTimestampsRef.current.filter(\n      (t) => t >= cutoff\n    );\n    return timestamps.length / (throughputWindowMs / 1000);\n  }, [eventHistory, throughputWindowMs]);\n\n  const progress = useMemo(\n    () => ({\n      runningTasks,\n      completedCount,\n      failedCount,\n      averageDurationMs,\n      throughputPerSecond,\n      currentQueueSize,\n      totalProcessed: completedCount + failedCount,\n      recentEventCount: eventHistory.length,\n    }),\n    [\n      runningTasks,\n      completedCount,\n      failedCount,\n      averageDurationMs,\n      throughputPerSecond,\n      currentQueueSize,\n      eventHistory.length,\n    ]\n  );\n\n  return {\n    runningTasks,\n    completedCount,\n    failedCount,\n    eventHistory,\n    averageDurationMs,\n    throughputPerSecond,\n    currentQueueSize,\n    progress,\n  };\n}\n"],"names":["useTransition","isPending","setIsPending","useState","useCallback","callback","Promise","resolve","then","useMutationObserver","targetRef","options","useEffect","node","current","observer","MutationObserver","observe","disconnect","listeners","Map","useEventBus","emit","event","args","handlers","get","forEach","handler","on","Set","set","add","delete","size","useWrappedChildren","children","injectProps","mergeStrategy","useMemo","enhanceChild","child","isValidElement","existingProps","props","mergedProps","_extends","existingStyle","style","injectStyle","cloneElement","Array","isArray","map","usePreferredTheme","theme","setTheme","window","darkQuery","matchMedia","lightQuery","matches","mediaQuery","handleChange","e","updateTheme","addEventListener","removeEventListener","getNetworkState","navigator","online","state","onLine","connection","undefined","effectiveType","downlink","rtt","saveData","type","connectionType","useNetworkState","setState","updateState","useClipboard","resetDelay","copied","setCopied","error","setError","reset","copy","async","clipboard","err","Error","writeText","text","setTimeout","String","paste","readText","useRageClick","onRageClick","threshold","timeWindow","distanceThreshold","onRageClickRef","useRef","clicksRef","handleClick","now","Date","record","time","x","clientX","y","clientY","cutoff","recent","filter","c","push","Infinity","inRange","distance","a","b","Math","hypot","length","count","useThreadedWorker","workerFn","mode","concurrency","maxConcurrent","max","loading","setLoading","result","setResult","queueSize","setQueueSize","queueRef","sequenceRef","activeCountRef","terminatedRef","workerFnRef","updateQueueSize","processNext","sort","priority","sequence","task","shift","fn","data","value","catch","reject","finally","run","runOptions","_runOptions$priority","promise","queueMicrotask","clearQueue","pending","t","terminate","connectionCache","requestToPromise","request","onsuccess","onerror","_request$error","DOMException","withCallbacks","onSuccess","onError","useIndexedDB","config","db","setDb","isReady","setIsReady","configRef","cancelled","name","version","tables","key","indexedDB","open","onupgradeneeded","target","tableName","Object","keys","schema","objectStoreNames","contains","_schema$autoIncrement","store","createObjectStore","keyPath","autoIncrement","indexes","indexName","createIndex","unique","_openDB","openDB","database","close","controller","hasTable","table","getStore","transaction","objectStore","insert","update","updates","existing","merged","put","exists","getKey","k","query","filterFn","openCursor","results","cursor","continue","upsert","bulkInsert","items","completed","item","i","req","_req$error","clear","createStandaloneController","createTableController","storeNames","tx","txContext","_request$error2","_req$error2","createTransactionController","createTransactionTableController","txPromise","oncomplete","_tx$error","callbackResult","withTransactionCallbacks","createDBController","IPV4_REGEX","DEFAULT_STUN_SERVERS","DEFAULT_TIMEOUT_MS","useWebRTCIP","stunServers","timeout","timeoutMs","onDetect","ips","setIps","pcRef","timeoutRef","reportedRef","onDetectRef","RTCPeerConnection","reported","finish","clearTimeout","addIP","ip","has","prev","pc","iceServers","urls","onicecandidate","candidate","match","extractIPv4FromCandidate","createDataChannel","createOffer","offer","setLocalDescription","message","join","useWasmCompute","wasmUrl","exportName","workerUrl","importObject","ready","setReady","workerRef","pendingResolveRef","pendingRejectRef","Worker","WebAssembly","instantiate","worker","blob","Blob","url","URL","createObjectURL","w","revokeObjectURL","createWorker","onMessage","_e$data","msgResult","msgError","postMessage","compute","input","useWorkerNotifications","maxHistory","throughputWindowMs","runningTasks","setRunningTasks","completedCount","setCompletedCount","failedCount","setFailedCount","eventHistory","setEventHistory","currentQueueSize","setCurrentQueueSize","completedTimestampsRef","durationSumRef","durationCountRef","ev","taskId","duration","timestamp","parseMessage","slice","includes","id","averageDurationMs","throughputPerSecond","progress","totalProcessed","recentEventCount"],"mappings":"2JAMgB,SAAAA,IAId,MAAOC,EAAWC,GAAgBC,GAAS,GAU3C,MAAO,CARiBC,EAAaC,IACnCH,GAAa,GACbI,QAAQC,UAAUC,KAAK,KACrBH,IACAH,GAAa,MAEd,IAEsBD,EAC3B,CCVgB,SAAAQ,EACdC,EACAL,EACAM,GAEAC,EAAU,KACR,MAAMC,EAAOH,EAAUI,QACvB,IAAKD,EAAM,OAEX,MAAME,EAAW,IAAIC,iBAAiBX,GAGtC,OAFAU,EAASE,QAAQJ,EAAMF,GAEhB,IAAMI,EAASG,cACrB,CAACR,EAAWL,EAAUM,GAC3B,CCrBA,MAAMQ,EAAY,IAAIC,aAMNC,IA2Bd,MAAO,CAAEC,KA1BIlB,EACX,CAAoBmB,KAAaC,KAC/B,MAAMC,EAAWN,EAAUO,IAAIH,GAC3BE,GACFA,EAASE,QAASC,GAAYA,KAAWJ,KAG7C,IAmBaK,GAhBJzB,EAAY,CAAoBmB,EAAUK,KACnD,IAAIH,EAAWN,EAAUO,IAAIH,GAO7B,OANKE,IACHA,EAAW,IAAIK,IACfX,EAAUY,IAAIR,EAAiBE,IAEjCA,EAASO,IAAIJ,GAEN,KACLH,EAAUQ,OAAOL,GACM,IAAnBH,EAAUS,MACZf,EAAUc,OAAOV,KAGpB,IAGL,yNCtBgB,SAAAY,EACdC,EACAC,EACAC,EAAyC,YAEzC,OAAOC,EAAQ,KACb,IAAKH,EAAU,OAAOA,EAEtB,MAAMI,EAAgBC,IACpB,IAAKC,EAAeD,GAAQ,OAAOA,EAEnC,MAAME,EAAiBF,EAAgBG,OAAS,CAAA,EAEhD,IAAIC,EAIFA,EAFoB,aAAlBP,EAESQ,KAAQH,EAAkBN,GAG1BS,EAAQT,GAAAA,EAAgBM,GAIrC,MAAMI,EAAiBJ,MAAAA,OAAAA,EAAAA,EAAkCK,MACnDC,EAA6C,MAA9BZ,OAA8B,EAA9BA,EAAgCW,MAqBrD,OAlBED,GACAE,GACyB,iBAAlBF,GACgB,iBAAhBE,IAGJJ,EAA+BG,MADZ,aAAlBV,EACmCQ,EAChCC,CAAAA,EAAAA,EACAE,GAGgCH,EAAA,CAAA,EAChCG,EACAF,IAKFG,EAAaT,EAAOI,IAG7B,OAAIM,MAAMC,QAAQhB,GACTA,EAASiB,IAAIb,GAGfA,EAAaJ,IACnB,CAACA,EAAUC,EAAaC,GAC7B,UChDgBgB,IACd,MAAOC,EAAOC,GAAYrD,EAAyB,KACjD,GAAsB,oBAAXsD,OAAwB,MAAO,gBAE1C,MAAMC,EAAYD,OAAOE,WAAW,gCAC9BC,EAAaH,OAAOE,WAAW,iCAErC,OAAID,EAAUG,QAAgB,OAC1BD,EAAWC,QAAgB,QACxB,kBAkCT,OA/BAjD,EAAU,KACR,GAAsB,oBAAX6C,OAAwB,OAEnC,MAAMK,EAAaL,OAAOE,WAAW,gCAE/BI,EAAgBC,IACpBR,EAASQ,EAAEH,QAAU,OAAS,UAI1BI,EAAcA,KAClB,MAAMP,EAAYD,OAAOE,WAAW,gCAC9BC,EAAaH,OAAOE,WAAW,iCAEdH,EAAnBE,EAAUG,QAAkB,OACvBD,EAAWC,QAAkB,QACxB,kBAGhBC,EAAWI,iBAAiB,SAAUH,GAGtC,MAAMH,EAAaH,OAAOE,WAAW,iCAGrC,OAFAC,EAAWM,iBAAiB,SAAUD,GAE/B,KACLH,EAAWK,oBAAoB,SAAUJ,GACzCH,EAAWO,oBAAoB,SAAUF,KAE1C,IAEIV,CACT,CC3BA,SAASa,IACP,GAAyB,oBAAdC,UACT,MAAO,CAAEC,QAAQ,GAGnB,MAAMC,EAAsB,CAC1BD,OAAQD,UAAUG,QAGdC,EACJJ,UACAI,WAoBF,OAlBIA,SAC+BC,IAA7BD,EAAWE,gBACbJ,EAAMI,cAAgBF,EAAWE,oBAEPD,IAAxBD,EAAWG,WACbL,EAAMK,SAAWH,EAAWG,eAEPF,IAAnBD,EAAWI,MACbN,EAAMM,IAAMJ,EAAWI,UAEGH,IAAxBD,EAAWK,WACbP,EAAMO,SAAWL,EAAWK,eAENJ,IAApBD,EAAWM,OACbR,EAAMS,eAAiBP,EAAWM,OAI/BR,CACT,UAuBgBU,IACd,MAAOV,EAAOW,GAAY/E,EAAuBiE,GA0BjD,OAxBAxD,EAAU,KACR,GAAsB,oBAAX6C,OAAwB,OAEnC,MAAM0B,EAAcA,IAAMD,EAASd,KAEnCX,OAAOS,iBAAiB,SAAUiB,GAClC1B,OAAOS,iBAAiB,UAAWiB,GAEnC,MAAMV,EACJJ,UACAI,WAKF,OAJIA,MAAAA,GAAAA,EAAYP,kBACdO,EAAWP,iBAAiB,SAAUiB,GAGjC,KACL1B,OAAOU,oBAAoB,SAAUgB,GACrC1B,OAAOU,oBAAoB,UAAWgB,GAClCV,MAAAA,GAAAA,EAAYN,qBACdM,EAAWN,oBAAoB,SAAUgB,KAG5C,IAEIZ,CACT,CCpFgB,SAAAa,EACdzE,EAA+B,CAAE,GAEjC,MAAM0E,WAAEA,EAAa,KAAS1E,GAEvB2E,EAAQC,GAAapF,GAAS,IAC9BqF,EAAOC,GAAYtF,EAAuB,MAE3CuF,EAAQtF,EAAY,KACxBmF,GAAU,GACVE,EAAS,OACR,IA+CH,MAAO,CAAEE,KA7CIvF,EACXwF,UAGE,GAFAH,EAAS,MAEgB,oBAAdpB,YAA8BA,UAAUwB,UAAW,CAC5D,MAAMC,EAAM,IAAIC,MAAM,kCAEtB,OADAN,EAASK,KAEX,CAEA,IAME,aALMzB,UAAUwB,UAAUG,UAAUC,GACpCV,GAAU,GACNF,EAAa,GACfa,WAAW,IAAMX,GAAU,GAAQF,IAGvC,CAAA,CAAE,MAAOrB,GACP,MAAM8B,EAAM9B,aAAa+B,MAAQ/B,EAAI,IAAI+B,MAAMI,OAAOnC,IAEtD,OADAyB,EAASK,IACF,CACT,GAEF,CAACT,IAsBYe,MAnBDhG,EAAYwF,UAGxB,GAFAH,EAAS,MAEgB,oBAAdpB,YAA8BA,UAAUwB,UAAW,CAC5D,MAAMC,EAAM,IAAIC,MAAM,kCAEtB,OADAN,EAASK,GACF,EACT,CAEA,IAEE,aADmBzB,UAAUwB,UAAUQ,UAEzC,CAAE,MAAOrC,GACP,MAAM8B,EAAM9B,aAAa+B,MAAQ/B,EAAI,IAAI+B,MAAMI,OAAOnC,IAEtD,OADAyB,EAASK,GACF,EACT,GACC,IAEmBR,SAAQE,QAAOE,QACvC,CChDgB,SAAAY,EACd5F,EACAC,GAEA,MAAM4F,YACJA,EAAWC,UACXA,EAAY,EAACC,WACbA,EAAa,IAAIC,kBACjBA,EAAoB,IAClB/F,EAEEgG,EAAiBC,EAAOL,GAC9BI,EAAe7F,QAAUyF,EAEzB,MAAMM,EAAYD,EAAsB,IAExChG,EAAU,KACR,MAAMC,EAAOH,EAAUI,QACvB,IAAKD,EAAM,OAEX,MAAMiG,EAAe9C,IACnB,MAAM+C,EAAMC,KAAKD,MACXE,EAAsB,CAAEC,KAAMH,EAAKI,EAAGnD,EAAEoD,QAASC,EAAGrD,EAAEsD,SAGtDC,EAASR,EAAMN,EACfe,EAFSX,EAAU/F,QAEH2G,OAAQC,GAAMA,EAAER,MAAQK,GAG9C,GAFAC,EAAOG,KAAKV,GAEcW,WAAtBlB,EAAgC,CAClC,MAAMmB,EAAUL,EAAOC,OACpBC,IAAMI,OAtDCC,EAsDQL,EAtDQM,EAsDLf,EArDpBgB,KAAKC,MAAMF,EAAEb,EAAIY,EAAEZ,EAAGa,EAAEX,EAAIU,EAAEV,IAqDCX,EAtDxC,IAAkBqB,EAAgBC,IAwD1B,GAAIH,EAAQM,QAAU3B,EAGpB,OAFAG,EAAe7F,QAAQ,CAAEsH,MAAOP,EAAQM,OAAQ5G,MAAOyC,SACvD6C,EAAU/F,QAAU,GAGxB,MACE,GAAI0G,EAAOW,QAAU3B,EAGnB,OAFAG,EAAe7F,QAAQ,CAAEsH,MAAOZ,EAAOW,OAAQ5G,MAAOyC,SACtD6C,EAAU/F,QAAU,IAKxB+F,EAAU/F,QAAU0G,GAItB,OADA3G,EAAKqD,iBAAiB,QAAS4C,GACxB,IAAMjG,EAAKsD,oBAAoB,QAAS2C,IAC9C,CAACpG,EAAW8F,EAAWC,EAAYC,GACxC,CClDgB,SAAA2B,EACdC,EACA3H,GAEA,MAAM4H,KAAEA,EAAIC,YAAEA,EAAc,GAAM7H,EAC5B8H,EAAyB,eAATF,EAAwB,EAAIN,KAAKS,IAAI,EAAGF,IAEvDG,EAASC,GAAczI,GAAS,IAChC0I,EAAQC,GAAa3I,OAA8BuE,IACnDc,EAAOC,GAAYtF,OAAkBuE,IACrCqE,EAAWC,GAAgB7I,EAAS,GAErC8I,EAAWrC,EAAqC,IAChDsC,EAActC,EAAO,GACrBuC,EAAiBvC,EAAO,GACxBwC,EAAgBxC,GAAO,GACvByC,EAAczC,EAAO0B,GAC3Be,EAAYvI,QAAUwH,EAEtB,MAAMgB,EAAkBlJ,EAAY,KAClC4I,EAAaC,EAASnI,QAAQqH,OAASgB,EAAerI,UACrD,IAEGyI,EAAcnJ,EAAY,KAC9B,GAAIgJ,EAActI,QAAS,OAC3B,GAAIqI,EAAerI,SAAW2H,EAAe,OAC7C,GAAgC,IAA5BQ,EAASnI,QAAQqH,OAGnB,OAF+B,IAA3BgB,EAAerI,SAAe8H,GAAW,QAC7CU,IAKFL,EAASnI,QAAQ0I,KAAK,CAACzB,EAAGC,IACpBD,EAAE0B,WAAazB,EAAEyB,SAAiB1B,EAAE0B,SAAWzB,EAAEyB,SAC9C1B,EAAE2B,SAAW1B,EAAE0B,UAExB,MAAMC,EAAOV,EAASnI,QAAQ8I,QAC9BT,EAAerI,SAAW,EAC1B8H,GAAW,GACXU,KAGAO,EADWR,EAAYvI,SACpB6I,EAAKG,MACLtJ,KAAMuJ,IACLjB,EAAUiB,GACVtE,OAASf,GACTiF,EAAKpJ,QAAQwJ,KAEdC,MAAOlE,IACNL,EAASK,GACT6D,EAAKM,OAAOnE,KAEboE,QAAQ,KACPf,EAAerI,SAAW,EAC1BwI,IACAC,MAIAN,EAASnI,QAAQqH,OAAS,GAAKgB,EAAerI,QAAU2H,GAC1Dc,KAED,CAACd,EAAea,IAEba,EAAM/J,EACV,CAAC0J,EAAaM,KAA6C,IAAAC,EACzD,GAAIjB,EAActI,QAChB,OAAOR,QAAQ2J,OAAO,IAAIlE,MAAM,yBAElC,MAAM0D,SAAQY,EAAGD,MAAAA,OAAAA,EAAAA,EAAYX,UAAQY,EAvHlB,EAwHbX,IAAaR,EAAYpI,QACzBwJ,EAAU,IAAIhK,QAAiB,CAACC,EAAS0J,KAC7ChB,EAASnI,QAAQ6G,KAAK,CAAEmC,OAAML,WAAUC,WAAUnJ,UAAS0J,aAK7D,OAHAX,IACAV,GAAW,GACX2B,eAAehB,GACRe,GAET,CAACf,EAAaD,IAGVkB,EAAapK,EAAY,KAC7B,MAAMqK,EAAUxB,EAASnI,QACzBmI,EAASnI,QAAU,GACnB2J,EAAQ9I,QAAS+I,GAAMA,EAAET,OAAO,IAAIlE,MAAM,6BAC1CuD,IAC+B,IAA3BH,EAAerI,SAAe8H,GAAW,IAC5C,CAACU,IAEEqB,EAAYvK,EAAY,KAC5BgJ,EAActI,SAAU,EACxB0J,KACC,CAACA,IASJ,OANA5J,EAAU,IACD,KACLwI,EAActI,SAAU,GAEzB,IAEI,CACLqJ,MACAxB,UACAE,SACArD,QACAuD,YACAyB,aACAG,YAEJ,CC5JA,MAAMC,EAAkB,IAAIxJ,ICEtB,SAAUyJ,EAAoBC,GAClC,OAAO,IAAIxK,QAAW,CAACC,EAAS0J,KAC9Ba,EAAQC,UAAY,IAAMxK,EAAQuK,EAAQjC,QAC1CiC,EAAQE,QAAU,KAAA,IAAAC,EAAA,OAChBhB,EAAoBgB,OAAdA,EAACH,EAAQtF,OAAKyF,EAAI,IAAIC,aAAa,8BAE/C,CCNA,SAASC,EACPb,EACA3J,GAEA,OAAKA,EACE2J,EACJ9J,KAAMqI,IACY,MAAjBlI,EAAQyK,WAARzK,EAAQyK,UAAYvC,GACbA,IAERmB,MAAOlE,IAEN,YADAnF,EAAQ0K,SAAR1K,EAAQ0K,QAAUvF,GACZA,IARWwE,CAUvB,CCqBM,SAAUgB,EAAaC,GAC3B,MAAOC,EAAIC,GAAStL,EAA+B,OAC5CqF,EAAOC,GAAYtF,EAA8B,OACjDuL,EAASC,GAAcxL,GAAS,GACjCyL,EAAYhF,EAAO2E,GA6BzB,OA5BAK,EAAU9K,QAAUyK,EAEpB3K,EAAU,KACR,IAAIiL,GAAY,EAChBpG,EAAS,MACTkG,GAAW,GACXF,EAAM,MAEN,MAAMK,KAAEA,EAAIC,QAAEA,EAAOC,OAAEA,GAAWJ,EAAU9K,QAe5C,OH3DY,SAAOyK,GACrB,MAAMU,EAAM,GAAGV,EAAOO,SAASP,EAAOQ,UACtC,IAAIzB,EAAUM,EAAgBlJ,IAAIuK,GAClC,OAAI3B,IACJA,EAKF,SAAiBiB,GACf,OAAO,IAAIjL,QAAqB,CAACC,EAAS0J,KACxC,MAAMa,EAAUoB,UAAUC,KAAKZ,EAAOO,KAAMP,EAAOQ,SACnDjB,EAAQE,QAAU,KAAAC,IAAAA,EAChB,OAAAhB,EAAoBgB,OAAdA,EAACH,EAAQtF,OAAKyF,EAAI,IAAIC,aAAa,6BAC3CJ,EAAQC,UAAY,IAAMxK,EAAQuK,EAAQjC,QAC1CiC,EAAQsB,gBAAmB7K,IACzB,MAAMiK,EAAMjK,EAAM8K,OAA4BxD,OACxCmD,EAAST,EAAOS,OACtB,IAAK,MAAMM,KAAaC,OAAOC,KAAKR,GAAS,CAC3C,MAAMS,EAAST,EAAOM,GACtB,IAAKd,EAAGkB,iBAAiBC,SAASL,GAAY,CAAA,IAAAM,EAC5C,MAAMC,EAAQrB,EAAGsB,kBAAkBR,EAAW,CAC5CS,QAASN,EAAOM,QAChBC,cAAmCJ,OAAtBA,EAAEH,EAAOO,gBAAaJ,IAErC,GAAIH,EAAOQ,QACT,IAAK,MAAMC,KAAaT,EAAOQ,QAC7BJ,EAAMM,YAAYD,EAAWA,EAAW,CAAEE,QAAQ,GAGxD,CACF,IAGN,CA9BYC,CAAQ9B,GAClBX,EAAgB7I,IAAIkK,EAAK3B,GAClBA,EACT,CGsCIgD,CAAO,CAAExB,OAAMC,UAASC,WACrBxL,KAAM+M,IACL,GAAI1B,EAEF,YADA0B,EAASC,QAGX,MAAMC,ECJE,SACdjC,GAIA,MAAO,CACL,MAAIA,GACF,OAAOA,CACT,EAEAkC,SAAS5B,GACAN,EAAGkB,iBAAiBC,SAASb,GAGtC6B,MAAM7B,GFmPM,SACdN,EACAc,GAEA,OArSF,SACEd,EACAc,GAEA,SAASsB,EAASrF,GAEhB,OADWiD,EAAGqC,YAAY,CAACvB,GAAY/D,GAC7BuF,YAAYxB,EACxB,CAEA,MAAO,CACLyB,OAAMA,CACJjE,EACAnJ,IAGOwK,EAAcN,EADP+C,EAAS,aACqB5L,IAAI8H,IAAQnJ,GAG1DqN,MAAAA,CACE/B,EACAgC,EACAtN,GAEA,MAAMkM,EAAQe,EAAS,aAEvB,OAAOzC,EACLN,EAFagC,EAAMnL,IAAIuK,IAGpBzL,KAAM0N,IACL,QAAiBxJ,IAAbwJ,EACF,MAAU,IAAAhD,aAAa,gBAAiB,iBAE1C,MAAMiD,EAAMrL,EAAQoL,CAAAA,EAAAA,EAAaD,GACjC,OAAOpD,EAAiBgC,EAAMuB,IAAID,MAEnC3N,KAAK,QACRG,EAEJ,EAEAsB,OAAMA,CACJgK,EACAtL,IAGOwK,EACLN,EAFY+C,EAAS,aAEE3L,OAAOgK,IAAMzL,KAAK,QACzCG,GAIJ0N,OAAOpC,GAEEpB,EADO+C,EAAS,YACOU,OAAOrC,IAAMzL,KAAM+N,QAAY7J,IAAN6J,GAGzDC,KAAAA,CACEC,EACA9N,GAEA,MACMmK,EADQ8C,EAAS,YACDc,aAChBC,EAAe,GACrB,OAAOxD,EACL,IAAI7K,QAAa,CAACC,EAAS0J,KACzBa,EAAQC,UAAY,KAClB,MAAM6D,EAAS9D,EAAQjC,OACnB+F,GACEH,EAASG,EAAO7E,QAAa4E,EAAQhH,KAAKiH,EAAO7E,OACrD6E,EAAOC,YAEPtO,EAAQoO,IAGZ7D,EAAQE,QAAU,KAAA,IAAAC,EAChB,OAAAhB,EAAoB,OAAdgB,EAACH,EAAQtF,OAAKyF,EAAI,IAAIC,aAAa,qBAE7CvK,EAEJ,EAEAmO,OAAMA,CACJhF,EACAnJ,IAGOwK,EAAcN,EADP+C,EAAS,aACqBQ,IAAItE,IAAQnJ,GAG1DoO,UAAAA,CACEC,EACArO,GAEA,MAAMkM,EAAQe,EAAS,aACjBpB,EAAsB,GAC5B,GAAqB,IAAjBwC,EAAM7G,OACR,OAAOgD,EAAc7K,QAAQC,QAAQiM,GAAO7L,GAE9C,IAAIsO,EAAY,EAgBhB,OAAO9D,EAfS,IAAI7K,QAAuB,CAACC,EAAS0J,KAKnD+E,EAAMrN,QAAQ,CAACuN,EAAMC,KACnB,MAAMC,EAAMvC,EAAM7K,IAAIkN,GACtBE,EAAIrE,UAAY,KACdyB,EAAK2C,GAAKC,EAAIvG,OANhBoG,IACIA,IAAcD,EAAM7G,QAAQ5H,EAAQiM,IAQxC4C,EAAIpE,QAAU,KAAAqE,IAAAA,SACZpF,EAAgBoF,OAAVA,EAACD,EAAI5J,OAAK6J,EAAI,IAAInE,aAAa,uBAGbvK,EAChC,EAEA2O,MAAM3O,GAEGwK,EACLN,EAFY+C,EAAS,aAEE0B,SAAS9O,KAAK,QACrCG,GAIJyH,MAAMzH,GAEGwK,EAAcN,EADP+C,EAAS,YACqBxF,SAAUzH,MAAAA,EAAAA,EAAW,CAAA,GAGvE,CAoKS4O,CAA2B/D,EAAIc,EACxC,CEvPakD,CAAsBhE,EAAIM,GAGnC+B,WAAAA,CACE4B,EACAlH,EACAlI,EACAM,GAEA,MAAM+O,EAAKlE,EAAGqC,YAAY4B,EAAYlH,GAChCoH,EAAgC,CACpChC,MAAQrB,GF8OA,SACdoD,EACApD,GAEA,OAtKF,SACEoD,EACApD,GAEA,SAASsB,IACP,OAAO8B,EAAG5B,YAAYxB,EACxB,CAEA,MAAO,CACLyB,OAAMA,CACJjE,EACAnJ,IAGOwK,EAAcN,EADP+C,IAC8B5L,IAAI8H,IAAQnJ,GAG1DqN,MAAAA,CACE/B,EACAgC,EACAtN,GAEA,MAAMkM,EAAQe,IACd,OAAOzC,EACLN,EAAiBgC,EAAMnL,IAAIuK,IACxBzL,KAAM0N,IACL,QAAiBxJ,IAAbwJ,EACF,UAAUhD,aAAa,gBAAiB,iBAE1C,MAAMiD,EAAMrL,KAAQoL,EAAaD,GACjC,OAAOpD,EAAiBgC,EAAMuB,IAAID,MAEnC3N,KAAK,QACRG,EAEJ,EAEAsB,OAAMA,CACJgK,EACAtL,IAGOwK,EACLN,EAFY+C,IAEW3L,OAAOgK,IAAMzL,KAAK,QACzCG,GAIJ0N,OAAOpC,GAEEpB,EADO+C,IACgBU,OAAOrC,IAAMzL,KAAM+N,QAAY7J,IAAN6J,GAGzDC,KAAAA,CACEC,EACA9N,GAEA,MACMmK,EADQ8C,IACQc,aAChBC,EAAe,GACrB,OAAOxD,EACL,IAAI7K,QAAa,CAACC,EAAS0J,KACzBa,EAAQC,UAAY,KAClB,MAAM6D,EAAS9D,EAAQjC,OACnB+F,GACEH,EAASG,EAAO7E,QAAa4E,EAAQhH,KAAKiH,EAAO7E,OACrD6E,EAAOC,YAEPtO,EAAQoO,IAGZ7D,EAAQE,QAAU,SAAA4E,EAAA,OAChB3F,EAAoB2F,OAAdA,EAAC9E,EAAQtF,OAAKoK,EAAI,IAAI1E,aAAa,qBAE7CvK,EAEJ,EAEAmO,OAAMA,CACJhF,EACAnJ,IAGOwK,EAAcN,EADP+C,IAC8BQ,IAAItE,IAAQnJ,GAG1DoO,UAAAA,CACEC,EACArO,GAEA,MAAMkM,EAAQe,IACRpB,EAAsB,GAC5B,GAAqB,IAAjBwC,EAAM7G,OACR,OAAOgD,EAAc7K,QAAQC,QAAQiM,GAAO7L,GAE9C,IAAIsO,EAAY,EAahB,OAAO9D,EAZS,IAAI7K,QAAuB,CAACC,EAAS0J,KACnD+E,EAAMrN,QAAQ,CAACuN,EAAMC,KACnB,MAAMC,EAAMvC,EAAM7K,IAAIkN,GACtBE,EAAIrE,UAAY,KACdyB,EAAK2C,GAAKC,EAAIvG,OACdoG,IACIA,IAAcD,EAAM7G,QAAQ5H,EAAQiM,IAE1C4C,EAAIpE,QAAU,KAAA,IAAA6E,EACZ,OAAA5F,EAAgB,OAAV4F,EAACT,EAAI5J,OAAKqK,EAAI,IAAI3E,aAAa,uBAGbvK,EAChC,EAEA2O,MAAM3O,GAEGwK,EACLN,EAFY+C,IAEW0B,SAAS9O,KAAK,QACrCG,GAIJyH,MAAMzH,GAEGwK,EAAcN,EADP+C,IAC8BxF,SAAiB,MAAPzH,EAAAA,EAAW,CAAA,GAGvE,CA0CSmP,CAA4BJ,EAAIpD,EACzC,CElPUyD,CAAiCL,EAAIpD,IAEnC0D,EAAY,IAAI1P,QAAc,CAACC,EAAS0J,KAC5CyF,EAAGO,WAAa,IAAM1P,IACtBmP,EAAG1E,QAAU,KAAAkF,IAAAA,EACX,OAAAjG,EAAe,OAATiG,EAACR,EAAGlK,OAAK0K,EAAI,IAAIhF,aAAa,0BAElCiF,EAAiB9P,EAASsP,GAEhC,OApDN,SACErF,EACA3J,GAEA,OAAKA,EACE2J,EACJ9J,KAAK,IAAMG,MAAAA,EAAQyK,eAARzK,EAAAA,EAAQyK,aACnBpB,MAAOlE,IAEN,MADAnF,MAAAA,EAAQ0K,SAAR1K,EAAQ0K,QAAUvF,GACZA,IALWwE,CAOvB,CAyCa8F,CADS9P,QAAQC,QAAQ4P,GAAgB3P,KAAK,IAAMwP,GAClBrP,EAC3C,EAEJ,CDnC2B0P,CAAmB9C,GACtC9B,EAAMgC,GACN9B,GAAW,KAEZ3B,MAAOlE,IACD+F,GAAWpG,EAASK,KAGtB,KACL+F,GAAY,IAEb,CAACN,EAAOO,KAAMP,EAAOQ,UAEjB,CAAEP,KAAIE,UAASlG,QACxB,CEtEA,MAAM8K,EACJ,6EAEIC,EAAiC,CAAC,gCAClCC,EAAqB,IAoDX,SAAAC,EACd9P,EAA8B,CAAE,GAEhC,MAAM+P,YACJA,EAAcH,EACdI,QAASC,EAAYJ,EAAkBK,SACvCA,GACElQ,GAEGmQ,EAAKC,GAAU5Q,EAAmB,KAClCwI,EAASC,GAAczI,GAAS,IAChCqF,EAAOC,GAAYtF,EAAwB,MAE5C6Q,EAAQpK,EAAiC,MACzCqK,EAAarK,EAA6C,MAC1DsK,EAActK,EAAoB,IAAI9E,KACtCqP,EAAcvK,EAAOiK,GA4E3B,OA3EAM,EAAYrQ,QAAU+P,EAEtBjQ,EAAU,KACR,GAnDuB,oBAAX6C,OAsDV,OAFAmF,GAAW,QACXnD,EAAS,mDAIX,GArDkC,oBAAtB2L,kBAwDV,OAFAxI,GAAW,QACXnD,EAAS,sCAIX,MAAM4L,EAAW,IAAIvP,IACrBoP,EAAYpQ,QAAUuQ,EAEtB,MAAMC,EAASA,KACTL,EAAWnQ,UACbyQ,aAAaN,EAAWnQ,SACxBmQ,EAAWnQ,QAAU,MAEnBkQ,EAAMlQ,UACRkQ,EAAMlQ,QAAQ0M,QACdwD,EAAMlQ,QAAU,MAElB8H,GAAW,IAGP4I,EAASC,IACTJ,EAASK,IAAID,KACjBJ,EAASrP,IAAIyP,GACbV,EAAQY,GACO,IAAIA,EAAMF,IAGN,MAAnBN,EAAYrQ,SAAZqQ,EAAYrQ,QAAU2Q,KAGxB,IACE,MAAMG,EAAK,IAAIR,kBAAkB,CAC/BS,WAAY,CAAC,CAAEC,KAAMpB,MAEvBM,EAAMlQ,QAAU8Q,EAEhBA,EAAGG,eAAkBxQ,IACnB,MAAMmG,EAAInG,EAAMyQ,UACXtK,GAAMA,EAAEsK,WArFrB,SAAkCA,GAChC,MAAMnO,EAAUmO,EAAUC,MAAM3B,GAChC,OAAOzM,EAAU,IAAIA,GAAW,EAClC,CAmFsBqO,CAAyBxK,EAAEsK,WACnCrQ,QAAQ6P,IAGhBI,EAAGO,kBAAkB,IAErBP,EAAGQ,cACA5R,KAAM6R,GAAUT,EAAGU,oBAAoBD,IACvCrI,MAAOlE,IACNL,EACEK,aAAeC,MAAQD,EAAIyM,QAAU,0BAEvCjB,MAGJL,EAAWnQ,QAAUoF,WAAW,IAAMoL,IAAUV,EAClD,CAAE,MAAO9K,GACPL,EAASK,aAAeC,MAAQD,EAAIyM,QAAU,uBAC9CjB,GACF,CAEA,MAAO,KACLA,MAED,CAACZ,EAAY8B,KAAK,KAAM5B,IAEpB,CAAEE,MAAKnI,UAASnD,QACzB,CCvDgB,SAAAiN,EACd9R,GAEA,MAAM+R,QAAEA,EAAOC,WAAEA,EAAa,UAASC,UAAEA,EAASC,aAAEA,GAAiBlS,GAE9DkI,EAAQC,GAAa3I,OAA8BuE,IACnDiE,EAASC,GAAczI,GAAS,IAChCqF,EAAOC,GAAYtF,EAAwB,OAC3C2S,EAAOC,GAAY5S,GAAS,GAE7B6S,EAAYpM,EAAsB,MAClCqM,EAAoBrM,EAA0C,MAC9DsM,EAAmBtM,EAAyC,MA4FlE,OA1FAhG,EAAU,KACR,GArDuB,oBAAX6C,OAwDV,OAFAgC,EAAS,mDACTmD,GAAW,GAGb,GAtDuB,oBAAXuK,OAyDV,OAFA1N,EAAS,oDACTmD,GAAW,GAGb,GAtDuB,oBAAhBwK,aAC4B,mBAA5BA,YAAYC,YAwDjB,OAFA5N,EAAS,yDACTmD,GAAW,GAIbnD,EAAS,MACTsN,GAAS,GACT,MAAMO,EAzDV,SAAsBV,GACpB,GAAIA,EACF,OAAW,IAAAO,OAAOP,GAEpB,MAAMW,EAAO,IAAIC,KAAK,CA3EG,ygCA2EmB,CAC1CzO,KAAM,2BAEF0O,EAAMC,IAAIC,gBAAgBJ,GAC1BK,EAAI,IAAIT,OAAOM,GAErB,OADAC,IAAIG,gBAAgBJ,GACbG,CACT,CA8CmBE,CAAalB,GAC5BI,EAAUlS,QAAUwS,EAEpB,MAAMS,EAAa/P,IAAmB,IAAAgQ,EACpC,MAAMjP,KAAEA,EAAM8D,OAAQoL,EAAWzO,MAAO0O,GAAmB,OAATF,EAAGhQ,EAAE8F,MAAIkK,EAAI,GAC/D,MAAa,UAATjP,GACFgO,GAAS,QACTnK,GAAW,IAGA,UAAT7D,GACFU,QAASyO,EAAAA,EAAY,iBACrBtL,GAAW,QACPsK,EAAiBpS,UACnBoS,EAAiBpS,QAAQ,IAAIiF,MAAMmO,IACnCjB,EAAkBnS,QAAU,KAC5BoS,EAAiBpS,QAAU,aAIlB,WAATiE,IACF+D,EAAUmL,GACVrL,GAAW,GACPqK,EAAkBnS,UACpBmS,EAAkBnS,QAAQmT,GAC1BhB,EAAkBnS,QAAU,KAC5BoS,EAAiBpS,QAAU,SAajC,OARAwS,EAAOpP,iBAAiB,UAAW6P,GACnCT,EAAOa,YAAY,CACjBpP,KAAM,OACN2N,UACAC,aACAE,aAA0B,MAAZA,EAAAA,EAAgB,CAC/B,IAEM,KACLS,EAAOnP,oBAAoB,UAAW4P,GACtCT,EAAO3I,YACPqI,EAAUlS,QAAU,KAChBoS,EAAiBpS,UACnBoS,EAAiBpS,QAAQ,IAAIiF,MAAM,sBACnCkN,EAAkBnS,QAAU,KAC5BoS,EAAiBpS,QAAU,QAG9B,CAAC4R,EAASC,EAAYC,EAAWC,IAsB7B,CAAEuB,QApBOhU,EACbiU,OACY/T,QAAQ,CAACC,EAAS0J,KACtB+I,EAAUlS,SAAYgS,EAIvBtN,EACFyE,EAAO,IAAIlE,MAAMP,KAGnByN,EAAkBnS,QAAUP,EAC5B2S,EAAiBpS,QAAUmJ,EAC3BrB,GAAW,GACXoK,EAAUlS,QAAQqT,YAAY,CAAEpP,KAAM,UAAWsP,WAV/CpK,EAAO,IAAIlE,MAAM,qBAavB,CAAC+M,EAAOtN,IAGQqD,SAAQF,UAASnD,QAAOsN,QAC5C,CCnHgB,SAAAwB,EACdhB,EACA3S,EAAyC,IAEzC,MAAM4T,WAAEA,EAAa,IAAGC,mBAAEA,EAAqB,KAAS7T,GAEjD8T,EAAcC,GAAmBvU,EAAmB,KACpDwU,EAAgBC,GAAqBzU,EAAS,IAC9C0U,EAAaC,GAAkB3U,EAAS,IACxC4U,EAAcC,GAAmB7U,EACtC,KAEK8U,EAAkBC,GAAuB/U,EAAS,GAEnDgV,EAAyBvO,EAAiB,IAC1CwO,EAAiBxO,EAAO,GACxByO,EAAmBzO,EAAO,GAEhChG,EAAU,KACR,IAAK0S,EAAQ,OAEb,MAAMS,EAAa/P,IACjB,MAAMsR,EAzDZ,SAAsBxL,GACpB,GAAY,MAARA,GAAgC,iBAATA,EAAmB,YAC9C,MACM/E,EADI+E,EACK/E,KACf,MACW,eAATA,GACS,aAATA,GACS,cAATA,GACS,eAATA,OAQK,CACLA,KAAMA,EACNwQ,OANiC,iBAVzBzL,EAUcyL,OAVdzL,EAUsCyL,YAAS7Q,EAOvD8Q,SANqC,iBAX7B1L,EAWgB0L,SAXhB1L,EAW0C0L,cAAW9Q,EAO7Dc,MAN+B,iBAZvBsE,EAYatE,MAZbsE,EAYoCtE,WAAQd,EAOpDxC,KAN6B,iBAbrB4H,EAaY5H,KAbZ4H,EAakC5H,UAAOwC,EAOjD+Q,UAAWzO,KAAKD,MAEpB,CAiCiB2O,CAAa1R,EAAE8F,MAC1B,GAAKwL,EAOL,GALAN,EAAiBrD,GACF,IAAIA,EAAM2D,GAAIK,OAAOpB,IAIpB,eAAZe,EAAGvQ,MAAyBuQ,EAAGC,OACjCb,EAAiB/C,GACfA,EAAKiE,SAASN,EAAGC,QAAW5D,EAAO,IAAIA,EAAM2D,EAAGC,cAEzCD,GAAY,aAAZA,EAAGvQ,KAAqB,CAC7BuQ,EAAGC,QACLb,EAAiB/C,GAASA,EAAKlK,OAAQoO,GAAOA,IAAOP,EAAGC,SAE1DX,EAAmBlN,GAAMA,EAAI,GAC7B,MAAMH,EAASP,KAAKD,MAAQyN,EAC5BW,EAAuBrU,QAAU,IAC5BqU,EAAuBrU,QAAQ2G,OAAQiD,GAAMA,GAAKnD,GACrD+N,EAAGG,WAEsB,iBAAhBH,EAAGE,WACZJ,EAAetU,SAAWwU,EAAGE,SAC7BH,EAAiBvU,SAAW,EAEhC,KAAuB,cAAZwU,EAAGvQ,MACRuQ,EAAGC,QACLb,EAAiB/C,GAASA,EAAKlK,OAAQoO,GAAOA,IAAOP,EAAGC,SAE1DT,EAAgBpN,GAAMA,EAAI,IACL,eAAZ4N,EAAGvQ,MAA4C,iBAAZuQ,EAAGpT,MAC/CgT,EAAoBI,EAAGpT,OAK3B,OADAoR,EAAOpP,iBAAiB,UAAW6P,GAC5B,IAAMT,EAAOnP,oBAAoB,UAAW4P,IAClD,CAACT,EAAQiB,IAEZ,MAAMuB,EAAoBvT,EAAQ,KAChC,MAAM6F,EAAQiN,EAAiBvU,QAE/B,OAAOsH,EAAQ,EADHgN,EAAetU,QACFsH,EAAQ,GAChC,CAAC2M,IAEEgB,EAAsBxT,EAAQ,KAClC,MACMgF,EADMP,KAAKD,MACIyN,EAIrB,OAHmBW,EAAuBrU,QAAQ2G,OAC/CiD,GAAMA,GAAKnD,GAEIY,QAAUqM,EAAqB,MAChD,CAACO,EAAcP,IAEZwB,EAAWzT,EACf,KAAO,CACLkS,eACAE,iBACAE,cACAiB,oBACAC,sBACAd,mBACAgB,eAAgBtB,EAAiBE,EACjCqB,iBAAkBnB,EAAa5M,SAEjC,CACEsM,EACAE,EACAE,EACAiB,EACAC,EACAd,EACAF,EAAa5M,SAIjB,MAAO,CACLsM,eACAE,iBACAE,cACAE,eACAe,oBACAC,sBACAd,mBACAe,WAEJ"}