{"version":3,"file":"storage-utils.mjs","sources":["../../../src/lib/shared/storage-utils.ts"],"sourcesContent":["/**\n * @file Unified Storage Utilities\n * @description Standardized storage abstractions for localStorage, sessionStorage,\n * and in-memory storage with TTL and type safety.\n *\n * @module shared/storage-utils\n */\n\nimport { isObject, isNumber } from './type-utils';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Storage item wrapper with metadata.\n */\nexport interface StorageItem<T> {\n  value: T;\n  timestamp: number;\n  ttl?: number;\n  version?: number;\n}\n\n/**\n * Storage options for set operations.\n */\nexport interface StorageSetOptions {\n  /** Time-to-live in milliseconds (0 = no expiration) */\n  ttlMs?: number;\n  /** Version number for migrations */\n  version?: number;\n}\n\n/**\n * Storage configuration.\n */\nexport interface StorageConfig {\n  /** Prefix for all keys */\n  prefix?: string;\n  /** Default TTL in milliseconds */\n  defaultTtlMs?: number;\n  /** Storage version */\n  version?: number;\n}\n\n// =============================================================================\n// Storage Wrapper\n// =============================================================================\n\n/**\n * Type-safe storage wrapper with TTL support.\n *\n * @example\n * ```ts\n * const storage = new StorageWrapper(localStorage, { prefix: 'app' });\n *\n * // Set with TTL\n * storage.set('user', { name: 'John' }, { ttlMs: 3600000 });\n *\n * // Get with type\n * const user = storage.get<User>('user');\n * ```\n */\nexport class StorageWrapper {\n  private storage: Storage;\n  private config: Required<StorageConfig>;\n\n  constructor(storage: Storage, config: StorageConfig = {}) {\n    this.storage = storage;\n    this.config = {\n      prefix: config.prefix ?? '',\n      defaultTtlMs: config.defaultTtlMs ?? 0,\n      version: config.version ?? 1,\n    };\n  }\n\n  /**\n   * Set a value in storage.\n   */\n  set<T>(key: string, value: T, options: StorageSetOptions = {}): boolean {\n    const fullKey = this.getKey(key);\n    const ttl = options.ttlMs ?? this.config.defaultTtlMs;\n\n    const item: StorageItem<T> = {\n      value,\n      timestamp: Date.now(),\n      ttl: ttl > 0 ? ttl : undefined,\n      version: options.version ?? this.config.version,\n    };\n\n    try {\n      this.storage.setItem(fullKey, JSON.stringify(item));\n      return true;\n    } catch (error) {\n      // Storage quota exceeded or other error\n      console.warn('[Storage] Failed to set item:', key, error);\n      return false;\n    }\n  }\n\n  /**\n   * Get a value from storage.\n   */\n  get<T>(key: string, defaultValue?: T): T | undefined {\n    const fullKey = this.getKey(key);\n\n    try {\n      const raw = this.storage.getItem(fullKey);\n      if (raw === null || raw === undefined || raw === '') return defaultValue;\n\n      const item = JSON.parse(raw) as unknown;\n      if (!this.isStorageItem(item)) {\n        // Legacy value without wrapper\n        return item as T;\n      }\n\n      // Check expiration\n      const {ttl} = item;\n      if (ttl !== undefined && ttl !== null && ttl > 0 && Date.now() - item.timestamp > ttl) {\n        this.remove(key);\n        return defaultValue;\n      }\n\n      return item.value as T;\n    } catch {\n      return defaultValue;\n    }\n  }\n\n  /**\n   * Remove a value from storage.\n   */\n  remove(key: string): void {\n    const fullKey = this.getKey(key);\n    this.storage.removeItem(fullKey);\n  }\n\n  /**\n   * Check if a key exists and is not expired.\n   */\n  has(key: string): boolean {\n    return this.get(key) !== undefined;\n  }\n\n  /**\n   * Get all keys with the configured prefix.\n   */\n  keys(): string[] {\n    const keys: string[] = [];\n    const prefix = this.config.prefix ? `${this.config.prefix}:` : '';\n\n    for (let i = 0; i < this.storage.length; i++) {\n      const key = this.storage.key(i);\n      if (key?.startsWith(prefix) === true) {\n        keys.push(prefix !== '' ? key.slice(prefix.length) : key);\n      }\n    }\n\n    return keys;\n  }\n\n  /**\n   * Clear all items with the configured prefix.\n   */\n  clear(): void {\n    const keysToRemove: string[] = [];\n    const prefix = this.config.prefix ? `${this.config.prefix}:` : '';\n\n    for (let i = 0; i < this.storage.length; i++) {\n      const key = this.storage.key(i);\n      if (key !== null && (prefix === '' || key.startsWith(prefix))) {\n        keysToRemove.push(key);\n      }\n    }\n\n    keysToRemove.forEach((key) => this.storage.removeItem(key));\n  }\n\n  /**\n   * Remove all expired items.\n   */\n  cleanup(): number {\n    let removed = 0;\n    const prefix = this.config.prefix ? `${this.config.prefix}:` : '';\n    const now = Date.now();\n\n    for (let i = this.storage.length - 1; i >= 0; i--) {\n      const key = this.storage.key(i);\n      if (key === null || (prefix && !key.startsWith(prefix))) continue;\n\n      try {\n        const raw = this.storage.getItem(key);\n        if (raw === null || raw === undefined || raw === '') continue;\n\n        const item = JSON.parse(raw) as unknown;\n        if (\n          this.isStorageItem(item) &&\n          item.ttl !== undefined &&\n          item.ttl !== null &&\n          item.ttl > 0 &&\n          now - item.timestamp > item.ttl\n        ) {\n          this.storage.removeItem(key);\n          removed++;\n        }\n      } catch {\n        // Corrupted item, remove it\n        this.storage.removeItem(key);\n        removed++;\n      }\n    }\n\n    return removed;\n  }\n\n  /**\n   * Get storage statistics.\n   */\n  getStats(): {\n    itemCount: number;\n    totalSize: number;\n    expiredCount: number;\n  } {\n    let itemCount = 0;\n    let totalSize = 0;\n    let expiredCount = 0;\n    const prefix = this.config.prefix ? `${this.config.prefix}:` : '';\n    const now = Date.now();\n\n    for (let i = 0; i < this.storage.length; i++) {\n      const key = this.storage.key(i);\n      if (key === null || (prefix !== '' && prefix !== null && prefix !== undefined && !key.startsWith(prefix))) continue;\n\n      itemCount++;\n      const value = this.storage.getItem(key);\n      if (value !== null && value !== undefined) {\n        totalSize += key.length + value.length;\n\n        try {\n          const item = JSON.parse(value) as unknown;\n          if (\n            this.isStorageItem(item) &&\n            item.ttl !== undefined &&\n            item.ttl !== null &&\n            item.ttl > 0 &&\n            now - item.timestamp > item.ttl\n          ) {\n            expiredCount++;\n          }\n        } catch {\n          // Ignore\n        }\n      }\n    }\n\n    return { itemCount, totalSize, expiredCount };\n  }\n\n  /**\n   * Get prefixed storage key.\n   */\n  private getKey(key: string): string {\n    return this.config.prefix ? `${this.config.prefix}:${key}` : key;\n  }\n\n  /**\n   * Check if item is a StorageItem wrapper.\n   */\n  private isStorageItem(value: unknown): value is StorageItem<unknown> {\n    return (\n      isObject(value) &&\n      'value' in value &&\n      'timestamp' in value &&\n      isNumber(value.timestamp)\n    );\n  }\n}\n\n// =============================================================================\n// Memory Storage\n// =============================================================================\n\n/**\n * In-memory storage implementation (SSR-safe fallback).\n */\nexport class MemoryStorage implements Storage {\n  private store = new Map<string, string>();\n\n  get length(): number {\n    return this.store.size;\n  }\n\n  key(index: number): string | null {\n    const keys = Array.from(this.store.keys());\n    return keys[index] ?? null;\n  }\n\n  getItem(key: string): string | null {\n    return this.store.get(key) ?? null;\n  }\n\n  setItem(key: string, value: string): void {\n    this.store.set(key, value);\n  }\n\n  removeItem(key: string): void {\n    this.store.delete(key);\n  }\n\n  clear(): void {\n    this.store.clear();\n  }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Check if localStorage is available.\n */\nexport function isLocalStorageAvailable(): boolean {\n  try {\n    const testKey = '__storage_test__';\n    window.localStorage.setItem(testKey, 'test');\n    window.localStorage.removeItem(testKey);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Check if sessionStorage is available.\n */\nexport function isSessionStorageAvailable(): boolean {\n  try {\n    const testKey = '__storage_test__';\n    window.sessionStorage.setItem(testKey, 'test');\n    window.sessionStorage.removeItem(testKey);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Get localStorage with fallback to memory storage.\n */\nexport function getLocalStorage(): Storage {\n  if (typeof window !== 'undefined' && isLocalStorageAvailable()) {\n    return window.localStorage;\n  }\n  return new MemoryStorage();\n}\n\n/**\n * Get sessionStorage with fallback to memory storage.\n */\nexport function getSessionStorage(): Storage {\n  if (typeof window !== 'undefined' && isSessionStorageAvailable()) {\n    return window.sessionStorage;\n  }\n  return new MemoryStorage();\n}\n\n/**\n * Create a localStorage wrapper with prefix.\n */\nexport function createLocalStorage(config: StorageConfig = {}): StorageWrapper {\n  return new StorageWrapper(getLocalStorage(), config);\n}\n\n/**\n * Create a sessionStorage wrapper with prefix.\n */\nexport function createSessionStorage(\n  config: StorageConfig = {}\n): StorageWrapper {\n  return new StorageWrapper(getSessionStorage(), config);\n}\n\n/**\n * Create a memory storage wrapper.\n */\nexport function createMemoryStorage(): StorageWrapper {\n  return new MemoryStorage() as unknown as StorageWrapper;\n}\n\n// =============================================================================\n// Convenience Functions\n// =============================================================================\n\n// Default storage instances\nlet defaultLocalStorage: StorageWrapper | null = null;\nlet defaultSessionStorage: StorageWrapper | null = null;\n\n/**\n * Get default localStorage wrapper.\n */\nfunction getDefaultLocalStorage(): StorageWrapper {\n  defaultLocalStorage ??= createLocalStorage({ prefix: 'app' });\n  return defaultLocalStorage;\n}\n\n/**\n * Get default sessionStorage wrapper.\n */\nfunction getDefaultSessionStorage(): StorageWrapper {\n  defaultSessionStorage ??= createSessionStorage({ prefix: 'app' });\n  return defaultSessionStorage;\n}\n\n/**\n * Set a value in localStorage.\n */\nexport function setLocal<T>(\n  key: string,\n  value: T,\n  options?: StorageSetOptions\n): boolean {\n  return getDefaultLocalStorage().set(key, value, options);\n}\n\n/**\n * Get a value from localStorage.\n */\nexport function getLocal<T>(key: string, defaultValue?: T): T | undefined {\n  return getDefaultLocalStorage().get<T>(key, defaultValue);\n}\n\n/**\n * Remove a value from localStorage.\n */\nexport function removeLocal(key: string): void {\n  getDefaultLocalStorage().remove(key);\n}\n\n/**\n * Set a value in sessionStorage.\n */\nexport function setSession<T>(\n  key: string,\n  value: T,\n  options?: StorageSetOptions\n): boolean {\n  return getDefaultSessionStorage().set(key, value, options);\n}\n\n/**\n * Get a value from sessionStorage.\n */\nexport function getSession<T>(key: string, defaultValue?: T): T | undefined {\n  return getDefaultSessionStorage().get<T>(key, defaultValue);\n}\n\n/**\n * Remove a value from sessionStorage.\n */\nexport function removeSession(key: string): void {\n  getDefaultSessionStorage().remove(key);\n}\n\n// =============================================================================\n// JSON Storage Helpers\n// =============================================================================\n\n/**\n * Safely parse JSON from storage with type guard.\n */\nexport function getJsonFromStorage<T>(\n  storage: Storage,\n  key: string,\n  guard: (value: unknown) => value is T\n): T | null {\n  try {\n    const raw = storage.getItem(key);\n    if (raw === null || raw === undefined || raw === '') return null;\n\n    const parsed: unknown = JSON.parse(raw);\n    return guard(parsed) ? parsed : null;\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Save JSON to storage.\n */\nexport function setJsonToStorage<T>(\n  storage: Storage,\n  key: string,\n  value: T\n): boolean {\n  try {\n    storage.setItem(key, JSON.stringify(value));\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n// =============================================================================\n// Storage Event Utilities\n// =============================================================================\n\n/**\n * Listen for storage changes across tabs.\n *\n * @param callback - Callback when storage changes\n * @param options - Filter options\n * @returns Unsubscribe function\n */\nexport function onStorageChange(\n  callback: (event: StorageEvent) => void,\n  options: { key?: string; storage?: Storage } = {}\n): () => void {\n  if (typeof window === 'undefined') {\n    return () => {};\n  }\n\n  const handler = (event: StorageEvent): void => {\n    // Filter by key if specified\n    if (options.key !== undefined && options.key !== null && options.key !== '' && event.key !== options.key) return;\n\n    // Filter by storage type if specified\n    if (options.storage !== undefined && options.storage !== null && event.storageArea !== options.storage) return;\n\n    callback(event);\n  };\n\n  window.addEventListener('storage', handler);\n  return () => window.removeEventListener('storage', handler);\n}\n\n/**\n * Watch a specific key for changes.\n */\nexport function watchStorageKey<T>(\n  key: string,\n  callback: (newValue: T | null, oldValue: T | null) => void,\n  options: { storage?: Storage } = {}\n): () => void {\n  return onStorageChange(\n    (event) => {\n      if (event.key !== key) return;\n\n      const parse = (val: string | null): T | null => {\n        if (val === null || val === undefined || val === '') return null;\n        try {\n          return JSON.parse(val) as T;\n        } catch {\n          return val as unknown as T;\n        }\n      };\n\n      callback(parse(event.newValue), parse(event.oldValue));\n    },\n    { key, storage: options.storage }\n  );\n}\n"],"names":["StorageWrapper","storage","config","key","value","options","fullKey","ttl","item","error","defaultValue","raw","keys","prefix","i","keysToRemove","removed","now","itemCount","totalSize","expiredCount","isObject","isNumber","MemoryStorage","index","isLocalStorageAvailable","testKey","isSessionStorageAvailable","getLocalStorage","getSessionStorage","createLocalStorage","createSessionStorage","createMemoryStorage","defaultLocalStorage","defaultSessionStorage","getDefaultLocalStorage","getDefaultSessionStorage","setLocal","getLocal","removeLocal","setSession","getSession","removeSession","getJsonFromStorage","guard","parsed","setJsonToStorage","onStorageChange","callback","handler","event","watchStorageKey","parse","val"],"mappings":";AAgEO,MAAMA,EAAe;AAAA,EAClB;AAAA,EACA;AAAA,EAER,YAAYC,GAAkBC,IAAwB,IAAI;AACxD,SAAK,UAAUD,GACf,KAAK,SAAS;AAAA,MACZ,QAAQC,EAAO,UAAU;AAAA,MACzB,cAAcA,EAAO,gBAAgB;AAAA,MACrC,SAASA,EAAO,WAAW;AAAA,IAAA;AAAA,EAE/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAOC,GAAaC,GAAUC,IAA6B,CAAA,GAAa;AACtE,UAAMC,IAAU,KAAK,OAAOH,CAAG,GACzBI,IAAMF,EAAQ,SAAS,KAAK,OAAO,cAEnCG,IAAuB;AAAA,MAC3B,OAAAJ;AAAA,MACA,WAAW,KAAK,IAAA;AAAA,MAChB,KAAKG,IAAM,IAAIA,IAAM;AAAA,MACrB,SAASF,EAAQ,WAAW,KAAK,OAAO;AAAA,IAAA;AAG1C,QAAI;AACF,kBAAK,QAAQ,QAAQC,GAAS,KAAK,UAAUE,CAAI,CAAC,GAC3C;AAAA,IACT,SAASC,GAAO;AAEd,qBAAQ,KAAK,iCAAiCN,GAAKM,CAAK,GACjD;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAON,GAAaO,GAAiC;AACnD,UAAMJ,IAAU,KAAK,OAAOH,CAAG;AAE/B,QAAI;AACF,YAAMQ,IAAM,KAAK,QAAQ,QAAQL,CAAO;AACxC,UAAIK,KAAQ,QAA6BA,MAAQ,GAAI,QAAOD;AAE5D,YAAMF,IAAO,KAAK,MAAMG,CAAG;AAC3B,UAAI,CAAC,KAAK,cAAcH,CAAI;AAE1B,eAAOA;AAIT,YAAM,EAAC,KAAAD,MAAOC;AACd,aAAyBD,KAAQ,QAAQA,IAAM,KAAK,KAAK,IAAA,IAAQC,EAAK,YAAYD,KAChF,KAAK,OAAOJ,CAAG,GACRO,KAGFF,EAAK;AAAA,IACd,QAAQ;AACN,aAAOE;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAOP,GAAmB;AACxB,UAAMG,IAAU,KAAK,OAAOH,CAAG;AAC/B,SAAK,QAAQ,WAAWG,CAAO;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAIH,GAAsB;AACxB,WAAO,KAAK,IAAIA,CAAG,MAAM;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAiB;AACf,UAAMS,IAAiB,CAAA,GACjBC,IAAS,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,MAAM,MAAM;AAE/D,aAASC,IAAI,GAAGA,IAAI,KAAK,QAAQ,QAAQA,KAAK;AAC5C,YAAMX,IAAM,KAAK,QAAQ,IAAIW,CAAC;AAC9B,MAAIX,GAAK,WAAWU,CAAM,MAAM,MAC9BD,EAAK,KAAKC,MAAW,KAAKV,EAAI,MAAMU,EAAO,MAAM,IAAIV,CAAG;AAAA,IAE5D;AAEA,WAAOS;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,UAAMG,IAAyB,CAAA,GACzBF,IAAS,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,MAAM,MAAM;AAE/D,aAASC,IAAI,GAAGA,IAAI,KAAK,QAAQ,QAAQA,KAAK;AAC5C,YAAMX,IAAM,KAAK,QAAQ,IAAIW,CAAC;AAC9B,MAAIX,MAAQ,SAASU,MAAW,MAAMV,EAAI,WAAWU,CAAM,MACzDE,EAAa,KAAKZ,CAAG;AAAA,IAEzB;AAEA,IAAAY,EAAa,QAAQ,CAACZ,MAAQ,KAAK,QAAQ,WAAWA,CAAG,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,UAAkB;AAChB,QAAIa,IAAU;AACd,UAAMH,IAAS,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,MAAM,MAAM,IACzDI,IAAM,KAAK,IAAA;AAEjB,aAASH,IAAI,KAAK,QAAQ,SAAS,GAAGA,KAAK,GAAGA,KAAK;AACjD,YAAMX,IAAM,KAAK,QAAQ,IAAIW,CAAC;AAC9B,UAAI,EAAAX,MAAQ,QAASU,KAAU,CAACV,EAAI,WAAWU,CAAM;AAErD,YAAI;AACF,gBAAMF,IAAM,KAAK,QAAQ,QAAQR,CAAG;AACpC,cAAIQ,KAAQ,QAA6BA,MAAQ,GAAI;AAErD,gBAAMH,IAAO,KAAK,MAAMG,CAAG;AAC3B,UACE,KAAK,cAAcH,CAAI,KACvBA,EAAK,QAAQ,UACbA,EAAK,QAAQ,QACbA,EAAK,MAAM,KACXS,IAAMT,EAAK,YAAYA,EAAK,QAE5B,KAAK,QAAQ,WAAWL,CAAG,GAC3Ba;AAAA,QAEJ,QAAQ;AAEN,eAAK,QAAQ,WAAWb,CAAG,GAC3Ba;AAAA,QACF;AAAA,IACF;AAEA,WAAOA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,WAIE;AACA,QAAIE,IAAY,GACZC,IAAY,GACZC,IAAe;AACnB,UAAMP,IAAS,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,MAAM,MAAM,IACzDI,IAAM,KAAK,IAAA;AAEjB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC5C,YAAMd,IAAM,KAAK,QAAQ,IAAI,CAAC;AAC9B,UAAIA,MAAQ,QAASU,MAAW,MAAMA,MAAW,QAAQA,MAAW,UAAa,CAACV,EAAI,WAAWU,CAAM,EAAI;AAE3G,MAAAK;AACA,YAAMd,IAAQ,KAAK,QAAQ,QAAQD,CAAG;AACtC,UAAIC,KAAU,MAA6B;AACzC,QAAAe,KAAahB,EAAI,SAASC,EAAM;AAEhC,YAAI;AACF,gBAAMI,IAAO,KAAK,MAAMJ,CAAK;AAC7B,UACE,KAAK,cAAcI,CAAI,KACvBA,EAAK,QAAQ,UACbA,EAAK,QAAQ,QACbA,EAAK,MAAM,KACXS,IAAMT,EAAK,YAAYA,EAAK,OAE5BY;AAAA,QAEJ,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,WAAAF,GAAW,WAAAC,GAAW,cAAAC,EAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKQ,OAAOjB,GAAqB;AAClC,WAAO,KAAK,OAAO,SAAS,GAAG,KAAK,OAAO,MAAM,IAAIA,CAAG,KAAKA;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAcC,GAA+C;AACnE,WACEiB,EAASjB,CAAK,KACd,WAAWA,KACX,eAAeA,KACfkB,EAASlB,EAAM,SAAS;AAAA,EAE5B;AACF;AASO,MAAMmB,EAAiC;AAAA,EACpC,4BAAY,IAAA;AAAA,EAEpB,IAAI,SAAiB;AACnB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAIC,GAA8B;AAEhC,WADa,MAAM,KAAK,KAAK,MAAM,MAAM,EAC7BA,CAAK,KAAK;AAAA,EACxB;AAAA,EAEA,QAAQrB,GAA4B;AAClC,WAAO,KAAK,MAAM,IAAIA,CAAG,KAAK;AAAA,EAChC;AAAA,EAEA,QAAQA,GAAaC,GAAqB;AACxC,SAAK,MAAM,IAAID,GAAKC,CAAK;AAAA,EAC3B;AAAA,EAEA,WAAWD,GAAmB;AAC5B,SAAK,MAAM,OAAOA,CAAG;AAAA,EACvB;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAA;AAAA,EACb;AACF;AASO,SAASsB,IAAmC;AACjD,MAAI;AACF,UAAMC,IAAU;AAChB,kBAAO,aAAa,QAAQA,GAAS,MAAM,GAC3C,OAAO,aAAa,WAAWA,CAAO,GAC/B;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAASC,IAAqC;AACnD,MAAI;AACF,UAAMD,IAAU;AAChB,kBAAO,eAAe,QAAQA,GAAS,MAAM,GAC7C,OAAO,eAAe,WAAWA,CAAO,GACjC;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAASE,IAA2B;AACzC,SAAI,OAAO,SAAW,OAAeH,MAC5B,OAAO,eAET,IAAIF,EAAA;AACb;AAKO,SAASM,IAA6B;AAC3C,SAAI,OAAO,SAAW,OAAeF,MAC5B,OAAO,iBAET,IAAIJ,EAAA;AACb;AAKO,SAASO,EAAmB5B,IAAwB,IAAoB;AAC7E,SAAO,IAAIF,EAAe4B,EAAA,GAAmB1B,CAAM;AACrD;AAKO,SAAS6B,EACd7B,IAAwB,IACR;AAChB,SAAO,IAAIF,EAAe6B,EAAA,GAAqB3B,CAAM;AACvD;AAKO,SAAS8B,IAAsC;AACpD,SAAO,IAAIT,EAAA;AACb;AAOA,IAAIU,IAA6C,MAC7CC,IAA+C;AAKnD,SAASC,IAAyC;AAChD,SAAAF,MAAwBH,EAAmB,EAAE,QAAQ,MAAA,CAAO,GACrDG;AACT;AAKA,SAASG,IAA2C;AAClD,SAAAF,MAA0BH,EAAqB,EAAE,QAAQ,MAAA,CAAO,GACzDG;AACT;AAKO,SAASG,EACdlC,GACAC,GACAC,GACS;AACT,SAAO8B,EAAA,EAAyB,IAAIhC,GAAKC,GAAOC,CAAO;AACzD;AAKO,SAASiC,EAAYnC,GAAaO,GAAiC;AACxE,SAAOyB,EAAA,EAAyB,IAAOhC,GAAKO,CAAY;AAC1D;AAKO,SAAS6B,EAAYpC,GAAmB;AAC7C,EAAAgC,EAAA,EAAyB,OAAOhC,CAAG;AACrC;AAKO,SAASqC,EACdrC,GACAC,GACAC,GACS;AACT,SAAO+B,EAAA,EAA2B,IAAIjC,GAAKC,GAAOC,CAAO;AAC3D;AAKO,SAASoC,EAActC,GAAaO,GAAiC;AAC1E,SAAO0B,EAAA,EAA2B,IAAOjC,GAAKO,CAAY;AAC5D;AAKO,SAASgC,EAAcvC,GAAmB;AAC/C,EAAAiC,EAAA,EAA2B,OAAOjC,CAAG;AACvC;AASO,SAASwC,EACd1C,GACAE,GACAyC,GACU;AACV,MAAI;AACF,UAAMjC,IAAMV,EAAQ,QAAQE,CAAG;AAC/B,QAAIQ,KAAQ,QAA6BA,MAAQ,GAAI,QAAO;AAE5D,UAAMkC,IAAkB,KAAK,MAAMlC,CAAG;AACtC,WAAOiC,EAAMC,CAAM,IAAIA,IAAS;AAAA,EAClC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAASC,EACd7C,GACAE,GACAC,GACS;AACT,MAAI;AACF,WAAAH,EAAQ,QAAQE,GAAK,KAAK,UAAUC,CAAK,CAAC,GACnC;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAaO,SAAS2C,EACdC,GACA3C,IAA+C,IACnC;AACZ,MAAI,OAAO,SAAW;AACpB,WAAO,MAAM;AAAA,IAAC;AAGhB,QAAM4C,IAAU,CAACC,MAA8B;AAE7C,IAAI7C,EAAQ,QAAQ,UAAaA,EAAQ,QAAQ,QAAQA,EAAQ,QAAQ,MAAM6C,EAAM,QAAQ7C,EAAQ,OAGjGA,EAAQ,YAAY,UAAaA,EAAQ,YAAY,QAAQ6C,EAAM,gBAAgB7C,EAAQ,WAE/F2C,EAASE,CAAK;AAAA,EAChB;AAEA,gBAAO,iBAAiB,WAAWD,CAAO,GACnC,MAAM,OAAO,oBAAoB,WAAWA,CAAO;AAC5D;AAKO,SAASE,EACdhD,GACA6C,GACA3C,IAAiC,CAAA,GACrB;AACZ,SAAO0C;AAAA,IACL,CAACG,MAAU;AACT,UAAIA,EAAM,QAAQ/C,EAAK;AAEvB,YAAMiD,IAAQ,CAACC,MAAiC;AAC9C,YAAIA,KAAQ,QAA6BA,MAAQ,GAAI,QAAO;AAC5D,YAAI;AACF,iBAAO,KAAK,MAAMA,CAAG;AAAA,QACvB,QAAQ;AACN,iBAAOA;AAAA,QACT;AAAA,MACF;AAEA,MAAAL,EAASI,EAAMF,EAAM,QAAQ,GAAGE,EAAMF,EAAM,QAAQ,CAAC;AAAA,IACvD;AAAA,IACA,EAAE,KAAA/C,GAAK,SAASE,EAAQ,QAAA;AAAA,EAAQ;AAEpC;"}