@walkthru-earth/objex-utils 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/constants.ts","../../../src/lib/file-icons/index.ts","../../../src/lib/query/engine.ts","../../../src/lib/storage/providers.ts","../../../src/lib/storage/url-adapter.ts","../../../src/lib/utils/cloud-url.ts","../../../src/lib/utils/cog.ts","../../../src/lib/utils/column-types.ts","../../../src/lib/utils/error.ts","../../../src/lib/utils/format.ts","../../../src/lib/utils/export.ts","../../../src/lib/utils/file-sort.ts","../../../src/lib/utils/geoarrow.ts","../../../src/lib/utils/hex.ts","../../../src/lib/utils/local-storage.ts","../../../src/lib/utils/markdown-sql.ts","../../../src/lib/utils/parquet-metadata.ts","../../../src/lib/utils/stac-geoparquet.ts","../../../src/lib/utils/storage-url.ts","../../../src/lib/utils/wkb.ts"],"names":["ext","Field","Float64","FixedSizeList","makeData","List","Utf8","Schema","Struct","RecordBatch","Table","globalBounds"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Shared constants used across the application.\n * Centralizes magic strings, numbers, and sets to prevent duplication.\n */\n\n// ── localStorage keys ──\n\nexport const STORAGE_KEYS = {\n\tSETTINGS: 'obstore-explore-settings',\n\tCONNECTIONS: 'obstore-explore-connections',\n\tQUERY_HISTORY: 'obstore-explore-query-history'\n} as const;\n\n// ── Geo / CRS constants ──\n\n/** EPSG codes considered WGS84 (no reprojection needed). */\nexport const WGS84_CODES = new Set([4326, 4979]);\n\n/**\n * Default target CRS for ST_Transform. Uses OGC:CRS84 (longitude, latitude)\n * to match GeoParquet 1.1+ spec and DuckDB v1.5's canonical form.\n * Functionally equivalent to EPSG:4326 under `geometry_always_xy = true`.\n */\nexport const DEFAULT_TARGET_CRS = 'OGC:CRS84';\n\n// ── Query engine constants ──\n\n/** DuckDB-WASM initialization timeout in ms. */\nexport const DUCKDB_INIT_TIMEOUT_MS = 30_000;\n\n/** Maximum entries kept in query history. */\nexport const MAX_QUERY_HISTORY_ENTRIES = 200;\n\n/** SQL preview truncation length (characters). */\nexport const SQL_PREVIEW_LENGTH = 120;\n\n// ── File browser constants ──\n\n/** Extensions that represent \"virtual files\" — directories that open as viewers. */\nexport const VIEWER_DIR_EXTENSIONS = new Set(['zarr', 'zr3']);\n\n// ── PMTiles ──\n\n/**\n * Golden-angle-based hue multiplier for evenly distributing layer colors.\n * 137 ≈ 360 × (1 − 1/φ) where φ is the golden ratio.\n */\nexport const LAYER_HUE_MULTIPLIER = 137;\n\n// ── Clipboard ──\n\n/** Duration (ms) to show \"Copied!\" feedback before resetting. */\nexport const COPY_FEEDBACK_MS = 2000;\n","/**\n * Centralized file type detection module.\n *\n * Single source of truth for extension → icon, color, label, category,\n * viewer, DuckDB read function, MIME type, and queryability.\n *\n * Used by: FileRow, FileTreeSidebar, ViewerRouter, TableViewer, WasmQueryEngine, etc.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type FileCategory =\n\t| 'data'\n\t| 'geo'\n\t| 'code'\n\t| 'document'\n\t| 'config'\n\t| 'image'\n\t| 'video'\n\t| 'audio'\n\t| 'archive'\n\t| 'database'\n\t| '3d'\n\t| 'other';\n\nexport type ViewerKind =\n\t| 'table'\n\t| 'image'\n\t| 'video'\n\t| 'audio'\n\t| 'markdown'\n\t| 'code'\n\t| 'cog'\n\t| 'pmtiles'\n\t| 'flatgeobuf'\n\t| 'pdf'\n\t| '3d'\n\t| 'archive'\n\t| 'database'\n\t| 'zarr'\n\t| 'copc'\n\t| 'notebook'\n\t| 'raw';\n\nexport type DuckDbReadFn = 'read_parquet' | 'read_csv' | 'read_json' | 'ST_Read';\n\nexport interface FileTypeInfo {\n\t/** Lucide icon name */\n\ticon: string;\n\t/** Tailwind color classes (light + dark) */\n\tcolor: string;\n\t/** Human-readable type label, e.g. \"Apache Parquet\" */\n\tlabel: string;\n\t/** High-level category */\n\tcategory: FileCategory;\n\t/** Which viewer component to use */\n\tviewer: ViewerKind;\n\t/** Whether this file can be queried with DuckDB */\n\tqueryable: boolean;\n\t/** DuckDB read function (null if not queryable) */\n\tduckdbReadFn: DuckDbReadFn | null;\n\t/** MIME type */\n\tmimeType: string;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_INFO: FileTypeInfo = {\n\ticon: 'File',\n\tcolor: 'text-zinc-400 dark:text-zinc-500',\n\tlabel: 'File',\n\tcategory: 'other',\n\tviewer: 'raw',\n\tqueryable: false,\n\tduckdbReadFn: null,\n\tmimeType: 'application/octet-stream'\n};\n\nconst FOLDER_INFO: FileTypeInfo = {\n\ticon: 'Folder',\n\tcolor: 'text-blue-500 dark:text-blue-400',\n\tlabel: 'Folder',\n\tcategory: 'other',\n\tviewer: 'raw',\n\tqueryable: false,\n\tduckdbReadFn: null,\n\tmimeType: 'inode/directory'\n};\n\n// ---------------------------------------------------------------------------\n// Extension registry\n// ---------------------------------------------------------------------------\n\nconst EXTENSIONS: Record<string, FileTypeInfo> = {\n\t// ── Data / Tabular ──────────────────────────────────────────────────\n\t'.parquet': {\n\t\ticon: 'Columns3',\n\t\tcolor: 'text-purple-600 dark:text-purple-400',\n\t\tlabel: 'Apache Parquet',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.geoparquet': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'GeoParquet',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.gpq': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'GeoParquet',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.gparquet': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'GeoParquet',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.csv': {\n\t\ticon: 'Table',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'CSV',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_csv',\n\t\tmimeType: 'text/csv'\n\t},\n\t'.tsv': {\n\t\ticon: 'Table',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'TSV',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_csv',\n\t\tmimeType: 'text/tab-separated-values'\n\t},\n\t'.json': {\n\t\ticon: 'Braces',\n\t\tcolor: 'text-yellow-600 dark:text-yellow-400',\n\t\tlabel: 'JSON',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/json'\n\t},\n\t'.jsonl': {\n\t\ticon: 'Braces',\n\t\tcolor: 'text-yellow-500 dark:text-yellow-400',\n\t\tlabel: 'JSON Lines',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_json',\n\t\tmimeType: 'application/x-jsonlines'\n\t},\n\t'.ndjson': {\n\t\ticon: 'Braces',\n\t\tcolor: 'text-yellow-500 dark:text-yellow-400',\n\t\tlabel: 'NDJSON',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_json',\n\t\tmimeType: 'application/x-ndjson'\n\t},\n\t'.geojson': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-emerald-600 dark:text-emerald-400',\n\t\tlabel: 'GeoJSON',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_json',\n\t\tmimeType: 'application/geo+json'\n\t},\n\t'.arrow': {\n\t\ticon: 'Zap',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Apache Arrow',\n\t\tcategory: 'data',\n\t\tviewer: 'raw',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.apache.arrow.file'\n\t},\n\t'.feather': {\n\t\ticon: 'Zap',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Feather',\n\t\tcategory: 'data',\n\t\tviewer: 'raw',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.apache.arrow.file'\n\t},\n\t'.ipc': {\n\t\ticon: 'Zap',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Arrow IPC',\n\t\tcategory: 'data',\n\t\tviewer: 'raw',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.apache.arrow.stream'\n\t},\n\n\t// ── Images ──────────────────────────────────────────────────────────\n\t'.png': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'PNG Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/png'\n\t},\n\t'.jpg': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'JPEG Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/jpeg'\n\t},\n\t'.jpeg': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'JPEG Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/jpeg'\n\t},\n\t'.gif': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'GIF Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/gif'\n\t},\n\t'.webp': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'WebP Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/webp'\n\t},\n\t'.avif': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'AVIF Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/avif'\n\t},\n\t'.svg': {\n\t\ticon: 'Palette',\n\t\tcolor: 'text-pink-600 dark:text-pink-400',\n\t\tlabel: 'SVG',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/svg+xml'\n\t},\n\t'.bmp': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'BMP Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/bmp'\n\t},\n\t'.ico': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'Icon',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/x-icon'\n\t},\n\n\t// ── Video ───────────────────────────────────────────────────────────\n\t'.mp4': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'MP4 Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/mp4'\n\t},\n\t'.webm': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'WebM Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/webm'\n\t},\n\t'.mov': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'MOV Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/quicktime'\n\t},\n\t'.avi': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'AVI Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/x-msvideo'\n\t},\n\t'.mkv': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'MKV Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/x-matroska'\n\t},\n\n\t// ── Audio ───────────────────────────────────────────────────────────\n\t'.mp3': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'MP3 Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/mpeg'\n\t},\n\t'.wav': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'WAV Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/wav'\n\t},\n\t'.ogg': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'OGG Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/ogg'\n\t},\n\t'.flac': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'FLAC Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/flac'\n\t},\n\t'.aac': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'AAC Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/aac'\n\t},\n\n\t// ── Code ────────────────────────────────────────────────────────────\n\t'.py': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-sky-600 dark:text-sky-400',\n\t\tlabel: 'Python',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-python'\n\t},\n\t'.ts': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-600 dark:text-blue-400',\n\t\tlabel: 'TypeScript',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/typescript'\n\t},\n\t'.js': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-yellow-500 dark:text-yellow-400',\n\t\tlabel: 'JavaScript',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/javascript'\n\t},\n\t'.rs': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-700 dark:text-orange-400',\n\t\tlabel: 'Rust',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-rust'\n\t},\n\t'.go': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-cyan-600 dark:text-cyan-400',\n\t\tlabel: 'Go',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-go'\n\t},\n\t'.java': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-red-600 dark:text-red-400',\n\t\tlabel: 'Java',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-java'\n\t},\n\t'.c': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c'\n\t},\n\t'.cpp': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C++',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c++'\n\t},\n\t'.h': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C Header',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c'\n\t},\n\t'.hpp': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C++ Header',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c++'\n\t},\n\t'.rb': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-red-500 dark:text-red-400',\n\t\tlabel: 'Ruby',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-ruby'\n\t},\n\t'.php': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-indigo-500 dark:text-indigo-400',\n\t\tlabel: 'PHP',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-php'\n\t},\n\t'.swift': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Swift',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-swift'\n\t},\n\t'.kt': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'Kotlin',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-kotlin'\n\t},\n\t'.scala': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-red-600 dark:text-red-400',\n\t\tlabel: 'Scala',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-scala'\n\t},\n\t'.r': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-600 dark:text-blue-400',\n\t\tlabel: 'R',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-r'\n\t},\n\t'.lua': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-800 dark:text-blue-400',\n\t\tlabel: 'Lua',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-lua'\n\t},\n\t'.html': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-orange-600 dark:text-orange-400',\n\t\tlabel: 'HTML',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/html'\n\t},\n\t'.css': {\n\t\ticon: 'Paintbrush',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'CSS',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/css'\n\t},\n\t'.sql': {\n\t\ticon: 'DatabaseZap',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'SQL',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-sql'\n\t},\n\t'.sh': {\n\t\ticon: 'Terminal',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'Shell Script',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-shellscript'\n\t},\n\t'.bash': {\n\t\ticon: 'Terminal',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'Bash Script',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-shellscript'\n\t},\n\t'.vim': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-green-700 dark:text-green-400',\n\t\tlabel: 'Vim Script',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.dockerfile': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-600 dark:text-blue-400',\n\t\tlabel: 'Dockerfile',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.makefile': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-600 dark:text-orange-400',\n\t\tlabel: 'Makefile',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\n\t// ── Documents ───────────────────────────────────────────────────────\n\t'.md': {\n\t\ticon: 'BookText',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'Markdown',\n\t\tcategory: 'document',\n\t\tviewer: 'markdown',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/markdown'\n\t},\n\t'.markdown': {\n\t\ticon: 'BookText',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'Markdown',\n\t\tcategory: 'document',\n\t\tviewer: 'markdown',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/markdown'\n\t},\n\t'.pdf': {\n\t\ticon: 'FileText',\n\t\tcolor: 'text-red-600 dark:text-red-400',\n\t\tlabel: 'PDF',\n\t\tcategory: 'document',\n\t\tviewer: 'pdf',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/pdf'\n\t},\n\t'.txt': {\n\t\ticon: 'FileText',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Text',\n\t\tcategory: 'document',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.log': {\n\t\ticon: 'FileText',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Log File',\n\t\tcategory: 'document',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\n\t// ── Config ──────────────────────────────────────────────────────────\n\t'.xml': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'XML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/xml'\n\t},\n\t'.yaml': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'YAML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/yaml'\n\t},\n\t'.yml': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'YAML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/yaml'\n\t},\n\t'.toml': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'TOML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.ini': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'INI',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.cfg': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Config',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.conf': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Config',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.env': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Environment',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\n\t// ── Archives ────────────────────────────────────────────────────────\n\t'.zip': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'ZIP Archive',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/zip'\n\t},\n\t'.tar': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'TAR Archive',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-tar'\n\t},\n\t'.gz': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'GZIP',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/gzip'\n\t},\n\t'.tgz': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'TGZ Archive',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/gzip'\n\t},\n\t'.7z': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: '7-Zip',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-7z-compressed'\n\t},\n\t'.rar': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'RAR',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.rar'\n\t},\n\t'.bz2': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'BZIP2',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-bzip2'\n\t},\n\n\t// ── Geo / Map ───────────────────────────────────────────────────────\n\t'.tif': {\n\t\ticon: 'Map',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'GeoTIFF',\n\t\tcategory: 'geo',\n\t\tviewer: 'cog',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/tiff'\n\t},\n\t'.tiff': {\n\t\ticon: 'Map',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'GeoTIFF',\n\t\tcategory: 'geo',\n\t\tviewer: 'cog',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/tiff'\n\t},\n\t'.pmtiles': {\n\t\ticon: 'Layers',\n\t\tcolor: 'text-teal-600 dark:text-teal-400',\n\t\tlabel: 'PMTiles',\n\t\tcategory: 'geo',\n\t\tviewer: 'pmtiles',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.fgb': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-teal-500 dark:text-teal-400',\n\t\tlabel: 'FlatGeobuf',\n\t\tcategory: 'geo',\n\t\tviewer: 'flatgeobuf',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.shp': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'Shapefile',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'ST_Read',\n\t\tmimeType: 'application/x-esri-shape'\n\t},\n\t'.gpkg': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'GeoPackage',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'ST_Read',\n\t\tmimeType: 'application/geopackage+sqlite3'\n\t},\n\n\t// ── Database ────────────────────────────────────────────────────────\n\t'.duckdb': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-yellow-600 dark:text-yellow-400',\n\t\tlabel: 'DuckDB',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: true,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.ducklake': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-teal-600 dark:text-teal-400',\n\t\tlabel: 'DuckLake',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: true,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.sqlite': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-sky-600 dark:text-sky-400',\n\t\tlabel: 'SQLite',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-sqlite3'\n\t},\n\t'.db': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-amber-500 dark:text-amber-400',\n\t\tlabel: 'Database',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\n\t// ── 3D Models ───────────────────────────────────────────────────────\n\t'.glb': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'GLB Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'model/gltf-binary'\n\t},\n\t'.gltf': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'glTF Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'model/gltf+json'\n\t},\n\t'.obj': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'OBJ Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.stl': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'STL Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'model/stl'\n\t},\n\t'.fbx': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'FBX Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\n\t// ── Notebooks ───────────────────────────────────────────────────────\n\t'.ipynb': {\n\t\ticon: 'BookOpen',\n\t\tcolor: 'text-orange-600 dark:text-orange-400',\n\t\tlabel: 'Jupyter Notebook',\n\t\tcategory: 'code',\n\t\tviewer: 'notebook',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-ipynb+json'\n\t},\n\n\t// ── Special ─────────────────────────────────────────────────────────\n\t'.zarr': {\n\t\ticon: 'Layers',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'Zarr',\n\t\tcategory: 'data',\n\t\tviewer: 'zarr',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.zr3': {\n\t\ticon: 'Layers',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'Zarr',\n\t\tcategory: 'data',\n\t\tviewer: 'zarr',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\n\t// ── Point Cloud ─────────────────────────────────────────────────────\n\t'.laz': {\n\t\ticon: 'Orbit',\n\t\tcolor: 'text-cyan-600 dark:text-cyan-400',\n\t\tlabel: 'COPC / LAZ',\n\t\tcategory: 'geo',\n\t\tviewer: 'copc',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.las': {\n\t\ticon: 'Orbit',\n\t\tcolor: 'text-cyan-600 dark:text-cyan-400',\n\t\tlabel: 'LAS Point Cloud',\n\t\tcategory: 'geo',\n\t\tviewer: 'copc',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Returns full file type information for a given extension.\n * Extension may be with or without leading dot: \".parquet\" or \"parquet\".\n */\nexport function getFileTypeInfo(extension: string, isDir = false): FileTypeInfo {\n\tif (isDir && extension) {\n\t\tconst ext = extension.startsWith('.') ? extension.toLowerCase() : `.${extension.toLowerCase()}`;\n\t\tconst found = EXTENSIONS[ext];\n\t\tif (found) return found;\n\t}\n\tif (isDir) return FOLDER_INFO;\n\tconst ext = extension.startsWith('.') ? extension.toLowerCase() : `.${extension.toLowerCase()}`;\n\treturn EXTENSIONS[ext] ?? DEFAULT_INFO;\n}\n\n/** Returns the DuckDB read function name for a file path. Falls back to read_parquet. */\nexport function getDuckDbReadFn(pathOrExt: string): string {\n\tconst ext = pathOrExt.includes('.') ? `.${pathOrExt.split('.').pop()!.toLowerCase()}` : '';\n\treturn EXTENSIONS[ext]?.duckdbReadFn ?? 'read_parquet';\n}\n\n/**\n * Returns a DuckDB FROM-clause expression for a file.\n *\n * For GeoJSON files the raw `read_json_auto` returns a single row with the\n * FeatureCollection structure (`type`, `features`, `bbox`). This helper\n * unnests the features array so each feature becomes its own row with\n * property columns + a geometry column.\n */\nexport function buildDuckDbSource(pathOrExt: string, url: string): string {\n\tconst ext = pathOrExt.includes('.') ? `.${pathOrExt.split('.').pop()!.toLowerCase()}` : '';\n\tif (ext === '.geojson') {\n\t\treturn `(SELECT unnest(feature.properties), to_json(feature.geometry)::VARCHAR AS geometry FROM (SELECT unnest(features) AS feature FROM read_json_auto('${url}', maximum_object_size=1073741824, ignore_errors=true)))`;\n\t}\n\tconst readFn = EXTENSIONS[ext]?.duckdbReadFn ?? 'read_parquet';\n\treturn `${readFn}('${url}')`;\n}\n\n/**\n * Cloud-native formats that DuckDB can query via range requests — metadata\n * reads (schema, row count) are cheap and don't download the full file.\n *\n * Other cloud-native formats (.fgb, .pmtiles, .zarr) also support range\n * requests but have dedicated viewers and don't go through DuckDB/TableViewer.\n */\nconst CLOUD_NATIVE_EXTS = new Set(['.parquet', '.geoparquet', '.gpq', '.gparquet', '.ducklake']);\n\nexport function isCloudNativeFormat(pathOrExt: string): boolean {\n\tconst ext = pathOrExt.includes('.') ? `.${pathOrExt.split('.').pop()!.toLowerCase()}` : '';\n\treturn CLOUD_NATIVE_EXTS.has(ext);\n}\n\n/** Returns the viewer kind for a given extension. */\nexport function getViewerKind(extension: string): ViewerKind {\n\treturn getFileTypeInfo(extension).viewer;\n}\n\n/** Returns whether a file can be queried with DuckDB. */\nexport function isQueryable(extension: string): boolean {\n\treturn getFileTypeInfo(extension).queryable;\n}\n\n/** Returns the MIME type for a file extension. */\nexport function getMimeType(extension: string): string {\n\treturn getFileTypeInfo(extension).mimeType;\n}\n\n/** Re-export folder info for components that need it directly. */\nexport { DEFAULT_INFO, FOLDER_INFO };\n","export class QueryCancelledError extends Error {\n\tconstructor() {\n\t\tsuper('Query cancelled');\n\t\tthis.name = 'QueryCancelledError';\n\t}\n}\n\nexport interface QueryHandle {\n\tresult: Promise<QueryResult>;\n\tcancel: () => Promise<boolean>;\n}\n\nexport interface MapQueryHandle {\n\tresult: Promise<MapQueryResult>;\n\tcancel: () => Promise<boolean>;\n}\n\nexport interface QueryResult {\n\tcolumns: string[];\n\ttypes: string[];\n\trowCount: number;\n\t/** Pre-parsed rows — avoids Arrow version mismatch in WASM engine */\n\trows: Record<string, any>[];\n}\n\n/** Raw column data for map rendering (bypasses toJSON serialization). */\nexport interface MapQueryResult {\n\t/** Geometry column as raw WKB binary arrays */\n\twkbArrays: Uint8Array[];\n\t/** Geometry type from ST_GeometryType (e.g., 'POLYGON') */\n\tgeometryType: string;\n\t/** Non-geometry attribute columns: name → JS values */\n\tattributes: Map<string, { values: any[]; type: string }>;\n\t/** Number of rows */\n\trowCount: number;\n}\n\nexport interface SchemaField {\n\tname: string;\n\ttype: string;\n\tnullable: boolean;\n}\n\n/**\n * Abstraction over a DuckDB query source. Decouples schema / CRS / count\n * helpers from assuming a file-backed path. `ref` is the FROM-clause target\n * inserted into generated SQL (e.g. `read_parquet('url')` for files, or\n * `attached_db.\"schema\".\"table\"` for attached databases). `filePath` is\n * optional and only used as a shortcut for Parquet file-level metadata\n * queries (`parquet_kv_metadata`, `parquet_file_metadata`), not for SQL.\n */\nexport interface QuerySource {\n\tref: string;\n\tfilePath?: string;\n}\n\nexport interface QueryEngine {\n\tquery(connId: string, sql: string): Promise<QueryResult>;\n\tqueryForMap(\n\t\tconnId: string,\n\t\tsql: string,\n\t\tgeomCol: string,\n\t\tgeomColType: string,\n\t\tsourceCrs?: string | null\n\t): Promise<MapQueryResult>;\n\tgetSchema(connId: string, source: QuerySource): Promise<SchemaField[]>;\n\tgetRowCount(connId: string, source: QuerySource): Promise<number>;\n\t/** Detect CRS from GeoParquet metadata. Returns e.g. 'EPSG:27700' or null if WGS84/unknown. */\n\tdetectCrs(connId: string, source: QuerySource, geomCol: string): Promise<string | null>;\n\t/** Combined schema + CRS detection in a single connection (fewer web worker round-trips). */\n\tgetSchemaAndCrs?(\n\t\tconnId: string,\n\t\tsource: QuerySource,\n\t\tfindGeoCol: (schema: SchemaField[]) => string | null\n\t): Promise<{ schema: SchemaField[]; geomCol: string | null; crs: string | null }>;\n\tqueryCancellable?(connId: string, sql: string): QueryHandle;\n\tqueryForMapCancellable?(\n\t\tconnId: string,\n\t\tsql: string,\n\t\tgeomCol: string,\n\t\tgeomColType: string,\n\t\tsourceCrs?: string | null\n\t): MapQueryHandle;\n\tforceCancel?(): Promise<void>;\n\t/** Register a file buffer in DuckDB-WASM's virtual filesystem for ATTACH. */\n\tregisterFileBuffer?(name: string, buffer: Uint8Array): Promise<void>;\n\t/** Drop a previously registered file from DuckDB-WASM's virtual filesystem. */\n\tdropFile?(name: string): Promise<void>;\n\treleaseMemory(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n","/**\n * Provider registry — single source of truth for all cloud storage providers.\n *\n * Centralizes endpoint patterns, regions, auth methods, and UI metadata.\n * Used by ConnectionDialog, browser-cloud adapter, host-detection, url-state, etc.\n */\n\n// ---------------------------------------------------------------------------\n// Provider type — the canonical union used by Connection, ConnectionConfig, etc.\n// ---------------------------------------------------------------------------\n\nexport type ProviderId =\n\t| 's3'\n\t| 'gcs'\n\t| 'r2'\n\t| 'minio'\n\t| 'azure'\n\t| 'storj'\n\t| 'b2'\n\t| 'digitalocean'\n\t| 'wasabi'\n\t| 'contabo'\n\t| 'hetzner'\n\t| 'linode'\n\t| 'ovhcloud';\n\n// ---------------------------------------------------------------------------\n// Region definition\n// ---------------------------------------------------------------------------\n\nexport interface ProviderRegion {\n\tcode: string;\n\tlabel: string;\n}\n\n// ---------------------------------------------------------------------------\n// Provider definition\n// ---------------------------------------------------------------------------\n\nexport interface ProviderDef {\n\t/** Display label in the UI. */\n\tlabel: string;\n\t/** Short description shown as helper text. */\n\tdescription: string;\n\t/** Auth method used by this provider. */\n\tauthMethod: 'sigv4' | 'sas-token';\n\t/** Whether the region field is relevant for this provider. */\n\tneedsRegion: boolean;\n\t/** Whether the endpoint field is required. */\n\tneedsEndpoint: boolean;\n\t/** Default region when creating a new connection. */\n\tdefaultRegion: string;\n\t/**\n\t * Endpoint template with `{region}` placeholder.\n\t * If null, the user must provide a custom endpoint (e.g. MinIO).\n\t * If a fixed string (no `{region}`), it's always the same (e.g. GCS).\n\t */\n\tendpointTemplate: string | null;\n\t/** Known regions with labels. Empty = free-form region input. */\n\tregions: ProviderRegion[];\n\t/** Bucket label override (e.g. Azure uses \"Container\"). */\n\tbucketLabel?: string;\n\t/** Default endpoint placeholder shown in the input. */\n\tendpointPlaceholder: string;\n\t/** URI schemes that map to this provider (lowercase, without \"://\"). */\n\tschemes: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nexport const PROVIDERS: Record<ProviderId, ProviderDef> = {\n\ts3: {\n\t\tlabel: 'AWS S3',\n\t\tdescription: 'Amazon S3 or any S3-compatible service',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: null,\n\t\tregions: [\n\t\t\t{ code: 'us-east-1', label: 'US East (N. Virginia)' },\n\t\t\t{ code: 'us-east-2', label: 'US East (Ohio)' },\n\t\t\t{ code: 'us-west-1', label: 'US West (N. California)' },\n\t\t\t{ code: 'us-west-2', label: 'US West (Oregon)' },\n\t\t\t{ code: 'eu-west-1', label: 'EU (Ireland)' },\n\t\t\t{ code: 'eu-west-2', label: 'EU (London)' },\n\t\t\t{ code: 'eu-west-3', label: 'EU (Paris)' },\n\t\t\t{ code: 'eu-central-1', label: 'EU (Frankfurt)' },\n\t\t\t{ code: 'eu-central-2', label: 'EU (Zurich)' },\n\t\t\t{ code: 'eu-north-1', label: 'EU (Stockholm)' },\n\t\t\t{ code: 'eu-south-1', label: 'EU (Milan)' },\n\t\t\t{ code: 'eu-south-2', label: 'EU (Spain)' },\n\t\t\t{ code: 'ap-northeast-1', label: 'Asia Pacific (Tokyo)' },\n\t\t\t{ code: 'ap-northeast-2', label: 'Asia Pacific (Seoul)' },\n\t\t\t{ code: 'ap-northeast-3', label: 'Asia Pacific (Osaka)' },\n\t\t\t{ code: 'ap-southeast-1', label: 'Asia Pacific (Singapore)' },\n\t\t\t{ code: 'ap-southeast-2', label: 'Asia Pacific (Sydney)' },\n\t\t\t{ code: 'ap-southeast-3', label: 'Asia Pacific (Jakarta)' },\n\t\t\t{ code: 'ap-south-1', label: 'Asia Pacific (Mumbai)' },\n\t\t\t{ code: 'ap-south-2', label: 'Asia Pacific (Hyderabad)' },\n\t\t\t{ code: 'ap-east-1', label: 'Asia Pacific (Hong Kong)' },\n\t\t\t{ code: 'sa-east-1', label: 'South America (São Paulo)' },\n\t\t\t{ code: 'ca-central-1', label: 'Canada (Central)' },\n\t\t\t{ code: 'ca-west-1', label: 'Canada (Calgary)' },\n\t\t\t{ code: 'me-south-1', label: 'Middle East (Bahrain)' },\n\t\t\t{ code: 'me-central-1', label: 'Middle East (UAE)' },\n\t\t\t{ code: 'af-south-1', label: 'Africa (Cape Town)' },\n\t\t\t{ code: 'il-central-1', label: 'Israel (Tel Aviv)' }\n\t\t],\n\t\tendpointPlaceholder: 'Leave empty for AWS, or enter custom S3 endpoint',\n\t\tschemes: ['s3', 's3a', 's3n', 'aws']\n\t},\n\n\tgcs: {\n\t\tlabel: 'Google Cloud',\n\t\tdescription: 'Google Cloud Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'auto',\n\t\tendpointTemplate: 'https://storage.googleapis.com',\n\t\tregions: [],\n\t\tendpointPlaceholder: 'https://storage.googleapis.com',\n\t\tschemes: ['gs', 'gcs']\n\t},\n\n\tr2: {\n\t\tlabel: 'Cloudflare R2',\n\t\tdescription: 'Cloudflare R2 Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: true,\n\t\tdefaultRegion: 'auto',\n\t\tendpointTemplate: null,\n\t\tregions: [],\n\t\tendpointPlaceholder: 'https://<account-id>.r2.cloudflarestorage.com',\n\t\tschemes: ['r2']\n\t},\n\n\tazure: {\n\t\tlabel: 'Azure',\n\t\tdescription: 'Azure Blob Storage',\n\t\tauthMethod: 'sas-token',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: true,\n\t\tdefaultRegion: '',\n\t\tendpointTemplate: null,\n\t\tregions: [],\n\t\tbucketLabel: 'Container',\n\t\tendpointPlaceholder: 'https://<account>.blob.core.windows.net',\n\t\tschemes: ['azure', 'az', 'abfs', 'abfss', 'wasbs', 'adl']\n\t},\n\n\tminio: {\n\t\tlabel: 'MinIO',\n\t\tdescription: 'Self-hosted MinIO or S3-compatible',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: true,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: null,\n\t\tregions: [],\n\t\tendpointPlaceholder: 'https://minio.example.com or http://localhost:9000',\n\t\tschemes: []\n\t},\n\n\tstorj: {\n\t\tlabel: 'Storj',\n\t\tdescription: 'Storj Decentralized Cloud',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us1',\n\t\tendpointTemplate: 'https://gateway.storjshare.io',\n\t\tregions: [\n\t\t\t{ code: 'us1', label: 'US1' },\n\t\t\t{ code: 'eu1', label: 'EU1' },\n\t\t\t{ code: 'ap1', label: 'AP1' }\n\t\t],\n\t\tendpointPlaceholder: 'https://gateway.storjshare.io',\n\t\tschemes: ['storj', 'sj']\n\t},\n\n\tb2: {\n\t\tlabel: 'Backblaze B2',\n\t\tdescription: 'Backblaze B2 Cloud Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-west-004',\n\t\tendpointTemplate: 'https://s3.{region}.backblazeb2.com',\n\t\tregions: [\n\t\t\t{ code: 'us-west-000', label: 'US West (Sacramento)' },\n\t\t\t{ code: 'us-west-001', label: 'US West (Stockton)' },\n\t\t\t{ code: 'us-west-002', label: 'US West (Phoenix)' },\n\t\t\t{ code: 'us-west-004', label: 'US West' },\n\t\t\t{ code: 'us-east-005', label: 'US East (Reston)' },\n\t\t\t{ code: 'eu-central-003', label: 'EU Central (Amsterdam)' },\n\t\t\t{ code: 'ca-central-001', label: 'Canada (Toronto)' }\n\t\t],\n\t\tendpointPlaceholder: 'https://s3.us-west-004.backblazeb2.com',\n\t\tschemes: []\n\t},\n\n\tdigitalocean: {\n\t\tlabel: 'DigitalOcean',\n\t\tdescription: 'DigitalOcean Spaces',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'nyc3',\n\t\tendpointTemplate: 'https://{region}.digitaloceanspaces.com',\n\t\tregions: [\n\t\t\t{ code: 'nyc3', label: 'New York 3' },\n\t\t\t{ code: 'sfo3', label: 'San Francisco 3' },\n\t\t\t{ code: 'ams3', label: 'Amsterdam 3' },\n\t\t\t{ code: 'sgp1', label: 'Singapore 1' },\n\t\t\t{ code: 'lon1', label: 'London 1' },\n\t\t\t{ code: 'fra1', label: 'Frankfurt 1' },\n\t\t\t{ code: 'tor1', label: 'Toronto 1' },\n\t\t\t{ code: 'blr1', label: 'Bangalore 1' },\n\t\t\t{ code: 'syd1', label: 'Sydney 1' }\n\t\t],\n\t\tendpointPlaceholder: 'https://nyc3.digitaloceanspaces.com',\n\t\tschemes: []\n\t},\n\n\twasabi: {\n\t\tlabel: 'Wasabi',\n\t\tdescription: 'Wasabi Hot Cloud Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: 'https://s3.{region}.wasabisys.com',\n\t\tregions: [\n\t\t\t{ code: 'us-east-1', label: 'US East 1 (Virginia)' },\n\t\t\t{ code: 'us-east-2', label: 'US East 2 (Virginia)' },\n\t\t\t{ code: 'us-central-1', label: 'US Central 1 (Texas)' },\n\t\t\t{ code: 'us-west-1', label: 'US West 1 (Oregon)' },\n\t\t\t{ code: 'eu-central-1', label: 'EU Central 1 (Amsterdam)' },\n\t\t\t{ code: 'eu-central-2', label: 'EU Central 2 (Frankfurt)' },\n\t\t\t{ code: 'eu-west-1', label: 'EU West 1 (London)' },\n\t\t\t{ code: 'eu-west-2', label: 'EU West 2 (Paris)' },\n\t\t\t{ code: 'ap-northeast-1', label: 'AP Northeast 1 (Tokyo)' },\n\t\t\t{ code: 'ap-northeast-2', label: 'AP Northeast 2 (Osaka)' },\n\t\t\t{ code: 'ap-southeast-1', label: 'AP Southeast 1 (Singapore)' },\n\t\t\t{ code: 'ap-southeast-2', label: 'AP Southeast 2 (Sydney)' },\n\t\t\t{ code: 'ca-central-1', label: 'Canada (Toronto)' }\n\t\t],\n\t\tendpointPlaceholder: 'https://s3.us-east-1.wasabisys.com',\n\t\tschemes: []\n\t},\n\n\tcontabo: {\n\t\tlabel: 'Contabo',\n\t\tdescription: 'Contabo Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'eu2',\n\t\tendpointTemplate: 'https://{region}.contabostorage.com',\n\t\tregions: [\n\t\t\t{ code: 'eu2', label: 'European Union' },\n\t\t\t{ code: 'usc1', label: 'US Central' },\n\t\t\t{ code: 'sin1', label: 'Singapore' }\n\t\t],\n\t\tendpointPlaceholder: 'https://eu2.contabostorage.com',\n\t\tschemes: []\n\t},\n\n\thetzner: {\n\t\tlabel: 'Hetzner',\n\t\tdescription: 'Hetzner Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'fsn1',\n\t\tendpointTemplate: 'https://{region}.your-objectstorage.com',\n\t\tregions: [\n\t\t\t{ code: 'fsn1', label: 'Falkenstein, DE' },\n\t\t\t{ code: 'nbg1', label: 'Nuremberg, DE' },\n\t\t\t{ code: 'hel1', label: 'Helsinki, FI' }\n\t\t],\n\t\tendpointPlaceholder: 'https://fsn1.your-objectstorage.com',\n\t\tschemes: []\n\t},\n\n\tlinode: {\n\t\tlabel: 'Linode / Akamai',\n\t\tdescription: 'Akamai / Linode Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: 'https://{region}.linodeobjects.com',\n\t\tregions: [\n\t\t\t{ code: 'us-east-1', label: 'Newark, NJ' },\n\t\t\t{ code: 'us-southeast-1', label: 'Atlanta, GA' },\n\t\t\t{ code: 'us-ord-1', label: 'Chicago, IL' },\n\t\t\t{ code: 'us-iad-1', label: 'Washington, DC' },\n\t\t\t{ code: 'us-lax-1', label: 'Los Angeles, CA' },\n\t\t\t{ code: 'us-sea-1', label: 'Seattle, WA' },\n\t\t\t{ code: 'us-mia-1', label: 'Miami, FL' },\n\t\t\t{ code: 'eu-central-1', label: 'Frankfurt, DE' },\n\t\t\t{ code: 'nl-ams-1', label: 'Amsterdam, NL' },\n\t\t\t{ code: 'gb-lon-1', label: 'London, UK' },\n\t\t\t{ code: 'fr-par-1', label: 'Paris, FR' },\n\t\t\t{ code: 'ap-south-1', label: 'Singapore' },\n\t\t\t{ code: 'jp-osa-1', label: 'Osaka, JP' },\n\t\t\t{ code: 'au-mel-1', label: 'Melbourne, AU' },\n\t\t\t{ code: 'br-gru-1', label: 'São Paulo, BR' },\n\t\t\t{ code: 'in-maa-1', label: 'Chennai, IN' },\n\t\t\t{ code: 'id-cgk-1', label: 'Jakarta, ID' },\n\t\t\t{ code: 'it-mil-1', label: 'Milan, IT' },\n\t\t\t{ code: 'se-sto-1', label: 'Stockholm, SE' }\n\t\t],\n\t\tendpointPlaceholder: 'https://us-east-1.linodeobjects.com',\n\t\tschemes: []\n\t},\n\n\tovhcloud: {\n\t\tlabel: 'OVHcloud',\n\t\tdescription: 'OVHcloud Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'gra',\n\t\tendpointTemplate: 'https://s3.{region}.io.cloud.ovh.net',\n\t\tregions: [\n\t\t\t{ code: 'gra', label: 'Gravelines, FR' },\n\t\t\t{ code: 'sbg', label: 'Strasbourg, FR' },\n\t\t\t{ code: 'bhs', label: 'Beauharnois, CA' },\n\t\t\t{ code: 'de', label: 'Frankfurt, DE' },\n\t\t\t{ code: 'uk', label: 'London, UK' },\n\t\t\t{ code: 'waw', label: 'Warsaw, PL' }\n\t\t],\n\t\tendpointPlaceholder: 'https://s3.gra.io.cloud.ovh.net',\n\t\tschemes: []\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// CORS help — provider-specific browser access guidance\n// ---------------------------------------------------------------------------\n\nexport interface CorsHelp {\n\t/** True if the provider returns CORS headers by default. */\n\tdefaultEnabled: boolean;\n\t/** Official CORS configuration docs URL. */\n\tdocsUrl?: string;\n\t/** Brief note shown in the UI. */\n\tnote?: string;\n\t/** CLI steps when no console UI or docs are insufficient. */\n\tcliSteps?: string[];\n}\n\nexport const CORS_HELP: Record<ProviderId, CorsHelp> = {\n\ts3: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html',\n\t\tnote: 'Enable via S3 Console: Bucket > Permissions > CORS, or use the AWS CLI.'\n\t},\n\tgcs: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://cloud.google.com/storage/docs/using-cors',\n\t\tnote: 'Use the gcloud CLI. GCS `responseHeader` is dual-purpose (Access-Control-Expose-Headers AND Access-Control-Allow-Headers), so every request header the browser sends must be listed or the preflight fails silently. For private buckets signed with HMAC, include the AWS SigV4 headers (Authorization, x-amz-date, x-amz-content-sha256). For DuckDB httpfs partial reads, also include Range and the conditional If-* headers.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n[\\n {\\n \"origin\": [\"*\"],\\n \"method\": [\"GET\", \"HEAD\"],\\n \"responseHeader\": [\\n \"Content-Type\",\\n \"Content-Length\",\\n \"Content-Range\",\\n \"Accept-Ranges\",\\n \"Range\",\\n \"If-Match\",\\n \"If-Modified-Since\",\\n \"If-None-Match\",\\n \"If-Unmodified-Since\",\\n \"ETag\",\\n \"Authorization\",\\n \"x-amz-content-sha256\",\\n \"x-amz-date\",\\n \"x-amz-*\",\\n \"x-goog-*\"\\n ],\\n \"maxAgeSeconds\": 3600\\n }\\n]',\n\t\t\t'gcloud storage buckets update gs://BUCKET --cors-file=cors.json'\n\t\t]\n\t},\n\tr2: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://developers.cloudflare.com/r2/buckets/cors/',\n\t\tnote: 'Enable via R2 Dashboard: Bucket > Settings > CORS Policy.'\n\t},\n\tazure: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl:\n\t\t\t'https://learn.microsoft.com/en-us/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services',\n\t\tnote: 'Enable via Azure Portal: Storage Account > Blob Service > CORS, or use the Azure CLI.',\n\t\tcliSteps: [\n\t\t\t'az storage cors add --services b --methods GET HEAD \\\\\\n --origins \"*\" --allowed-headers \"*\" \\\\\\n --exposed-headers \"*\" --max-age 3600 \\\\\\n --account-name ACCOUNT'\n\t\t]\n\t},\n\tminio: {\n\t\tdefaultEnabled: true,\n\t\tdocsUrl: 'https://docs.min.io/enterprise/aistor-object-store/reference/cli/mc-cors/',\n\t\tnote: 'MinIO allows all origins by default. For custom rules, use mc cors set.'\n\t},\n\tstorj: {\n\t\tdefaultEnabled: true,\n\t\tnote: 'Storj S3 gateway returns CORS headers by default.'\n\t},\n\tb2: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://www.backblaze.com/docs/cloud-storage-cross-origin-resource-sharing-rules',\n\t\tnote: 'Enable via B2 Console: Bucket Settings > CORS Rules, or use the B2 CLI.',\n\t\tcliSteps: [\n\t\t\t'b2 bucket update --cors-rules \\'[{\\n \"corsRuleName\": \"allow-all\",\\n \"allowedOrigins\": [\"*\"],\\n \"allowedOperations\": [\"s3_head\", \"s3_get\"],\\n \"allowedHeaders\": [\"*\"],\\n \"maxAgeSeconds\": 3600\\n}]\\' BUCKET allPublic'\n\t\t]\n\t},\n\tdigitalocean: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://docs.digitalocean.com/products/spaces/how-to/configure-cors/',\n\t\tnote: 'Enable via Control Panel: Space > Settings > CORS Configurations.'\n\t},\n\twasabi: {\n\t\tdefaultEnabled: true,\n\t\tdocsUrl: 'https://docs.wasabi.com/docs/bucket-policy',\n\t\tnote: 'Wasabi returns CORS headers by default for all buckets.'\n\t},\n\tcontabo: {\n\t\tdefaultEnabled: false,\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://REGION.contaboobj.com'\n\t\t]\n\t},\n\thetzner: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://docs.hetzner.com/storage/object-storage/howto-protect-objects/cors/',\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://REGION.your-objectstorage.com \\\\\\n --region REGION'\n\t\t]\n\t},\n\tlinode: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://www.linode.com/docs/guides/working-with-cors-linode-object-storage/',\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://REGION.linodeobjects.com'\n\t\t]\n\t},\n\tovhcloud: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl:\n\t\t\t'https://help.ovhcloud.com/csm/en-public-cloud-storage-s3-cors?id=kb_article_view&sysparm_article=KB0058291',\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://s3.REGION.io.cloud.ovh.net'\n\t\t]\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// Read-only access help — provider-specific bucket policy guidance\n// ---------------------------------------------------------------------------\n\nexport interface ReadOnlyHelp {\n\t/** Brief note shown in the UI. */\n\tnote: string;\n\t/** Official docs URL. */\n\tdocsUrl?: string;\n\t/** CLI steps to apply a read-only bucket policy. */\n\tcliSteps?: string[];\n}\n\nexport const READ_ONLY_HELP: Partial<Record<ProviderId, ReadOnlyHelp>> = {\n\ts3: {\n\t\tnote: 'Use IAM policies to create a read-only user, or apply a bucket policy that allows only s3:GetObject and s3:ListBucket.',\n\t\tdocsUrl: 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-policies-s3.html'\n\t},\n\tgcs: {\n\t\tnote: 'Assign the Storage Object Viewer role (roles/storage.objectViewer) to the service account.',\n\t\tdocsUrl: 'https://cloud.google.com/storage/docs/access-control/iam-roles'\n\t},\n\tr2: {\n\t\tnote: 'Create an API token with Object Read permissions in the R2 dashboard.',\n\t\tdocsUrl: 'https://developers.cloudflare.com/r2/api/tokens/'\n\t},\n\tazure: {\n\t\tnote: 'Generate a SAS token with Read and List permissions only. Avoid granting Write or Delete.',\n\t\tdocsUrl: 'https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview'\n\t},\n\tb2: {\n\t\tnote: 'Create an application key with readFiles and listBuckets capabilities only.',\n\t\tdocsUrl: 'https://www.backblaze.com/docs/cloud-storage-application-keys'\n\t},\n\thetzner: {\n\t\tnote: 'Keys have full read/write by default. Use a bucket policy with the correct ARN format to deny write and policy actions. To undo, generate a new admin key from the Hetzner Console.',\n\t\tdocsUrl:\n\t\t\t'https://docs.hetzner.com/storage/object-storage/faq/s3-credentials/#how-do-i-restrict-access-per-key',\n\t\tcliSteps: [\n\t\t\t'Find your project ID from the Hetzner Console URL:\\nhttps://console.hetzner.com/projects/<PROJECT_ID>/servers',\n\t\t\t'Create a policy.json file:\\n{\\n \"Version\": \"2012-10-17\",\\n \"Statement\": [\\n {\\n \"Sid\": \"DenyWrites\",\\n \"Effect\": \"Deny\",\\n \"Principal\": {\\n \"AWS\": \"arn:aws:iam:::user/p<PROJECT_ID>:<ACCESS_KEY>\"\\n },\\n \"Action\": [\\n \"s3:PutObject\",\\n \"s3:DeleteObject\",\\n \"s3:AbortMultipartUpload\",\\n \"s3:PutBucketPolicy\",\\n \"s3:DeleteBucketPolicy\"\\n ],\\n \"Resource\": [\\n \"arn:aws:s3:::BUCKET\",\\n \"arn:aws:s3:::BUCKET/*\"\\n ]\\n }\\n ]\\n}',\n\t\t\t'aws s3api put-bucket-policy --bucket BUCKET \\\\\\n --policy file://policy.json \\\\\\n --endpoint-url https://REGION.your-objectstorage.com \\\\\\n --region REGION',\n\t\t\t'Note: This key can no longer modify the policy.\\nTo restore write access, generate a new key in the\\nHetzner Console and use it to delete the policy.'\n\t\t]\n\t},\n\tminio: {\n\t\tnote: 'Create a read-only policy with mc admin policy, or use the built-in readonly canned policy.',\n\t\tdocsUrl: 'https://docs.min.io/enterprise/aistor-object-store/administration/iam/access/'\n\t},\n\tdigitalocean: {\n\t\tnote: 'Spaces keys are project-wide. Use a bucket policy to restrict write actions for a specific key.',\n\t\tdocsUrl: 'https://docs.digitalocean.com/products/spaces/how-to/manage-access/'\n\t},\n\twasabi: {\n\t\tnote: 'Create a sub-user with a read-only policy in the Wasabi Console.',\n\t\tdocsUrl: 'https://docs.wasabi.com/docs/creating-a-user-account-and-access-key'\n\t},\n\tcontabo: {\n\t\tnote: 'S3-compatible bucket policies. Use a Deny policy for write actions with the key ARN.',\n\t\tcliSteps: [\n\t\t\t'Create a policy.json with a Deny statement for s3:PutObject and s3:DeleteObject.',\n\t\t\t'aws s3api put-bucket-policy --bucket BUCKET \\\\\\n --policy file://policy.json \\\\\\n --endpoint-url https://REGION.contaboobj.com'\n\t\t]\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** All provider IDs, ordered for the UI. */\nexport const PROVIDER_IDS: ProviderId[] = [\n\t's3',\n\t'gcs',\n\t'r2',\n\t'azure',\n\t'b2',\n\t'digitalocean',\n\t'wasabi',\n\t'storj',\n\t'hetzner',\n\t'contabo',\n\t'linode',\n\t'ovhcloud',\n\t'minio'\n];\n\n/** Get provider def, falling back to S3 for unknown. */\nexport function getProvider(id: string): ProviderDef {\n\treturn PROVIDERS[id as ProviderId] ?? PROVIDERS.s3;\n}\n\n/** Build endpoint URL from template + region. */\nexport function buildEndpointFromTemplate(id: ProviderId, region: string): string {\n\tconst def = PROVIDERS[id];\n\tif (!def?.endpointTemplate) return '';\n\treturn def.endpointTemplate.replace('{region}', region);\n}\n\n/**\n * Resolve an endpoint URL for a provider using its registered template,\n * falling back to the provider's default region when none is supplied.\n * Returns '' when the provider has no template (e.g. plain S3 or MinIO).\n */\nexport function resolveProviderEndpoint(provider: string, region?: string): string {\n\tconst def = PROVIDERS[provider as ProviderId];\n\tif (!def?.endpointTemplate) return '';\n\treturn buildEndpointFromTemplate(provider as ProviderId, region || def.defaultRegion);\n}\n\n/**\n * Build the base URL for API requests (endpoint + bucket).\n * Used by browser-cloud adapter and url-state.\n */\nexport function buildProviderBaseUrl(\n\tprovider: ProviderId,\n\tendpoint: string,\n\tbucket: string,\n\tregion: string\n): string {\n\tif (endpoint) {\n\t\treturn `${endpoint.replace(/\\/$/, '')}/${bucket}`;\n\t}\n\tconst def = PROVIDERS[provider];\n\tif (def?.endpointTemplate) {\n\t\tconst resolved = def.endpointTemplate.replace('{region}', region || def.defaultRegion);\n\t\treturn `${resolved}/${bucket}`;\n\t}\n\t// Fallback: AWS S3 path-style\n\treturn `https://s3.${region || 'us-east-1'}.amazonaws.com/${bucket}`;\n}\n\n/** Check if a provider uses the GCS JSON API (not S3 XML). */\nexport function isGcsProvider(provider: string, endpoint: string): boolean {\n\treturn provider === 'gcs' || (!!endpoint && /storage\\.googleapis\\.com/i.test(endpoint));\n}\n\n// ---------------------------------------------------------------------------\n// Access mode — single source of truth for how any HTTP client (DuckDB httpfs,\n// COG/Zarr/PMTiles libraries, fetch, img, video) can read files for a given\n// connection. Used by url.ts (URL construction), query/wasm.ts (S3 config\n// short-circuit), canStreamDirectly (viewer routing).\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal connection shape needed to decide access mode.\n * Kept loose so callers don't need to import the full Connection type.\n */\nexport interface AccessModeInput {\n\tprovider: string;\n\tanonymous?: boolean;\n\tendpoint?: string;\n}\n\n/**\n * How a connection's files can be read by the browser:\n *\n * - `public-https`: plain HTTPS via any HTTP client. No auth, no signing.\n * Covers anonymous AWS/GCS/R2/Storj/Wasabi/etc.\n * - `sas-https`: HTTPS with SAS token embedded in the URL. Still works with\n * any HTTP client. Azure only.\n * - `signed-s3`: requires SigV4 signing. DuckDB uses the `s3://` URI and\n * signs it via its S3 config; other viewers must go through the storage\n * adapter (which returns a blob) instead of streaming the HTTPS URL.\n */\nexport type AccessMode = 'public-https' | 'sas-https' | 'signed-s3';\n\nexport function getAccessMode(conn: AccessModeInput): AccessMode {\n\tif (conn.provider === 'azure') return 'sas-https';\n\t// Anonymous buckets: every provider serves files over plain HTTPS without\n\t// signing (AWS path/vhost, GCS, R2 public, Storj, Wasabi, DO, etc.).\n\tif (conn.anonymous) return 'public-https';\n\t// Authenticated: needs SigV4 signing.\n\treturn 'signed-s3';\n}\n\n/**\n * True when the connection's files can be fetched by any HTTP client\n * (fetch/img/video/DuckDB httpfs/COG/Zarr/etc.) without the storage adapter.\n */\nexport function isPubliclyStreamable(conn: AccessModeInput): boolean {\n\tconst mode = getAccessMode(conn);\n\treturn mode === 'public-https' || mode === 'sas-https';\n}\n","import type { FileEntry, WriteResult } from '../types.js';\nimport type { StorageAdapter } from './adapter.js';\n\n/**\n * Minimal adapter for direct HTTPS URLs (source: 'url').\n * Only supports read/head — no listing or writing.\n * The `path` parameter is the full HTTPS URL.\n */\nexport class UrlAdapter implements StorageAdapter {\n\treadonly supportsWrite = false;\n\n\tasync read(\n\t\turl: string,\n\t\toffset?: number,\n\t\tlength?: number,\n\t\tsignal?: AbortSignal\n\t): Promise<Uint8Array> {\n\t\tconst headers: Record<string, string> = {};\n\t\tif (offset !== undefined && length !== undefined) {\n\t\t\theaders.Range = `bytes=${offset}-${offset + length - 1}`;\n\t\t} else if (offset !== undefined) {\n\t\t\theaders.Range = `bytes=${offset}-`;\n\t\t}\n\n\t\tconst res = await fetch(url, { headers, signal });\n\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\treturn new Uint8Array(await res.arrayBuffer());\n\t}\n\n\tasync head(url: string, signal?: AbortSignal): Promise<FileEntry> {\n\t\tconst res = await fetch(url, { method: 'HEAD', signal });\n\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\tconst name = url.split('/').pop()?.split('?')[0] || 'file';\n\t\tconst ext = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n\t\treturn {\n\t\t\tname,\n\t\t\tpath: url,\n\t\t\tis_dir: false,\n\t\t\tsize: Number(res.headers.get('content-length') || 0),\n\t\t\tmodified: new Date(res.headers.get('last-modified') || 0).getTime(),\n\t\t\textension: ext\n\t\t};\n\t}\n\n\tasync list(): Promise<FileEntry[]> {\n\t\treturn [];\n\t}\n\n\tasync put(): Promise<WriteResult> {\n\t\tthrow new Error('Write not supported for direct URL sources');\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tthrow new Error('Delete not supported for direct URL sources');\n\t}\n\n\tasync deletePrefix(): Promise<{ deleted: number }> {\n\t\tthrow new Error('Delete not supported for direct URL sources');\n\t}\n\n\tasync copy(): Promise<WriteResult> {\n\t\tthrow new Error('Copy not supported for direct URL sources');\n\t}\n}\n","/**\n * Cloud storage protocol URL utilities — pure TS, no Svelte dependency.\n *\n * Converts cloud protocol URLs (s3://, gs://) to HTTPS URLs for browser access.\n * Provider-aware native scheme lookup.\n */\n\nimport { buildProviderBaseUrl, PROVIDERS, type ProviderId } from '../storage/providers.js';\n\n/** AWS region pattern — matches prefixes like \"us-west-2\", \"eu-central-1\", etc. */\nconst AWS_REGION_RE =\n\t/^(us|eu|ap|sa|ca|me|af|il)-(north|south|east|west|central|northeast|southeast|northwest|southwest)-\\d+/;\n\n/**\n * Map provider to its native URI scheme prefix.\n * Derived from the registry's `schemes` array (first entry is the primary scheme).\n * Falls back to 's3' for providers without a scheme (S3-compatible).\n */\nexport function getNativeScheme(provider: string): string {\n\tconst def = PROVIDERS[provider as ProviderId];\n\tif (def?.schemes.length) return def.schemes[0];\n\treturn 's3';\n}\n\n/**\n * Safely decode a percent-encoded URI component.\n * Returns the original string if decoding fails (malformed sequences).\n */\nexport function safeDecodeURIComponent(s: string): string {\n\ttry {\n\t\treturn decodeURIComponent(s);\n\t} catch {\n\t\treturn s;\n\t}\n}\n\n/**\n * Convert a cloud storage protocol URL (s3://, gs://) to an HTTPS URL\n * for browser access. Returns the original URL if already HTTP(S) or unknown.\n *\n * Supported:\n * - `s3://bucket/key` → `https://s3.{region}.amazonaws.com/{bucket}/{key}`\n * (region auto-detected from bucket name when possible)\n * - `gs://bucket/key` → `https://storage.googleapis.com/{bucket}/{key}`\n */\nexport function resolveCloudUrl(url: string): string {\n\t// S3 / S3-compatible: s3://, s3a://, s3n://\n\tconst s3Match = url.match(/^s3[an]?:\\/\\/([^/]+)\\/?(.*)$/);\n\tif (s3Match) {\n\t\tconst [, bucket, key] = s3Match;\n\t\t// Detect region from bucket name (e.g. \"us-west-2.opendata.source.coop\")\n\t\tconst regionMatch = bucket.match(AWS_REGION_RE);\n\t\tconst region = regionMatch ? regionMatch[0] : 'us-east-1';\n\t\tconst base = buildProviderBaseUrl('s3', '', bucket, region);\n\t\treturn key ? `${base}/${key}` : base;\n\t}\n\n\t// Google Cloud Storage: gs://, gcs://\n\tconst gcsMatch = url.match(/^gcs?:\\/\\/([^/]+)\\/?(.*)$/);\n\tif (gcsMatch) {\n\t\tconst [, bucket, key] = gcsMatch;\n\t\tconst base = buildProviderBaseUrl('gcs', '', bucket, '');\n\t\treturn key ? `${base}/${key}` : base;\n\t}\n\n\treturn url;\n}\n","import type { GetTileDataOptions, MinimalDataT } from '@developmentseed/deck.gl-geotiff';\nimport { inferRenderPipeline } from '@developmentseed/deck.gl-geotiff';\nimport type { RasterModule, RenderTileResult } from '@developmentseed/deck.gl-raster';\nimport {\n\tColormap,\n\tFilterNoDataVal,\n\tLinearRescale\n} from '@developmentseed/deck.gl-raster/gpu-modules';\nimport loadEpsg from '@developmentseed/epsg/all';\nimport epsgCsvUrl from '@developmentseed/epsg/all.csv.gz?url';\nimport type { GeoTIFF as GeoTIFFType, Overview } from '@developmentseed/geotiff';\nimport { GeoTIFF } from '@developmentseed/geotiff';\nimport type { EpsgResolver, ProjectionDefinition } from '@developmentseed/proj';\nimport { parseWkt } from '@developmentseed/proj';\nimport type { Device } from '@luma.gl/core';\nimport type maplibregl from 'maplibre-gl';\nimport proj4Lib from 'proj4';\nimport { COLORMAP_INDEX, type ColormapName, getColormapTexture } from './colormap-sprite.js';\n\n// ─── Constants ───────────────────────────────────────────────────\n\n/**\n * Patches a GLSL ES 3.00 compile error in `@developmentseed/deck.gl-raster`\n * v0.6.0-alpha.1. The `Colormap` shader module injects\n * `uniform sampler2DArray colormapTexture;` without a precision qualifier,\n * which the Apple-GPU path of luma.gl's WebGL2 backend rejects with\n * `ERROR: 'sampler2DArray' : No precision specified`. In GLSL ES 3.00,\n * every sampler type other than `sampler2D`/`samplerCube` needs explicit\n * precision in fragment shaders.\n *\n * Chain this module immediately BEFORE `Colormap` in the renderPipeline so\n * the combined `fs:#decl` inject emits the precision declaration first,\n * then the sampler uniform. Remove once upstream ships the precision fix.\n */\nconst Sampler2DArrayPrecision = {\n\tname: 'sampler2darray-precision',\n\tfs: '',\n\tinject: {\n\t\t'fs:#decl': 'precision highp sampler2DArray;\\n'\n\t}\n} as const;\n\n/** SampleFormat tag value → human label. */\nexport const SF_LABELS: Record<number, string> = {\n\t1: 'uint',\n\t2: 'int',\n\t3: 'float',\n\t4: 'void',\n\t5: 'complex int',\n\t6: 'complex float'\n};\n\n// ─── Color ramps ─────────────────────────────────────────────────\n\n/**\n * Any of the 107 named ramps shipped in `@developmentseed/deck.gl-raster`'s\n * `colormaps.png` sprite (matplotlib + rio-tiler + cmocean). Rendering is\n * GPU-side via the `Colormap` shader module; switching ramps is a uniform\n * update, no tile re-decode.\n */\nexport type ColorRampId = ColormapName;\n\n// Previously this file hosted a handcoded `COLOR_RAMP_STOPS` table plus\n// `interpolateRamp` / `rampToGradientCss` helpers used by both the CPU\n// single-band baker and the CogControls UI preview. All three callers\n// migrated to the shipped `colormaps.png` sprite (107 ramps, GPU-sampled\n// via the `Colormap` shader module), so previews are now CSS backgrounds\n// sliced from the sprite — no handcoded stops needed. See\n// `utils/colormap-sprite.ts::spriteBackgroundStyle` and\n// `components/viewers/CogControls.svelte::rampBg`.\n\n// ─── Band configuration ─────────────────────────────────────────\n\nexport interface BandConfig {\n\tmode: 'rgb' | 'single';\n\t/** 0-indexed band indices for RGB channels */\n\trBand: number;\n\tgBand: number;\n\tbBand: number;\n\t/** 0-indexed band index for single-band mode */\n\tband: number;\n\tcolorRamp: ColorRampId;\n}\n\n/** Create a sensible default band config based on COG metadata. */\nexport function defaultBandConfig(bandCount: number, sampleFormat: number): BandConfig {\n\tif (bandCount >= 3 && bandCount <= 4) {\n\t\treturn {\n\t\t\tmode: 'rgb',\n\t\t\trBand: 0,\n\t\t\tgBand: 1,\n\t\t\tbBand: 2,\n\t\t\tband: 0,\n\t\t\tcolorRamp: 'viridis'\n\t\t};\n\t}\n\treturn {\n\t\tmode: 'single',\n\t\trBand: 0,\n\t\tgBand: 0,\n\t\tbBand: 0,\n\t\tband: 0,\n\t\tcolorRamp: sampleFormat === 2 || sampleFormat === 3 ? 'terrain' : 'viridis'\n\t};\n}\n\n/** Check if the config matches the default for this COG (no user changes). */\nexport function isDefaultBandConfig(\n\tconfig: BandConfig,\n\tbandCount: number,\n\tsampleFormat: number\n): boolean {\n\tconst def = defaultBandConfig(bandCount, sampleFormat);\n\treturn (\n\t\tconfig.mode === def.mode &&\n\t\tconfig.rBand === def.rBand &&\n\t\tconfig.gBand === def.gBand &&\n\t\tconfig.bBand === def.bBand &&\n\t\tconfig.band === def.band &&\n\t\tconfig.colorRamp === def.colorRamp\n\t);\n}\n\n// ─── TIFF tag inspection ─────────────────────────────────────────\n\nexport interface CogTagInfo {\n\t/** TIFF SampleFormat[0] value. 1=uint, 2=int, 3=float. Defaults to 1 when absent. */\n\tsampleFormat: number;\n\t/** True when SampleFormat[0] === 1 (unsigned integer). */\n\tisUint: boolean;\n\t/**\n\t * True when Photometric === 3 (Palette) and the ColorMap tag is present.\n\t * These COGs should defer to the library's default Colormap GPU module,\n\t * not our custom JS pipeline, so the embedded palette renders correctly.\n\t */\n\tisPaletteIndexed: boolean;\n}\n\n/**\n * Inspect the TIFF tags that drive pipeline selection. Centralizes the\n * Photometric.Palette === 3 magic number and the SampleFormat fallback in one\n * place so viewers don't reimplement raw tag reads. Photometric values come\n * from the @cogeotiff/core Photometric enum.\n */\nexport function inspectCogTags(geotiff: GeoTIFFType): CogTagInfo {\n\tconst tags = geotiff.cachedTags;\n\tconst sampleFormat = tags.sampleFormat?.[0] ?? 1;\n\treturn {\n\t\tsampleFormat,\n\t\tisUint: sampleFormat === 1,\n\t\tisPaletteIndexed: tags.photometric === 3 && Boolean(tags.colorMap)\n\t};\n}\n\n/**\n * Check if a given band config requires a custom pipeline (vs library default).\n * Library default only works for uint with standard RGB band order, or for\n * palette-indexed uint COGs where the embedded ColorMap tag auto-renders.\n */\nexport function needsCustomPipelineForConfig(geotiff: GeoTIFFType, config: BandConfig): boolean {\n\tconst tags = geotiff.cachedTags;\n\tconst sf = tags.sampleFormat;\n\tconst isUint = sf !== null && sf[0] === 1;\n\t// GPU textures accept 1-4 channels; COGs with more samples per pixel (embeddings,\n\t// hyperspectral, multi-band features) must route through the CPU pipeline which\n\t// reads selected band indices and bakes RGBA. Otherwise the library throws\n\t// \"Unsupported SamplesPerPixel N\" in verifySamplesPerPixel.\n\tif (geotiff.count > 4) return true;\n\tif (!isUint) return true;\n\t// Palette-indexed uint COGs with an embedded ColorMap tag are auto-rendered\n\t// by the library via its Colormap GPU module. Defer to the default pipeline\n\t// only while the user has not changed the default band config.\n\t// Photometric.Palette === 3 in @cogeotiff/core.\n\tif (\n\t\ttags.photometric === 3 &&\n\t\ttags.colorMap &&\n\t\tisDefaultBandConfig(config, geotiff.count, sf[0])\n\t) {\n\t\treturn false;\n\t}\n\tif (config.mode === 'single') return true;\n\tif (config.rBand !== 0 || config.gBand !== 1 || config.bBand !== 2) return true;\n\t// 4-band uint (e.g. NAIP RGB+NIR) must route through the CPU pipeline.\n\t// The library default maps all 4 samples to RGBA, turning the extra band\n\t// into a variable alpha channel even when it is not an alpha declaration.\n\t// The custom pipeline explicitly picks 3 bands and bakes alpha=255.\n\tif (geotiff.count === 4) return true;\n\treturn false;\n}\n\n// ─── Linear rescale (GPU shader module, default pipeline only) ───\n\n/**\n * Min/max rescale values applied via the `LinearRescale` shader module. Values\n * are in normalized shader space [0, 1]. Default `{ min: 0, max: 1 }` is a\n * no-op and the library-default pipeline is used as-is.\n */\nexport interface RescaleConfig {\n\tmin: number;\n\tmax: number;\n}\n\nexport const DEFAULT_RESCALE: RescaleConfig = { min: 0, max: 1 };\n\n/** True when the rescale values would produce a visible change on the GPU. */\nexport function isRescaleActive(cfg: RescaleConfig): boolean {\n\treturn cfg.min !== DEFAULT_RESCALE.min || cfg.max !== DEFAULT_RESCALE.max;\n}\n\n/**\n * Build a `getTileData` + `renderTile` pair that reuses the library-default\n * uint pipeline (via `inferRenderPipeline`) and appends `LinearRescale` to the\n * returned render pipeline. Only safe to use when the default pipeline would\n * have been chosen anyway, i.e. `needsCustomPipelineForConfig(geotiff, cfg)`\n * is false. For non-uint or custom band configs the custom JS pipeline already\n * bakes RGBA in CPU and a GPU rescale would be cosmetic.\n *\n * `inferRenderPipeline` needs the GPU `Device` which arrives in the first\n * tile's `GetTileDataOptions`, so the pipeline is built lazily on first call.\n */\nexport function createRescaledPipeline(\n\tgeotiff: GeoTIFFType,\n\trescale: RescaleConfig\n): {\n\tgetTileData: (\n\t\timage: GeoTIFFType | Overview,\n\t\toptions: GetTileDataOptions\n\t) => Promise<MinimalDataT>;\n\trenderTile: (data: MinimalDataT) => RenderTileResult;\n} {\n\tlet builtFor: Device | null = null;\n\tlet defaultGetTileData:\n\t\t| ((image: GeoTIFFType | Overview, options: GetTileDataOptions) => Promise<MinimalDataT>)\n\t\t| null = null;\n\tlet defaultRenderTile: ((data: MinimalDataT) => RenderTileResult) | null = null;\n\n\tfunction ensureBuilt(device: Device): void {\n\t\tif (builtFor === device && defaultGetTileData && defaultRenderTile) return;\n\t\tconst inferred = inferRenderPipeline(geotiff, device);\n\t\t// `inferRenderPipeline` returns generic callbacks. `MinimalDataT` is the\n\t\t// contractual superset used by COGLayer — safe upcast.\n\t\tdefaultGetTileData = inferred.getTileData as unknown as (\n\t\t\timage: GeoTIFFType | Overview,\n\t\t\toptions: GetTileDataOptions\n\t\t) => Promise<MinimalDataT>;\n\t\tdefaultRenderTile = inferred.renderTile as unknown as (data: MinimalDataT) => RenderTileResult;\n\t\tbuiltFor = device;\n\t}\n\n\treturn {\n\t\tgetTileData: async (image, options) => {\n\t\t\tensureBuilt(options.device);\n\t\t\treturn defaultGetTileData!(image, options);\n\t\t},\n\t\trenderTile: (data) => {\n\t\t\tconst base = defaultRenderTile!(data);\n\t\t\tconst pipeline = base.renderPipeline ?? [];\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\trenderPipeline: [\n\t\t\t\t\t...pipeline,\n\t\t\t\t\t{ module: LinearRescale, props: { rescaleMin: rescale.min, rescaleMax: rescale.max } }\n\t\t\t\t]\n\t\t\t};\n\t\t}\n\t};\n}\n\nexport interface BandRenderPipelineOptions {\n\t/** Value treated as \"no-data\" and zeroed out by `FilterNoDataVal`. */\n\tnoDataVal?: number | null;\n\t/** Linear rescale applied after no-data masking. Omit for no rescaling. */\n\trescale?: RescaleConfig;\n}\n\n/**\n * Build a `renderPipeline` array for `MultiCOGLayer` / raster mosaics.\n * Combines optional `FilterNoDataVal` + `LinearRescale` stages in the order\n * the GPU expects (no-data mask first, then rescale).\n */\nexport function buildBandRenderPipeline(opts: BandRenderPipelineOptions = {}): RasterModule[] {\n\tconst modules: RasterModule[] = [];\n\tif (opts.noDataVal !== undefined && opts.noDataVal !== null) {\n\t\tmodules.push({\n\t\t\tmodule: FilterNoDataVal,\n\t\t\tprops: { noDataVal: opts.noDataVal }\n\t\t});\n\t}\n\tif (opts.rescale && isRescaleActive(opts.rescale)) {\n\t\tmodules.push({\n\t\t\tmodule: LinearRescale,\n\t\t\tprops: { rescaleMin: opts.rescale.min, rescaleMax: opts.rescale.max }\n\t\t});\n\t}\n\treturn modules;\n}\n\n// ─── GeoTIFF normalization for COGLayer ──────────────────────────\n\n// Web Mercator's safe latitude limit. EPSG:4326 bboxes outside ±85.051129° hit\n// out-of-domain proj4 NaN when the library generates its tile matrix set.\nconst WM_LAT_LIMIT = 85.051129;\n\n/**\n * Apply the two upstream-bug workarounds a GeoTIFF needs before being handed\n * to `COGLayer`:\n * 1. Strip oversized overviews (image smaller than tile size). These produce\n * out-of-domain proj4 NaN during pre-flight reprojection.\n * 2. Clamp EPSG:4326 bbox to Web Mercator's safe range. Global 4326 COGs with\n * ±90° extents crash the tile matrix generator.\n *\n * Mutates the GeoTIFF in place. Safe to call repeatedly. Kept out of the\n * Svelte component so MultiCOG/Mosaic can apply the same fix per sub-COG.\n */\nexport function normalizeCogGeotiff(geotiff: GeoTIFFType): void {\n\tconst validOverviews = geotiff.overviews.filter(\n\t\t(ov) => ov.width >= ov.tileWidth && ov.height >= ov.tileHeight\n\t);\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t(geotiff as any).overviews = validOverviews;\n\n\tif (geotiff.crs === 4326) {\n\t\tconst [x0, y0, x1, y1] = geotiff.bbox;\n\t\tconst clamped = [\n\t\t\tMath.max(x0, -180),\n\t\t\tMath.max(y0, -WM_LAT_LIMIT),\n\t\t\tMath.min(x1, 180),\n\t\t\tMath.min(y1, WM_LAT_LIMIT)\n\t\t] as [number, number, number, number];\n\t\tif (clamped[0] !== x0 || clamped[1] !== y0 || clamped[2] !== x1 || clamped[3] !== y1) {\n\t\t\tObject.defineProperty(geotiff, 'bbox', {\n\t\t\t\tvalue: clamped,\n\t\t\t\twritable: false,\n\t\t\t\tconfigurable: true\n\t\t\t});\n\t\t}\n\t}\n}\n\n// ─── Pipeline dispatch ────────────────────────────────────────────\n\n/**\n * Resolved COGLayer data props. Empty object means \"library default pipeline\".\n * Spread into `new COGLayer({ ..., ...resolved })` to activate.\n *\n * COGLayer's data-prop types are a discriminated XOR and the four pipelines we\n * dispatch to return different DataT shapes (`CustomTileData`, `MinimalDataT`).\n * Typing this as `Record<string, any>` matches the `customProps` pattern\n * already used at the COGLayer boundary and keeps the dispatch site simple.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ResolvedCogPipeline = Record<string, any>;\n\nexport interface SelectCogPipelineOptions {\n\t/** Active band/color config, or null/undefined when not yet resolved. */\n\tbandConfig?: BandConfig | null;\n\t/** Linear rescale GPU module values. No-op when omitted or at defaults. */\n\trescale?: RescaleConfig;\n\t/**\n\t * Forwarded to the CPU bake factories in single-band mode; receives a\n\t * 64-bin histogram of normalized data after each tile for slider UI.\n\t */\n\tonHistogram?: (bins: Uint32Array) => void;\n}\n\n/**\n * Decide which getTileData/renderTile pair COGLayer should use for a GeoTIFF.\n * Four outcomes, in priority order:\n *\n * 1. Custom configurable (band swap, color ramp) — when bandConfig is active\n * and needsCustomPipelineForConfig is true (non-uint, mode=single, or\n * non-standard RGB band order).\n * 2. Custom non-uint (Int/Float source) — when no bandConfig yet but the\n * GeoTIFF itself forces custom handling.\n * 3. Library default + LinearRescale — uint path is fine AND the user moved\n * the rescale slider away from defaults.\n * 4. Library default — returns `{}`, caller spreads into COGLayer props.\n *\n * Pure dispatch. Kept separate from the Svelte component so MultiCOG/Mosaic\n * viewers can call it per sub-COG without re-implementing the decision tree.\n */\nexport function selectCogPipeline(\n\tgeotiff: GeoTIFFType,\n\topts: SelectCogPipelineOptions = {}\n): ResolvedCogPipeline {\n\tconst { bandConfig, rescale } = opts;\n\tconst useCustom = bandConfig\n\t\t? needsCustomPipelineForConfig(geotiff, bandConfig)\n\t\t: needsCustomPipeline(geotiff);\n\n\tif (useCustom && bandConfig) {\n\t\treturn {\n\t\t\tgetTileData: createConfigurableGetTileData(geotiff, bandConfig, {\n\t\t\t\tonHistogram: opts.onHistogram\n\t\t\t}),\n\t\t\trenderTile: buildCustomRenderTile(bandConfig, rescale)\n\t\t};\n\t}\n\tif (useCustom) {\n\t\t// Synthesize a single-band config so the GPU Colormap path still\n\t\t// applies when a non-uint COG renders without a user-chosen ramp.\n\t\tconst fallbackSf = geotiff.cachedTags.sampleFormat?.[0] ?? 1;\n\t\tconst fallbackConfig = defaultBandConfig(geotiff.count, fallbackSf);\n\t\treturn {\n\t\t\tgetTileData: createCustomGetTileData(geotiff, { onHistogram: opts.onHistogram }),\n\t\t\trenderTile: buildCustomRenderTile(fallbackConfig, rescale)\n\t\t};\n\t}\n\tif (rescale && isRescaleActive(rescale)) {\n\t\tconst pipeline = createRescaledPipeline(geotiff, rescale);\n\t\treturn {\n\t\t\tgetTileData: pipeline.getTileData,\n\t\t\trenderTile: pipeline.renderTile\n\t\t};\n\t}\n\treturn {};\n}\n\nconst BITMAP_SOURCE = 'geotiff-bitmap-src';\nconst BITMAP_LAYER = 'geotiff-bitmap-layer';\n\n// ─── Types ───────────────────────────────────────────────────────\n\nexport interface GeoBounds {\n\twest: number;\n\tsouth: number;\n\teast: number;\n\tnorth: number;\n}\n\nexport interface CogInfo {\n\twidth: number;\n\theight: number;\n\tbandCount: number;\n\tdataType: string;\n\tbounds: GeoBounds;\n\tdownsampled?: boolean;\n}\n\n// ─── Pure helpers ────────────────────────────────────────────────\n\n/** Safely clamp a number to a range, treating NaN/Infinity as the fallback. */\nexport function safeClamp(v: number, lo: number, hi: number, fallback: number): number {\n\treturn Number.isFinite(v) ? Math.max(lo, Math.min(hi, v)) : fallback;\n}\n\n/** Clamp geographic bounds to valid MapLibre web-Mercator range. */\nexport function clampBounds(b: GeoBounds): GeoBounds {\n\treturn {\n\t\twest: safeClamp(b.west, -180, 180, -180),\n\t\tsouth: safeClamp(b.south, -85.051129, 85.051129, -85.051129),\n\t\teast: safeClamp(b.east, -180, 180, 180),\n\t\tnorth: safeClamp(b.north, -85.051129, 85.051129, 85.051129)\n\t};\n}\n\n/**\n * Build a data-type label from GeoTIFF sample format and bits per sample.\n * e.g. \"uint8\", \"float32\", \"int16\"\n */\nexport function buildDataTypeLabel(sampleFormat: number, bitsPerSample: number): string {\n\treturn `${SF_LABELS[sampleFormat] ?? `sf${sampleFormat}`}${bitsPerSample ?? ''}`;\n}\n\n// ─── Map helpers (depend on maplibre-gl) ─────────────────────────\n\n/**\n * Query the GPU's MAX_TEXTURE_SIZE from MapLibre's WebGL context.\n * Falls back to 4096 (lowest common denominator for mobile GPUs).\n */\nexport function getMaxTextureSize(map: maplibregl.Map): number {\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\tconst gl = (map as any).painter?.context?.gl as WebGL2RenderingContext | null;\n\t\tif (gl) return gl.getParameter(gl.MAX_TEXTURE_SIZE) as number;\n\t} catch {\n\t\t/* fallback */\n\t}\n\treturn 4096;\n}\n\n/**\n * Fit the map to COG bounds with responsive padding.\n * Uses smaller padding on mobile to zoom in closer, ensuring overviews load\n * properly instead of appearing black at very low zoom levels.\n * After fitting, bumps zoom +2 when the viewport settles at a very low level.\n */\nexport function fitCogBounds(map: maplibregl.Map, b: GeoBounds): void {\n\tconst isMobile = window.innerWidth < 640;\n\tconst viewportMin = Math.min(window.innerWidth, window.innerHeight);\n\tconst padding = isMobile ? 5 : Math.max(10, Math.round(viewportMin * 0.04));\n\tmap.fitBounds(\n\t\t[\n\t\t\t[b.west, b.south],\n\t\t\t[b.east, b.north]\n\t\t],\n\t\t{ padding, maxZoom: 18, speed: 1.2, maxDuration: 2000 }\n\t);\n\tconst lonSpan = b.east - b.west;\n\tconst latSpan = b.north - b.south;\n\tconst isLargeExtent = lonSpan > 90 || latSpan > 45;\n\tif (!isLargeExtent) {\n\t\tmap.once('moveend', () => {\n\t\t\tconst z = map.getZoom();\n\t\t\tconst minZoom = isMobile ? 10 : 8;\n\t\t\tif (z < minZoom) {\n\t\t\t\tmap.zoomTo(z + 2, { duration: 500 });\n\t\t\t}\n\t\t});\n\t}\n}\n\n/** Remove the native bitmap source/layer from the map (idempotent). */\nexport function cleanupNativeBitmap(map: maplibregl.Map): void {\n\ttry {\n\t\tif (map.getLayer(BITMAP_LAYER)) map.removeLayer(BITMAP_LAYER);\n\t} catch {\n\t\t/* already removed */\n\t}\n\ttry {\n\t\tif (map.getSource(BITMAP_SOURCE)) map.removeSource(BITMAP_SOURCE);\n\t} catch {\n\t\t/* already removed */\n\t}\n}\n\n// ─── Terrain color ramp ──────────────────────────────────────────\n\n/** Terrain-inspired color ramp: deep blue → green → brown → white. */\nconst TERRAIN_RAMP: [number, number, number][] = [\n\t[0, 0, 128], // deep water\n\t[0, 100, 200], // shallow water\n\t[0, 154, 80], // lowland green\n\t[120, 180, 50], // mid green\n\t[200, 170, 60], // savanna\n\t[180, 120, 50], // brown\n\t[140, 90, 40], // dark brown\n\t[200, 200, 200], // rock\n\t[255, 255, 255] // snow / peak\n];\n\n/** Interpolate a 0..1 value into a terrain RGB color. */\nfunction terrainColor(t: number): [number, number, number] {\n\tconst n = TERRAIN_RAMP.length - 1;\n\tconst idx = Math.max(0, Math.min(n, t * n));\n\tconst lo = Math.floor(idx);\n\tconst hi = Math.min(lo + 1, n);\n\tconst f = idx - lo;\n\treturn [\n\t\tMath.round(TERRAIN_RAMP[lo][0] + f * (TERRAIN_RAMP[hi][0] - TERRAIN_RAMP[lo][0])),\n\t\tMath.round(TERRAIN_RAMP[lo][1] + f * (TERRAIN_RAMP[hi][1] - TERRAIN_RAMP[lo][1])),\n\t\tMath.round(TERRAIN_RAMP[lo][2] + f * (TERRAIN_RAMP[hi][2] - TERRAIN_RAMP[lo][2]))\n\t];\n}\n\n// ─── Non-tiled bitmap rendering ──────────────────────────────────\n\n/**\n * Compute geographic bounds (WGS84) from a GeoTIFF's native CRS bbox\n * using edge-sampling for accuracy with non-linear projections.\n */\nasync function computeGeographicBounds(\n\tgeotiff: GeoTIFF,\n\tsignal: AbortSignal\n): Promise<GeoBounds | null> {\n\tconst crs = geotiff.crs;\n\tconst [x0, y0, x1, y1] = geotiff.bbox;\n\n\t// EPSG:4326 — bbox is already geographic\n\tif (crs === 4326) {\n\t\treturn clampBounds({ west: x0, south: y0, east: x1, north: y1 });\n\t}\n\n\t// For other CRS, resolve the projection definition from the bundled EPSG\n\t// database (numeric codes) or fall back to ProjJSON.\n\tlet proj4Def: string;\n\tif (typeof crs === 'number') {\n\t\tconst wkt = await lookupEpsgWkt(crs);\n\t\tif (signal.aborted) return null;\n\t\tif (!wkt) return null;\n\t\tproj4Def = wkt;\n\t} else {\n\t\t// ProjJson — try to pass directly to proj4 (limited support)\n\t\tproj4Def = JSON.stringify(crs);\n\t}\n\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\tconst conv = proj4Lib(proj4Def, 'EPSG:4326') as any;\n\t\tconst N = 4;\n\t\tconst pts: [number, number][] = [];\n\t\tfor (let i = 0; i <= N; i++) {\n\t\t\tconst t = i / N;\n\t\t\tpts.push([x0 + t * (x1 - x0), y0]);\n\t\t\tpts.push([x0 + t * (x1 - x0), y1]);\n\t\t\tpts.push([x0, y0 + t * (y1 - y0)]);\n\t\t\tpts.push([x1, y0 + t * (y1 - y0)]);\n\t\t}\n\t\tlet w = 180;\n\t\tlet s = 90;\n\t\tlet e = -180;\n\t\tlet n = -90;\n\t\tfor (const [px, py] of pts) {\n\t\t\tconst r = conv.forward([px, py], false);\n\t\t\tif (\n\t\t\t\tNumber.isFinite(r[0]) &&\n\t\t\t\tNumber.isFinite(r[1]) &&\n\t\t\t\tMath.abs(r[0]) <= 180 &&\n\t\t\t\tMath.abs(r[1]) <= 90\n\t\t\t) {\n\t\t\t\tw = Math.min(w, r[0]);\n\t\t\t\te = Math.max(e, r[0]);\n\t\t\t\ts = Math.min(s, r[1]);\n\t\t\t\tn = Math.max(n, r[1]);\n\t\t\t}\n\t\t}\n\t\tif (w < e && s < n) {\n\t\t\treturn clampBounds({ west: w, south: s, east: e, north: n });\n\t\t}\n\t} catch {\n\t\t/* proj4 conversion failed */\n\t}\n\treturn null;\n}\n\nconst MAX_NONTILED_PIXELS = 100_000_000;\n\n/**\n * Render a non-tiled GeoTIFF as a MapLibre native image source (bitmap).\n * Opens the file with @developmentseed/geotiff, reads band 0, normalizes\n * to grayscale RGBA, and adds to the map as a raster layer.\n *\n * Returns CogInfo for the metadata panel.\n */\nexport async function renderNonTiledBitmap(options: {\n\turl: string;\n\tmap: maplibregl.Map;\n\tsignal: AbortSignal;\n\tgeotiff?: GeoTIFF;\n}): Promise<CogInfo> {\n\tconst { url, map, signal } = options;\n\n\t// Open GeoTIFF (reuse if already opened for pre-flight)\n\tconst geotiff = options.geotiff ?? (await GeoTIFF.fromUrl(url));\n\tif (signal.aborted) throw new DOMException('Aborted', 'AbortError');\n\n\tconst imgW = geotiff.width;\n\tconst imgH = geotiff.height;\n\tconst totalPixels = imgW * imgH;\n\tconst bandCount = geotiff.count;\n\tconst nodata = geotiff.nodata;\n\n\t// Determine data type from the underlying TIFF image\n\tconst tiffImage = geotiff.image;\n\t// @cogeotiff/core TiffImage stores tag values\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst sampleFormat = (tiffImage as any).value?.('SampleFormat')?.[0] ?? 1;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst bitsPerSample = (tiffImage as any).value?.('BitsPerSample')?.[0] ?? 8;\n\tconst dataType = buildDataTypeLabel(sampleFormat, bitsPerSample);\n\n\t// Compute geographic bounds\n\tconst geoBounds = await computeGeographicBounds(geotiff, signal);\n\tif (signal.aborted) throw new DOMException('Aborted', 'AbortError');\n\tif (!geoBounds) {\n\t\tthrow new Error('Cannot determine geographic bounds for non-tiled GeoTIFF');\n\t}\n\n\t// Size gate\n\tif (totalPixels > MAX_NONTILED_PIXELS) {\n\t\tfitCogBounds(map, geoBounds);\n\t\tthrow new Error(\n\t\t\t`Non-tiled GeoTIFF too large (${imgW.toLocaleString()} \\u00d7 ${imgH.toLocaleString()} = ` +\n\t\t\t\t`${(totalPixels / 1e6).toFixed(0)}M pixels). Convert to COG: ` +\n\t\t\t\t`gdal_translate -of COG input.tif output.tif`\n\t\t);\n\t}\n\n\t// Cap to GPU texture limit\n\tconst maxTexDim = getMaxTextureSize(map);\n\tconst needsDownsample = imgW > maxTexDim || imgH > maxTexDim;\n\tlet readW = imgW;\n\tlet readH = imgH;\n\tif (needsDownsample) {\n\t\tconst scale = Math.min(maxTexDim / imgW, maxTexDim / imgH);\n\t\treadW = Math.max(1, Math.round(imgW * scale));\n\t\treadH = Math.max(1, Math.round(imgH * scale));\n\t}\n\n\t// Read band 0 via a single tile fetch (non-tiled → single strip)\n\t// For non-tiled images, fetch tile (0,0) which returns the entire image\n\tconst tile = await geotiff.fetchTile(0, 0, { signal });\n\tif (signal.aborted) throw new DOMException('Aborted', 'AbortError');\n\n\tconst arr = tile.array;\n\tconst bandData: ArrayLike<number> = arr.layout === 'band-separate' ? arr.bands[0] : arr.data;\n\tconst isSingleBand = bandCount === 1;\n\n\t// Compute min/max for linear stretch (with scale/offset applied)\n\tlet bMin = Infinity;\n\tlet bMax = -Infinity;\n\tconst len = Math.min(bandData.length, readW * readH);\n\tfor (let i = 0; i < len; i++) {\n\t\tconst raw = bandData[i];\n\t\tif (nodata !== null && raw === nodata) continue;\n\t\tif (!Number.isFinite(raw)) continue;\n\t\tconst v = raw;\n\t\tif (v < bMin) bMin = v;\n\t\tif (v > bMax) bMax = v;\n\t}\n\tif (!Number.isFinite(bMin)) {\n\t\tbMin = 0;\n\t\tbMax = 1;\n\t}\n\tconst bRange = bMax - bMin || 1;\n\n\t// Normalize to RGBA (terrain color ramp for single-band int/float)\n\tconst pixelCount = len;\n\tconst useTerrainRamp = isSingleBand && (sampleFormat === 2 || sampleFormat === 3);\n\tconst rgba = new Uint8ClampedArray(pixelCount * 4);\n\tfor (let i = 0; i < pixelCount; i++) {\n\t\tconst raw = bandData[i];\n\t\tconst isND = (nodata !== null && raw === nodata) || !Number.isFinite(raw);\n\t\tconst idx = i * 4;\n\t\tif (isND) {\n\t\t\trgba[idx] = 0;\n\t\t\trgba[idx + 1] = 0;\n\t\t\trgba[idx + 2] = 0;\n\t\t\trgba[idx + 3] = 0;\n\t\t\tcontinue;\n\t\t}\n\t\tconst t = Math.max(0, Math.min(1, (raw - bMin) / bRange));\n\t\tif (useTerrainRamp) {\n\t\t\tconst [r, g, b] = terrainColor(t);\n\t\t\trgba[idx] = r;\n\t\t\trgba[idx + 1] = g;\n\t\t\trgba[idx + 2] = b;\n\t\t} else {\n\t\t\tconst gray = Math.round(t * 255);\n\t\t\trgba[idx] = gray;\n\t\t\trgba[idx + 1] = gray;\n\t\t\trgba[idx + 2] = gray;\n\t\t}\n\t\trgba[idx + 3] = 255;\n\t}\n\n\t// Render to canvas → data URL\n\tconst canvas = document.createElement('canvas');\n\tcanvas.width = readW;\n\tcanvas.height = readH;\n\tconst ctx = canvas.getContext('2d')!;\n\tctx.putImageData(new ImageData(rgba, readW, readH), 0, 0);\n\tconst dataUrl = canvas.toDataURL();\n\tcanvas.width = 0;\n\tcanvas.height = 0;\n\n\t// Add to MapLibre as native image source\n\tcleanupNativeBitmap(map);\n\tmap.addSource(BITMAP_SOURCE, {\n\t\ttype: 'image',\n\t\turl: dataUrl,\n\t\tcoordinates: [\n\t\t\t[geoBounds.west, geoBounds.north],\n\t\t\t[geoBounds.east, geoBounds.north],\n\t\t\t[geoBounds.east, geoBounds.south],\n\t\t\t[geoBounds.west, geoBounds.south]\n\t\t]\n\t});\n\tmap.addLayer({\n\t\tid: BITMAP_LAYER,\n\t\tsource: BITMAP_SOURCE,\n\t\ttype: 'raster',\n\t\tpaint: { 'raster-opacity': 1 }\n\t});\n\n\treturn {\n\t\twidth: imgW,\n\t\theight: imgH,\n\t\tbandCount,\n\t\tdataType,\n\t\tbounds: geoBounds,\n\t\tdownsampled: needsDownsample\n\t};\n}\n\n// ─── Custom pipeline for non-uint COGs ───────────────────────────\n\n/** Result type returned by our custom getTileData. */\nexport interface CustomTileData {\n\timageData: ImageData;\n\twidth: number;\n\theight: number;\n\t/**\n\t * `sampler2DArray` colormap texture for single-band renders. Set by\n\t * `createConfigurableGetTileData` / `createCustomGetTileData` when the\n\t * first tile resolves the device-bound sprite texture; `undefined` for\n\t * RGB-mode tiles (no colormap needed). Passed through to `renderTile`\n\t * so the Colormap shader module can bind it on every layer.\n\t */\n\tcolormapTexture?: Texture;\n\t/**\n\t * Normalized `color.r` sentinel value for nodata pixels in single-band\n\t * mode. The `Colormap` shader module overwrites all 4 output channels\n\t * from the 1D ramp sample, destroying the α=0 flag, so we reserve\n\t * `r = 0` for nodata and renormalize valid data into `(0, 1]`.\n\t * `FilterNoDataVal` then discards matching fragments before the ramp\n\t * lookup. `undefined` for RGB tiles.\n\t */\n\tnodataSentinel?: number;\n}\n\n// Avoid pulling in the @luma.gl/core Texture type at the top of the file via\n// a value import; the existing top-level `Device` import is `type`-only.\ntype Texture = import('@luma.gl/core').Texture;\n\n/**\n * Check whether a GeoTIFF needs a custom render pipeline.\n * v0.3's inferRenderPipeline only supports unsigned integers (SampleFormat 1).\n * Signed int (2) and float (3) need custom getTileData/renderTile.\n */\nexport function needsCustomPipeline(geotiff: GeoTIFFType): boolean {\n\tconst tags = geotiff.cachedTags;\n\tconst sf = tags.sampleFormat;\n\t// sampleFormat is null or not uint → needs custom\n\treturn sf === null || sf[0] !== 1;\n}\n\n/** Shared options for the CPU tile-baking factories. */\nexport interface CustomGetTileDataOptions {\n\t/**\n\t * Called after each baked tile with a 64-bin histogram of normalized\n\t * single-band values (0..1, nodata excluded). Bins accumulate across\n\t * tiles; receivers should treat the array as monotonically growing and\n\t * debounce UI updates. Never invoked in RGB mode.\n\t */\n\tonHistogram?: (bins: Uint32Array) => void;\n}\n\n/** Number of histogram buckets produced by the CPU bake. */\nexport const HISTOGRAM_BIN_COUNT = 64;\n\n/**\n * Create custom getTileData for non-uint COGs.\n * Reads band 0, normalizes using GDAL statistics / per-tile adaptive stretch,\n * bakes a grayscale `r`-channel image so the GPU `Colormap` shader module\n * (wired downstream by `selectCogPipeline`) can apply the ramp by sampling\n * `colormaps.png`. Reserves `r = 0` for nodata so `FilterNoDataVal` can\n * discard those fragments before the ramp sample.\n */\nexport function createCustomGetTileData(geotiff: GeoTIFFType, opts: CustomGetTileDataOptions = {}) {\n\t// Read Scale/Offset TIFF tags (GDAL convention for scaled datasets like DEMs)\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst tags = geotiff.cachedTags as Record<string, any>;\n\t// GDAL stores data-scaling Scale/Offset as TIFF tags (33550-area).\n\t// @developmentseed/geotiff exposes them in cachedTags but the TS type\n\t// doesn't declare them — access via any.\n\tconst gdalScale: number | null = tags.scale ?? null;\n\tconst gdalOffset: number | null = tags.offset ?? null;\n\tconst hasScaleOffset =\n\t\tgdalScale !== null && gdalOffset !== null && (gdalScale !== 1 || gdalOffset !== 0);\n\n\t// Pre-compute normalization range from stored GDAL statistics if available\n\tconst stats = geotiff.storedStats;\n\tlet globalMin: number | null = null;\n\tlet globalMax: number | null = null;\n\tif (stats) {\n\t\tconst band1Stats = stats.get(1); // GDAL uses 1-based indexing\n\t\tif (band1Stats) {\n\t\t\tglobalMin = band1Stats.min ?? null;\n\t\t\tglobalMax = band1Stats.max ?? null;\n\t\t}\n\t}\n\n\t// If we have global stats, apply scale/offset to get real-world units\n\tif (globalMin !== null && globalMax !== null && hasScaleOffset) {\n\t\tglobalMin = globalMin * (gdalScale ?? 1) + (gdalOffset ?? 0);\n\t\tglobalMax = globalMax * (gdalScale ?? 1) + (gdalOffset ?? 0);\n\t}\n\n\tconst bandCount = geotiff.count;\n\tconst isSingleBand = bandCount === 1;\n\n\t// Shared range across all tiles — when no GDAL stats exist, the first\n\t// tile's scan seeds the range and subsequent tiles widen it. This\n\t// eliminates visible seams between tiles caused by per-tile normalization.\n\tlet sharedMin = globalMin;\n\tlet sharedMax = globalMax;\n\n\t// Resolve the sprite texture from the first tile's device; reuse per-device.\n\tlet texturePromise: Promise<Texture> | null = null;\n\tconst histogram = isSingleBand ? new Uint32Array(HISTOGRAM_BIN_COUNT) : null;\n\n\treturn async (\n\t\timage: GeoTIFFType | Overview,\n\t\toptions: { x: number; y: number; pool: unknown; signal?: AbortSignal; device: Device }\n\t): Promise<CustomTileData> => {\n\t\tif (isSingleBand && !texturePromise) {\n\t\t\ttexturePromise = getColormapTexture(options.device);\n\t\t}\n\n\t\tconst [tile, colormapTexture] = await Promise.all([\n\t\t\timage.fetchTile(options.x, options.y, {\n\t\t\t\tboundless: false,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\tpool: options.pool as any,\n\t\t\t\tsignal: options.signal\n\t\t\t}),\n\t\t\ttexturePromise ?? Promise.resolve<Texture | undefined>(undefined)\n\t\t]);\n\n\t\tconst arr = tile.array;\n\t\tconst { width, height, nodata } = arr;\n\t\tconst bandData: ArrayLike<number> = arr.layout === 'band-separate' ? arr.bands[0] : arr.data;\n\n\t\tconst pixelCount = width * height;\n\t\tconst scale = gdalScale ?? 1;\n\t\tconst offset = gdalOffset ?? 0;\n\n\t\t// When no global stats, scan this tile and widen the shared range\n\t\tif (sharedMin === null || sharedMax === null) {\n\t\t\tlet tMin = Infinity;\n\t\t\tlet tMax = -Infinity;\n\t\t\tfor (let i = 0; i < pixelCount; i++) {\n\t\t\t\tconst raw = bandData[i];\n\t\t\t\tif (nodata !== null && raw === nodata) continue;\n\t\t\t\tif (!Number.isFinite(raw)) continue;\n\t\t\t\tconst v = hasScaleOffset ? raw * scale + offset : raw;\n\t\t\t\tif (v < tMin) tMin = v;\n\t\t\t\tif (v > tMax) tMax = v;\n\t\t\t}\n\t\t\tif (Number.isFinite(tMin)) {\n\t\t\t\tsharedMin = tMin;\n\t\t\t\tsharedMax = tMax;\n\t\t\t} else {\n\t\t\t\tsharedMin = 0;\n\t\t\t\tsharedMax = 1;\n\t\t\t}\n\t\t}\n\t\tconst rangeMin = sharedMin!;\n\t\tconst rangeMax = sharedMax!;\n\t\tconst range = rangeMax - rangeMin || 1;\n\n\t\t// Render to RGBA. For single-band we bake normalized value into the\n\t\t// `r` channel and reserve `r = 0` for nodata (see CustomTileData\n\t\t// docs). Multi-band non-uint keeps the plain grayscale + α=255\n\t\t// output so the default library pipeline consumes it unchanged.\n\t\tconst rgba = new Uint8ClampedArray(pixelCount * 4);\n\t\tfor (let i = 0; i < pixelCount; i++) {\n\t\t\tconst raw = bandData[i];\n\t\t\tconst isND = (nodata !== null && raw === nodata) || !Number.isFinite(raw);\n\t\t\tconst idx = i * 4;\n\t\t\tif (isND) {\n\t\t\t\trgba[idx] = 0;\n\t\t\t\trgba[idx + 1] = 0;\n\t\t\t\trgba[idx + 2] = 0;\n\t\t\t\trgba[idx + 3] = 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst v = hasScaleOffset ? raw * scale + offset : raw;\n\t\t\tconst t = Math.max(0, Math.min(1, (v - rangeMin) / range));\n\t\t\tif (isSingleBand) {\n\t\t\t\t// Reserve r=0 for nodata; valid data maps to [1, 255].\n\t\t\t\tconst gray = 1 + Math.round(t * 254);\n\t\t\t\trgba[idx] = gray;\n\t\t\t\trgba[idx + 1] = 0;\n\t\t\t\trgba[idx + 2] = 0;\n\t\t\t\tif (histogram) {\n\t\t\t\t\tconst bin = Math.min(HISTOGRAM_BIN_COUNT - 1, Math.floor(t * HISTOGRAM_BIN_COUNT));\n\t\t\t\t\thistogram[bin]++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst gray = Math.round(t * 255);\n\t\t\t\trgba[idx] = gray;\n\t\t\t\trgba[idx + 1] = gray;\n\t\t\t\trgba[idx + 2] = gray;\n\t\t\t}\n\t\t\trgba[idx + 3] = 255;\n\t\t}\n\n\t\tif (histogram && opts.onHistogram) opts.onHistogram(histogram);\n\n\t\treturn {\n\t\t\timageData: new ImageData(rgba, width, height),\n\t\t\twidth,\n\t\t\theight,\n\t\t\tcolormapTexture: isSingleBand ? colormapTexture : undefined,\n\t\t\tnodataSentinel: isSingleBand ? 0 : undefined\n\t\t};\n\t};\n}\n\n/**\n * Custom renderTile for COGs that use the CPU pipeline. For RGB mode (and\n * legacy multi-band non-uint), the `image` slot carries a fully-baked RGBA\n * `ImageData` and there is nothing to append on the GPU. For single-band\n * mode, the image carries a normalized `r`-channel and this function\n * appends `FilterNoDataVal` (to discard r=0 nodata sentinels), optional\n * `LinearRescale` (brightness/contrast slider), and the sprite-based\n * `Colormap` module so switching ramps is a uniform update — no tile\n * re-decode required. The `colormapTexture` is stashed on `data` by the\n * corresponding `getTileData` factory; if the sprite failed to resolve we\n * fall back to the plain grayscale image.\n */\nexport function buildCustomRenderTile(\n\tconfig: BandConfig,\n\trescale?: RescaleConfig\n): (data: CustomTileData) => RenderTileResult {\n\treturn (data) => {\n\t\tif (config.mode === 'rgb' || !data.colormapTexture) {\n\t\t\treturn { image: data.imageData };\n\t\t}\n\t\tconst colormapIndex = COLORMAP_INDEX[config.colorRamp] ?? COLORMAP_INDEX.viridis;\n\t\tconst pipeline: RasterModule[] = [\n\t\t\t{\n\t\t\t\tmodule: FilterNoDataVal,\n\t\t\t\tprops: { value: (data.nodataSentinel ?? 0) / 255 }\n\t\t\t}\n\t\t];\n\t\tif (rescale && isRescaleActive(rescale)) {\n\t\t\tpipeline.push({\n\t\t\t\tmodule: LinearRescale,\n\t\t\t\tprops: { rescaleMin: rescale.min, rescaleMax: rescale.max }\n\t\t\t});\n\t\t}\n\t\tpipeline.push(\n\t\t\t// Precision shim must come before Colormap, its `fs:#decl` inject\n\t\t\t// declares `precision highp sampler2DArray;` so the subsequent\n\t\t\t// sampler uniform compiles on WebGL2 / Apple GPU.\n\t\t\t{ module: Sampler2DArrayPrecision, props: {} },\n\t\t\t{\n\t\t\t\tmodule: Colormap,\n\t\t\t\tprops: {\n\t\t\t\t\tcolormapTexture: data.colormapTexture,\n\t\t\t\t\tcolormapIndex,\n\t\t\t\t\treversed: false\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t\treturn { image: data.imageData, renderPipeline: pipeline };\n\t};\n}\n\n// ─── Configurable custom pipeline ────────────────────────────────\n\n/**\n * Extract band data arrays from a raster tile.\n * Returns an array of typed arrays, one per band.\n */\nfunction extractBands(\n\tarr: {\n\t\tlayout: string;\n\t\tbands?: ArrayLike<number>[];\n\t\tdata?: ArrayLike<number>;\n\t\tcount: number;\n\t\twidth: number;\n\t\theight: number;\n\t},\n\tbandCount: number,\n\tpixelCount: number\n): ArrayLike<number>[] {\n\tif (arr.layout === 'band-separate' && arr.bands) {\n\t\treturn arr.bands as ArrayLike<number>[];\n\t}\n\t// pixel-interleaved → split into per-band arrays\n\tconst data = arr.data!;\n\tconst bands: ArrayLike<number>[] = [];\n\tfor (let b = 0; b < bandCount; b++) {\n\t\tconst band = new Float64Array(pixelCount);\n\t\tfor (let i = 0; i < pixelCount; i++) {\n\t\t\tband[i] = (data as ArrayLike<number>)[i * bandCount + b];\n\t\t}\n\t\tbands.push(band);\n\t}\n\treturn bands;\n}\n\n/**\n * Compute per-band min/max from an array of band data.\n * Returns [min[], max[]] for the requested band indices.\n */\nfunction computeBandRanges(\n\tbands: ArrayLike<number>[],\n\tbandIndices: number[],\n\tpixelCount: number,\n\tnodata: number | null\n): { mins: number[]; maxs: number[] } {\n\tconst mins: number[] = [];\n\tconst maxs: number[] = [];\n\tfor (const bi of bandIndices) {\n\t\tconst band = bands[bi];\n\t\tif (!band) {\n\t\t\tmins.push(0);\n\t\t\tmaxs.push(1);\n\t\t\tcontinue;\n\t\t}\n\t\tlet bMin = Infinity;\n\t\tlet bMax = -Infinity;\n\t\tfor (let i = 0; i < pixelCount; i++) {\n\t\t\tconst v = band[i];\n\t\t\tif (nodata !== null && v === nodata) continue;\n\t\t\tif (!Number.isFinite(v)) continue;\n\t\t\tif (v < bMin) bMin = v;\n\t\t\tif (v > bMax) bMax = v;\n\t\t}\n\t\tmins.push(Number.isFinite(bMin) ? bMin : 0);\n\t\tmaxs.push(Number.isFinite(bMax) ? bMax : 1);\n\t}\n\treturn { mins, maxs };\n}\n\n/**\n * Create a configurable getTileData that respects BandConfig.\n * Supports RGB mode (multi-band → R,G,B with alpha=255, fully baked) and\n * single-band mode (band N normalized into the `r` channel; the ramp is\n * applied downstream by the GPU `Colormap` module via `buildCustomRenderTile`).\n */\nexport function createConfigurableGetTileData(\n\tgeotiff: GeoTIFFType,\n\tconfig: BandConfig,\n\topts: CustomGetTileDataOptions = {}\n) {\n\tconst bandCount = geotiff.count;\n\n\t// Shared per-band ranges across tiles (seeded on first tile, widened by subsequent)\n\tconst sharedMins = new Map<number, number>();\n\tconst sharedMaxs = new Map<number, number>();\n\n\t// Resolve the sprite texture from the first tile's device; reuse per-device.\n\tlet texturePromise: Promise<Texture> | null = null;\n\tconst histogram = config.mode === 'single' ? new Uint32Array(HISTOGRAM_BIN_COUNT) : null;\n\n\treturn async (\n\t\timage: GeoTIFFType | Overview,\n\t\toptions: { x: number; y: number; pool: unknown; signal?: AbortSignal; device: Device }\n\t): Promise<CustomTileData> => {\n\t\tif (config.mode === 'single' && !texturePromise) {\n\t\t\ttexturePromise = getColormapTexture(options.device);\n\t\t}\n\n\t\tconst [tile, colormapTexture] = await Promise.all([\n\t\t\timage.fetchTile(options.x, options.y, {\n\t\t\t\tboundless: false,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\tpool: options.pool as any,\n\t\t\t\tsignal: options.signal\n\t\t\t}),\n\t\t\ttexturePromise ?? Promise.resolve<Texture | undefined>(undefined)\n\t\t]);\n\n\t\tconst arr = tile.array;\n\t\tconst { width, height, nodata } = arr;\n\t\tconst pixelCount = width * height;\n\t\tconst bands = extractBands(arr, bandCount, pixelCount);\n\n\t\tconst rgba = new Uint8ClampedArray(pixelCount * 4);\n\n\t\tif (config.mode === 'rgb') {\n\t\t\t// RGB mode: map 3 bands to R, G, B\n\t\t\tconst indices = [config.rBand, config.gBand, config.bBand];\n\t\t\t// Compute ranges for the 3 selected bands\n\t\t\tfor (const bi of indices) {\n\t\t\t\tif (!sharedMins.has(bi)) {\n\t\t\t\t\tconst { mins, maxs } = computeBandRanges(bands, [bi], pixelCount, nodata);\n\t\t\t\t\tsharedMins.set(bi, mins[0]);\n\t\t\t\t\tsharedMaxs.set(bi, maxs[0]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst rBand = bands[config.rBand];\n\t\t\tconst gBand = bands[config.gBand];\n\t\t\tconst bBand = bands[config.bBand];\n\t\t\tconst rMin = sharedMins.get(config.rBand)!;\n\t\t\tconst rMax = sharedMaxs.get(config.rBand)!;\n\t\t\tconst gMin = sharedMins.get(config.gBand)!;\n\t\t\tconst gMax = sharedMaxs.get(config.gBand)!;\n\t\t\tconst bMin = sharedMins.get(config.bBand)!;\n\t\t\tconst bMax = sharedMaxs.get(config.bBand)!;\n\t\t\tconst rRange = rMax - rMin || 1;\n\t\t\tconst gRange = gMax - gMin || 1;\n\t\t\tconst bRange = bMax - bMin || 1;\n\n\t\t\tfor (let i = 0; i < pixelCount; i++) {\n\t\t\t\tconst rv = rBand?.[i] ?? 0;\n\t\t\t\tconst gv = gBand?.[i] ?? 0;\n\t\t\t\tconst bv = bBand?.[i] ?? 0;\n\t\t\t\tconst isND =\n\t\t\t\t\t(nodata !== null && (rv === nodata || gv === nodata || bv === nodata)) ||\n\t\t\t\t\t!Number.isFinite(rv);\n\t\t\t\tconst idx = i * 4;\n\t\t\t\tif (isND) {\n\t\t\t\t\trgba[idx] = 0;\n\t\t\t\t\trgba[idx + 1] = 0;\n\t\t\t\t\trgba[idx + 2] = 0;\n\t\t\t\t\trgba[idx + 3] = 0;\n\t\t\t\t} else {\n\t\t\t\t\trgba[idx] = Math.round(Math.max(0, Math.min(1, (rv - rMin) / rRange)) * 255);\n\t\t\t\t\trgba[idx + 1] = Math.round(Math.max(0, Math.min(1, (gv - gMin) / gRange)) * 255);\n\t\t\t\t\trgba[idx + 2] = Math.round(Math.max(0, Math.min(1, (bv - bMin) / bRange)) * 255);\n\t\t\t\t\trgba[idx + 3] = 255;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Single-band mode: normalize the selected band into the `r`\n\t\t\t// channel and reserve `r = 0` as a nodata sentinel that\n\t\t\t// `FilterNoDataVal` discards before the `Colormap` GPU lookup.\n\t\t\tconst bi = config.band;\n\t\t\tconst bandData = bands[bi];\n\t\t\tif (!sharedMins.has(bi) && bandData) {\n\t\t\t\tconst { mins, maxs } = computeBandRanges(bands, [bi], pixelCount, nodata);\n\t\t\t\tsharedMins.set(bi, mins[0]);\n\t\t\t\tsharedMaxs.set(bi, maxs[0]);\n\t\t\t}\n\t\t\tconst rangeMin = sharedMins.get(bi) ?? 0;\n\t\t\tconst rangeMax = sharedMaxs.get(bi) ?? 1;\n\t\t\tconst range = rangeMax - rangeMin || 1;\n\n\t\t\tfor (let i = 0; i < pixelCount; i++) {\n\t\t\t\tconst raw = bandData?.[i] ?? 0;\n\t\t\t\tconst isND = (nodata !== null && raw === nodata) || !Number.isFinite(raw);\n\t\t\t\tconst idx = i * 4;\n\t\t\t\tif (isND) {\n\t\t\t\t\trgba[idx] = 0;\n\t\t\t\t\trgba[idx + 1] = 0;\n\t\t\t\t\trgba[idx + 2] = 0;\n\t\t\t\t\trgba[idx + 3] = 0;\n\t\t\t\t} else {\n\t\t\t\t\tconst t = Math.max(0, Math.min(1, (raw - rangeMin) / range));\n\t\t\t\t\trgba[idx] = 1 + Math.round(t * 254);\n\t\t\t\t\trgba[idx + 1] = 0;\n\t\t\t\t\trgba[idx + 2] = 0;\n\t\t\t\t\trgba[idx + 3] = 255;\n\t\t\t\t\tif (histogram) {\n\t\t\t\t\t\tconst bin = Math.min(HISTOGRAM_BIN_COUNT - 1, Math.floor(t * HISTOGRAM_BIN_COUNT));\n\t\t\t\t\t\thistogram[bin]++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (histogram && opts.onHistogram) opts.onHistogram(histogram);\n\t\t}\n\n\t\treturn {\n\t\t\timageData: new ImageData(rgba, width, height),\n\t\t\twidth,\n\t\t\theight,\n\t\t\tcolormapTexture: config.mode === 'single' ? colormapTexture : undefined,\n\t\t\tnodataSentinel: config.mode === 'single' ? 0 : undefined\n\t\t};\n\t};\n}\n\n// ─── Pixel inspection ────────────────────────────────────────────\n\nexport interface PixelValue {\n\tlng: number;\n\tlat: number;\n\tvalues: number[];\n\trow: number;\n\tcol: number;\n}\n\n// ─── EPSG resolution via bundled database ────────────────────────\n\n/**\n * Look up the WKT string for an EPSG code from the bundled\n * `@developmentseed/epsg` database. The CSV is streamed, gunzipped and parsed\n * once on first use, subsequent lookups share the cached map via the\n * `loadEpsg()` internal singleton promise.\n */\nasync function lookupEpsgWkt(code: number): Promise<string | null> {\n\tconst db = await loadEpsg(epsgCsvUrl);\n\treturn db.get(code) ?? null;\n}\n\n// Units that `@developmentseed/proj` `metersPerUnit` accepts.\nconst ACCEPTED_CRS_UNITS = new Set([\n\t'm',\n\t'metre',\n\t'meter',\n\t'meters',\n\t'foot',\n\t'us survey foot',\n\t'degree'\n]);\n\n/**\n * Normalize a parsed projection definition so `generateTileMatrixSet` can\n * compute metersPerUnit. wkt-parser sets `units = wkt.UNIT.name.toLowerCase()`\n * and some EPSG WKT entries in the bundled database have a missing or\n * non-standard UNIT node, which surfaces as `units = \"unknown\"` and a downstream\n * throw. Infer the unit from `to_meter` or projection type when possible.\n */\nfunction normalizeCrsUnits(def: ProjectionDefinition): ProjectionDefinition {\n\tconst current = def.units?.toLowerCase();\n\tif (current && ACCEPTED_CRS_UNITS.has(current)) return def;\n\tif (def.projName === 'longlat') {\n\t\tdef.units = 'degree';\n\t\treturn def;\n\t}\n\tconst toMeter = def.to_meter;\n\tif (toMeter === undefined || Math.abs(toMeter - 1) < 1e-9) {\n\t\tdef.units = 'meter';\n\t} else if (Math.abs(toMeter - 0.3048) < 1e-9) {\n\t\tdef.units = 'foot';\n\t} else if (Math.abs(toMeter - 1200 / 3937) < 1e-9) {\n\t\tdef.units = 'us survey foot';\n\t}\n\treturn def;\n}\n\n/**\n * Create an async EPSG resolver for `@developmentseed/deck.gl-geotiff`.\n * Looks up the numeric EPSG code in the bundled WKT database and returns the\n * `ProjectionDefinition` produced by `parseWkt`. Throws a clear error when the\n * code is not present in the database.\n */\nexport function createEpsgResolver(): EpsgResolver {\n\tconst cache = new Map<number, ProjectionDefinition>();\n\treturn async (code: number): Promise<ProjectionDefinition> => {\n\t\tconst cached = cache.get(code);\n\t\tif (cached) return cached;\n\t\tconst wkt = await lookupEpsgWkt(code);\n\t\tif (!wkt) {\n\t\t\tthrow new Error(`EPSG:${code} not found in bundled projection database`);\n\t\t}\n\t\tconst def = normalizeCrsUnits(parseWkt(wkt));\n\t\tcache.set(code, def);\n\t\treturn def;\n\t};\n}\n\n/**\n * Resolve a proj4-compatible definition for a CRS read from a GeoTIFF.\n * For numeric EPSG codes this returns the WKT string from the bundled EPSG\n * database, which `proj4()` accepts directly. For ProjJSON it falls back to a\n * JSON string. Returns null for EPSG:4326 (no conversion needed) or when the\n * code is not present in the database.\n */\nexport async function resolveProj4Def(\n\tcrs: number | unknown,\n\t_signal: AbortSignal\n): Promise<string | null> {\n\tif (crs === 4326) return null;\n\tif (typeof crs === 'number') {\n\t\treturn lookupEpsgWkt(crs);\n\t}\n\t// ProjJSON — stringify for proj4\n\treturn JSON.stringify(crs);\n}\n\n/**\n * Read pixel values at a given lng/lat from a GeoTIFF.\n * Converts WGS84 → source CRS → pixel coords, fetches the tile, reads all bands.\n */\nexport async function readPixelAtLngLat(\n\tgeotiff: GeoTIFFType,\n\tlng: number,\n\tlat: number,\n\tproj4Def: string | null,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpool: any,\n\tsignal?: AbortSignal\n): Promise<PixelValue | null> {\n\t// Convert WGS84 to source CRS\n\tlet srcX = lng;\n\tlet srcY = lat;\n\tif (proj4Def) {\n\t\ttry {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\tconst conv = proj4Lib(proj4Def, 'EPSG:4326') as any;\n\t\t\t[srcX, srcY] = conv.inverse([lng, lat]);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// Get pixel indices (row, col)\n\tconst [row, col] = geotiff.index(srcX, srcY);\n\tif (row < 0 || row >= geotiff.height || col < 0 || col >= geotiff.width) return null;\n\n\t// Compute tile indices\n\tconst tileX = Math.floor(col / geotiff.tileWidth);\n\tconst tileY = Math.floor(row / geotiff.tileHeight);\n\n\t// Fetch tile\n\tconst tile = await geotiff.fetchTile(tileX, tileY, { pool, signal });\n\tconst arr = tile.array;\n\n\t// Read all band values at this pixel\n\tconst localCol = col - tileX * arr.width;\n\tconst localRow = row - tileY * arr.height;\n\tconst pixelIndex = localRow * arr.width + localCol;\n\n\tconst values: number[] = [];\n\tif (arr.layout === 'band-separate') {\n\t\tfor (let b = 0; b < arr.count; b++) {\n\t\t\tvalues.push((arr as { bands: ArrayLike<number>[] }).bands[b][pixelIndex]);\n\t\t}\n\t} else {\n\t\tfor (let b = 0; b < arr.count; b++) {\n\t\t\tvalues.push((arr as { data: ArrayLike<number> }).data[pixelIndex * arr.count + b]);\n\t\t}\n\t}\n\n\treturn { lng, lat, values, row, col };\n}\n","export type TypeCategory =\n\t| 'number'\n\t| 'string'\n\t| 'date'\n\t| 'boolean'\n\t| 'geo'\n\t| 'binary'\n\t| 'json'\n\t| 'other';\n\nconst NUMBER_TYPES = [\n\t'TINYINT',\n\t'SMALLINT',\n\t'INTEGER',\n\t'BIGINT',\n\t'HUGEINT',\n\t'UTINYINT',\n\t'USMALLINT',\n\t'UINTEGER',\n\t'UBIGINT',\n\t'FLOAT',\n\t'DOUBLE',\n\t'DECIMAL',\n\t'NUMERIC',\n\t'REAL',\n\t'INT',\n\t'INT1',\n\t'INT2',\n\t'INT4',\n\t'INT8',\n\t'SIGNED',\n\t'SHORT',\n\t'LONG'\n];\n\nconst STRING_TYPES = ['VARCHAR', 'TEXT', 'STRING', 'CHAR', 'BPCHAR', 'NAME', 'UUID', 'ENUM'];\n\nconst DATE_TYPES = [\n\t'DATE',\n\t'TIME',\n\t'TIMESTAMP',\n\t'TIMESTAMP_S',\n\t'TIMESTAMP_MS',\n\t'TIMESTAMP_NS',\n\t'TIMESTAMP WITH TIME ZONE',\n\t'TIMESTAMPTZ',\n\t'INTERVAL',\n\t'TIMESTAMP_TZ'\n];\n\nconst BOOLEAN_TYPES = ['BOOLEAN', 'BOOL', 'LOGICAL'];\n\nconst GEO_TYPES = [\n\t'GEOMETRY',\n\t'POINT',\n\t'LINESTRING',\n\t'POLYGON',\n\t'MULTIPOINT',\n\t'MULTILINESTRING',\n\t'MULTIPOLYGON',\n\t'GEOMETRYCOLLECTION',\n\t'WKB_GEOMETRY'\n];\n\nconst BINARY_TYPES = ['BLOB', 'BYTEA', 'BINARY', 'VARBINARY'];\n\nconst JSON_TYPES = ['JSON', 'JSONB'];\n\nexport function classifyType(duckdbType: string): TypeCategory {\n\tconst upper = duckdbType.toUpperCase().trim();\n\n\t// Handle parameterized types like DECIMAL(18,3), VARCHAR(100)\n\tconst base = upper.replace(/\\(.*\\)/, '').trim();\n\n\tif (NUMBER_TYPES.includes(base)) return 'number';\n\tif (STRING_TYPES.includes(base)) return 'string';\n\tif (DATE_TYPES.includes(base)) return 'date';\n\tif (BOOLEAN_TYPES.includes(base)) return 'boolean';\n\tif (GEO_TYPES.includes(base)) return 'geo';\n\tif (BINARY_TYPES.includes(base)) return 'binary';\n\tif (JSON_TYPES.includes(base)) return 'json';\n\n\t// Compound types\n\tif (base.startsWith('STRUCT') || base.startsWith('MAP') || base.startsWith('UNION'))\n\t\treturn 'json';\n\tif (base.endsWith('[]') || base.startsWith('LIST')) return 'json';\n\n\t// Fallback checks\n\tif (\n\t\tupper.includes('INT') ||\n\t\tupper.includes('FLOAT') ||\n\t\tupper.includes('DOUBLE') ||\n\t\tupper.includes('DECIMAL') ||\n\t\tupper.includes('NUMERIC')\n\t)\n\t\treturn 'number';\n\tif (upper.includes('CHAR') || upper.includes('TEXT') || upper.includes('STRING')) return 'string';\n\tif (upper.includes('TIME') || upper.includes('DATE')) return 'date';\n\tif (upper.includes('BOOL')) return 'boolean';\n\tif (upper.includes('GEOMETRY') || upper.includes('GEO') || upper.includes('WKB')) return 'geo';\n\tif (upper.includes('BLOB') || upper.includes('BINARY')) return 'binary';\n\tif (\n\t\tupper.includes('JSON') ||\n\t\tupper.includes('STRUCT') ||\n\t\tupper.includes('MAP') ||\n\t\tupper.includes('LIST')\n\t)\n\t\treturn 'json';\n\n\treturn 'other';\n}\n\nconst TYPE_COLORS: Record<TypeCategory, string> = {\n\tnumber: 'text-blue-500',\n\tstring: 'text-green-500',\n\tdate: 'text-amber-500',\n\tboolean: 'text-purple-500',\n\tgeo: 'text-teal-500',\n\tbinary: 'text-zinc-500',\n\tjson: 'text-orange-500',\n\tother: 'text-zinc-400'\n};\n\nconst TYPE_BADGE_CLASSES: Record<TypeCategory, string> = {\n\tnumber: 'bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/20',\n\tstring: 'bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/20',\n\tdate: 'bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/20',\n\tboolean: 'bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/20',\n\tgeo: 'bg-teal-500/10 text-teal-600 dark:text-teal-400 border-teal-500/20',\n\tbinary: 'bg-zinc-500/10 text-zinc-600 dark:text-zinc-400 border-zinc-500/20',\n\tjson: 'bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/20',\n\tother: 'bg-zinc-500/10 text-zinc-500 dark:text-zinc-400 border-zinc-500/20'\n};\n\nconst TYPE_LABELS: Record<TypeCategory, string> = {\n\tnumber: '#',\n\tstring: 'Aa',\n\tdate: 'dt',\n\tboolean: 'T/F',\n\tgeo: 'geo',\n\tbinary: '01',\n\tjson: '{}',\n\tother: '?'\n};\n\nexport function typeColor(category: TypeCategory): string {\n\treturn TYPE_COLORS[category];\n}\n\nexport function typeBadgeClass(category: TypeCategory): string {\n\treturn TYPE_BADGE_CLASSES[category];\n}\n\nexport function typeLabel(category: TypeCategory): string {\n\treturn TYPE_LABELS[category];\n}\n","/**\n * Shared error handling for async viewer load operations.\n */\n\n/**\n * Extract an error message from an unknown caught value.\n * Returns null for AbortError (caller should silently return).\n */\nexport function handleLoadError(err: unknown): string | null {\n\tif (err instanceof DOMException && err.name === 'AbortError') return null;\n\treturn err instanceof Error ? err.message : String(err);\n}\n","/**\n * Formats a byte count into a human-readable string.\n */\nexport function formatFileSize(bytes: number): string {\n\tif (bytes < 0) return '0 B';\n\tif (bytes === 0) return '0 B';\n\n\tconst units = ['B', 'KB', 'MB', 'GB', 'TB'];\n\tconst base = 1024;\n\tconst exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(base)), units.length - 1);\n\tconst value = bytes / base ** exponent;\n\n\t// Use integer display for bytes, one decimal for everything else\n\tif (exponent === 0) return `${bytes} B`;\n\treturn `${value.toFixed(1)} ${units[exponent]}`;\n}\n\n/**\n * Formats a unix timestamp (milliseconds) to a human-readable date string.\n * Shows relative time for recent dates, absolute for older ones.\n */\nexport function formatDate(timestamp: number): string {\n\tif (!timestamp || timestamp <= 0 || !Number.isFinite(timestamp)) return '--';\n\n\tconst date = new Date(timestamp);\n\tconst now = Date.now();\n\tconst diffMs = now - timestamp;\n\tconst diffSeconds = Math.floor(diffMs / 1000);\n\tconst diffMinutes = Math.floor(diffSeconds / 60);\n\tconst diffHours = Math.floor(diffMinutes / 60);\n\tconst diffDays = Math.floor(diffHours / 24);\n\n\tif (diffSeconds < 60) return 'Just now';\n\tif (diffMinutes < 60) return `${diffMinutes}m ago`;\n\tif (diffHours < 24) return `${diffHours}h ago`;\n\tif (diffDays < 7) return `${diffDays}d ago`;\n\n\t// For older dates, show absolute date\n\treturn date.toLocaleDateString(undefined, {\n\t\tyear: 'numeric',\n\t\tmonth: 'short',\n\t\tday: 'numeric'\n\t});\n}\n\n/**\n * Extracts the file extension from a filename, including the leading dot.\n * Returns an empty string if no extension is found.\n */\nexport function getFileExtension(filename: string): string {\n\tconst lastDot = filename.lastIndexOf('.');\n\tif (lastDot <= 0) return '';\n\treturn filename.slice(lastDot).toLowerCase();\n}\n\n/**\n * JSON replacer that converts BigInt values to strings.\n * Use with `JSON.stringify(value, jsonReplacerBigInt)`.\n */\nexport function jsonReplacerBigInt(_key: string, value: unknown): unknown {\n\treturn typeof value === 'bigint' ? value.toString() : value;\n}\n\n/**\n * Format a value for display in tables, attribute panels, and exports.\n * Handles null, undefined, Date, BigInt, and objects uniformly.\n */\nexport function formatValue(value: unknown): string {\n\tif (value === null || value === undefined) return 'NULL';\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value === 'bigint') return value.toString();\n\tif (typeof value === 'object') return JSON.stringify(value, jsonReplacerBigInt);\n\treturn String(value);\n}\n","import { jsonReplacerBigInt } from './format.js';\n\nfunction triggerDownload(content: string, filename: string, mimeType: string) {\n\tconst blob = new Blob([content], { type: mimeType });\n\tconst url = URL.createObjectURL(blob);\n\tconst a = document.createElement('a');\n\ta.href = url;\n\ta.download = filename;\n\tdocument.body.appendChild(a);\n\ta.click();\n\tdocument.body.removeChild(a);\n\tURL.revokeObjectURL(url);\n}\n\n/** Format a cell value for export (empty string for null/undefined). */\nfunction formatCellValue(value: unknown): string {\n\tif (value === null || value === undefined) return '';\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value === 'bigint') return value.toString();\n\tif (typeof value === 'object') return JSON.stringify(value, jsonReplacerBigInt);\n\treturn String(value);\n}\n\n/**\n * Escape a CSV field value per RFC 4180.\n */\nexport function escapeCsvField(value: string): string {\n\tif (value.includes(',') || value.includes('\"') || value.includes('\\n') || value.includes('\\r')) {\n\t\treturn `\"${value.replace(/\"/g, '\"\"')}\"`;\n\t}\n\treturn value;\n}\n\n/**\n * Serialize column/row data to a CSV string.\n * Pure function — no browser APIs, works in Node.js.\n */\nexport function serializeToCsv(columns: string[], rows: Record<string, unknown>[]): string {\n\tconst header = columns.map(escapeCsvField).join(',');\n\tconst body = rows\n\t\t.map((row) => columns.map((col) => escapeCsvField(formatCellValue(row[col]))).join(','))\n\t\t.join('\\n');\n\treturn `${header}\\n${body}`;\n}\n\n/**\n * Serialize column/row data to a formatted JSON string.\n * Pure function — no browser APIs, works in Node.js.\n */\nexport function serializeToJson(columns: string[], rows: Record<string, unknown>[]): string {\n\tconst data = rows.map((row) => {\n\t\tconst obj: Record<string, unknown> = {};\n\t\tfor (const col of columns) {\n\t\t\tconst val = row[col];\n\t\t\tif (val instanceof Date) {\n\t\t\t\tobj[col] = val.toISOString();\n\t\t\t} else {\n\t\t\t\tobj[col] = val ?? null;\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t});\n\treturn JSON.stringify(data, jsonReplacerBigInt, 2);\n}\n\n/**\n * Export data as CSV file (triggers browser download).\n */\nexport function exportToCsv(columns: string[], rows: Record<string, unknown>[], filename: string) {\n\ttriggerDownload(\n\t\tserializeToCsv(columns, rows),\n\t\tfilename.endsWith('.csv') ? filename : `${filename}.csv`,\n\t\t'text/csv;charset=utf-8;'\n\t);\n}\n\n/**\n * Export data as JSON file (triggers browser download).\n */\nexport function exportToJson(columns: string[], rows: Record<string, unknown>[], filename: string) {\n\ttriggerDownload(\n\t\tserializeToJson(columns, rows),\n\t\tfilename.endsWith('.json') ? filename : `${filename}.json`,\n\t\t'application/json'\n\t);\n}\n","/**\n * Pure file entry sorting — framework-agnostic, works in Node.js.\n */\n\nimport type { FileEntry } from '../types.js';\n\nexport type SortField = 'name' | 'size' | 'modified' | 'extension';\nexport type SortDirection = 'asc' | 'desc';\n\nexport interface SortConfig {\n\tfield: SortField;\n\tdirection: SortDirection;\n}\n\n/**\n * Sort file entries by the given config.\n * Directories always sort before files regardless of sort field.\n * Returns a new array (does not mutate the input).\n */\nexport function sortFileEntries(entries: FileEntry[], config: SortConfig): FileEntry[] {\n\tconst sorted = [...entries];\n\tconst dir = config.direction === 'asc' ? 1 : -1;\n\n\tsorted.sort((a, b) => {\n\t\t// Directories always come first\n\t\tif (a.is_dir && !b.is_dir) return -1;\n\t\tif (!a.is_dir && b.is_dir) return 1;\n\n\t\tswitch (config.field) {\n\t\t\tcase 'name':\n\t\t\t\treturn dir * a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });\n\t\t\tcase 'size':\n\t\t\t\treturn dir * (a.size - b.size);\n\t\t\tcase 'modified':\n\t\t\t\treturn dir * (a.modified - b.modified);\n\t\t\tcase 'extension':\n\t\t\t\treturn dir * a.extension.localeCompare(b.extension, undefined, { sensitivity: 'base' });\n\t\t\tdefault:\n\t\t\t\treturn 0;\n\t\t}\n\t});\n\n\treturn sorted;\n}\n\n/**\n * Toggle sort config: same field flips direction, new field starts ascending.\n */\nexport function toggleSortField(current: SortConfig, field: SortField): SortConfig {\n\tif (current.field === field) {\n\t\treturn { field, direction: current.direction === 'asc' ? 'desc' : 'asc' };\n\t}\n\treturn { field, direction: 'asc' };\n}\n","/**\n * Direct WKB → GeoArrow bridge (zero-copy).\n *\n * Reads raw WKB binary directly into pre-allocated Arrow typed arrays\n * without any intermediate JS object allocation. No parseWKB(), no GeoJSON.\n *\n * Data flow: WKB Uint8Array[] → DataView binary reads → Float64Array/Int32Array\n * → arrow.makeData() → arrow.Table with ARROW:extension:name metadata\n */\n\nimport type { Data } from 'apache-arrow';\nimport {\n\tField,\n\tFixedSizeList,\n\tFloat64,\n\tList,\n\tmakeData,\n\tRecordBatch,\n\tSchema,\n\tStruct,\n\tTable,\n\tUtf8\n} from 'apache-arrow';\n\nexport type GeoArrowGeomType =\n\t| 'point'\n\t| 'linestring'\n\t| 'polygon'\n\t| 'multipoint'\n\t| 'multilinestring'\n\t| 'multipolygon';\n\nexport interface GeoArrowResult {\n\ttable: Table;\n\tgeometryType: GeoArrowGeomType;\n\tbounds: [number, number, number, number]; // [minX, minY, maxX, maxY]\n\t/** Maps local table row index → original WKB array index (for selection lookup). */\n\tsourceIndices: number[];\n}\n\n/** Map DuckDB ST_GeometryType output to our normalized type. */\nexport function normalizeGeomType(raw: string): GeoArrowGeomType {\n\tconst s = raw.toUpperCase().replace(/\\s+/g, '');\n\tif (s === 'POINT') return 'point';\n\tif (s === 'LINESTRING') return 'linestring';\n\tif (s === 'POLYGON') return 'polygon';\n\tif (s === 'MULTIPOINT') return 'multipoint';\n\tif (s === 'MULTILINESTRING') return 'multilinestring';\n\tif (s === 'MULTIPOLYGON') return 'multipolygon';\n\treturn 'polygon'; // fallback\n}\n\n/** GeoArrow extension name for each geometry type. */\nconst EXTENSION_NAMES: Record<GeoArrowGeomType, string> = {\n\tpoint: 'geoarrow.point',\n\tlinestring: 'geoarrow.linestring',\n\tpolygon: 'geoarrow.polygon',\n\tmultipoint: 'geoarrow.multipoint',\n\tmultilinestring: 'geoarrow.multilinestring',\n\tmultipolygon: 'geoarrow.multipolygon'\n};\n\n// ─── WKB binary header reader ────────────────────────────────────────\n\ninterface WkbHeader {\n\ttype: number; // base geometry type (1–6)\n\tle: boolean; // little-endian\n\tcoordStride: number; // bytes per coordinate point (16=2D, 24=3D/M, 32=ZM)\n\tdataOffset: number; // byte offset where geometry data begins\n}\n\n/** Read WKB/EWKB header — 5 bytes + optional SRID. No allocations. */\nfunction readWkbHeader(wkb: Uint8Array): WkbHeader | null {\n\tif (wkb.length < 5) return null;\n\tconst le = wkb[0] === 1;\n\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\tconst rawType = dv.getUint32(1, le);\n\n\tlet headerSize = 5; // byte_order(1) + type(4)\n\n\t// EWKB SRID flag — 4 extra bytes after type\n\tif ((rawType & 0x20000000) !== 0) headerSize += 4;\n\n\t// EWKB dimension flags\n\tconst ewkbZ = (rawType & 0x80000000) !== 0;\n\tconst ewkbM = (rawType & 0x40000000) !== 0;\n\n\t// Strip all EWKB flags to get base type\n\tlet type = rawType & 0x0fffffff;\n\n\t// ISO Z/M ranges: 1001–1006 (Z), 2001–2006 (M), 3001–3006 (ZM)\n\tlet isoZ = false;\n\tlet isoM = false;\n\tif (type > 3000) {\n\t\tisoZ = true;\n\t\tisoM = true;\n\t\ttype -= 3000;\n\t} else if (type > 2000) {\n\t\tisoM = true;\n\t\ttype -= 2000;\n\t} else if (type > 1000) {\n\t\tisoZ = true;\n\t\ttype -= 1000;\n\t}\n\n\tconst dims = (ewkbZ || isoZ ? 1 : 0) + (ewkbM || isoM ? 1 : 0);\n\tconst coordStride = (2 + dims) * 8; // 16, 24, or 32 bytes\n\n\treturn { type, le, coordStride, dataOffset: headerSize };\n}\n\n/** Classify WKB type from first 5 bytes. No full parse. */\nfunction classifyWkbType(wkb: Uint8Array): GeoArrowGeomType | null {\n\tconst h = readWkbHeader(wkb);\n\tif (!h) return null;\n\tswitch (h.type) {\n\t\tcase 1:\n\t\t\treturn 'point';\n\t\tcase 2:\n\t\t\treturn 'linestring';\n\t\tcase 3:\n\t\t\treturn 'polygon';\n\t\tcase 4:\n\t\t\treturn 'multipoint';\n\t\tcase 5:\n\t\t\treturn 'multilinestring';\n\t\tcase 6:\n\t\t\treturn 'multipolygon';\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n// ─── Bounds tracking ─────────────────────────────────────────────────\n\ninterface BoundsTracker {\n\tminX: number;\n\tminY: number;\n\tmaxX: number;\n\tmaxY: number;\n}\n\nfunction newBounds(): BoundsTracker {\n\treturn { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };\n}\n\n/** Update bounds, skipping NaN coordinates (EMPTY geometries, invalid data). */\nfunction expandBounds(b: BoundsTracker, x: number, y: number) {\n\tif (Number.isNaN(x) || Number.isNaN(y)) return;\n\tif (x < b.minX) b.minX = x;\n\tif (y < b.minY) b.minY = y;\n\tif (x > b.maxX) b.maxX = x;\n\tif (y > b.maxY) b.maxY = y;\n}\n\n// ─── Arrow coordinate type (shared) ─────────────────────────────────\n\nconst coordField = new Field('xy', new Float64());\nconst coordType = new FixedSizeList(2, coordField);\n\n/** Build FixedSizeList<Float64> Data from a pre-allocated Float64Array. */\nfunction makeCoordData(coords: Float64Array, numPoints: number): Data<FixedSizeList> {\n\tconst floatData = makeData({ type: new Float64(), length: coords.length, data: coords });\n\treturn makeData({ type: coordType, length: numPoints, nullCount: 0, child: floatData });\n}\n\n// ─── Direct WKB → Arrow builders (zero intermediate objects) ─────────\n\n/**\n * POINT: [byte_order:1][type:4][x:8][y:8]\n * Direct read — 2 Float64 reads per geometry. Zero parseWKB.\n */\nfunction buildPointData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst coords = new Float64Array(n * 2);\n\n\tfor (let i = 0; i < n; i++) {\n\t\tconst wkb = wkbs[i];\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 1) {\n\t\t\tcoords[i * 2] = 0;\n\t\t\tcoords[i * 2 + 1] = 0;\n\t\t\tcontinue;\n\t\t}\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst x = dv.getFloat64(h.dataOffset, h.le);\n\t\tconst y = dv.getFloat64(h.dataOffset + 8, h.le);\n\t\tcoords[i * 2] = x;\n\t\tcoords[i * 2 + 1] = y;\n\t\texpandBounds(b, x, y);\n\t}\n\n\treturn makeCoordData(coords, n);\n}\n\n/**\n * LINESTRING: [byte_order:1][type:4][num_points:4][x:8,y:8 × n]\n * Two-pass: count first to pre-allocate, then extract.\n */\nfunction buildLineStringData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsets = new Int32Array(n + 1);\n\tlet totalCoords = 0;\n\n\t// Pass 1: count coordinates\n\tfor (let i = 0; i < n; i++) {\n\t\tgeomOffsets[i] = totalCoords;\n\t\tconst h = readWkbHeader(wkbs[i]);\n\t\tif (!h || h.type !== 2) continue;\n\t\tconst dv = new DataView(wkbs[i].buffer, wkbs[i].byteOffset, wkbs[i].byteLength);\n\t\tconst numPts = dv.getUint32(h.dataOffset, h.le);\n\t\ttotalCoords += numPts;\n\t}\n\tgeomOffsets[n] = totalCoords;\n\n\t// Pass 2: extract coordinates directly from binary\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 2) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPts = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\tconst x = dv.getFloat64(off, h.le);\n\t\t\tconst y = dv.getFloat64(off + 8, h.le);\n\t\t\tcoords[ci++] = x;\n\t\t\tcoords[ci++] = y;\n\t\t\texpandBounds(b, x, y);\n\t\t\toff += h.coordStride;\n\t\t}\n\t}\n\n\tconst fslData = makeCoordData(coords, totalCoords);\n\tconst listType = new List(new Field('vertices', coordType));\n\treturn makeData({\n\t\ttype: listType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: fslData\n\t});\n}\n\n/**\n * POLYGON: [byte_order:1][type:4][num_rings:4]\n * { [num_points:4][x:8,y:8 × n] } × rings\n * Two-pass: count rings+coords first, then extract.\n */\nfunction buildPolygonData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsets = new Int32Array(n + 1);\n\tlet totalRings = 0;\n\tlet totalCoords = 0;\n\n\t// Pass 1: count rings and coordinates\n\tfor (let i = 0; i < n; i++) {\n\t\tgeomOffsets[i] = totalRings;\n\t\tconst h = readWkbHeader(wkbs[i]);\n\t\tif (!h || h.type !== 3) continue;\n\t\tconst dv = new DataView(wkbs[i].buffer, wkbs[i].byteOffset, wkbs[i].byteLength);\n\t\tconst numRings = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\tconst numPts = dv.getUint32(off, h.le);\n\t\t\toff += 4 + numPts * h.coordStride;\n\t\t\ttotalCoords += numPts;\n\t\t\ttotalRings++;\n\t\t}\n\t}\n\tgeomOffsets[n] = totalRings;\n\n\t// Pass 2: extract coordinates and ring offsets\n\tconst ringOffsets = new Int32Array(totalRings + 1);\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet ri = 0;\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 3) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numRings = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\tringOffsets[ri++] = ci >> 1; // coordIndex = ci / 2\n\t\t\tconst numPts = dv.getUint32(off, h.le);\n\t\t\toff += 4;\n\t\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t\tconst x = dv.getFloat64(off, h.le);\n\t\t\t\tconst y = dv.getFloat64(off + 8, h.le);\n\t\t\t\tcoords[ci++] = x;\n\t\t\t\tcoords[ci++] = y;\n\t\t\t\texpandBounds(b, x, y);\n\t\t\t\toff += h.coordStride;\n\t\t\t}\n\t\t}\n\t}\n\tringOffsets[totalRings] = ci >> 1;\n\n\tconst coordCount = ci >> 1;\n\tconst fslData = makeCoordData(coords, coordCount);\n\n\tconst ringListType = new List(new Field('vertices', coordType));\n\tconst ringListData = makeData({\n\t\ttype: ringListType,\n\t\tlength: totalRings,\n\t\tnullCount: 0,\n\t\tvalueOffsets: ringOffsets,\n\t\tchild: fslData\n\t});\n\n\tconst polyType = new List(new Field('rings', ringListType));\n\treturn makeData({\n\t\ttype: polyType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: ringListData\n\t});\n}\n\n/** MultiPoint has same Arrow structure as LineString: List<FixedSizeList(2)>. */\nfunction buildMultiPointData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\t// MultiPoint WKB: [header][num_points:4]{Point WKB × n}\n\t// Each inner point has its own WKB header.\n\tconst n = wkbs.length;\n\tconst geomOffsets = new Int32Array(n + 1);\n\tlet totalCoords = 0;\n\n\t// Pass 1: count\n\tfor (let i = 0; i < n; i++) {\n\t\tgeomOffsets[i] = totalCoords;\n\t\tconst h = readWkbHeader(wkbs[i]);\n\t\tif (!h || h.type !== 4) continue;\n\t\tconst dv = new DataView(wkbs[i].buffer, wkbs[i].byteOffset, wkbs[i].byteLength);\n\t\ttotalCoords += dv.getUint32(h.dataOffset, h.le);\n\t}\n\tgeomOffsets[n] = totalCoords;\n\n\t// Pass 2: extract from inner point WKBs\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 4) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPts = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t// Each inner point is a full WKB: skip its header to get coords\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (innerH) {\n\t\t\t\tconst x = dv.getFloat64(off + innerH.dataOffset, innerH.le);\n\t\t\t\tconst y = dv.getFloat64(off + innerH.dataOffset + 8, innerH.le);\n\t\t\t\tcoords[ci++] = x;\n\t\t\t\tcoords[ci++] = y;\n\t\t\t\texpandBounds(b, x, y);\n\t\t\t\toff += innerH.dataOffset + innerH.coordStride;\n\t\t\t} else {\n\t\t\t\tcoords[ci++] = 0;\n\t\t\t\tcoords[ci++] = 0;\n\t\t\t\toff += 21; // minimum point WKB size\n\t\t\t}\n\t\t}\n\t}\n\n\tconst fslData = makeCoordData(coords, totalCoords);\n\tconst listType = new List(new Field('vertices', coordType));\n\treturn makeData({\n\t\ttype: listType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: fslData\n\t});\n}\n\n/**\n * MULTILINESTRING: [header][num_lines:4]{LineString WKB × n}\n * Each inner LineString has its own WKB header.\n */\nfunction buildMultiLineStringData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsetsArr: number[] = [0];\n\tlet totalLines = 0;\n\tlet totalCoords = 0;\n\n\t// Pass 1: count lines and coordinates\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 5) {\n\t\t\tgeomOffsetsArr.push(totalLines);\n\t\t\tcontinue;\n\t\t}\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numLines = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let l = 0; l < numLines; l++) {\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst innerDv = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off);\n\t\t\tconst numPts = innerDv.getUint32(innerH.dataOffset, innerH.le);\n\t\t\ttotalCoords += numPts;\n\t\t\toff += innerH.dataOffset + 4 + numPts * innerH.coordStride;\n\t\t\ttotalLines++;\n\t\t}\n\t\tgeomOffsetsArr.push(totalLines);\n\t}\n\n\t// Pass 2: extract\n\tconst geomOffsets = new Int32Array(geomOffsetsArr);\n\tconst lineOffsets = new Int32Array(totalLines + 1);\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet li = 0;\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 5) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numLines = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let l = 0; l < numLines; l++) {\n\t\t\tlineOffsets[li++] = ci >> 1;\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst numPts = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off).getUint32(\n\t\t\t\tinnerH.dataOffset,\n\t\t\t\tinnerH.le\n\t\t\t);\n\t\t\tlet ptOff = off + innerH.dataOffset + 4;\n\t\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t\tconst x = dv.getFloat64(ptOff, innerH.le);\n\t\t\t\tconst y = dv.getFloat64(ptOff + 8, innerH.le);\n\t\t\t\tcoords[ci++] = x;\n\t\t\t\tcoords[ci++] = y;\n\t\t\t\texpandBounds(b, x, y);\n\t\t\t\tptOff += innerH.coordStride;\n\t\t\t}\n\t\t\toff = ptOff;\n\t\t}\n\t}\n\tlineOffsets[totalLines] = ci >> 1;\n\n\tconst fslData = makeCoordData(coords, ci >> 1);\n\tconst lineListType = new List(new Field('vertices', coordType));\n\tconst lineListData = makeData({\n\t\ttype: lineListType,\n\t\tlength: totalLines,\n\t\tnullCount: 0,\n\t\tvalueOffsets: lineOffsets,\n\t\tchild: fslData\n\t});\n\n\tconst multiLineType = new List(new Field('lines', lineListType));\n\treturn makeData({\n\t\ttype: multiLineType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: lineListData\n\t});\n}\n\n/**\n * MULTIPOLYGON: [header][num_polys:4]{Polygon WKB × n}\n * Each inner Polygon has its own WKB header.\n */\nfunction buildMultiPolygonData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsetsArr: number[] = [0];\n\tlet totalPolys = 0;\n\tlet totalRings = 0;\n\tlet totalCoords = 0;\n\n\t// Pass 1: count polygons, rings, coordinates\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 6) {\n\t\t\tgeomOffsetsArr.push(totalPolys);\n\t\t\tcontinue;\n\t\t}\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPolys = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let p = 0; p < numPolys; p++) {\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst innerDv = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off);\n\t\t\tconst numRings = innerDv.getUint32(innerH.dataOffset, innerH.le);\n\t\t\tlet ringOff = innerH.dataOffset + 4;\n\t\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\t\tconst numPts = innerDv.getUint32(ringOff, innerH.le);\n\t\t\t\tringOff += 4 + numPts * innerH.coordStride;\n\t\t\t\ttotalCoords += numPts;\n\t\t\t\ttotalRings++;\n\t\t\t}\n\t\t\toff += ringOff;\n\t\t\ttotalPolys++;\n\t\t}\n\t\tgeomOffsetsArr.push(totalPolys);\n\t}\n\n\t// Pass 2: extract\n\tconst geomOffsets = new Int32Array(geomOffsetsArr);\n\tconst polyOffsets = new Int32Array(totalPolys + 1);\n\tconst ringOffsets = new Int32Array(totalRings + 1);\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet pi = 0;\n\tlet ri = 0;\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 6) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPolys = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let p = 0; p < numPolys; p++) {\n\t\t\tpolyOffsets[pi++] = ri;\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst innerDv = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off);\n\t\t\tconst numRings = innerDv.getUint32(innerH.dataOffset, innerH.le);\n\t\t\tlet ringOff = off + innerH.dataOffset + 4;\n\t\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\t\tringOffsets[ri++] = ci >> 1;\n\t\t\t\tconst numPts = dv.getUint32(ringOff, innerH.le);\n\t\t\t\tringOff += 4;\n\t\t\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t\t\tconst x = dv.getFloat64(ringOff, innerH.le);\n\t\t\t\t\tconst y = dv.getFloat64(ringOff + 8, innerH.le);\n\t\t\t\t\tcoords[ci++] = x;\n\t\t\t\t\tcoords[ci++] = y;\n\t\t\t\t\texpandBounds(b, x, y);\n\t\t\t\t\tringOff += innerH.coordStride;\n\t\t\t\t}\n\t\t\t}\n\t\t\toff = ringOff;\n\t\t}\n\t}\n\tpolyOffsets[totalPolys] = ri;\n\tringOffsets[totalRings] = ci >> 1;\n\n\tconst fslData = makeCoordData(coords, ci >> 1);\n\n\tconst ringListType = new List(new Field('vertices', coordType));\n\tconst ringListData = makeData({\n\t\ttype: ringListType,\n\t\tlength: totalRings,\n\t\tnullCount: 0,\n\t\tvalueOffsets: ringOffsets,\n\t\tchild: fslData\n\t});\n\n\tconst polyListType = new List(new Field('rings', ringListType));\n\tconst polyListData = makeData({\n\t\ttype: polyListType,\n\t\tlength: totalPolys,\n\t\tnullCount: 0,\n\t\tvalueOffsets: polyOffsets,\n\t\tchild: ringListData\n\t});\n\n\tconst multiPolyType = new List(new Field('polygons', polyListType));\n\treturn makeData({\n\t\ttype: multiPolyType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: polyListData\n\t});\n}\n\n// ─── Build a single GeoArrow table for one type group ────────────────\n\n/** Build attribute columns for a subset of rows identified by indices. */\nfunction buildAttributeColumns(\n\tindices: number[],\n\tattributes: Map<string, { values: any[]; type: string }>\n): { fields: Field[]; data: Data[] } {\n\tconst n = indices.length;\n\tconst fields: Field[] = [];\n\tconst dataArr: Data[] = [];\n\n\tfor (const [name, col] of attributes) {\n\t\tconst { values } = col;\n\n\t\t// Detect whether values are numeric or string\n\t\tlet isNumeric = true;\n\t\tconst sampleEnd = Math.min(n, 100);\n\t\tfor (let i = 0; i < sampleEnd; i++) {\n\t\t\tif (values[indices[i]] != null && typeof values[indices[i]] !== 'number') {\n\t\t\t\tisNumeric = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (isNumeric) {\n\t\t\tconst arr = new Float64Array(n);\n\t\t\tfor (let i = 0; i < n; i++) arr[i] = values[indices[i]] ?? NaN;\n\t\t\tconst data = makeData({ type: new Float64(), length: n, data: arr });\n\t\t\tfields.push(new Field(name, new Float64(), true));\n\t\t\tdataArr.push(data);\n\t\t} else {\n\t\t\tconst encoder = new TextEncoder();\n\t\t\tconst offsets = new Int32Array(n + 1);\n\t\t\tlet totalBytes = 0;\n\n\t\t\t// Single pass: encode directly into a growing buffer\n\t\t\tconst strParts: Uint8Array[] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\toffsets[i] = totalBytes;\n\t\t\t\tconst s = values[indices[i]] != null ? String(values[indices[i]]) : '';\n\t\t\t\tconst encoded = encoder.encode(s);\n\t\t\t\tstrParts.push(encoded);\n\t\t\t\ttotalBytes += encoded.length;\n\t\t\t}\n\t\t\toffsets[n] = totalBytes;\n\n\t\t\tconst valueBuffer = new Uint8Array(totalBytes);\n\t\t\tlet pos = 0;\n\t\t\tfor (const sv of strParts) {\n\t\t\t\tvalueBuffer.set(sv, pos);\n\t\t\t\tpos += sv.length;\n\t\t\t}\n\n\t\t\tconst data = makeData({\n\t\t\t\ttype: new Utf8(),\n\t\t\t\tlength: n,\n\t\t\t\tvalueOffsets: offsets,\n\t\t\t\tdata: valueBuffer\n\t\t\t});\n\t\t\tfields.push(new Field(name, new Utf8(), true));\n\t\t\tdataArr.push(data);\n\t\t}\n\t}\n\n\treturn { fields, data: dataArr };\n}\n\n/** Build a single GeoArrow table for one geometry type group. */\nfunction buildSingleTable(\n\tgeomType: GeoArrowGeomType,\n\twkbs: Uint8Array[],\n\tindices: number[],\n\tattributes: Map<string, { values: any[]; type: string }>,\n\tb: BoundsTracker\n): GeoArrowResult {\n\tconst n = wkbs.length;\n\n\tlet geomData: Data;\n\tswitch (geomType) {\n\t\tcase 'point':\n\t\t\tgeomData = buildPointData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'linestring':\n\t\t\tgeomData = buildLineStringData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'polygon':\n\t\t\tgeomData = buildPolygonData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'multipoint':\n\t\t\tgeomData = buildMultiPointData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'multilinestring':\n\t\t\tgeomData = buildMultiLineStringData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'multipolygon':\n\t\t\tgeomData = buildMultiPolygonData(wkbs, b);\n\t\t\tbreak;\n\t}\n\n\tconst extensionName = EXTENSION_NAMES[geomType];\n\tconst geomMetadata = new Map<string, string>([\n\t\t['ARROW:extension:name', extensionName],\n\t\t[\n\t\t\t'ARROW:extension:metadata',\n\t\t\tJSON.stringify({\n\t\t\t\tcrs: {\n\t\t\t\t\ttype: 'name',\n\t\t\t\t\tproperties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }\n\t\t\t\t}\n\t\t\t})\n\t\t]\n\t]);\n\n\tconst geomField = new Field('geometry', geomData.type, false, geomMetadata);\n\tconst attrCols = buildAttributeColumns(indices, attributes);\n\n\tconst fields: Field[] = [geomField, ...attrCols.fields];\n\tconst childrenData: Data[] = [geomData, ...attrCols.data];\n\n\tconst arrowSchema = new Schema(fields);\n\tconst structType = new Struct(fields);\n\tconst structData = makeData({\n\t\ttype: structType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tchildren: childrenData\n\t});\n\tconst batch = new RecordBatch(arrowSchema, structData);\n\tconst table = new Table(arrowSchema, batch);\n\n\treturn {\n\t\ttable,\n\t\tgeometryType: geomType,\n\t\tbounds: [b.minX, b.minY, b.maxX, b.maxY],\n\t\tsourceIndices: indices\n\t};\n}\n\n// ─── Main entry point ────────────────────────────────────────────────\n\n/**\n * Build GeoArrow tables from raw WKB arrays, automatically splitting by geometry type.\n * Returns one GeoArrowResult per non-empty type group, with shared merged bounds.\n *\n * @param wkbArrays Raw WKB binary arrays from DuckDB\n * @param attributes Attribute columns (non-geometry)\n * @param knownGeomType If provided (e.g. from GeoParquet metadata), skip classification\n */\nexport function buildGeoArrowTables(\n\twkbArrays: Uint8Array[],\n\tattributes: Map<string, { values: any[]; type: string }>,\n\tknownGeomType?: GeoArrowGeomType\n): GeoArrowResult[] {\n\tif (wkbArrays.length === 0) return [];\n\n\t// Fast path: known geometry type from metadata — skip classification entirely\n\tif (knownGeomType) {\n\t\tconst globalBounds = newBounds();\n\t\tconst indices = Array.from({ length: wkbArrays.length }, (_, i) => i);\n\t\tconst result = buildSingleTable(knownGeomType, wkbArrays, indices, attributes, globalBounds);\n\t\treturn [result];\n\t}\n\n\t// Classify by reading only the type bytes (5 bytes per WKB, not full parse)\n\tconst groups = new Map<GeoArrowGeomType, { wkbs: Uint8Array[]; indices: number[] }>();\n\n\tfor (let i = 0; i < wkbArrays.length; i++) {\n\t\tconst geomType = classifyWkbType(wkbArrays[i]);\n\t\tif (!geomType) continue;\n\n\t\tlet group = groups.get(geomType);\n\t\tif (!group) {\n\t\t\tgroup = { wkbs: [], indices: [] };\n\t\t\tgroups.set(geomType, group);\n\t\t}\n\t\tgroup.wkbs.push(wkbArrays[i]);\n\t\tgroup.indices.push(i);\n\t}\n\n\tif (groups.size === 0) return [];\n\n\tconst globalBounds = newBounds();\n\tconst results: GeoArrowResult[] = [];\n\n\tfor (const [geomType, { wkbs, indices }] of groups) {\n\t\tconst result = buildSingleTable(geomType, wkbs, indices, attributes, globalBounds);\n\t\tresults.push(result);\n\t}\n\n\t// Share merged bounds across all results\n\tconst mergedBounds: [number, number, number, number] = [\n\t\tglobalBounds.minX,\n\t\tglobalBounds.minY,\n\t\tglobalBounds.maxX,\n\t\tglobalBounds.maxY\n\t];\n\tfor (const r of results) r.bounds = mergedBounds;\n\n\treturn results;\n}\n","export interface HexRow {\n\toffset: string;\n\thex: string[];\n\tascii: string;\n}\n\n/**\n * Generates a hex dump from binary data.\n * Returns rows of offset | hex bytes | ASCII representation.\n */\nexport function generateHexDump(data: Uint8Array, bytesPerRow = 16): HexRow[] {\n\tconst rows: HexRow[] = [];\n\n\tfor (let i = 0; i < data.length; i += bytesPerRow) {\n\t\tconst slice = data.slice(i, i + bytesPerRow);\n\t\tconst offset = i.toString(16).padStart(8, '0');\n\n\t\tconst hex: string[] = [];\n\t\tfor (let j = 0; j < bytesPerRow; j++) {\n\t\t\tif (j < slice.length) {\n\t\t\t\thex.push(slice[j].toString(16).padStart(2, '0'));\n\t\t\t} else {\n\t\t\t\thex.push(' ');\n\t\t\t}\n\t\t}\n\n\t\tlet ascii = '';\n\t\tfor (let j = 0; j < slice.length; j++) {\n\t\t\tconst byte = slice[j];\n\t\t\tascii += byte >= 0x20 && byte <= 0x7e ? String.fromCharCode(byte) : '.';\n\t\t}\n\n\t\trows.push({ offset, hex, ascii });\n\t}\n\n\treturn rows;\n}\n","/**\n * Generic localStorage helpers with SSR safety.\n *\n * Used by connection, settings, and query-history stores to avoid\n * repeating the same load/persist/try-catch/SSR-guard pattern.\n */\n\n/**\n * Load a JSON value from localStorage.\n * Returns `defaultValue` on SSR, missing key, or parse error.\n */\nexport function loadFromStorage<T>(key: string, defaultValue: T): T {\n\tif (typeof window === 'undefined') return defaultValue;\n\ttry {\n\t\tconst raw = localStorage.getItem(key);\n\t\tif (raw) return JSON.parse(raw) as T;\n\t} catch {\n\t\t// ignore parse errors\n\t}\n\treturn defaultValue;\n}\n\n/**\n * Persist a JSON-serializable value to localStorage.\n * Silently no-ops on SSR or storage errors (quota, private browsing).\n */\nexport function persistToStorage(key: string, value: unknown): void {\n\tif (typeof window === 'undefined') return;\n\ttry {\n\t\tlocalStorage.setItem(key, JSON.stringify(value));\n\t} catch {\n\t\t// ignore storage errors\n\t}\n}\n","export interface SqlBlock {\n\tname: string;\n\tsql: string;\n\tstartLine: number;\n\tendLine: number;\n}\n\nexport interface ParsedMarkdownDocument {\n\tfrontmatter: Record<string, any>;\n\tcontent: string;\n\tsqlBlocks: SqlBlock[];\n}\n\n/**\n * Parse a markdown document with YAML frontmatter and SQL code blocks.\n *\n * Evidence-compatible syntax:\n * ```sql query_name\n * SELECT * FROM table\n * ```\n */\nexport async function parseMarkdownDocument(markdown: string): Promise<ParsedMarkdownDocument> {\n\tlet frontmatter: Record<string, any> = {};\n\tlet content = markdown;\n\n\tconst fmMatch = markdown.match(/^---\\n([\\s\\S]*?)\\n---\\n/);\n\tif (fmMatch) {\n\t\ttry {\n\t\t\tconst { default: YAML } = await import('yaml');\n\t\t\tfrontmatter = YAML.parse(fmMatch[1]) || {};\n\t\t} catch {\n\t\t\t// Invalid YAML or yaml peer dep not installed, ignore frontmatter\n\t\t}\n\t\tcontent = markdown.slice(fmMatch[0].length);\n\t}\n\n\t// Extract SQL blocks\n\tconst sqlBlocks: SqlBlock[] = [];\n\tconst lines = content.split('\\n');\n\tlet i = 0;\n\n\twhile (i < lines.length) {\n\t\tconst line = lines[i];\n\t\tconst match = line.match(/^```sql\\s+(\\w[\\w-]*)\\s*$/);\n\n\t\tif (match) {\n\t\t\tconst name = match[1];\n\t\t\tconst startLine = i;\n\t\t\tconst sqlLines: string[] = [];\n\t\t\ti++;\n\n\t\t\twhile (i < lines.length && lines[i] !== '```') {\n\t\t\t\tsqlLines.push(lines[i]);\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\tsqlBlocks.push({\n\t\t\t\tname,\n\t\t\t\tsql: sqlLines.join('\\n'),\n\t\t\t\tstartLine,\n\t\t\t\tendLine: i\n\t\t\t});\n\t\t}\n\t\ti++;\n\t}\n\n\treturn { frontmatter, content, sqlBlocks };\n}\n\n/**\n * Interpolate template variables in markdown text.\n * Supports {queryName.rows[0].columnName} syntax.\n */\nexport function interpolateTemplates(\n\ttext: string,\n\tqueryResults: Map<string, Record<string, any>[]>\n): string {\n\treturn text.replace(/\\{(\\w+)\\.rows\\[(\\d+)\\]\\.(\\w+)\\}/g, (match, queryName, rowIdx, colName) => {\n\t\tconst rows = queryResults.get(queryName);\n\t\tif (!rows) return match;\n\t\tconst row = rows[parseInt(rowIdx, 10)];\n\t\tif (!row) return match;\n\t\tconst value = row[colName];\n\t\treturn value !== undefined ? String(value) : match;\n\t});\n}\n\n/**\n * Replace SQL blocks in markdown content with placeholder markers\n * that can be replaced with rendered components.\n */\nexport function markSqlBlocks(content: string): string {\n\treturn content.replace(\n\t\t/```sql\\s+(\\w[\\w-]*)\\s*\\n([\\s\\S]*?)```/g,\n\t\t(_, name) => `<div data-sql-block=\"${name}\"></div>`\n\t);\n}\n","/**\n * Lightweight Parquet metadata reader using hyparquet.\n *\n * Reads schema, row count, CRS, and geometry types from the Parquet footer\n * via a single HTTP range request (~512KB). No DuckDB boot needed.\n *\n * This provides instant metadata display before DuckDB-WASM finishes loading.\n */\n\nimport { WGS84_CODES } from '../constants.js';\nimport type { GeoArrowGeomType } from './geoarrow.js';\n\nexport interface GeoColumnMeta {\n\tencoding: string;\n\tgeometryTypes: string[];\n\tcrs: any | null;\n\tbbox?: number[];\n}\n\nexport interface GeoParquetMeta {\n\tprimaryColumn: string;\n\tcolumns: Record<string, GeoColumnMeta>;\n}\n\nexport interface ParquetFileMetadata {\n\t/** Total number of rows across all row groups. */\n\trowCount: number;\n\t/** Column schema (name + type). Leaf columns only (structs flattened to children). */\n\tschema: { name: string; type: string }[];\n\t/**\n\t * Top-level column names as written. Includes struct/group parents (e.g.\n\t * `assets`, `bbox`) that `schema` flattens away. Required for stac-geoparquet\n\t * detection, which looks up struct columns by their parent name.\n\t */\n\ttopLevelColumns: string[];\n\t/** GeoParquet \"geo\" metadata if present. */\n\tgeo: GeoParquetMeta | null;\n\t/** True when file has legacy GeoParquet metadata (schema_version 0.x without \"version\" field). */\n\tlegacyGeoParquet: boolean;\n\t/** Tool that created the file (e.g. \"pyarrow 15.0.0\"). */\n\tcreatedBy: string | null;\n\t/** Number of row groups. */\n\tnumRowGroups: number;\n\t/** Primary compression codec (e.g. \"SNAPPY\", \"ZSTD\"). */\n\tcompression: string | null;\n}\n\n/** Map hyparquet schema element types to DuckDB-like type strings. */\nfunction mapParquetType(col: any): string {\n\tconst lt = col.logical_type;\n\tif (lt) {\n\t\t// Parquet Format 2.11+ native geometry/geography types\n\t\tif (lt.type === 'GEOMETRY' || lt.type === 'GEOGRAPHY') return 'GEOMETRY';\n\t\t// String types\n\t\tif (lt.type === 'STRING' || lt.type === 'UTF8') return 'VARCHAR';\n\t\tif (lt.type === 'JSON') return 'JSON';\n\t\tif (lt.type === 'UUID') return 'UUID';\n\t\tif (lt.type === 'ENUM') return 'VARCHAR';\n\t\t// Integer types\n\t\tif (lt.type === 'INT' || lt.type === 'INTEGER') {\n\t\t\tconst bits = lt.bitWidth ?? 32;\n\t\t\tconst signed = lt.isSigned !== false;\n\t\t\tif (bits <= 8) return signed ? 'TINYINT' : 'UTINYINT';\n\t\t\tif (bits <= 16) return signed ? 'SMALLINT' : 'USMALLINT';\n\t\t\tif (bits <= 32) return signed ? 'INTEGER' : 'UINTEGER';\n\t\t\treturn signed ? 'BIGINT' : 'UBIGINT';\n\t\t}\n\t\t// Decimal\n\t\tif (lt.type === 'DECIMAL') return `DECIMAL(${lt.precision ?? 18},${lt.scale ?? 0})`;\n\t\t// Date/Time\n\t\tif (lt.type === 'DATE') return 'DATE';\n\t\tif (lt.type === 'TIME') return 'TIME';\n\t\tif (lt.type === 'TIMESTAMP') return 'TIMESTAMP';\n\t\t// Binary\n\t\tif (lt.type === 'BSON') return 'BLOB';\n\t}\n\n\t// Fallback to physical type\n\tconst ct = col.converted_type;\n\tif (ct === 'UTF8') return 'VARCHAR';\n\tif (ct === 'JSON') return 'JSON';\n\tif (ct === 'DATE') return 'DATE';\n\tif (ct === 'TIMESTAMP_MILLIS' || ct === 'TIMESTAMP_MICROS') return 'TIMESTAMP';\n\tif (ct === 'DECIMAL') return `DECIMAL(${col.precision ?? 18},${col.scale ?? 0})`;\n\tif (ct === 'INT_8') return 'TINYINT';\n\tif (ct === 'INT_16') return 'SMALLINT';\n\tif (ct === 'INT_32') return 'INTEGER';\n\tif (ct === 'INT_64') return 'BIGINT';\n\tif (ct === 'UINT_8') return 'UTINYINT';\n\tif (ct === 'UINT_16') return 'USMALLINT';\n\tif (ct === 'UINT_32') return 'UINTEGER';\n\tif (ct === 'UINT_64') return 'UBIGINT';\n\n\tconst pt = col.type;\n\tif (pt === 'BOOLEAN') return 'BOOLEAN';\n\tif (pt === 'INT32') return 'INTEGER';\n\tif (pt === 'INT64') return 'BIGINT';\n\tif (pt === 'INT96') return 'TIMESTAMP';\n\tif (pt === 'FLOAT') return 'FLOAT';\n\tif (pt === 'DOUBLE') return 'DOUBLE';\n\tif (pt === 'BYTE_ARRAY') return 'BLOB';\n\tif (pt === 'FIXED_LEN_BYTE_ARRAY') return 'BLOB';\n\n\treturn 'VARCHAR';\n}\n\n/**\n * Read Parquet footer metadata from a remote URL using hyparquet.\n * Uses HTTP range requests — typically a single ~512KB fetch.\n */\nexport async function readParquetMetadata(url: string): Promise<ParquetFileMetadata> {\n\tconst { parquetMetadataAsync, asyncBufferFromUrl } = await import('hyparquet');\n\n\tconst file = await asyncBufferFromUrl({ url });\n\tconst metadata = await parquetMetadataAsync(file);\n\n\t// Row count from row group metadata (no data scan needed)\n\tconst rowCount = metadata.row_groups.reduce(\n\t\t(sum: number, rg: any) => sum + Number(rg.num_rows),\n\t\t0\n\t);\n\n\t// Schema from metadata (skip root element at index 0)\n\tconst schema = metadata.schema\n\t\t.slice(1)\n\t\t.filter((col: any) => col.num_children === undefined) // skip group elements\n\t\t.map((col: any) => ({\n\t\t\tname: col.name,\n\t\t\ttype: mapParquetType(col)\n\t\t}));\n\n\t// Walk depth-first to collect top-level column names (including struct parents).\n\t// hyparquet serializes the schema as a flat depth-first array where the root\n\t// carries `num_children` and each group element claims the next N siblings.\n\tconst topLevelColumns: string[] = [];\n\tconst root = metadata.schema[0];\n\tconst rootChildren = root?.num_children ?? 0;\n\tlet cursor = 1;\n\tfor (let i = 0; i < rootChildren && cursor < metadata.schema.length; i++) {\n\t\tconst el = metadata.schema[cursor];\n\t\tif (el?.name) topLevelColumns.push(el.name);\n\t\tcursor += countSubtree(metadata.schema, cursor);\n\t}\n\n\t// GeoParquet \"geo\" key-value metadata\n\tlet geo: GeoParquetMeta | null = null;\n\tlet legacyGeoParquet = false;\n\tconst geoKv = metadata.key_value_metadata?.find((kv: any) => kv.key === 'geo');\n\tif (geoKv) {\n\t\ttry {\n\t\t\tconst geoJson = JSON.parse(geoKv.value ?? '');\n\n\t\t\t// Detect legacy GeoParquet (schema_version 0.x without \"version\" field).\n\t\t\t// Early geopandas (<0.12) wrote schema_version instead of version.\n\t\t\t// DuckDB's spatial extension rejects these files with:\n\t\t\t// \"Geoparquet metadata does not have a version\"\n\t\t\tif (geoJson.schema_version && !geoJson.version) {\n\t\t\t\tlegacyGeoParquet = true;\n\t\t\t}\n\n\t\t\tgeo = {\n\t\t\t\tprimaryColumn: geoJson.primary_column ?? 'geometry',\n\t\t\t\tcolumns: {}\n\t\t\t};\n\t\t\tif (geoJson.columns) {\n\t\t\t\tfor (const [colName, colMeta] of Object.entries(geoJson.columns) as [string, any][]) {\n\t\t\t\t\tgeo.columns[colName] = {\n\t\t\t\t\t\tencoding: colMeta.encoding ?? 'WKB',\n\t\t\t\t\t\tgeometryTypes: colMeta.geometry_types ?? [],\n\t\t\t\t\t\tcrs: colMeta.crs ?? null,\n\t\t\t\t\t\tbbox: colMeta.bbox\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// malformed geo metadata — ignore\n\t\t}\n\t}\n\n\t// Created-by tool\n\tconst createdBy = metadata.created_by ?? null;\n\n\t// Row group count\n\tconst numRowGroups = metadata.row_groups.length;\n\n\t// Compression: collect unique codecs from first row group's columns\n\tlet compression: string | null = null;\n\tif (numRowGroups > 0 && metadata.row_groups[0].columns) {\n\t\tconst codecs = new Set<string>();\n\t\tfor (const col of metadata.row_groups[0].columns) {\n\t\t\tconst codec = col.meta_data?.codec;\n\t\t\tif (codec) codecs.add(codec);\n\t\t}\n\t\tif (codecs.size === 1) {\n\t\t\tcompression = [...codecs][0];\n\t\t} else if (codecs.size > 1) {\n\t\t\tcompression = [...codecs].join(', ');\n\t\t}\n\t}\n\n\treturn {\n\t\trowCount,\n\t\tschema,\n\t\ttopLevelColumns,\n\t\tgeo,\n\t\tlegacyGeoParquet,\n\t\tcreatedBy,\n\t\tnumRowGroups,\n\t\tcompression\n\t};\n}\n\n/** Count how many schema elements belong to the subtree rooted at `start` (inclusive). */\nfunction countSubtree(schema: any[], start: number): number {\n\tconst el = schema[start];\n\tif (!el) return 0;\n\tconst n = el.num_children ?? 0;\n\tlet cursor = start + 1;\n\tfor (let i = 0; i < n; i++) {\n\t\tcursor += countSubtree(schema, cursor);\n\t}\n\treturn cursor - start;\n}\n\n/**\n * Extract EPSG code from GeoParquet CRS metadata.\n * Returns null for WGS84/CRS84 (no reprojection needed).\n */\nexport function extractEpsgFromGeoMeta(geo: GeoParquetMeta): string | null {\n\tconst primaryCol = geo.columns[geo.primaryColumn];\n\tif (!primaryCol?.crs) return null;\n\n\tconst crs = primaryCol.crs;\n\n\t// OGC CRS84 is lon/lat WGS84\n\tif (crs.type === 'name' && crs.properties?.name?.includes('CRS84')) return null;\n\n\t// PROJJSON: { \"id\": { \"authority\": \"EPSG\", \"code\": 27700 } }\n\tif (crs.id?.authority === 'EPSG') {\n\t\tconst code = crs.id.code;\n\t\tif (WGS84_CODES.has(code)) return null;\n\t\treturn `EPSG:${code}`;\n\t}\n\n\treturn null;\n}\n\n/**\n * Extract normalized geometry types from GeoParquet metadata.\n * Returns the set of geometry types for the primary column.\n */\nexport function extractGeometryTypes(geo: GeoParquetMeta): GeoArrowGeomType[] {\n\tconst primaryCol = geo.columns[geo.primaryColumn];\n\tif (!primaryCol?.geometryTypes?.length) return [];\n\n\tconst typeMap: Record<string, GeoArrowGeomType> = {\n\t\tPoint: 'point',\n\t\tLineString: 'linestring',\n\t\tPolygon: 'polygon',\n\t\tMultiPoint: 'multipoint',\n\t\tMultiLineString: 'multilinestring',\n\t\tMultiPolygon: 'multipolygon'\n\t};\n\n\tconst types: GeoArrowGeomType[] = [];\n\tfor (const raw of primaryCol.geometryTypes) {\n\t\t// GeoParquet geometry_types may include Z/M suffixes like \"Polygon Z\"\n\t\tconst base = raw.split(' ')[0];\n\t\tconst mapped = typeMap[base];\n\t\tif (mapped && !types.includes(mapped)) types.push(mapped);\n\t}\n\treturn types;\n}\n\n/**\n * Extract bounds from GeoParquet metadata (bbox field).\n * Returns [minX, minY, maxX, maxY] or null.\n */\nexport function extractBounds(geo: GeoParquetMeta): [number, number, number, number] | null {\n\tconst primaryCol = geo.columns[geo.primaryColumn];\n\tif (!primaryCol?.bbox || primaryCol.bbox.length < 4) return null;\n\treturn [primaryCol.bbox[0], primaryCol.bbox[1], primaryCol.bbox[2], primaryCol.bbox[3]];\n}\n","/**\n * stac-geoparquet helpers.\n *\n * Pure TypeScript, zero Svelte / DuckDB / deck.gl dependencies. Re-exported\n * through `@walkthru-earth/objex-utils` so other projects can consume the\n * detection + row-to-Item transforms without pulling the Svelte lib.\n *\n * The module is decoupled from WKB decoding: callers pass a `wkbParser`\n * callback (the objex Svelte lib threads its `parseWKB`; other consumers\n * can plug in `geoarrow-wasm`, `wkx`, or any other library).\n */\n\nimport type { StacAsset, StacItem, StacLink } from './stac.js';\n\n/** Minimal schema column shape. Works with hyparquet, DuckDB, Arrow. */\nexport interface StacGeoparquetSchemaColumn {\n\tname: string;\n\ttype?: string;\n}\n\n/** Bbox in struct shape as produced by DuckDB's `bbox struct(xmin,ymin,xmax,ymax)`. */\nexport interface StacBboxStruct {\n\txmin: number;\n\tymin: number;\n\txmax: number;\n\tymax: number;\n}\n\n/** Generic Record shape representing a single stac-geoparquet row after DuckDB decoding. */\nexport type StacGeoparquetRow = Record<string, unknown>;\n\nexport interface StacRowToItemOptions {\n\t/**\n\t * Decoder for the geometry column. Accepts a Uint8Array of WKB bytes and\n\t * returns a GeoJSON geometry object (or null on failure).\n\t *\n\t * Consumers in the objex Svelte lib should pass `parseWKB` from\n\t * `@walkthru-earth/objex-utils`. Other projects can use any WKB library.\n\t */\n\twkbParser?: (bytes: Uint8Array) => unknown;\n\t/**\n\t * Column name holding the WKB bytes. Defaults to `'geom_wkb'` because the\n\t * recommended SQL projection is `ST_AsWKB(geometry) AS geom_wkb`.\n\t */\n\twkbColumn?: string;\n\t/** Override the column holding the pre-decoded GeoJSON geometry, when available. */\n\tgeometryColumn?: string;\n}\n\n/** Columns every stac-geoparquet file MUST carry per the stac-geoparquet spec. */\nexport const STAC_GEOPARQUET_REQUIRED_COLUMNS = [\n\t'stac_version',\n\t'type',\n\t'geometry',\n\t'assets'\n] as const;\n\n/**\n * Detect stac-geoparquet by presence of the required STAC columns.\n *\n * Deliberately type-agnostic: some pipelines know the type (DuckDB DESCRIBE,\n * Arrow Field), others only have the name list (hyparquet schema walk). The\n * set of names is sufficient for routing.\n */\nexport function isStacGeoparquetSchema(schema: StacGeoparquetSchemaColumn[]): boolean {\n\tif (!Array.isArray(schema) || schema.length === 0) return false;\n\tconst names = new Set(schema.map((c) => c.name));\n\treturn STAC_GEOPARQUET_REQUIRED_COLUMNS.every((c) => names.has(c));\n}\n\n/**\n * Flatten a DuckDB `struct(xmin,ymin,xmax,ymax)` bbox to the `[minX, minY, maxX, maxY]`\n * array shape that STAC Items and deck.gl-geotiff MosaicLayer expect.\n *\n * Pass-through for arrays so callers that already have `[minX,minY,maxX,maxY]`\n * shape (e.g. from a Feature's `bbox` field) don't need a separate path.\n */\nexport function flattenStacBbox(\n\tbbox: StacBboxStruct | number[] | null | undefined\n): [number, number, number, number] | null {\n\tif (!bbox) return null;\n\tif (Array.isArray(bbox)) {\n\t\tif (bbox.length < 4) return null;\n\t\tconst [minX, minY, maxX, maxY] = bbox;\n\t\tif (![minX, minY, maxX, maxY].every((v) => Number.isFinite(v))) return null;\n\t\treturn [minX, minY, maxX, maxY];\n\t}\n\tif (typeof bbox === 'object') {\n\t\tconst { xmin, ymin, xmax, ymax } = bbox as StacBboxStruct;\n\t\tif (![xmin, ymin, xmax, ymax].every((v) => Number.isFinite(v))) return null;\n\t\treturn [xmin, ymin, xmax, ymax];\n\t}\n\treturn null;\n}\n\n/**\n * Resolve a possibly-relative STAC asset href against the parquet file URL.\n *\n * `./foo.tif` or `foo.tif` → absolute against `baseUrl`. Absolute URLs\n * (`http(s)://`, `s3://`, `gs://`, etc.) are returned unchanged.\n */\nexport function resolveStacAssetHref(href: string, baseUrl: string): string {\n\tif (!href) return href;\n\tif (/^[a-z][a-z0-9+\\-.]*:\\/\\//i.test(href)) return href;\n\ttry {\n\t\treturn new URL(href, baseUrl).toString();\n\t} catch {\n\t\treturn href;\n\t}\n}\n\n/**\n * Pick the \"primary\" asset from a STAC Item's `assets` map.\n *\n * Priority: caller-specified `preferredKeys` → `data` key → first asset with\n * `roles` containing `'data'` → first asset. Returns `null` if the map is\n * empty or not an object.\n */\nexport function pickStacPrimaryAsset(\n\tassets: Record<string, StacAsset> | null | undefined,\n\tpreferredKeys?: readonly string[]\n): { key: string; asset: StacAsset } | null {\n\tif (!assets || typeof assets !== 'object') return null;\n\tconst entries = Object.entries(assets).filter(\n\t\t([, a]) => a && typeof a === 'object' && typeof (a as StacAsset).href === 'string'\n\t) as [string, StacAsset][];\n\tif (entries.length === 0) return null;\n\n\tif (preferredKeys) {\n\t\tfor (const key of preferredKeys) {\n\t\t\tconst match = entries.find(([k]) => k === key);\n\t\t\tif (match) return { key: match[0], asset: match[1] };\n\t\t}\n\t}\n\tconst data = entries.find(([k]) => k === 'data');\n\tif (data) return { key: data[0], asset: data[1] };\n\n\tconst byRole = entries.find(([, a]) => Array.isArray(a.roles) && a.roles.includes('data'));\n\tif (byRole) return { key: byRole[0], asset: byRole[1] };\n\n\treturn { key: entries[0][0], asset: entries[0][1] };\n}\n\n/**\n * Normalize the `assets` value read from a stac-geoparquet row.\n *\n * DuckDB returns `assets` as a `struct` with a fixed set of named fields (one\n * per asset key present at write-time), which decodes to a plain object.\n * Some rows may have `null` asset values for keys that don't apply to them;\n * those are filtered out.\n */\nfunction normalizeAssetsField(\n\tvalue: unknown,\n\tbaseUrl: string\n): Record<string, StacAsset> | undefined {\n\tif (!value || typeof value !== 'object') return undefined;\n\tconst out: Record<string, StacAsset> = {};\n\tfor (const [key, raw] of Object.entries(value as Record<string, unknown>)) {\n\t\tif (!raw || typeof raw !== 'object') continue;\n\t\tconst asset = raw as StacAsset & Record<string, unknown>;\n\t\tif (typeof asset.href !== 'string' || !asset.href) continue;\n\t\tout[key] = {\n\t\t\t...asset,\n\t\t\thref: resolveStacAssetHref(asset.href, baseUrl)\n\t\t};\n\t}\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** Normalize the `links` field, resolving relative hrefs against `baseUrl`. */\nfunction normalizeLinksField(value: unknown, baseUrl: string): StacLink[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst links: StacLink[] = [];\n\tfor (const raw of value) {\n\t\tif (!raw || typeof raw !== 'object') continue;\n\t\tconst link = raw as StacLink;\n\t\tif (typeof link.href !== 'string' || typeof link.rel !== 'string') continue;\n\t\tlinks.push({ ...link, href: resolveStacAssetHref(link.href, baseUrl) });\n\t}\n\treturn links.length > 0 ? links : undefined;\n}\n\n/**\n * Convert one stac-geoparquet row into a standard STAC Item JSON object.\n *\n * Handles:\n * - `assets` named-struct flattening + relative href resolution\n * - `bbox` struct → `[minX, minY, maxX, maxY]` array\n * - Optional WKB geometry → GeoJSON via `opts.wkbParser`\n * - `datetime` → ISO string (passes through already-string values)\n * - Promotes `properties.*` columns (`proj:*`, `datetime`) onto `item.properties`\n */\nexport function stacRowToItem(\n\trow: StacGeoparquetRow,\n\tbaseUrl: string,\n\topts: StacRowToItemOptions = {}\n): StacItem {\n\tconst { wkbParser, wkbColumn = 'geom_wkb', geometryColumn = 'geometry' } = opts;\n\n\tlet geometry: unknown = row[geometryColumn];\n\tif (!geometry) {\n\t\tconst wkb = row[wkbColumn];\n\t\tif (wkb && wkbParser) {\n\t\t\tconst bytes = wkb instanceof Uint8Array ? wkb : toUint8Array(wkb);\n\t\t\tif (bytes) {\n\t\t\t\ttry {\n\t\t\t\t\tgeometry = wkbParser(bytes) ?? undefined;\n\t\t\t\t} catch {\n\t\t\t\t\tgeometry = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst bbox = flattenStacBbox(row.bbox as StacBboxStruct | number[] | undefined) ?? undefined;\n\tconst assets = normalizeAssetsField(row.assets, baseUrl);\n\tconst links = normalizeLinksField(row.links, baseUrl);\n\n\tconst properties: Record<string, unknown> = {};\n\t// Hoist common STAC-property columns that live at row level in stac-geoparquet.\n\tfor (const [key, value] of Object.entries(row)) {\n\t\tif (value === null || value === undefined) continue;\n\t\tif (key.startsWith('proj:') || key.startsWith('raster:') || key.startsWith('eo:')) {\n\t\t\tproperties[key] = value;\n\t\t}\n\t\tif (key === 'datetime') {\n\t\t\tproperties.datetime = value instanceof Date ? value.toISOString() : String(value);\n\t\t}\n\t\tif (key === 'bands') {\n\t\t\tproperties.bands = value;\n\t\t}\n\t}\n\n\tconst item: StacItem = {\n\t\ttype: 'Feature',\n\t\tstac_version: typeof row.stac_version === 'string' ? row.stac_version : '1.0.0',\n\t\tid: typeof row.id === 'string' ? row.id : String(row.id ?? ''),\n\t\tproperties\n\t};\n\tif (typeof row.collection === 'string') item.collection = row.collection;\n\tif (Array.isArray(row.stac_extensions)) {\n\t\t(item as unknown as { stac_extensions: unknown[] }).stac_extensions = row.stac_extensions;\n\t}\n\tif (bbox) item.bbox = bbox;\n\tif (geometry) item.geometry = geometry;\n\tif (assets) item.assets = assets;\n\tif (links) item.links = links;\n\n\treturn item;\n}\n\n/** Best-effort coercion of a value that may already be bytes into a Uint8Array. */\nfunction toUint8Array(value: unknown): Uint8Array | null {\n\tif (value instanceof Uint8Array) return value;\n\tif (value instanceof ArrayBuffer) return new Uint8Array(value);\n\tif (ArrayBuffer.isView(value)) {\n\t\tconst view = value as ArrayBufferView;\n\t\treturn new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n\t}\n\tif (Array.isArray(value)) return new Uint8Array(value as number[]);\n\treturn null;\n}\n","/**\n * Universal cloud storage URL / bucket parser.\n *\n * Accepts the many URI/URL formats that users commonly paste and extracts\n * the correct bucket, region, endpoint, and provider.\n *\n * Supported URI schemes:\n * s3:// s3a:// s3n:// aws:// — Amazon S3 / S3-compatible\n * r2:// — Cloudflare R2\n * gs:// gcs:// — Google Cloud Storage\n * azure:// az:// — Azure Blob Storage\n * abfs:// abfss:// — Azure Data Lake (ADLS Gen2)\n * wasbs:// — Azure Blob (Hadoop WASB driver)\n * swift:// — OpenStack Swift\n * file:// filesystem:// — Local filesystem\n *\n * Supported HTTPS URL patterns:\n * https://<bucket>.s3.<region>.amazonaws.com[/prefix] — AWS virtual-hosted\n * https://s3.<region>.amazonaws.com/<bucket>[/prefix] — AWS path-style\n * https://s3.amazonaws.com/<bucket> — AWS global\n * https://<account>.r2.cloudflarestorage.com/<bucket> — Cloudflare R2\n * https://storage.googleapis.com/<bucket> — Google Cloud Storage\n * https://<bucket>.storage.googleapis.com[/prefix] — GCS virtual-hosted\n * https://<bucket>.<region>.digitaloceanspaces.com — DigitalOcean Spaces\n * https://<region>.digitaloceanspaces.com/<bucket> — DO Spaces path-style\n * https://s3.<region>.wasabisys.com/<bucket> — Wasabi\n * https://f<id>.backblazeb2.com/file/<bucket> — Backblaze B2\n * https://<bucket>.s3.<region>.backblazeb2.com — B2 S3-compatible\n * https://<bucket>.oss-<region>.aliyuncs.com — Alibaba Cloud OSS\n * https://<bucket>.cos.<region>.myqcloud.com — Tencent COS\n * https://storage.yandexcloud.net/<bucket> — Yandex Cloud\n * https://gateway.storjshare.io/<bucket> — Storj S3 gateway\n * https://link.storjshare.io/raw/<access>/<bucket> — Storj linksharing\n * https://<custom-endpoint>/<bucket> — Generic S3-compatible\n *\n * Also handles plain bucket names (no protocol).\n */\n\nimport { PROVIDERS } from '../storage/providers.js';\n\nexport type StorageProvider = string;\n\nexport interface ParsedStorageUrl {\n\tbucket: string;\n\tregion: string;\n\tendpoint: string;\n\tprovider: StorageProvider;\n\t/** Original prefix/path after bucket, if any */\n\tprefix: string;\n}\n\n/**\n * Build SCHEME_MAP from the provider registry's `schemes` arrays.\n * Each scheme like \"s3\" generates an entry `\"s3://\": { provider: \"s3\", strip: 5 }`.\n */\nfunction buildSchemeMap(): Record<string, { provider: StorageProvider; strip: number }> {\n\tconst map: Record<string, { provider: StorageProvider; strip: number }> = {};\n\tfor (const [id, def] of Object.entries(PROVIDERS)) {\n\t\tfor (const scheme of def.schemes) {\n\t\t\tconst key = `${scheme}://`;\n\t\t\tmap[key] = { provider: id, strip: key.length };\n\t\t}\n\t}\n\t// Non-registry schemes (no corresponding provider)\n\tmap['swift://'] = { provider: 'unknown', strip: 8 };\n\treturn map;\n}\n\n/** All recognized URI scheme prefixes (lowercase), derived from provider registry */\nconst SCHEME_MAP = buildSchemeMap();\n\n/**\n * Shared host matchers. Used by both `parseStorageUrl` and `isKnownBucketHost`\n * so provider recognition has a single source of truth.\n */\nconst AWS_VHOST_RE = /^(.+)\\.s3[.-]([a-z0-9-]+)\\.amazonaws\\.com$/;\nconst AWS_PATH_RE = /^s3[.-]([a-z0-9-]+)\\.amazonaws\\.com$/;\nconst AWS_GLOBAL_HOST = 's3.amazonaws.com';\nconst R2_RE = /^([a-z0-9]+)\\.r2\\.cloudflarestorage\\.com$/;\nconst GCS_GLOBAL_HOST = 'storage.googleapis.com';\nconst GCS_VHOST_RE = /^(.+)\\.storage\\.googleapis\\.com$/;\nconst DO_VHOST_RE = /^(.+)\\.([a-z0-9-]+)\\.digitaloceanspaces\\.com$/;\nconst DO_PATH_RE = /^([a-z0-9-]+)\\.digitaloceanspaces\\.com$/;\nconst WASABI_RE = /^s3\\.([a-z0-9-]+)\\.wasabisys\\.com$/;\nconst B2_S3_RE = /^(.+)\\.s3\\.([a-z0-9-]+)\\.backblazeb2\\.com$/;\nconst B2_NATIVE_RE = /^f[a-z0-9]+\\.backblazeb2\\.com$/;\nconst OSS_RE = /^(.+)\\.(oss-[a-z0-9-]+)\\.aliyuncs\\.com$/;\nconst COS_RE = /^(.+)\\.cos\\.([a-z0-9-]+)\\.myqcloud\\.com$/;\nconst YANDEX_HOST = 'storage.yandexcloud.net';\nconst CONTABO_RE = /^([a-z0-9]+)\\.contabostorage\\.com$/;\nconst HETZNER_RE = /^([a-z0-9]+)\\.your-objectstorage\\.com$/;\nconst LINODE_VHOST_RE = /^(.+)\\.([a-z0-9-]+)\\.linodeobjects\\.com$/;\nconst LINODE_PATH_RE = /^([a-z0-9-]+)\\.linodeobjects\\.com$/;\nconst OVH_RE = /^s3\\.([a-z0-9-]+)\\.io\\.cloud\\.ovh\\.(?:net|us)$/;\nconst AZURE_BLOB_RE = /^([a-z0-9]+)\\.blob\\.core\\.windows\\.net$/;\nconst STORJ_GATEWAY_RE = /^gateway\\.(?:([a-z0-9]+)\\.)?storjshare\\.io$/;\nconst STORJ_LINK_RE = /^link\\.(?:([a-z0-9]+)\\.)?storjshare\\.io$/;\n\nfunction isMinioLikeHost(host: string): boolean {\n\treturn (\n\t\thost.includes('minio') ||\n\t\thost === 'localhost' ||\n\t\thost === '127.0.0.1' ||\n\t\thost.startsWith('192.168.') ||\n\t\thost.startsWith('10.')\n\t);\n}\n\n/** STAC API path test, one source of truth. Tests pathname only. */\nexport const STAC_API_PATH_RE = /\\/(collections|items|catalogs|search)(\\/|\\?|$)/i;\n\n/**\n * Returns true when the host matches any of the provider host patterns\n * that `parseStorageUrl` recognizes on the HTTPS branch.\n */\nexport function isKnownBucketHost(host: string): boolean {\n\tif (!host) return false;\n\tif (AWS_VHOST_RE.test(host)) return true;\n\tif (AWS_PATH_RE.test(host)) return true;\n\tif (host === AWS_GLOBAL_HOST) return true;\n\tif (R2_RE.test(host)) return true;\n\tif (host === GCS_GLOBAL_HOST) return true;\n\tif (GCS_VHOST_RE.test(host)) return true;\n\tif (DO_VHOST_RE.test(host)) return true;\n\tif (DO_PATH_RE.test(host)) return true;\n\tif (WASABI_RE.test(host)) return true;\n\tif (B2_S3_RE.test(host)) return true;\n\tif (B2_NATIVE_RE.test(host)) return true;\n\tif (OSS_RE.test(host)) return true;\n\tif (COS_RE.test(host)) return true;\n\tif (host === YANDEX_HOST) return true;\n\tif (CONTABO_RE.test(host)) return true;\n\tif (HETZNER_RE.test(host)) return true;\n\tif (LINODE_VHOST_RE.test(host)) return true;\n\tif (LINODE_PATH_RE.test(host)) return true;\n\tif (OVH_RE.test(host)) return true;\n\tif (AZURE_BLOB_RE.test(host)) return true;\n\tif (STORJ_GATEWAY_RE.test(host)) return true;\n\tif (STORJ_LINK_RE.test(host)) return true;\n\tif (isMinioLikeHost(host)) return true;\n\treturn false;\n}\n\nexport interface Defaults {\n\tregion?: string;\n\tendpoint?: string;\n\tprovider?: StorageProvider;\n}\n\nfunction defaultResult(defaults: Defaults): ParsedStorageUrl {\n\treturn {\n\t\tbucket: '',\n\t\tregion: defaults.region || 'us-east-1',\n\t\tendpoint: defaults.endpoint || '',\n\t\tprovider: defaults.provider || 's3',\n\t\tprefix: ''\n\t};\n}\n\nfunction splitBucketPrefix(rest: string): { bucket: string; prefix: string } {\n\tconst slashIdx = rest.indexOf('/');\n\tif (slashIdx >= 0) {\n\t\treturn {\n\t\t\tbucket: rest.slice(0, slashIdx),\n\t\t\tprefix: rest.slice(slashIdx + 1).replace(/\\/+$/, '')\n\t\t};\n\t}\n\treturn { bucket: rest, prefix: '' };\n}\n\n/**\n * Parse a user-provided bucket/URL string into structured storage connection parts.\n */\nexport function parseStorageUrl(input: string, defaults: Defaults = {}): ParsedStorageUrl {\n\tconst trimmed = input.trim();\n\n\t// ── Custom URI schemes (s3://, gs://, r2://, az://, etc.) ──────────\n\tconst lower = trimmed.toLowerCase();\n\tfor (const [scheme, { provider, strip }] of Object.entries(SCHEME_MAP)) {\n\t\tif (lower.startsWith(scheme)) {\n\t\t\tconst rest = trimmed.slice(strip);\n\t\t\tconst { bucket, prefix } = splitBucketPrefix(rest);\n\t\t\treturn {\n\t\t\t\tbucket,\n\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\tendpoint: defaults.endpoint || '',\n\t\t\t\tprovider,\n\t\t\t\tprefix\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── HTTP(S) URL ─────────────────────────────────────────────────\n\tif (lower.startsWith('http://') || lower.startsWith('https://')) {\n\t\ttry {\n\t\t\tconst url = new URL(trimmed);\n\t\t\tconst host = url.hostname;\n\t\t\tconst pathParts = url.pathname.replace(/^\\//, '').split('/').filter(Boolean);\n\n\t\t\t// --- AWS S3 ---\n\n\t\t\t// Virtual-hosted: <bucket>.s3.<region>.amazonaws.com\n\t\t\tconst awsVhost = host.match(AWS_VHOST_RE);\n\t\t\tif (awsVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: awsVhost[1],\n\t\t\t\t\tregion: awsVhost[2],\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Path-style: s3.<region>.amazonaws.com/<bucket>\n\t\t\tconst awsPath = host.match(AWS_PATH_RE);\n\t\t\tif (awsPath && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: awsPath[1],\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Global: s3.amazonaws.com/<bucket>\n\t\t\tif (host === AWS_GLOBAL_HOST && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Cloudflare R2 ---\n\t\t\t// <account>.r2.cloudflarestorage.com/<bucket>\n\t\t\tconst r2Match = host.match(R2_RE);\n\t\t\tif (r2Match && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: 'auto',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'r2',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Google Cloud Storage ---\n\t\t\t// storage.googleapis.com/<bucket>\n\t\t\tif (host === GCS_GLOBAL_HOST && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us',\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 'gcs',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// <bucket>.storage.googleapis.com\n\t\t\tconst gcsVhost = host.match(GCS_VHOST_RE);\n\t\t\tif (gcsVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: gcsVhost[1],\n\t\t\t\t\tregion: defaults.region || 'us',\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 'gcs',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- DigitalOcean Spaces ---\n\t\t\t// <bucket>.<region>.digitaloceanspaces.com\n\t\t\tconst doVhost = host.match(DO_VHOST_RE);\n\t\t\tif (doVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: doVhost[1],\n\t\t\t\t\tregion: doVhost[2],\n\t\t\t\t\tendpoint: `${url.protocol}//${doVhost[2]}.digitaloceanspaces.com`,\n\t\t\t\t\tprovider: 'digitalocean',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// <region>.digitaloceanspaces.com/<bucket>\n\t\t\tconst doPath = host.match(DO_PATH_RE);\n\t\t\tif (doPath && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: doPath[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'digitalocean',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Wasabi ---\n\t\t\t// s3.<region>.wasabisys.com/<bucket>\n\t\t\tconst wasabiMatch = host.match(WASABI_RE);\n\t\t\tif (wasabiMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: wasabiMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'wasabi',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Backblaze B2 ---\n\t\t\t// <bucket>.s3.<region>.backblazeb2.com (S3-compatible)\n\t\t\tconst b2S3 = host.match(B2_S3_RE);\n\t\t\tif (b2S3) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: b2S3[1],\n\t\t\t\t\tregion: b2S3[2],\n\t\t\t\t\tendpoint: `${url.protocol}//s3.${b2S3[2]}.backblazeb2.com`,\n\t\t\t\t\tprovider: 'b2',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// f<id>.backblazeb2.com/file/<bucket>\n\t\t\tconst b2Native = host.match(B2_NATIVE_RE);\n\t\t\tif (b2Native && pathParts[0] === 'file' && pathParts.length > 1) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[1],\n\t\t\t\t\tregion: defaults.region || 'us-west-000',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'b2',\n\t\t\t\t\tprefix: pathParts.slice(2).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Alibaba Cloud OSS ---\n\t\t\t// <bucket>.oss-<region>.aliyuncs.com\n\t\t\tconst ossMatch = host.match(OSS_RE);\n\t\t\tif (ossMatch) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: ossMatch[1],\n\t\t\t\t\tregion: ossMatch[2],\n\t\t\t\t\tendpoint: `${url.protocol}//${ossMatch[2]}.aliyuncs.com`,\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Tencent Cloud COS ---\n\t\t\t// <bucket>.cos.<region>.myqcloud.com\n\t\t\tconst cosMatch = host.match(COS_RE);\n\t\t\tif (cosMatch) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: cosMatch[1],\n\t\t\t\t\tregion: cosMatch[2],\n\t\t\t\t\tendpoint: `${url.protocol}//cos.${cosMatch[2]}.myqcloud.com`,\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Yandex Cloud ---\n\t\t\t// storage.yandexcloud.net/<bucket>\n\t\t\tif (host === YANDEX_HOST && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'ru-central1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Contabo ---\n\t\t\t// <region>.contabostorage.com/<bucket>\n\t\t\tconst contaboMatch = host.match(CONTABO_RE);\n\t\t\tif (contaboMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: contaboMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'contabo',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Hetzner ---\n\t\t\t// <region>.your-objectstorage.com/<bucket>\n\t\t\tconst hetznerMatch = host.match(HETZNER_RE);\n\t\t\tif (hetznerMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: hetznerMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'hetzner',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Linode / Akamai ---\n\t\t\t// <bucket>.<region>.linodeobjects.com or <region>.linodeobjects.com/<bucket>\n\t\t\tconst linodeVhost = host.match(LINODE_VHOST_RE);\n\t\t\tif (linodeVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: linodeVhost[1],\n\t\t\t\t\tregion: linodeVhost[2],\n\t\t\t\t\tendpoint: `${url.protocol}//${linodeVhost[2]}.linodeobjects.com`,\n\t\t\t\t\tprovider: 'linode',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst linodePath = host.match(LINODE_PATH_RE);\n\t\t\tif (linodePath && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: linodePath[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'linode',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- OVHcloud ---\n\t\t\t// s3.<region>.io.cloud.ovh.net/<bucket>\n\t\t\tconst ovhMatch = host.match(OVH_RE);\n\t\t\tif (ovhMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: ovhMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'ovhcloud',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- MinIO ---\n\t\t\t// Common patterns: minio.<domain>, localhost with port\n\t\t\tif (isMinioLikeHost(host) && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'minio',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Azure Blob Storage ---\n\t\t\t// <account>.blob.core.windows.net/<container>\n\t\t\tconst azureBlob = host.match(AZURE_BLOB_RE);\n\t\t\tif (azureBlob && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || '',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'azure',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Storj ---\n\t\t\t// S3 gateway: gateway.storjshare.io/<bucket> (or gateway.<region>.storjshare.io)\n\t\t\tconst storjGateway = host.match(STORJ_GATEWAY_RE);\n\t\t\tif (storjGateway && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: storjGateway[1] || defaults.region || 'us1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'storj',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Linksharing: link.storjshare.io/raw/<access>/<bucket>/... or /s/<access>/<bucket>/...\n\t\t\tconst storjLink = host.match(STORJ_LINK_RE);\n\t\t\tif (storjLink && pathParts.length >= 3 && (pathParts[0] === 'raw' || pathParts[0] === 's')) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[2],\n\t\t\t\t\tregion: storjLink[1] || defaults.region || 'us1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}/${pathParts[0]}/${pathParts[1]}`,\n\t\t\t\t\tprovider: 'storj',\n\t\t\t\t\tprefix: pathParts.slice(3).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- STAC API endpoints (Element 84, MPC, etc.) ---\n\t\t\t// Paths like /v1/collections/.../items/... are not S3 buckets, the\n\t\t\t// first path segment is an API version, not a bucket name. Return\n\t\t\t// no bucket so detectHostBucket() falls through and the URL opens\n\t\t\t// as a direct remote fetch.\n\t\t\tif (STAC_API_PATH_RE.test(url.pathname)) {\n\t\t\t\treturn {\n\t\t\t\t\t...defaultResult(defaults),\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Generic custom endpoint with bucket in path ---\n\t\t\tif (pathParts.length > 0) {\n\t\t\t\tconst endpoint = `${url.protocol}//${url.host}`;\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\t\tendpoint,\n\t\t\t\t\tprovider: defaults.provider || 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Just a host, no path — treat as endpoint with no bucket\n\t\t\treturn {\n\t\t\t\t...defaultResult(defaults),\n\t\t\t\tendpoint: `${url.protocol}//${url.host}`\n\t\t\t};\n\t\t} catch {\n\t\t\t// Not a valid URL, fall through to plain bucket name\n\t\t}\n\t}\n\n\t// ── Plain bucket name (no protocol) ─────────────────────────────\n\tconst cleaned = trimmed.replace(/^\\/+|\\/+$/g, '');\n\treturn {\n\t\tbucket: cleaned,\n\t\tregion: defaults.region || 'us-east-1',\n\t\tendpoint: defaults.endpoint || '',\n\t\tprovider: defaults.provider || 's3',\n\t\tprefix: ''\n\t};\n}\n\n/**\n * Returns true if the input looks like a URL/URI rather than a plain bucket name.\n * Covers all recognized cloud storage URI schemes.\n */\nexport function looksLikeUrl(input: string): boolean {\n\tconst lower = input.trim().toLowerCase();\n\tif (lower.startsWith('http://') || lower.startsWith('https://')) return true;\n\tfor (const scheme of Object.keys(SCHEME_MAP)) {\n\t\tif (lower.startsWith(scheme)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Given a parsed URL result, build a human-readable summary of what was detected.\n */\nexport function describeParseResult(parsed: ParsedStorageUrl): string {\n\tconst parts: string[] = [];\n\tif (parsed.bucket) parts.push(`bucket=\"${parsed.bucket}\"`);\n\tif (parsed.endpoint) parts.push(`endpoint=\"${parsed.endpoint}\"`);\n\tif (parsed.region && parsed.region !== 'us-east-1') parts.push(`region=\"${parsed.region}\"`);\n\tif (parsed.provider !== 's3') parts.push(`provider=${parsed.provider}`);\n\tif (parsed.prefix) parts.push(`prefix=\"${parsed.prefix}\"`);\n\treturn parts.length > 0 ? `Detected: ${parts.join(', ')}` : '';\n}\n\nexport type UrlClassification =\n\t| { kind: 'scheme'; parsed: ParsedStorageUrl }\n\t| { kind: 'object-storage'; parsed: ParsedStorageUrl }\n\t| { kind: 'stac-api'; url: URL }\n\t| { kind: 'remote-file'; url: URL };\n\n/**\n * Classify a user-supplied URL/URI into one of four buckets. Unparseable or\n * plain inputs fall through to `remote-file` with a best-effort URL parse,\n * returning a synthetic `https://` URL when `new URL()` would throw.\n */\nexport function classifyUrl(input: string): UrlClassification {\n\tconst trimmed = input.trim();\n\tconst lower = trimmed.toLowerCase();\n\n\tfor (const scheme of Object.keys(SCHEME_MAP)) {\n\t\tif (lower.startsWith(scheme)) {\n\t\t\treturn { kind: 'scheme', parsed: parseStorageUrl(trimmed) };\n\t\t}\n\t}\n\n\tif (lower.startsWith('http://') || lower.startsWith('https://')) {\n\t\tlet url: URL;\n\t\ttry {\n\t\t\turl = new URL(trimmed);\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tkind: 'remote-file',\n\t\t\t\turl: new URL(`https://${trimmed.replace(/^https?:\\/\\//i, '')}`)\n\t\t\t};\n\t\t}\n\t\tconst parsed = parseStorageUrl(trimmed);\n\t\tif (parsed.bucket && isKnownBucketHost(url.hostname)) {\n\t\t\treturn { kind: 'object-storage', parsed };\n\t\t}\n\t\tif (STAC_API_PATH_RE.test(url.pathname)) {\n\t\t\treturn { kind: 'stac-api', url };\n\t\t}\n\t\treturn { kind: 'remote-file', url };\n\t}\n\n\ttry {\n\t\treturn { kind: 'remote-file', url: new URL(trimmed) };\n\t} catch {\n\t\treturn { kind: 'remote-file', url: new URL(`https://${trimmed}`) };\n\t}\n}\n","/**\n * Lightweight WKB (Well-Known Binary) parser for extracting coordinates.\n * Supports Point, LineString, Polygon, and Multi* variants.\n * Handles standard WKB, ISO WKB (with Z/M), and EWKB (PostGIS SRID).\n */\n\nexport type GeoType =\n\t| 'Point'\n\t| 'LineString'\n\t| 'Polygon'\n\t| 'MultiPoint'\n\t| 'MultiLineString'\n\t| 'MultiPolygon'\n\t| 'Unknown';\n\nexport interface ParsedGeometry {\n\ttype: GeoType;\n\tcoordinates: number[] | number[][] | number[][][] | number[][][][];\n}\n\n// WKB type codes\nconst WKB_POINT = 1;\nconst WKB_LINESTRING = 2;\nconst WKB_POLYGON = 3;\nconst WKB_MULTIPOINT = 4;\nconst WKB_MULTILINESTRING = 5;\nconst WKB_MULTIPOLYGON = 6;\n\n// EWKB flags\nconst EWKB_Z_FLAG = 0x80000000;\nconst EWKB_M_FLAG = 0x40000000;\nconst EWKB_SRID_FLAG = 0x20000000;\n\n/**\n * Normalize binary data from various formats to Uint8Array.\n * Handles Uint8Array, ArrayBuffer, number arrays, hex strings,\n * and DuckDB toJSON() blob objects ({0: byte, 1: byte, ...}).\n */\nexport function toBinary(value: unknown): Uint8Array | null {\n\tif (value === null || value === undefined) return null;\n\tif (value instanceof Uint8Array) return value;\n\tif (value instanceof ArrayBuffer) return new Uint8Array(value);\n\tif (Array.isArray(value) && value.length > 0 && typeof value[0] === 'number') {\n\t\treturn new Uint8Array(value);\n\t}\n\tif (typeof value === 'string' && /^[0-9a-fA-F]+$/.test(value) && value.length % 2 === 0) {\n\t\tconst bytes = new Uint8Array(value.length / 2);\n\t\tfor (let i = 0; i < value.length; i += 2) {\n\t\t\tbytes[i / 2] = parseInt(value.substring(i, i + 2), 16);\n\t\t}\n\t\treturn bytes;\n\t}\n\t// DuckDB toJSON() serializes BLOB/GEOMETRY as {\"0\": byte, \"1\": byte, ...}\n\tif (typeof value === 'object' && !Array.isArray(value)) {\n\t\tconst obj = value as Record<string, number>;\n\t\tconst keys = Object.keys(obj);\n\t\tif (keys.length > 4 && typeof obj['0'] === 'number') {\n\t\t\tconst arr = new Uint8Array(keys.length);\n\t\t\tfor (let i = 0; i < keys.length; i++) arr[i] = obj[i];\n\t\t\treturn arr;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Parse a WKB binary blob into coordinates and geometry type.\n */\nexport function parseWKB(data: Uint8Array): ParsedGeometry | null {\n\tif (data.length < 5) return null;\n\ttry {\n\t\treturn readGeometry(new DataView(data.buffer, data.byteOffset, data.byteLength), 0).geometry;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readGeometry(\n\tview: DataView,\n\toffset: number\n): { geometry: ParsedGeometry; offset: number } {\n\tconst le = view.getUint8(offset) === 1;\n\toffset += 1;\n\n\tlet typeInt = view.getUint32(offset, le);\n\toffset += 4;\n\n\t// Detect coordinate dimensions from EWKB flags or ISO type ranges\n\tconst hasZ =\n\t\t(typeInt & EWKB_Z_FLAG) !== 0 ||\n\t\t(typeInt % 10000 >= 1000 && typeInt % 10000 < 2000) ||\n\t\t(typeInt % 10000 >= 3000 && typeInt % 10000 < 4000);\n\tconst hasM =\n\t\t(typeInt & EWKB_M_FLAG) !== 0 ||\n\t\t(typeInt % 10000 >= 2000 && typeInt % 10000 < 3000) ||\n\t\t(typeInt % 10000 >= 3000 && typeInt % 10000 < 4000);\n\n\t// Skip SRID if present (EWKB)\n\tif (typeInt & EWKB_SRID_FLAG) offset += 4;\n\n\t// Strip all flags to get base geometry type\n\ttypeInt = (typeInt & 0x0000ffff) % 1000;\n\n\tconst extraDims = (hasZ ? 1 : 0) + (hasM ? 1 : 0);\n\tconst rd = (o: number) => view.getFloat64(o, le);\n\tconst ru = (o: number) => view.getUint32(o, le);\n\n\tfunction readPoint(off: number): { coords: number[]; offset: number } {\n\t\tconst x = rd(off);\n\t\tconst y = rd(off + 8);\n\t\treturn { coords: [x, y], offset: off + 16 + extraDims * 8 };\n\t}\n\n\tfunction readLineString(off: number): { coords: number[][]; offset: number } {\n\t\tconst n = ru(off);\n\t\toff += 4;\n\t\tconst coords: number[][] = [];\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst pt = readPoint(off);\n\t\t\tcoords.push(pt.coords);\n\t\t\toff = pt.offset;\n\t\t}\n\t\treturn { coords, offset: off };\n\t}\n\n\tfunction readPolygon(off: number): { coords: number[][][]; offset: number } {\n\t\tconst n = ru(off);\n\t\toff += 4;\n\t\tconst coords: number[][][] = [];\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst ring = readLineString(off);\n\t\t\tcoords.push(ring.coords);\n\t\t\toff = ring.offset;\n\t\t}\n\t\treturn { coords, offset: off };\n\t}\n\n\tswitch (typeInt) {\n\t\tcase WKB_POINT: {\n\t\t\tconst pt = readPoint(offset);\n\t\t\treturn { geometry: { type: 'Point', coordinates: pt.coords }, offset: pt.offset };\n\t\t}\n\t\tcase WKB_LINESTRING: {\n\t\t\tconst ls = readLineString(offset);\n\t\t\treturn { geometry: { type: 'LineString', coordinates: ls.coords }, offset: ls.offset };\n\t\t}\n\t\tcase WKB_POLYGON: {\n\t\t\tconst pg = readPolygon(offset);\n\t\t\treturn { geometry: { type: 'Polygon', coordinates: pg.coords }, offset: pg.offset };\n\t\t}\n\t\tcase WKB_MULTIPOINT: {\n\t\t\tconst n = ru(offset);\n\t\t\toffset += 4;\n\t\t\tconst coords: number[][] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst r = readGeometry(view, offset);\n\t\t\t\tcoords.push(r.geometry.coordinates as number[]);\n\t\t\t\toffset = r.offset;\n\t\t\t}\n\t\t\treturn { geometry: { type: 'MultiPoint', coordinates: coords }, offset };\n\t\t}\n\t\tcase WKB_MULTILINESTRING: {\n\t\t\tconst n = ru(offset);\n\t\t\toffset += 4;\n\t\t\tconst coords: number[][][] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst r = readGeometry(view, offset);\n\t\t\t\tcoords.push(r.geometry.coordinates as number[][]);\n\t\t\t\toffset = r.offset;\n\t\t\t}\n\t\t\treturn { geometry: { type: 'MultiLineString', coordinates: coords }, offset };\n\t\t}\n\t\tcase WKB_MULTIPOLYGON: {\n\t\t\tconst n = ru(offset);\n\t\t\toffset += 4;\n\t\t\tconst coords: number[][][][] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst r = readGeometry(view, offset);\n\t\t\t\tcoords.push(r.geometry.coordinates as number[][][]);\n\t\t\t\toffset = r.offset;\n\t\t\t}\n\t\t\treturn { geometry: { type: 'MultiPolygon', coordinates: coords }, offset };\n\t\t}\n\t\tdefault:\n\t\t\treturn { geometry: { type: 'Unknown', coordinates: [] }, offset };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Geometry column detection\n// ---------------------------------------------------------------------------\n\n/** Exact well-known geometry column names (lowercase for comparison). */\nconst GEO_NAMES = [\n\t'geometry',\n\t'geom',\n\t'wkb_geometry',\n\t'the_geom',\n\t'shape',\n\t'geo',\n\t'wkt_geometry',\n\t'the_geog',\n\t'geog',\n\t'way',\n\t'ora_geometry'\n];\n\n/** Type keywords that indicate a geometry column. */\nconst GEO_TYPE_KEYWORDS = [\n\t'geometry',\n\t'geography',\n\t'wkb',\n\t'point',\n\t'linestring',\n\t'polygon',\n\t'multipoint',\n\t'multilinestring',\n\t'multipolygon',\n\t'geometrycollection',\n\t'sdo_geometry'\n];\n\n/**\n * Tokens in column names that hint at geometry content. Matched against\n * snake_case / kebab-case / camelCase tokens only — never as loose substrings\n * (e.g. `_geographic_` must not match `geo` via the `_geo` substring, because\n * count columns like `n_geographic_entities` are INT, not geometry).\n */\nconst GEO_NAME_HINTS = ['geom', 'geometry', 'wkb', 'wkt', 'shape', 'spatial', 'geo'];\n\n/** Split a column name into lowercase tokens for hint matching. */\nfunction tokenizeColumnName(name: string): string[] {\n\treturn name\n\t\t.replace(/([a-z])([A-Z])/g, '$1_$2')\n\t\t.replace(/([a-z])([0-9])/g, '$1_$2')\n\t\t.toLowerCase()\n\t\t.split(/[^a-z0-9]+/)\n\t\t.filter(Boolean);\n}\n\n/** Valid GeoJSON geometry type names. */\nconst GEOJSON_TYPES = [\n\t'Point',\n\t'LineString',\n\t'Polygon',\n\t'MultiPoint',\n\t'MultiLineString',\n\t'MultiPolygon'\n];\n\n/** Check if a value is a GeoJSON geometry object ({type, coordinates}). */\nfunction isGeoJSONGeometry(value: unknown): value is { type: GeoType; coordinates: unknown } {\n\tif (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n\tconst obj = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof obj.type === 'string' && GEOJSON_TYPES.includes(obj.type) && obj.coordinates != null\n\t);\n}\n\n/**\n * Find the geometry column name from a schema.\n *\n * Detection priority:\n * 1. Column type contains a geometry keyword (GEOMETRY, POINT, WKB, etc.)\n * 2. Exact well-known column name with BLOB/BINARY type\n * 3. Exact well-known column name regardless of type\n * 4. Column name contains a geo-related substring with BLOB/BINARY type\n * 5. Column name contains a geo-related substring regardless of type\n */\nexport function findGeoColumn(schema: { name: string; type: string }[]): string | null {\n\t// Priority 1: column type contains a geometry keyword\n\t// Skip STRUCT/MAP/LIST types — their field names can false-positive\n\t// (e.g. STRUCT(... Geometry VARCHAR ...) matches 'geometry')\n\tfor (const f of schema) {\n\t\tconst t = f.type.toLowerCase();\n\t\tif (t.startsWith('struct') || t.startsWith('map') || t.startsWith('list')) continue;\n\t\tif (GEO_TYPE_KEYWORDS.some((kw) => t.includes(kw))) return f.name;\n\t}\n\n\t// Priority 2: exact well-known name with binary type\n\tfor (const f of schema) {\n\t\tconst n = f.name.toLowerCase();\n\t\tconst t = f.type.toLowerCase();\n\t\tconst isBinary = t.includes('blob') || t.includes('binary') || t.includes('bytea');\n\t\tif (GEO_NAMES.includes(n) && isBinary) return f.name;\n\t}\n\n\t// Priority 3: exact well-known name, any type\n\tfor (const f of schema) {\n\t\tif (GEO_NAMES.includes(f.name.toLowerCase())) return f.name;\n\t}\n\n\t// Priority 4: name token matches geo hint with binary type\n\tfor (const f of schema) {\n\t\tconst tokens = tokenizeColumnName(f.name);\n\t\tconst t = f.type.toLowerCase();\n\t\tconst isBinary = t.includes('blob') || t.includes('binary') || t.includes('bytea');\n\t\tif (isBinary && tokens.some((tok) => GEO_NAME_HINTS.includes(tok))) return f.name;\n\t}\n\n\t// Priority 5: name token matches geo hint, any type\n\tfor (const f of schema) {\n\t\tconst tokens = tokenizeColumnName(f.name);\n\t\tif (tokens.some((tok) => GEO_NAME_HINTS.includes(tok))) return f.name;\n\t}\n\n\treturn null;\n}\n\n/**\n * Check if a value looks like valid WKB by inspecting its first bytes.\n * WKB starts with a byte-order marker (0x00 big-endian, 0x01 little-endian)\n * followed by a uint32 geometry type code.\n */\nfunction looksLikeWKB(value: unknown): boolean {\n\tconst bytes = toBinary(value);\n\tif (!bytes || bytes.length < 5) return false;\n\n\tconst bom = bytes[0];\n\tif (bom !== 0x00 && bom !== 0x01) return false;\n\n\tconst le = bom === 0x01;\n\tconst view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n\tlet typeInt = view.getUint32(1, le);\n\n\t// Strip EWKB flags\n\ttypeInt = (typeInt & 0x0000ffff) % 1000;\n\n\t// Valid base geometry types are 1–7\n\treturn typeInt >= 1 && typeInt <= 7;\n}\n\n/**\n * Fallback: probe actual row data to find a column containing WKB geometry.\n * Use this when schema-only detection via `findGeoColumn()` returns null.\n * Samples the first row and checks each BLOB/binary column for WKB magic bytes.\n */\nexport function findGeoColumnFromRows(\n\trows: Record<string, unknown>[],\n\tschema: { name: string; type: string }[]\n): string | null {\n\tif (rows.length === 0) return null;\n\n\tconst sample = rows[0];\n\n\t// First pass: check binary-typed columns\n\tfor (const f of schema) {\n\t\tconst t = f.type.toLowerCase();\n\t\tconst isBinary = t.includes('blob') || t.includes('binary') || t.includes('bytea');\n\t\tif (isBinary && looksLikeWKB(sample[f.name])) return f.name;\n\t}\n\n\t// Second pass: check any column that holds binary-like data or WKT strings\n\tfor (const [key, value] of Object.entries(sample)) {\n\t\tif (value instanceof Uint8Array || value instanceof ArrayBuffer) {\n\t\t\tif (looksLikeWKB(value)) return key;\n\t\t}\n\t\tif (typeof value === 'string') {\n\t\t\t// Hex-encoded WKB\n\t\t\tif (/^[0-9a-fA-F]+$/.test(value) && value.length >= 10 && looksLikeWKB(value)) {\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\t// WKT string (from DuckDB spatial GEOMETRY type)\n\t\t\tif (isWKT(value)) return key;\n\t\t}\n\t\t// GeoJSON geometry object (from DuckDB read_json_auto struct serialization)\n\t\tif (isGeoJSONGeometry(value)) return key;\n\t\t// GeoJSON JSON string (from DuckDB to_json()::VARCHAR)\n\t\tif (typeof value === 'string' && value.startsWith('{')) {\n\t\t\ttry {\n\t\t\t\tif (isGeoJSONGeometry(JSON.parse(value))) return key;\n\t\t\t} catch {\n\t\t\t\t// not JSON\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// WKT detection (used by findGeoColumnFromRows for column sniffing)\n// ---------------------------------------------------------------------------\n\nconst WKT_TYPES = [\n\t'POINT',\n\t'LINESTRING',\n\t'POLYGON',\n\t'MULTIPOINT',\n\t'MULTILINESTRING',\n\t'MULTIPOLYGON'\n];\n\n/** Check if a string looks like WKT. */\nfunction isWKT(value: unknown): value is string {\n\tif (typeof value !== 'string') return false;\n\tconst s = value.trimStart().toUpperCase();\n\treturn WKT_TYPES.some((t) => s.startsWith(t) || s.startsWith(`MULTI${t}`));\n}\n"]}
1
+ {"version":3,"sources":["../../../src/lib/constants.ts","../../../src/lib/file-icons/index.ts","../../../src/lib/query/engine.ts","../../../src/lib/storage/providers.ts","../../../src/lib/storage/url-adapter.ts","../src/app-config.ts","../src/stac.ts","../src/channel-composite.ts","../src/clipboard.ts","../src/cloud-url.ts","../src/cog-asset.ts","../src/cog-info.ts","../src/column-types.ts","../src/connection-identity.ts","../src/error.ts","../src/format.ts","../src/export.ts","../src/file-sort.ts","../src/geoarrow.ts","../src/geometry-type.ts","../src/hex.ts","../src/stac-storage-extension.ts","../src/storage-url.ts","../src/host-detection.ts","../src/local-storage.ts","../src/lru.ts","../src/map-pixel-inspect.ts","../src/markdown-sql.ts","../src/markdown-sql-context.ts","../src/notebook.ts","../src/parquet-metadata.ts","../src/stac-facets.ts","../src/stac-geoparquet.ts","../src/stac-hydrate.ts","../src/stac-pushdown.ts","../src/stac-source.ts","../src/stac-source-api.ts","../src/stac-source-static.ts","../src/storage-smoketest.ts","../src/wkb.ts"],"names":["ext","a","Field","Float64","FixedSizeList","makeData","List","Utf8","Schema","Struct","RecordBatch","Table","globalBounds","SLASH","stripTrailingSlashes","stripEdgeSlashes","parsed","el","buf","reason"],"mappings":";;;;;AAOO,IAAM,YAAA,GAAe;AAAA,EAC3B,QAAA,EAAU,0BAAA;AAAA,EACV,WAAA,EAAa,6BAAA;AAAA,EACb,aAAA,EAAe;AAChB;AAKO,IAAM,8BAAc,IAAI,GAAA,CAAI,CAAC,IAAA,EAAM,IAAI,CAAC;AAOxC,IAAM,kBAAA,GAAqB;AAK3B,IAAM,sBAAA,GAAyB;AAG/B,IAAM,yBAAA,GAA4B;AAGlC,IAAM,kBAAA,GAAqB;AAK3B,IAAM,wCAAwB,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,KAAK,CAAC;AAQrD,IAAM,oBAAA,GAAuB;AAK7B,IAAM,gBAAA,GAAmB;;;ACmBhC,IAAM,YAAA,GAA6B;AAAA,EAClC,IAAA,EAAM,MAAA;AAAA,EACN,KAAA,EAAO,kCAAA;AAAA,EACP,KAAA,EAAO,MAAA;AAAA,EACP,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,KAAA;AAAA,EACR,SAAA,EAAW,KAAA;AAAA,EACX,YAAA,EAAc,IAAA;AAAA,EACd,QAAA,EAAU;AACX,CAAA;AAEA,IAAM,WAAA,GAA4B;AAAA,EACjC,IAAA,EAAM,QAAA;AAAA,EACN,KAAA,EAAO,kCAAA;AAAA,EACP,KAAA,EAAO,QAAA;AAAA,EACP,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,KAAA;AAAA,EACR,SAAA,EAAW,KAAA;AAAA,EACX,YAAA,EAAc,IAAA;AAAA,EACd,QAAA,EAAU;AACX,CAAA;AAMA,IAAM,UAAA,GAA2C;AAAA;AAAA,EAEhD,UAAA,EAAY;AAAA,IACX,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,gBAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,cAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,aAAA,EAAe;AAAA,IACd,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,cAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,cAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,WAAA,EAAa;AAAA,IACZ,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,cAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,UAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,UAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACT,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,SAAA,EAAW;AAAA,IACV,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,UAAA,EAAY;AAAA,IACX,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,wCAAA;AAAA,IACP,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACT,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,cAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,UAAA,EAAY;AAAA,IACX,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,MAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,gCAAA;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,IAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,gCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,GAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,gCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACT,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,OAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,QAAA,EAAU;AAAA,IACT,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,gCAAA;AAAA,IACP,KAAA,EAAO,OAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,IAAA,EAAM;AAAA,IACL,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,GAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,aAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,cAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,aAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,aAAA,EAAe;AAAA,IACd,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,WAAA,EAAa;AAAA,IACZ,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,WAAA,EAAa;AAAA,IACZ,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,gCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,aAAA;AAAA,IACP,QAAA,EAAU,QAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,aAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,aAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,aAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,OAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,KAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,OAAA;AAAA,IACP,QAAA,EAAU,SAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,KAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,UAAA,EAAY;AAAA,IACX,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,SAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,SAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,YAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,SAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,OAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,SAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,SAAA,EAAW;AAAA,IACV,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,WAAA,EAAa;AAAA,IACZ,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,IAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,SAAA,EAAW;AAAA,IACV,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,gCAAA;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,KAAA,EAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,oCAAA;AAAA,IACP,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU,UAAA;AAAA,IACV,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,IAAA;AAAA,IACV,MAAA,EAAQ,IAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,IAAA;AAAA,IACV,MAAA,EAAQ,IAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,IAAA;AAAA,IACV,MAAA,EAAQ,IAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,IAAA;AAAA,IACV,MAAA,EAAQ,IAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,WAAA;AAAA,IACP,QAAA,EAAU,IAAA;AAAA,IACV,MAAA,EAAQ,IAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,QAAA,EAAU;AAAA,IACT,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,kBAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,OAAA,EAAS;AAAA,IACR,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,sCAAA;AAAA,IACP,KAAA,EAAO,MAAA;AAAA,IACP,QAAA,EAAU,MAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA;AAAA,EAGA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA,GACX;AAAA,EACA,MAAA,EAAQ;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,kCAAA;AAAA,IACP,KAAA,EAAO,iBAAA;AAAA,IACP,QAAA,EAAU,KAAA;AAAA,IACV,MAAA,EAAQ,MAAA;AAAA,IACR,SAAA,EAAW,KAAA;AAAA,IACX,YAAA,EAAc,IAAA;AAAA,IACd,QAAA,EAAU;AAAA;AAEZ,CAAA;AAUO,SAAS,eAAA,CAAgB,SAAA,EAAmB,KAAA,GAAQ,KAAA,EAAqB;AAC/E,EAAA,IAAI,SAAS,SAAA,EAAW;AACvB,IAAA,MAAMA,IAAAA,GAAM,SAAA,CAAU,UAAA,CAAW,GAAG,CAAA,GAAI,SAAA,CAAU,WAAA,EAAY,GAAI,CAAA,CAAA,EAAI,SAAA,CAAU,WAAA,EAAa,CAAA,CAAA;AAC7F,IAAA,MAAM,KAAA,GAAQ,WAAWA,IAAG,CAAA;AAC5B,IAAA,IAAI,OAAO,OAAO,KAAA;AAAA,EACnB;AACA,EAAA,IAAI,OAAO,OAAO,WAAA;AAClB,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,UAAA,CAAW,GAAG,CAAA,GAAI,SAAA,CAAU,WAAA,EAAY,GAAI,CAAA,CAAA,EAAI,SAAA,CAAU,WAAA,EAAa,CAAA,CAAA;AAC7F,EAAA,OAAO,UAAA,CAAW,GAAG,CAAA,IAAK,YAAA;AAC3B;AAGO,SAAS,gBAAgB,SAAA,EAA2B;AAC1D,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,QAAA,CAAS,GAAG,IAAI,CAAA,CAAA,EAAI,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,CAAG,WAAA,EAAa,CAAA,CAAA,GAAK,EAAA;AACxF,EAAA,OAAO,UAAA,CAAW,GAAG,CAAA,EAAG,YAAA,IAAgB,cAAA;AACzC;AAUO,SAAS,iBAAA,CAAkB,WAAmB,GAAA,EAAqB;AACzE,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,QAAA,CAAS,GAAG,IAAI,CAAA,CAAA,EAAI,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,CAAG,WAAA,EAAa,CAAA,CAAA,GAAK,EAAA;AACxF,EAAA,IAAI,QAAQ,UAAA,EAAY;AACvB,IAAA,OAAO,oJAAoJ,GAAG,CAAA,wDAAA,CAAA;AAAA,EAC/J;AACA,EAAA,MAAM,MAAA,GAAS,UAAA,CAAW,GAAG,CAAA,EAAG,YAAA,IAAgB,cAAA;AAChD,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,EAAA,EAAK,GAAG,CAAA,EAAA,CAAA;AACzB;AASA,IAAM,iBAAA,uBAAwB,GAAA,CAAI,CAAC,YAAY,aAAA,EAAe,MAAA,EAAQ,WAAA,EAAa,WAAW,CAAC,CAAA;AAExF,SAAS,oBAAoB,SAAA,EAA4B;AAC/D,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,QAAA,CAAS,GAAG,IAAI,CAAA,CAAA,EAAI,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,CAAG,WAAA,EAAa,CAAA,CAAA,GAAK,EAAA;AACxF,EAAA,OAAO,iBAAA,CAAkB,IAAI,GAAG,CAAA;AACjC;AAGO,SAAS,cAAc,SAAA,EAA+B;AAC5D,EAAA,OAAO,eAAA,CAAgB,SAAS,CAAA,CAAE,MAAA;AACnC;AAGO,SAAS,YAAY,SAAA,EAA4B;AACvD,EAAA,OAAO,eAAA,CAAgB,SAAS,CAAA,CAAE,SAAA;AACnC;AAGO,SAAS,YAAY,SAAA,EAA2B;AACtD,EAAA,OAAO,eAAA,CAAgB,SAAS,CAAA,CAAE,QAAA;AACnC;;;AC9oCO,IAAM,mBAAA,GAAN,cAAkC,KAAA,CAAM;AAAA,EAC9C,WAAA,GAAc;AACb,IAAA,KAAA,CAAM,iBAAiB,CAAA;AACvB,IAAA,IAAA,CAAK,IAAA,GAAO,qBAAA;AAAA,EACb;AACD;;;ACmEO,IAAM,SAAA,GAA6C;AAAA,EACzD,EAAA,EAAI;AAAA,IACH,KAAA,EAAO,QAAA;AAAA,IACP,WAAA,EAAa,wCAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,WAAA;AAAA,IACf,gBAAA,EAAkB,IAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,uBAAA,EAAwB;AAAA,MACpD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,gBAAA,EAAiB;AAAA,MAC7C,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,yBAAA,EAA0B;AAAA,MACtD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,kBAAA,EAAmB;AAAA,MAC/C,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,cAAA,EAAe;AAAA,MAC3C,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,aAAA,EAAc;AAAA,MAC1C,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,EAAa;AAAA,MACzC,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,gBAAA,EAAiB;AAAA,MAChD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,aAAA,EAAc;AAAA,MAC7C,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,gBAAA,EAAiB;AAAA,MAC9C,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,YAAA,EAAa;AAAA,MAC1C,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,YAAA,EAAa;AAAA,MAC1C,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,sBAAA,EAAuB;AAAA,MACxD,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,sBAAA,EAAuB;AAAA,MACxD,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,sBAAA,EAAuB;AAAA,MACxD,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,0BAAA,EAA2B;AAAA,MAC5D,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,uBAAA,EAAwB;AAAA,MACzD,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,wBAAA,EAAyB;AAAA,MAC1D,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,uBAAA,EAAwB;AAAA,MACrD,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,0BAAA,EAA2B;AAAA,MACxD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,0BAAA,EAA2B;AAAA,MACvD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,8BAAA,EAA4B;AAAA,MACxD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,kBAAA,EAAmB;AAAA,MAClD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,kBAAA,EAAmB;AAAA,MAC/C,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,uBAAA,EAAwB;AAAA,MACrD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,mBAAA,EAAoB;AAAA,MACnD,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,oBAAA,EAAqB;AAAA,MAClD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,mBAAA;AAAoB,KACpD;AAAA,IACA,mBAAA,EAAqB,kDAAA;AAAA,IACrB,OAAA,EAAS,CAAC,IAAA,EAAM,KAAA,EAAO,OAAO,KAAK;AAAA,GACpC;AAAA,EAEA,GAAA,EAAK;AAAA,IACJ,KAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAa,sBAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,KAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,MAAA;AAAA,IACf,gBAAA,EAAkB,gCAAA;AAAA,IAClB,SAAS,EAAC;AAAA,IACV,mBAAA,EAAqB,gCAAA;AAAA,IACrB,OAAA,EAAS,CAAC,IAAA,EAAM,KAAK;AAAA,GACtB;AAAA,EAEA,EAAA,EAAI;AAAA,IACH,KAAA,EAAO,eAAA;AAAA,IACP,WAAA,EAAa,uBAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,KAAA;AAAA,IACb,aAAA,EAAe,IAAA;AAAA,IACf,aAAA,EAAe,MAAA;AAAA,IACf,gBAAA,EAAkB,IAAA;AAAA,IAClB,SAAS,EAAC;AAAA,IACV,mBAAA,EAAqB,+CAAA;AAAA,IACrB,OAAA,EAAS,CAAC,IAAI;AAAA,GACf;AAAA,EAEA,KAAA,EAAO;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,WAAA,EAAa,oBAAA;AAAA,IACb,UAAA,EAAY,WAAA;AAAA,IACZ,WAAA,EAAa,KAAA;AAAA,IACb,aAAA,EAAe,IAAA;AAAA,IACf,aAAA,EAAe,EAAA;AAAA,IACf,gBAAA,EAAkB,IAAA;AAAA,IAClB,SAAS,EAAC;AAAA,IACV,WAAA,EAAa,WAAA;AAAA,IACb,mBAAA,EAAqB,yCAAA;AAAA,IACrB,SAAS,CAAC,OAAA,EAAS,MAAM,MAAA,EAAQ,OAAA,EAAS,SAAS,KAAK;AAAA,GACzD;AAAA,EAEA,KAAA,EAAO;AAAA,IACN,KAAA,EAAO,yBAAA;AAAA,IACP,WAAA,EAAa,qDAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,KAAA;AAAA,IACb,aAAA,EAAe,IAAA;AAAA,IACf,aAAA,EAAe,WAAA;AAAA,IACf,gBAAA,EAAkB,IAAA;AAAA,IAClB,SAAS,EAAC;AAAA,IACV,mBAAA,EAAqB,iDAAA;AAAA,IACrB,SAAS;AAAC,GACX;AAAA,EAEA,KAAA,EAAO;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,WAAA,EAAa,2BAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,KAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,KAAA;AAAA,IACf,gBAAA,EAAkB,+BAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,KAAA,EAAM;AAAA,MAC5B,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,KAAA,EAAM;AAAA,MAC5B,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,KAAA;AAAM,KAC7B;AAAA,IACA,mBAAA,EAAqB,+BAAA;AAAA,IACrB,OAAA,EAAS,CAAC,OAAA,EAAS,IAAI;AAAA,GACxB;AAAA,EAEA,EAAA,EAAI;AAAA,IACH,KAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAa,4BAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,aAAA;AAAA,IACf,gBAAA,EAAkB,qCAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,sBAAA,EAAuB;AAAA,MACrD,EAAE,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,oBAAA,EAAqB;AAAA,MACnD,EAAE,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,mBAAA,EAAoB;AAAA,MAClD,EAAE,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,SAAA,EAAU;AAAA,MACxC,EAAE,IAAA,EAAM,aAAA,EAAe,KAAA,EAAO,kBAAA,EAAmB;AAAA,MACjD,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,wBAAA,EAAyB;AAAA,MAC1D,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,kBAAA;AAAmB,KACrD;AAAA,IACA,mBAAA,EAAqB,wCAAA;AAAA,IACrB,SAAS;AAAC,GACX;AAAA,EAEA,YAAA,EAAc;AAAA,IACb,KAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAa,qBAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,MAAA;AAAA,IACf,gBAAA,EAAkB,yCAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,YAAA,EAAa;AAAA,MACpC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,iBAAA,EAAkB;AAAA,MACzC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAc;AAAA,MACrC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAc;AAAA,MACrC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAW;AAAA,MAClC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAc;AAAA,MACrC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,WAAA,EAAY;AAAA,MACnC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,aAAA,EAAc;AAAA,MACrC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,UAAA;AAAW,KACnC;AAAA,IACA,mBAAA,EAAqB,qCAAA;AAAA,IACrB,SAAS;AAAC,GACX;AAAA,EAEA,MAAA,EAAQ;AAAA,IACP,KAAA,EAAO,QAAA;AAAA,IACP,WAAA,EAAa,0BAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,WAAA;AAAA,IACf,gBAAA,EAAkB,mCAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,sBAAA,EAAuB;AAAA,MACnD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,sBAAA,EAAuB;AAAA,MACnD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,sBAAA,EAAuB;AAAA,MACtD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,oBAAA,EAAqB;AAAA,MACjD,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,0BAAA,EAA2B;AAAA,MAC1D,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,0BAAA,EAA2B;AAAA,MAC1D,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,oBAAA,EAAqB;AAAA,MACjD,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,mBAAA,EAAoB;AAAA,MAChD,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,wBAAA,EAAyB;AAAA,MAC1D,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,wBAAA,EAAyB;AAAA,MAC1D,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,4BAAA,EAA6B;AAAA,MAC9D,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,yBAAA,EAA0B;AAAA,MAC3D,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,kBAAA;AAAmB,KACnD;AAAA,IACA,mBAAA,EAAqB,oCAAA;AAAA,IACrB,SAAS;AAAC,GACX;AAAA,EAEA,OAAA,EAAS;AAAA,IACR,KAAA,EAAO,SAAA;AAAA,IACP,WAAA,EAAa,wBAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,KAAA;AAAA,IACf,gBAAA,EAAkB,qCAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,gBAAA,EAAiB;AAAA,MACvC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,YAAA,EAAa;AAAA,MACpC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,WAAA;AAAY,KACpC;AAAA,IACA,mBAAA,EAAqB,gCAAA;AAAA,IACrB,SAAS;AAAC,GACX;AAAA,EAEA,OAAA,EAAS;AAAA,IACR,KAAA,EAAO,SAAA;AAAA,IACP,WAAA,EAAa,wBAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,MAAA;AAAA,IACf,gBAAA,EAAkB,yCAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,iBAAA,EAAkB;AAAA,MACzC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,eAAA,EAAgB;AAAA,MACvC,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,cAAA;AAAe,KACvC;AAAA,IACA,mBAAA,EAAqB,qCAAA;AAAA,IACrB,SAAS;AAAC,GACX;AAAA,EAEA,MAAA,EAAQ;AAAA,IACP,KAAA,EAAO,iBAAA;AAAA,IACP,WAAA,EAAa,gCAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,WAAA;AAAA,IACf,gBAAA,EAAkB,oCAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,YAAA,EAAa;AAAA,MACzC,EAAE,IAAA,EAAM,gBAAA,EAAkB,KAAA,EAAO,aAAA,EAAc;AAAA,MAC/C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,aAAA,EAAc;AAAA,MACzC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,gBAAA,EAAiB;AAAA,MAC5C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,iBAAA,EAAkB;AAAA,MAC7C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,aAAA,EAAc;AAAA,MACzC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,WAAA,EAAY;AAAA,MACvC,EAAE,IAAA,EAAM,cAAA,EAAgB,KAAA,EAAO,eAAA,EAAgB;AAAA,MAC/C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,eAAA,EAAgB;AAAA,MAC3C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,YAAA,EAAa;AAAA,MACxC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,WAAA,EAAY;AAAA,MACvC,EAAE,IAAA,EAAM,YAAA,EAAc,KAAA,EAAO,WAAA,EAAY;AAAA,MACzC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,WAAA,EAAY;AAAA,MACvC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,eAAA,EAAgB;AAAA,MAC3C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,kBAAA,EAAgB;AAAA,MAC3C,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,aAAA,EAAc;AAAA,MACzC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,aAAA,EAAc;AAAA,MACzC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,WAAA,EAAY;AAAA,MACvC,EAAE,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,eAAA;AAAgB,KAC5C;AAAA,IACA,mBAAA,EAAqB,qCAAA;AAAA,IACrB,SAAS;AAAC,GACX;AAAA,EAEA,QAAA,EAAU;AAAA,IACT,KAAA,EAAO,UAAA;AAAA,IACP,WAAA,EAAa,yBAAA;AAAA,IACb,UAAA,EAAY,OAAA;AAAA,IACZ,WAAA,EAAa,IAAA;AAAA,IACb,aAAA,EAAe,KAAA;AAAA,IACf,aAAA,EAAe,KAAA;AAAA,IACf,gBAAA,EAAkB,sCAAA;AAAA,IAClB,OAAA,EAAS;AAAA,MACR,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,gBAAA,EAAiB;AAAA,MACvC,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,gBAAA,EAAiB;AAAA,MACvC,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,iBAAA,EAAkB;AAAA,MACxC,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,eAAA,EAAgB;AAAA,MACrC,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,YAAA,EAAa;AAAA,MAClC,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,YAAA;AAAa,KACpC;AAAA,IACA,mBAAA,EAAqB,iCAAA;AAAA,IACrB,SAAS;AAAC;AAEZ;AAsLO,IAAM,YAAA,GAA6B;AAAA,EACzC,IAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,cAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA;AACD;AAGO,SAAS,YAAY,EAAA,EAAyB;AACpD,EAAA,OAAO,SAAA,CAAU,EAAgB,CAAA,IAAK,SAAA,CAAU,EAAA;AACjD;AAGO,SAAS,yBAAA,CAA0B,IAAgB,MAAA,EAAwB;AACjF,EAAA,MAAM,GAAA,GAAM,UAAU,EAAE,CAAA;AACxB,EAAA,IAAI,CAAC,GAAA,EAAK,gBAAA,EAAkB,OAAO,EAAA;AACnC,EAAA,OAAO,GAAA,CAAI,gBAAA,CAAiB,OAAA,CAAQ,UAAA,EAAY,MAAM,CAAA;AACvD;AAOO,SAAS,uBAAA,CAAwB,UAAkB,MAAA,EAAyB;AAClF,EAAA,MAAM,GAAA,GAAM,UAAU,QAAsB,CAAA;AAC5C,EAAA,IAAI,CAAC,GAAA,EAAK,gBAAA,EAAkB,OAAO,EAAA;AACnC,EAAA,OAAO,yBAAA,CAA0B,QAAA,EAAwB,MAAA,IAAU,GAAA,CAAI,aAAa,CAAA;AACrF;AAMO,SAAS,oBAAA,CACf,QAAA,EACA,QAAA,EACA,MAAA,EACA,MAAA,EACS;AACT,EAAA,IAAI,QAAA,EAAU;AACb,IAAA,OAAO,GAAG,QAAA,CAAS,OAAA,CAAQ,OAAO,EAAE,CAAC,IAAI,MAAM,CAAA,CAAA;AAAA,EAChD;AACA,EAAA,MAAM,GAAA,GAAM,UAAU,QAAQ,CAAA;AAC9B,EAAA,IAAI,KAAK,gBAAA,EAAkB;AAC1B,IAAA,MAAM,WAAW,GAAA,CAAI,gBAAA,CAAiB,QAAQ,UAAA,EAAY,MAAA,IAAU,IAAI,aAAa,CAAA;AACrF,IAAA,OAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAAA,EAC7B;AAEA,EAAA,OAAO,CAAA,WAAA,EAAc,MAAA,IAAU,WAAW,CAAA,eAAA,EAAkB,MAAM,CAAA,CAAA;AACnE;AAGO,SAAS,aAAA,CAAc,UAAkB,QAAA,EAA2B;AAC1E,EAAA,OAAO,aAAa,KAAA,IAAU,CAAC,CAAC,QAAA,IAAY,2BAAA,CAA4B,KAAK,QAAQ,CAAA;AACtF;AAgCO,SAAS,cAAc,IAAA,EAAmC;AAChE,EAAA,IAAI,IAAA,CAAK,QAAA,KAAa,OAAA,EAAS,OAAO,WAAA;AAGtC,EAAA,IAAI,IAAA,CAAK,WAAW,OAAO,cAAA;AAE3B,EAAA,OAAO,WAAA;AACR;AAMO,SAAS,qBAAqB,IAAA,EAAgC;AACpE,EAAA,MAAM,IAAA,GAAO,cAAc,IAAI,CAAA;AAC/B,EAAA,OAAO,IAAA,KAAS,kBAAkB,IAAA,KAAS,WAAA;AAC5C;;;ACpnBO,IAAM,aAAN,MAA2C;AAAA,EACxC,aAAA,GAAgB,KAAA;AAAA,EAEzB,MAAM,IAAA,CACL,GAAA,EACA,MAAA,EACA,QACA,MAAA,EACsB;AACtB,IAAA,MAAM,UAAkC,EAAC;AACzC,IAAA,IAAI,MAAA,KAAW,MAAA,IAAa,MAAA,KAAW,MAAA,EAAW;AACjD,MAAA,OAAA,CAAQ,QAAQ,CAAA,MAAA,EAAS,MAAM,CAAA,CAAA,EAAI,MAAA,GAAS,SAAS,CAAC,CAAA,CAAA;AAAA,IACvD,CAAA,MAAA,IAAW,WAAW,MAAA,EAAW;AAChC,MAAA,OAAA,CAAQ,KAAA,GAAQ,SAAS,MAAM,CAAA,CAAA,CAAA;AAAA,IAChC;AAEA,IAAA,MAAM,MAAM,MAAM,KAAA,CAAM,KAAK,EAAE,OAAA,EAAS,QAAQ,CAAA;AAChD,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,GAAA,CAAI,UAAU,CAAA,CAAE,CAAA;AACpE,IAAA,OAAO,IAAI,UAAA,CAAW,MAAM,GAAA,CAAI,aAAa,CAAA;AAAA,EAC9C;AAAA,EAEA,MAAM,IAAA,CAAK,GAAA,EAAa,MAAA,EAA0C;AACjE,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK,EAAE,MAAA,EAAQ,MAAA,EAAQ,QAAQ,CAAA;AACvD,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,GAAA,CAAI,UAAU,CAAA,CAAE,CAAA;AACpE,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,EAAG,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,MAAA;AACpD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,CAAG,WAAA,EAAY,GAAI,EAAA;AACxE,IAAA,OAAO;AAAA,MACN,IAAA;AAAA,MACA,IAAA,EAAM,GAAA;AAAA,MACN,MAAA,EAAQ,KAAA;AAAA,MACR,MAAM,MAAA,CAAO,GAAA,CAAI,QAAQ,GAAA,CAAI,gBAAgB,KAAK,CAAC,CAAA;AAAA,MACnD,QAAA,EAAU,IAAI,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,IAAI,eAAe,CAAA,IAAK,CAAC,CAAA,CAAE,OAAA,EAAQ;AAAA,MAClE,SAAA,EAAW;AAAA,KACZ;AAAA,EACD;AAAA,EAEA,MAAM,IAAA,GAA6B;AAClC,IAAA,OAAO,EAAC;AAAA,EACT;AAAA,EAEA,MAAM,GAAA,GAA4B;AACjC,IAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,EAC7D;AAAA,EAEA,MAAM,MAAA,GAAwB;AAC7B,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC9D;AAAA,EAEA,MAAM,YAAA,GAA6C;AAClD,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC9D;AAAA,EAEA,MAAM,IAAA,GAA6B;AAClC,IAAA,MAAM,IAAI,MAAM,2CAA2C,CAAA;AAAA,EAC5D;AACD;;;AClBO,IAAM,kBAAA,GAAgC;AAAA,EAC5C,QAAA,EAAU,EAAE,KAAA,EAAO,QAAA,EAAU,QAAQ,IAAA,EAAM,YAAA,EAAc,GAAA,EAAM,eAAA,EAAiB,GAAA,EAAK;AAAA,EACrF,IAAI,EAAE,kBAAA,EAAoB,MAAM,YAAA,EAAc,IAAA,EAAM,cAAc,IAAA,EAAK;AAAA,EACvE,UAAU,EAAC;AAAA,EACX,gBAAgB,EAAC;AAAA,EACjB,aAAa;AACd;AAIA,SAAS,SAAS,CAAA,EAAoC;AACrD,EAAA,OAAO,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,GAAK,CAAA,GAAmB,MAAA;AAC9E;AAEO,SAAS,YAAY,CAAA,EAA+B;AAC1D,EAAA,OAAO,MAAM,OAAA,IAAW,CAAA,KAAM,MAAA,IAAU,CAAA,KAAM,WAAW,CAAA,GAAI,MAAA;AAC9D;AAEO,SAAS,aAAa,CAAA,EAAgC;AAC5D,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,IAAA,GAAO,MAAA,GAAS,CAAA,GAAI,CAAA,CAAE,IAAA,EAAK,GAAI,MAAA;AAClE;AAEO,SAAS,kBAAkB,CAAA,EAAgC;AACjE,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAY,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,IAAK,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA;AAChF;AAEO,SAAS,WAAW,CAAA,EAAiC;AAC3D,EAAA,OAAO,OAAO,CAAA,KAAM,SAAA,GAAY,CAAA,GAAI,MAAA;AACrC;AAGO,SAAS,kBAAqB,UAAA,EAAqD;AACzF,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC3B,IAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,MAAA,EAAW,OAAO,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,MAAA;AACR;AAGO,SAAS,qBAAqB,KAAA,EAA2C;AAC/E,EAAA,IAAI,KAAA,KAAU,QAAQ,OAAO,KAAA;AAC7B,EAAA,IAAI,KAAA,KAAU,QAAQ,OAAO,IAAA;AAC7B,EAAA,OAAO,MAAA;AACR;AAEA,SAAS,eAAe,CAAA,EAAyC;AAChE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,GAAG,OAAO,MAAA;AAC9B,EAAA,MAAM,MAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,OAAO,CAAA,EAAG;AACpB,IAAA,MAAM,CAAA,GAAI,SAAS,GAAG,CAAA;AACtB,IAAA,IAAI,CAAC,CAAA,EAAG;AACR,IAAA,MAAM,EAAA,GAAK,YAAA,CAAa,CAAA,CAAE,EAAE,CAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,CAAA,CAAE,KAAK,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,CAAA,CAAE,GAAG,CAAA;AAC9B,IAAA,MAAM,IAAA,GAAO,EAAE,IAAA,KAAS,QAAA,IAAY,EAAE,IAAA,KAAS,QAAA,GAAW,EAAE,IAAA,GAAO,MAAA;AACnE,IAAA,IAAI,CAAC,EAAA,IAAM,CAAC,SAAS,CAAC,GAAA,IAAO,CAAC,IAAA,EAAM;AACpC,IAAA,MAAM,OAAA,GAAU,EAAE,OAAA,KAAY,OAAA,IAAW,EAAE,OAAA,KAAY,MAAA,GAAS,EAAE,OAAA,GAAU,MAAA;AAC5E,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,KAAA,EAAO,GAAA,EAAK,IAAA,EAAM,GAAI,OAAA,GAAU,EAAE,OAAA,EAAQ,GAAI,IAAK,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,GAAA;AACR;AAEA,SAAS,kBAAkB,CAAA,EAA0C;AACpE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,GAAG,OAAO,MAAA;AAC9B,EAAA,MAAM,MAAwB,EAAC;AAC/B,EAAA,KAAA,MAAW,OAAO,CAAA,EAAG;AACpB,IAAA,MAAM,CAAA,GAAI,SAAS,GAAG,CAAA;AACtB,IAAA,IAAI,CAAC,CAAA,EAAG;AACR,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,CAAA,CAAE,IAAI,CAAA;AAChC,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,CAAA,CAAE,MAAM,CAAA;AACpC,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,EAAQ;AACtB,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,CAAA,CAAE,MAAM,CAAA;AACpC,IAAA,MAAM,QAAA,GAAW,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA;AACxC,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,CAAA,CAAE,SAAS,CAAA;AACxC,IAAA,MAAM,UAAA,GACL,EAAE,UAAA,KAAe,OAAA,IAAW,EAAE,UAAA,KAAe,WAAA,GAAc,EAAE,UAAA,GAAa,MAAA;AAC3E,IAAA,MAAM,UAAA,GAAa,YAAA,CAAa,CAAA,CAAE,UAAU,CAAA;AAC5C,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MACR,IAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA,EAAU,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA,IAAK,IAAA;AAAA,MACtC,GAAI,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,KAAW,EAAC;AAAA,MACzC,GAAI,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,KAAa,EAAC;AAAA,MAC7C,GAAI,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,KAAc,EAAC;AAAA,MAC/C,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe,EAAC;AAAA,MACjD,GAAI,UAAA,KAAe,MAAA,GAAY,EAAE,UAAA,KAAe;AAAC,KACjD,CAAA;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACR;AASO,SAAS,cAAA,CACf,MAAA,EACA,OAAA,EACA,MAAA,EAC4B;AAC5B,EAAA,MAAM,OAAO,MAAA,CAAO,QAAA;AACpB,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAC9B,EAAA,IAAI,MAAA,EAAQ;AACX,IAAA,MAAM,SAAS,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,MAAM,CAAA;AAC/C,IAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,EACpB;AACA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,OAAO,CAAA;AAC/C,EAAA,IAAI,SAAA,EAAW;AACd,IAAA,MAAM,YAAY,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,SAAS,CAAA;AACrD,IAAA,IAAI,WAAW,OAAO,SAAA;AAAA,EACvB;AACA,EAAA,OAAO,IAAA,CAAK,KAAK,CAAC,CAAA,KAAM,EAAE,OAAA,KAAY,OAAO,CAAA,IAAK,IAAA,CAAK,CAAC,CAAA;AACzD;AAOO,SAAS,cAAA,CAAe,MAAiB,QAAA,EAA8B;AAC7E,EAAA,MAAM,CAAA,GAAI,SAAS,QAAQ,CAAA;AAC3B,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,CAAA,CAAE,QAAQ,KAAK,EAAC;AACnC,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,CAAA,CAAE,EAAE,KAAK,EAAC;AAC7B,EAAA,MAAM,EAAA,GAAK,QAAA,CAAS,CAAA,CAAE,cAAc,KAAK,EAAC;AAC1C,EAAA,OAAO;AAAA,IACN,QAAA,EAAU;AAAA,MACT,OAAO,WAAA,CAAY,CAAA,CAAE,KAAK,CAAA,IAAK,KAAK,QAAA,CAAS,KAAA;AAAA,MAC7C,QAAQ,YAAA,CAAa,CAAA,CAAE,MAAM,CAAA,IAAK,KAAK,QAAA,CAAS,MAAA;AAAA,MAChD,cAAc,iBAAA,CAAkB,CAAA,CAAE,YAAY,CAAA,IAAK,KAAK,QAAA,CAAS,YAAA;AAAA,MACjE,iBAAiB,iBAAA,CAAkB,CAAA,CAAE,eAAe,CAAA,IAAK,KAAK,QAAA,CAAS;AAAA,KACxE;AAAA,IACA,EAAA,EAAI;AAAA,MACH,oBAAoB,UAAA,CAAW,CAAA,CAAE,kBAAkB,CAAA,IAAK,KAAK,EAAA,CAAG,kBAAA;AAAA,MAChE,cAAc,UAAA,CAAW,CAAA,CAAE,YAAY,CAAA,IAAK,KAAK,EAAA,CAAG,YAAA;AAAA,MACpD,cAAc,UAAA,CAAW,CAAA,CAAE,YAAY,CAAA,IAAK,KAAK,EAAA,CAAG;AAAA,KACrD;AAAA,IACA,QAAA,EAAU,cAAA,CAAe,CAAA,CAAE,QAAQ,KAAK,IAAA,CAAK,QAAA;AAAA,IAC7C,iBAAiB,MAAyC;AACzD,MAAA,MAAM,QAAQ,YAAA,CAAa,EAAA,CAAG,KAAK,CAAA,IAAK,KAAK,cAAA,CAAe,KAAA;AAC5D,MAAA,MAAM,OAAO,YAAA,CAAa,EAAA,CAAG,IAAI,CAAA,IAAK,KAAK,cAAA,CAAe,IAAA;AAC1D,MAAA,OAAO,EAAE,GAAI,KAAA,KAAU,MAAA,GAAY,EAAE,OAAM,GAAI,EAAC,EAAI,GAAI,SAAS,MAAA,GAAY,EAAE,IAAA,EAAK,GAAI,EAAC,EAAG;AAAA,IAC7F,CAAA,GAAG;AAAA,IACH,WAAA,EAAa,iBAAA,CAAkB,CAAA,CAAE,WAAW,KAAK,IAAA,CAAK;AAAA,GACvD;AACD;;;ACzHO,IAAM,mBAAA,GAAsB,CAAC,QAAA,EAAU,OAAA,EAAS,QAAQ,kBAAkB;AAG1E,SAAS,WAAW,IAAA,EAAiC;AAC3D,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAU,OAAO,KAAA;AAC9C,EAAA,MAAM,GAAA,GAAM,IAAA;AACZ,EAAA,OAAO,GAAA,CAAI,IAAA,KAAS,SAAA,IAAa,OAAO,IAAI,YAAA,KAAiB,QAAA;AAC9D;AAGO,SAAS,wBAAwB,IAAA,EAA8C;AACrF,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAU,OAAO,KAAA;AAC9C,EAAA,MAAM,GAAA,GAAM,IAAA;AACZ,EAAA,IAAI,GAAA,CAAI,IAAA,KAAS,mBAAA,EAAqB,OAAO,KAAA;AAC7C,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,QAAQ,KAAK,GAAA,CAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AACtE,EAAA,IAAI,OAAO,GAAA,CAAI,YAAA,KAAiB,QAAA,EAAU,OAAO,IAAA;AACjD,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,QAAA,CAAS,CAAC,CAAC,CAAA;AAClC;AAGO,SAAS,iBAAiB,IAAA,EAAuC;AACvE,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAU,OAAO,KAAA;AAC9C,EAAA,MAAM,GAAA,GAAM,IAAA;AACZ,EAAA,OACC,GAAA,CAAI,IAAA,KAAS,YAAA,IAAgB,OAAO,GAAA,CAAI,iBAAiB,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AAE9F;AAGO,SAAS,cAAc,IAAA,EAAoC;AACjE,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,UAAU,OAAO,KAAA;AAC9C,EAAA,MAAM,GAAA,GAAM,IAAA;AACZ,EAAA,OAAO,GAAA,CAAI,IAAA,KAAS,SAAA,IAAa,OAAO,GAAA,CAAI,iBAAiB,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AACjG;AAWO,SAAS,aAAa,IAAA,EAAiC;AAC7D,EAAA,IAAI,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,IAAA,EAAK;AACxD,EAAA,IAAI,uBAAA,CAAwB,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAI,IAAA,EAAK;AAC9E,EAAA,IAAI,gBAAA,CAAiB,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,YAAA,EAAc,SAAS,IAAA,EAAK;AACvE,EAAA,IAAI,aAAA,CAAc,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AACjE,EAAA,OAAO,EAAE,MAAM,MAAA,EAAO;AACvB;AAQO,SAAS,gBAAA,CAAiB,MAAgB,SAAA,EAAmC;AACnF,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAC/B,EAAA,IAAI,SAAA,IAAa,OAAO,SAAS,CAAA,EAAG,MAAM,OAAO,MAAA,CAAO,SAAS,CAAA,CAAE,IAAA;AACnE,EAAA,KAAA,MAAW,OAAO,mBAAA,EAAqB;AACtC,IAAA,IAAI,OAAO,GAAG,CAAA,EAAG,MAAM,OAAO,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA;AAAA,EAC3C;AACA,EAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,EAAG;AAC1C,IAAA,MAAM,CAAA,GAAI,OAAO,KAAA,EAAO,IAAA,KAAS,WAAW,KAAA,CAAM,IAAA,CAAK,aAAY,GAAI,EAAA;AACvE,IAAA,IAAI,OAAO,IAAA,IAAQ,CAAA,CAAE,SAAS,MAAM,CAAA,SAAU,KAAA,CAAM,IAAA;AAAA,EACrD;AACA,EAAA,OAAO,IAAA;AACR;AAGO,SAAS,oBAAoB,IAAA,EAAyB;AAC5D,EAAA,OAAO,aAAa,IAAI,CAAA,KAAM,IAAA,IAAQ,gBAAA,CAAiB,IAAI,CAAA,KAAM,IAAA;AAClE;AAKO,SAAS,sBAAsB,IAAA,EAAyB;AAC9D,EAAA,IAAI,WAAA,CAAY,yBAAA,CAA0B,IAAI,CAAC,GAAG,OAAO,IAAA;AACzD,EAAA,OAAO,oBAAA,CAAqB,uBAAA,CAAwB,IAAI,CAAC,CAAA;AAC1D;AAGO,SAAS,aAAa,IAAA,EAAyD;AACrF,EAAA,IAAI,KAAA,CAAM,QAAQ,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,IAAA,CAAK,UAAU,CAAA,EAAG;AACtD,IAAA,OAAO,CAAC,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,GAAG,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,OAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAAA,EAC/F;AACA,EAAA,OAAO,IAAA;AACR;AAaO,SAAS,qBAAA,CACf,OAGA,QAAA,EAC0B;AAC1B,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,IAAA;AAChD,EAAA,IAAI,UAAA,CAAW,KAAK,CAAA,EAAG;AACtB,IAAA,MAAM,IAAA,GAAO,aAAa,KAAK,CAAA;AAC/B,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,KAAA,EAAO,QAAQ,CAAA;AAC7C,IAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,IAAA,OAAO;AAAA,MACN,EAAA,EAAI,MAAA,CAAO,KAAA,CAAM,EAAA,IAAM,IAAI,CAAA;AAAA,MAC3B,IAAA;AAAA,MACA;AAAA,KACD;AAAA,EACD;AACA,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,IAAK,GAAA,CAAI,IAAA,CAAK,MAAA,IAAU,CAAA,IAAK,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,EAAU;AACpF,IAAA,OAAO;AAAA,MACN,EAAA,EAAI,MAAA,CAAO,GAAA,CAAI,EAAA,IAAM,IAAI,IAAI,CAAA;AAAA,MAC7B,IAAA,EAAM,CAAC,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,MAAA,CAAO,GAAA,CAAI,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA;AAAA,MACzF,MAAM,GAAA,CAAI;AAAA,KACX;AAAA,EACD;AACA,EAAA,OAAO,IAAA;AACR;AASO,SAAS,cAAA,CAAe,MAAgB,IAAA,EAAgD;AAC9F,EAAA,MAAM,KAAA,GAAS,IAAA,CAAK,UAAA,IAAc,EAAC;AACnC,EAAA,MAAM,IAAA,GAAO,MAAM,WAAW,CAAA;AAC9B,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,EAAM,OAAO,KAAK,IAAI,CAAA,CAAA;AACtD,EAAA,MAAM,GAAA,GAAM,MAAM,eAAe,CAAA;AACjC,EAAA,MAAM,IAAA,GAAO,MAAM,oBAAoB,CAAA;AACvC,EAAA,MAAM,EAAA,GAAK,MAAM,kBAAkB,CAAA;AACnC,EAAA,IAAI,GAAA,IAAO,IAAA,IAAQ,IAAA,IAAQ,IAAA,IAAQ,EAAA,IAAM,IAAA,EAAM,OAAO,CAAA,EAAA,EAAK,GAAG,CAAA,EAAG,IAAI,CAAA,EAAG,EAAE,CAAA,CAAA;AAC1E,EAAA,MAAM,EAAA,GAAK,MAAM,cAAc,CAAA;AAC/B,EAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,EAAA,EAAI,OAAO,KAAK,EAAE,CAAA,CAAA;AAChD,EAAA,OAAO,CAAA,EAAA,EAAK,IAAA,CAAK,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,IAAA,CAAK,CAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA;AACjG;AAKA,IAAM,kBAAA,GAAiD;AAAA,EACtD,GAAA,EAAK,CAAC,KAAA,EAAO,KAAA,EAAO,MAAM,YAAY,CAAA;AAAA,EACtC,KAAA,EAAO,CAAC,OAAA,EAAS,KAAA,EAAO,MAAM,cAAc,CAAA;AAAA,EAC5C,IAAA,EAAM,CAAC,MAAA,EAAQ,KAAA,EAAO,MAAM,aAAa,CAAA;AAAA,EACzC,KAAK,CAAC,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,MAAM,KAAK,CAAA;AAAA,EACxC,KAAA,EAAO,CAAC,QAAA,EAAU,OAAA,EAAS,KAAK,CAAA;AAAA,EAChC,KAAA,EAAO,CAAC,QAAA,EAAU,OAAA,EAAS,KAAK,CAAA;AAAA,EAChC,OAAA,EAAS,CAAC,UAAA,EAAY,SAAA,EAAW,OAAO,IAAI;AAC7C,CAAA;AASO,SAAS,0BAA0B,IAAA,EAAyB;AAClE,EAAA,MAAM,MAAe,EAAC;AACtB,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAC/B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAClB,IAAA,MAAM,KAAA,GAAQ,MAAM,UAAU,CAAA;AAC9B,IAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,UAAU,CAAA,EAAG;AAC9C,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,CAAC,CAAA,EAAG,aAAa,WAAA,EAAY;AAClD,MAAA,IAAI,MAAA,IAAU,UAAA,CAAW,MAAM,CAAA,EAAG;AACjC,QAAA,IAAI,CAAC,GAAA,CAAI,MAAM,GAAG,GAAA,CAAI,MAAM,IAAI,KAAA,CAAM,IAAA;AACtC,QAAA;AAAA,MACD;AAAA,IACD;AACA,IAAA,KAAA,MAAW,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,kBAAkB,CAAA,EAAiB;AACjE,MAAA,IAAI,kBAAA,CAAmB,IAAI,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,IAAK,CAAC,GAAA,CAAI,IAAI,CAAA,EAAG;AACzD,QAAA,GAAA,CAAI,IAAI,IAAI,KAAA,CAAM,IAAA;AAClB,QAAA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACA,EAAA,OAAO,GAAA;AACR;AAEA,SAAS,WAAW,KAAA,EAAkC;AACrD,EAAA,OACC,KAAA,KAAU,KAAA,IACV,KAAA,KAAU,OAAA,IACV,KAAA,KAAU,MAAA,IACV,KAAA,KAAU,KAAA,IACV,KAAA,KAAU,OAAA,IACV,KAAA,KAAU,OAAA,IACV,KAAA,KAAU,SAAA;AAEZ;AAGO,SAAS,YAAY,GAAA,EAAuB;AAClD,EAAA,OAAO,QAAQ,GAAA,CAAI,GAAA,IAAO,GAAA,CAAI,KAAA,IAAS,IAAI,IAAI,CAAA;AAChD;AAkCO,SAAS,wBAAwB,IAAA,EAAmC;AAC1E,EAAA,MAAM,MAAyB,EAAC;AAChC,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAC/B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAClB,IAAA,MAAM,YAAY,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,GAAW,MAAM,IAAA,GAAO,MAAA;AAGhE,IAAA,IAAI,SAAA,IAAa,CAAC,2BAAA,CAA4B,IAAA,CAAK,SAAS,CAAA,EAAG;AAC/D,IAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,MAAM,KAAK,CAAA,GAAK,MAAM,KAAA,GAAqB,MAAA;AACvE,IAAA,IACC,KAAA,KACC,KAAA,CAAM,QAAA,CAAS,WAAW,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,CAAA,EACtF;AACD,MAAA;AAAA,IACD;AACA,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAC,CAAA,GAAI,KAAA,CAAM,UAAU,CAAA,GAAI,MAAA;AACvE,IAAA,MAAM,QAAA,GAAW,KAAA;AACjB,IAAA,MAAM,WAAA,GAAc,MAAM,OAAA,CAAQ,QAAA,CAAS,cAAc,CAAC,CAAA,GACtD,QAAA,CAAS,cAAc,CAAA,GACxB,MAAA;AACH,IAAA,MAAM,SAAA,GAAY,WAAA,EAAa,MAAA,IAAU,OAAA,EAAS,MAAA;AAClD,IAAA,IAAI,OAAO,SAAA,KAAc,QAAA,IAAY,SAAA,GAAY,CAAA,EAAG;AACpD,IAAA,MAAM,UAAA,GAAa,OAAA,GAAU,CAAC,CAAA,EAAG,aAAa,WAAA,EAAY;AAC1D,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MACR,GAAA;AAAA,MACA,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,UAAA;AAAA,MACA,SAAA,EAAW,OAAO,SAAA,KAAc,QAAA,GAAW,SAAA,GAAY,CAAA;AAAA,MACvD,KAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAO,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,GAAW,MAAM,KAAA,GAAQ;AAAA,KACvD,CAAA;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACR;AAaO,SAAS,uBAAA,CACf,QACA,IAAA,EACqB;AACrB,EAAA,MAAM,WAAW,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,eAAe,IAAI,CAAA;AACzD,EAAA,IAAI,QAAA,SAAiB,QAAA,CAAS,GAAA;AAC9B,EAAA,MAAM,SAAA,GAAY,kBAAA,CAAmB,IAAI,CAAA,IAAK,EAAC;AAC/C,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAA,CAAK,CAAC,MAAM,SAAA,CAAU,QAAA,CAAS,CAAA,CAAE,GAAG,CAAC,CAAA;AAC1D,EAAA,OAAO,KAAA,EAAO,GAAA;AACf;AAOO,SAAS,sBAAA,CACf,QACA,SAAA,EAC6C;AAC7C,EAAA,MAAM,CAAA,GAAI,uBAAA,CAAwB,MAAA,EAAQ,SAAA,CAAU,CAAC,CAAA;AACrD,EAAA,MAAM,CAAA,GAAI,uBAAA,CAAwB,MAAA,EAAQ,SAAA,CAAU,CAAC,CAAA;AACrD,EAAA,MAAM,CAAA,GAAI,uBAAA,CAAwB,MAAA,EAAQ,SAAA,CAAU,CAAC,CAAA;AACrD,EAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,IAAK,CAAC,GAAG,OAAO,IAAA;AAC3B,EAAA,OAAO,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAClB;AAGO,SAAS,qBAAqB,MAAA,EAAoC;AACxE,EAAA,OAAO,OAAO,MAAA,IAAU,CAAA;AACzB;AAUO,SAAS,oBAAoB,IAAA,EAAmC;AACtE,EAAA,MAAM,MAAyB,EAAC;AAChC,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAC/B,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAClB,IAAA,MAAM,YAAY,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,GAAW,MAAM,IAAA,GAAO,MAAA;AAChE,IAAA,IAAI,SAAA,IAAa,CAAC,2BAAA,CAA4B,IAAA,CAAK,SAAS,CAAA,EAAG;AAC/D,IAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,MAAM,KAAK,CAAA,GAAK,MAAM,KAAA,GAAqB,MAAA;AACvE,IAAA,IACC,KAAA,KACC,KAAA,CAAM,QAAA,CAAS,WAAW,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,CAAA,EACtF;AACD,MAAA;AAAA,IACD;AACA,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAC,CAAA,GAAI,KAAA,CAAM,UAAU,CAAA,GAAI,MAAA;AACvE,IAAA,MAAM,QAAA,GAAW,KAAA;AACjB,IAAA,MAAM,WAAA,GAAc,MAAM,OAAA,CAAQ,QAAA,CAAS,cAAc,CAAC,CAAA,GACtD,QAAA,CAAS,cAAc,CAAA,GACxB,MAAA;AACH,IAAA,MAAM,SAAA,GAAY,WAAA,EAAa,MAAA,IAAU,OAAA,EAAS,MAAA;AAClD,IAAA,MAAM,UAAA,GAAa,OAAA,GAAU,CAAC,CAAA,EAAG,aAAa,WAAA,EAAY;AAC1D,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MACR,GAAA;AAAA,MACA,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,UAAA;AAAA,MACA,SAAA,EAAW,OAAO,SAAA,KAAc,QAAA,GAAW,SAAA,GAAY,MAAA;AAAA,MACvD,KAAA;AAAA,MACA,SAAA;AAAA,MACA,OAAO,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,GAAW,MAAM,KAAA,GAAQ;AAAA,KACvD,CAAA;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACR;;;AChaO,IAAM,OAAA,GAAuB;AAAA,EACnC;AAAA,IACC,EAAA,EAAI,eAAA;AAAA,IACJ,QAAA,EAAU,8BAAA;AAAA,IACV,OAAO,EAAE,CAAA,EAAG,OAAO,CAAA,EAAG,OAAA,EAAS,GAAG,MAAA;AAAO,GAC1C;AAAA,EACA;AAAA,IACC,EAAA,EAAI,gBAAA;AAAA,IACJ,QAAA,EAAU,iCAAA;AAAA,IACV,OAAO,EAAE,CAAA,EAAG,OAAO,CAAA,EAAG,KAAA,EAAO,GAAG,OAAA;AAAQ,GACzC;AAAA,EACA;AAAA,IACC,EAAA,EAAI,MAAA;AAAA,IACJ,QAAA,EAAU,yBAAA;AAAA,IACV,OAAO,EAAE,CAAA,EAAG,SAAS,CAAA,EAAG,OAAA,EAAS,GAAG,KAAA;AAAM,GAC3C;AAAA,EACA;AAAA,IACC,EAAA,EAAI,YAAA;AAAA,IACJ,QAAA,EAAU,+BAAA;AAAA,IACV,OAAO,EAAE,CAAA,EAAG,OAAO,CAAA,EAAG,OAAA,EAAS,GAAG,KAAA;AAAM,GACzC;AAAA,EACA;AAAA,IACC,EAAA,EAAI,aAAA;AAAA,IACJ,QAAA,EAAU,gCAAA;AAAA,IACV,OAAO,EAAE,CAAA,EAAG,SAAS,CAAA,EAAG,KAAA,EAAO,GAAG,MAAA;AAAO;AAE3C;AAEA,SAAS,mBAAmB,MAAA,EAAuC;AAClE,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IACzB,KAAK,CAAA,CAAE,GAAA;AAAA,IACP,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,UAAA,EAAY,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA;AAAA,IACxB,WAAW,CAAA,CAAE,SAAA;AAAA,IACb,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,WAAW,CAAA,CAAE,SAAA;AAAA,IACb,OAAO,CAAA,CAAE;AAAA,GACV,CAAE,CAAA;AACH;AAGO,SAAS,iBAAiB,MAAA,EAAiC;AACjE,EAAA,MAAM,GAAA,GAAM,mBAAmB,MAAM,CAAA;AACrC,EAAA,OAAO,OAAA,CAAQ,OAAO,CAAC,CAAA,KAAM,uBAAuB,GAAA,EAAK,CAAA,CAAE,KAAK,CAAA,KAAM,IAAI,CAAA;AAC3E;AAGO,SAAS,WAAA,CAAY,QAAoB,MAAA,EAA4C;AAC3F,EAAA,MAAM,GAAA,GAAM,mBAAmB,MAAM,CAAA;AACrC,EAAA,MAAM,CAAA,GAAI,sBAAA,CAAuB,GAAA,EAAK,MAAA,CAAO,KAAK,CAAA;AAClD,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,OAAO;AAAA,IACN,GAAG,EAAE,QAAA,EAAU,CAAA,CAAE,CAAA,EAAG,WAAW,CAAA,EAAE;AAAA,IACjC,GAAG,EAAE,QAAA,EAAU,CAAA,CAAE,CAAA,EAAG,WAAW,CAAA,EAAE;AAAA,IACjC,GAAG,EAAE,QAAA,EAAU,CAAA,CAAE,CAAA,EAAG,WAAW,CAAA;AAAE,GAClC;AACD;AAGO,SAAS,sBAAA,CACf,MAAA,EACA,CAAA,EACA,MAAA,EACU;AACV,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,MAAA,EAAQ,MAAM,CAAA;AAC3C,EAAA,IAAI,CAAC,UAAU,OAAO,KAAA;AACtB,EAAA,OACC,QAAA,CAAS,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,CAAA,CAAE,QAAA,IAC5B,QAAA,CAAS,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,CAAA,CAAE,QAAA,IAC5B,QAAA,CAAS,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,CAAA,CAAE,QAAA,IAC5B,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA,IAClB,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA,IAClB,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA;AAEpB;AAWO,SAAS,gBAAA,CACf,QACA,MAAA,EAC0B;AAC1B,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AACxB,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AACxB,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AACxB,EAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,IAAK,CAAC,GAAG,OAAO,IAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAACC,EAAAA,KAAM,CAACA,EAAAA,CAAE,GAAA,EAAKA,EAAC,CAAC,CAAC,CAAA;AACnD,EAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA;AACtB,EAAA,IAAI,CAAC,EAAA,IAAM,CAAC,EAAA,IAAM,CAAC,IAAI,OAAO,IAAA;AAC9B,EAAA,MAAM,GAAA,GAAwB;AAAA,IAC7B,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,QAAQ,CAAA,EAAG,EAAA,CAAG,SAAS,CAAA,EAAE;AAAA,IAC3E,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,QAAQ,CAAA,EAAG,EAAA,CAAG,SAAS,CAAA,EAAE;AAAA,IAC3E,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,QAAQ,CAAA,EAAG,EAAA,CAAG,SAAS,CAAA;AAAE,GAC5E;AACA,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AACxB,EAAA,IAAI,CAAA,EAAG;AACN,IAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA;AACtB,IAAA,IAAI,EAAA,EAAI,GAAA,CAAI,CAAA,GAAI,EAAE,UAAU,CAAA,EAAG,SAAA,EAAW,SAAA,CAAU,MAAA,CAAO,GAAA,CAAI,QAAQ,CAAA,EAAG,EAAA,CAAG,SAAS,CAAA,EAAE;AAAA,EACzF;AACA,EAAA,OAAO,GAAA;AACR;AAGO,SAAS,cAAA,CAAe,GAAqB,QAAA,EAA0C;AAC7F,EAAA,MAAM,CAAA,GAAI,IAAI,eAAA,EAAgB;AAC9B,EAAA,CAAA,CAAE,GAAA,CAAI,GAAA,EAAK,CAAA,CAAE,CAAA,CAAE,QAAQ,CAAA;AACvB,EAAA,CAAA,CAAE,GAAA,CAAI,GAAA,EAAK,CAAA,CAAE,CAAA,CAAE,QAAQ,CAAA;AACvB,EAAA,CAAA,CAAE,GAAA,CAAI,GAAA,EAAK,CAAA,CAAE,CAAA,CAAE,QAAQ,CAAA;AACvB,EAAA,IAAI,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA,EAAG,CAAA,CAAE,GAAA,CAAI,QAAA,EAAU,MAAA,CAAO,CAAA,CAAE,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9D,EAAA,IAAI,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA,EAAG,CAAA,CAAE,GAAA,CAAI,QAAA,EAAU,MAAA,CAAO,CAAA,CAAE,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9D,EAAA,IAAI,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA,EAAG,CAAA,CAAE,GAAA,CAAI,QAAA,EAAU,MAAA,CAAO,CAAA,CAAE,CAAA,CAAE,SAAS,CAAC,CAAA;AAC9D,EAAA,IAAI,EAAE,CAAA,EAAG;AACR,IAAA,CAAA,CAAE,GAAA,CAAI,GAAA,EAAK,CAAA,CAAE,CAAA,CAAE,QAAQ,CAAA;AACvB,IAAA,IAAI,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA,EAAG,CAAA,CAAE,GAAA,CAAI,QAAA,EAAU,MAAA,CAAO,CAAA,CAAE,CAAA,CAAE,SAAS,CAAC,CAAA;AAAA,EAC/D;AACA,EAAA,IAAI,QAAA,EAAU,CAAA,CAAE,GAAA,CAAI,QAAA,EAAU,QAAQ,CAAA;AACtC,EAAA,OAAO,CAAA;AACR;AAEA,SAAS,SAAA,CAAU,KAAoB,SAAA,EAA2B;AACjE,EAAA,IAAI,CAAC,KAAK,OAAO,CAAA;AACjB,EAAA,MAAM,CAAA,GAAI,OAAO,GAAG,CAAA;AACpB,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,GAAG,OAAO,CAAA;AAChC,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACtB,EAAA,IAAI,CAAA,GAAI,GAAG,OAAO,CAAA;AAClB,EAAA,IAAI,KAAK,SAAA,EAAW,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,YAAY,CAAC,CAAA;AACpD,EAAA,OAAO,CAAA;AACR;;;ACpJA,eAAsB,eAAA,CACrB,MACA,UAAA,EACmB;AACnB,EAAA,IAAI;AACH,IAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AACxC,IAAA,UAAA,GAAa,IAAI,CAAA;AACjB,IAAA,UAAA,CAAW,MAAM,UAAA,GAAa,KAAK,CAAA,EAAG,gBAAgB,CAAA;AACtD,IAAA,OAAO,IAAA;AAAA,EACR,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,KAAA;AAAA,EACR;AACD;AAOO,SAAS,mBAAA,CAAoB,MAAe,QAAA,EAAwB;AAC1E,EAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,gBAAA,CAAiB,QAAQ,CAAA,EAAG;AAClD,IAAA,GAAA,CAAI,gBAAA,CAAiB,SAAS,YAAY;AACzC,MAAA,MAAM,IAAA,GAAO,kBAAA,CAAoB,GAAA,CAAoB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACvE,MAAA,IAAI;AACH,QAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AACxC,QAAA,GAAA,CAAI,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC1B,QAAA,UAAA,CAAW,MAAM,GAAA,CAAI,SAAA,CAAU,MAAA,CAAO,QAAQ,GAAG,gBAAgB,CAAA;AAAA,MAClE,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACD,CAAC,CAAA;AAAA,EACF;AACD;;;AC1BA,IAAM,aAAA,GACL,wGAAA;AAOM,SAAS,gBAAgB,QAAA,EAA0B;AACzD,EAAA,MAAM,GAAA,GAAM,UAAU,QAAsB,CAAA;AAC5C,EAAA,IAAI,KAAK,OAAA,CAAQ,MAAA,EAAQ,OAAO,GAAA,CAAI,QAAQ,CAAC,CAAA;AAC7C,EAAA,OAAO,IAAA;AACR;AAMO,SAAS,uBAAuB,CAAA,EAAmB;AACzD,EAAA,IAAI;AACH,IAAA,OAAO,mBAAmB,CAAC,CAAA;AAAA,EAC5B,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,CAAA;AAAA,EACR;AACD;AAWO,SAAS,gBAAgB,GAAA,EAAqB;AAEpD,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,KAAA,CAAM,kCAAkC,CAAA;AAC5D,EAAA,IAAI,OAAA,EAAS;AACZ,IAAA,MAAM,GAAG,MAAA,EAAQ,GAAG,CAAA,GAAI,OAAA;AAExB,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,CAAM,aAAa,CAAA;AAC9C,IAAA,MAAM,MAAA,GAAS,WAAA,GAAc,WAAA,CAAY,CAAC,CAAA,GAAI,WAAA;AAC9C,IAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,IAAA,EAAM,EAAA,EAAI,QAAQ,MAAM,CAAA;AAC1D,IAAA,OAAO,GAAA,GAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,IAAA;AAAA,EACjC;AAGA,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,KAAA,CAAM,+BAA+B,CAAA;AAC1D,EAAA,IAAI,QAAA,EAAU;AACb,IAAA,MAAM,GAAG,MAAA,EAAQ,GAAG,CAAA,GAAI,QAAA;AACxB,IAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAE,CAAA;AACvD,IAAA,OAAO,GAAA,GAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,IAAA;AAAA,EACjC;AAEA,EAAA,OAAO,GAAA;AACR;;;ACpBA,IAAM,UAAA,GAAa,2BAAA;AACnB,IAAM,iCAAiB,IAAI,GAAA,CAAI,CAAC,WAAA,EAAa,UAAA,EAAY,UAAU,CAAC,CAAA;AAkB7D,SAAS,iBAAiB,IAAA,EAA4B;AAC5D,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAC/B,EAAA,MAAM,KAAA,GAAS,IAAA,CAAK,UAAA,IAAc,EAAC;AACnC,EAAA,MAAM,YAAY,KAAA,CAAM,OAAA,CAAQ,MAAM,KAAK,CAAA,GACvC,MAAM,KAAA,GACP,MAAA;AACH,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAClB,IAAA,MAAM,YAAY,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,GAAW,MAAM,IAAA,GAAO,MAAA;AAChE,IAAA,IAAI,SAAA,IAAa,CAAC,UAAA,CAAW,IAAA,CAAK,SAAS,CAAA,EAAG;AAC9C,IAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,GAAK,KAAA,CAAM,QAAqB,EAAC;AACxE,IAAA,IAAI,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,eAAe,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG;AAC9C,IAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAC,CAAA,GAAI,KAAA,CAAM,UAAU,CAAA,GAAI,MAAA;AACvE,IAAA,MAAM,QAAA,GAAW,KAAA;AACjB,IAAA,MAAM,WAAA,GAAc,MAAM,OAAA,CAAQ,QAAA,CAAS,cAAc,CAAC,CAAA,GACtD,QAAA,CAAS,cAAc,CAAA,GACxB,MAAA;AACH,IAAA,MAAM,eAAe,KAAA,CAAM,OAAA,CAAQ,SAAS,KAAK,CAAA,GAC7C,SAAS,KAAA,GACV,MAAA;AAKH,IAAA,MAAM,YACL,YAAA,EAAc,MAAA,IAAU,aAAa,MAAA,IAAU,OAAA,EAAS,UAAU,SAAA,EAAW,MAAA;AAC9E,IAAA,MAAM,cAAA,GAAiB,OAAO,SAAA,KAAc,QAAA,IAAY,SAAA,GAAY,CAAA;AAMpE,IAAA,MAAM,YAAA,GAAe,WAAW,YAAA,IAAgB,SAAA;AAChD,IAAA,MAAM,QAAA,GAAW,YAAA,GACd,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA,KAAM;AACxB,MAAA,MAAM,IAAK,CAAA,EAA+B,WAAA;AAC1C,MAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,CAAE,aAAY,GAAI,EAAA;AAAA,IAClD,CAAC,IACA,EAAC;AACJ,IAAA,MAAM,WAAA,GAAc,eAAe,YAAA,IAAgB,SAAA;AACnD,IAAA,MAAM,KAAA,GAAS,WAAA,GAAc,CAAC,CAAA,EAA2C,SAAA;AACzE,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MACR,GAAA;AAAA,MACA,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,SAAA,EAAW,iBAAkB,SAAA,GAAuB,CAAA;AAAA,MACpD,cAAA;AAAA,MACA,KAAA,EAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,MAAA;AAAA,MAC3C,QAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAO,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,GAAW,MAAM,KAAA,GAAQ,MAAA;AAAA,MACvD;AAAA,KACA,CAAA;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACR;AAOO,SAAS,kBAAA,CAAmB,MAAc,eAAA,EAAoC;AACpF,EAAA,MAAM,KAAA,GAAQ,OAAO,eAAA,KAAoB,QAAA,IAAY,eAAA,GAAkB,CAAA;AACvE,EAAA,OAAO;AAAA,IACN,GAAA,EAAK,MAAA;AAAA,IACL,IAAA;AAAA,IACA,SAAA,EAAW,QAAQ,eAAA,GAAkB,CAAA;AAAA,IACrC,cAAA,EAAgB,KAAA;AAAA,IAChB,UAAU,EAAC;AAAA,IACX,OAAO;AAAC,GACT;AACD;AAeO,SAAS,0BACf,MAAA,EAC4F;AAC5F,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAGhC,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACvB,IAAA,IAAI,CAAA,CAAE,SAAA,KAAc,CAAA,KAAM,CAAA,CAAE,KAAA,CAAM,QAAA,CAAS,QAAQ,CAAA,IAAK,gBAAA,CAAiB,CAAA,CAAE,QAAQ,CAAA,CAAA,EAAI;AACtF,MAAA,OAAO;AAAA,QACN,SAAA,EAAW;AAAA,UACV,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,CAAE,GAAA,EAAK,SAAA,EAAW,aAAA,CAAc,CAAA,CAAE,QAAA,EAAU,KAAA,EAAO,CAAC,CAAA,EAAE;AAAA,UACrE,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,CAAE,GAAA,EAAK,SAAA,EAAW,aAAA,CAAc,CAAA,CAAE,QAAA,EAAU,OAAA,EAAS,CAAC,CAAA,EAAE;AAAA,UACvE,CAAA,EAAG,EAAE,QAAA,EAAU,CAAA,CAAE,GAAA,EAAK,SAAA,EAAW,aAAA,CAAc,CAAA,CAAE,QAAA,EAAU,MAAA,EAAQ,CAAC,CAAA;AAAE,SACvE;AAAA,QACA,MAAA,EAAQ;AAAA,OACT;AAAA,IACD;AAAA,EACD;AAGA,EAAA,MAAM,GAAA,GAAM,OAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,KAAM,KAAK,CAAA;AACtD,EAAA,MAAM,KAAA,GAAQ,OAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,KAAM,OAAO,CAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,OAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,CAAC,CAAA,KAAM,MAAM,CAAA;AACxD,EAAA,IAAI,GAAA,IAAO,SAAS,IAAA,EAAM;AACzB,IAAA,OAAO;AAAA,MACN,SAAA,EAAW;AAAA,QACV,GAAG,EAAE,QAAA,EAAU,GAAA,CAAI,GAAA,EAAK,WAAW,CAAA,EAAE;AAAA,QACrC,GAAG,EAAE,QAAA,EAAU,KAAA,CAAM,GAAA,EAAK,WAAW,CAAA,EAAE;AAAA,QACvC,GAAG,EAAE,QAAA,EAAU,IAAA,CAAK,GAAA,EAAK,WAAW,CAAA;AAAE,OACvC;AAAA,MACA,MAAA,EAAQ;AAAA,KACT;AAAA,EACD;AAGA,EAAA,IAAI,MAAA,CAAO,UAAU,CAAA,EAAG;AACvB,IAAA,OAAO;AAAA,MACN,SAAA,EAAW;AAAA,QACV,CAAA,EAAG,EAAE,QAAA,EAAU,MAAA,CAAO,CAAC,CAAA,CAAE,GAAA,EAAK,WAAW,CAAA,EAAE;AAAA,QAC3C,CAAA,EAAG,EAAE,QAAA,EAAU,MAAA,CAAO,CAAC,CAAA,CAAE,GAAA,EAAK,WAAW,CAAA,EAAE;AAAA,QAC3C,CAAA,EAAG,EAAE,QAAA,EAAU,MAAA,CAAO,CAAC,CAAA,CAAE,GAAA,EAAK,WAAW,CAAA;AAAE,OAC5C;AAAA,MACA,MAAA,EAAQ;AAAA,KACT;AAAA,EACD;AAGA,EAAA,MAAM,IAAA,GAAO,OAAO,CAAC,CAAA;AACrB,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3C,EAAA,OAAO;AAAA,IACN,SAAA,EAAW;AAAA,MACV,GAAG,EAAE,QAAA,EAAU,IAAA,CAAK,GAAA,EAAK,WAAW,CAAA,EAAE;AAAA,MACtC,CAAA,EAAG,EAAE,QAAA,EAAU,IAAA,CAAK,GAAA,EAAK,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,EAAE;AAAA,MACtD,CAAA,EAAG,EAAE,QAAA,EAAU,IAAA,CAAK,GAAA,EAAK,WAAW,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA;AAAE,KACvD;AAAA,IACA,MAAA,EAAQ;AAAA,GACT;AACD;AAEA,SAAS,iBAAiB,EAAA,EAAuB;AAChD,EAAA,OAAO,EAAA,CAAG,QAAA,CAAS,KAAK,CAAA,IAAK,EAAA,CAAG,SAAS,OAAO,CAAA,IAAK,EAAA,CAAG,QAAA,CAAS,MAAM,CAAA;AACxE;AAEA,SAAS,aAAA,CAAc,EAAA,EAAc,IAAA,EAAc,QAAA,EAA0B;AAC5E,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,OAAA,CAAQ,IAAI,CAAA;AACzB,EAAA,OAAO,CAAA,IAAK,IAAI,CAAA,GAAI,QAAA;AACrB;AAGO,SAAS,uBAAuB,CAAA,EAA8B;AACpE,EAAA,OAAO,CAAA,CAAE,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,CAAA,CAAE,YAAY,CAAA,CAAE,CAAA,CAAE,QAAA,KAAa,CAAA,CAAE,CAAA,CAAE,QAAA;AAC9D;AAGO,SAAS,iBAAiB,CAAA,EAA8B;AAC9D,EAAA,OAAO,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA,IAAK,CAAA,CAAE,EAAE,SAAA,KAAc,CAAA,IAAK,CAAA,CAAE,CAAA,CAAE,SAAA,KAAc,CAAA;AACxE;;;AChOO,IAAM,SAAA,GAAoC;AAAA,EAChD,CAAA,EAAG,MAAA;AAAA,EACH,CAAA,EAAG,KAAA;AAAA,EACH,CAAA,EAAG,OAAA;AAAA,EACH,CAAA,EAAG,MAAA;AAAA,EACH,CAAA,EAAG,aAAA;AAAA,EACH,CAAA,EAAG;AACJ;AAmBO,SAAS,SAAA,CAAU,CAAA,EAAW,EAAA,EAAY,EAAA,EAAY,QAAA,EAA0B;AACtF,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,CAAC,CAAC,CAAA,GAAI,QAAA;AAC7D;AAGO,SAAS,YAAY,CAAA,EAAyB;AACpD,EAAA,OAAO;AAAA,IACN,MAAM,SAAA,CAAU,CAAA,CAAE,IAAA,EAAM,IAAA,EAAM,KAAK,IAAI,CAAA;AAAA,IACvC,OAAO,SAAA,CAAU,CAAA,CAAE,KAAA,EAAO,UAAA,EAAY,WAAW,UAAU,CAAA;AAAA,IAC3D,MAAM,SAAA,CAAU,CAAA,CAAE,IAAA,EAAM,IAAA,EAAM,KAAK,GAAG,CAAA;AAAA,IACtC,OAAO,SAAA,CAAU,CAAA,CAAE,KAAA,EAAO,UAAA,EAAY,WAAW,SAAS;AAAA,GAC3D;AACD;AAMO,SAAS,kBAAA,CAAmB,cAAsB,aAAA,EAA+B;AACvF,EAAA,OAAO,CAAA,EAAG,UAAU,YAAY,CAAA,IAAK,KAAK,YAAY,CAAA,CAAE,CAAA,EAAG,aAAA,IAAiB,EAAE,CAAA,CAAA;AAC/E;;;AC5CA,IAAM,YAAA,GAAe;AAAA,EACpB,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA;AACD,CAAA;AAEA,IAAM,YAAA,GAAe,CAAC,SAAA,EAAW,MAAA,EAAQ,UAAU,MAAA,EAAQ,QAAA,EAAU,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AAE3F,IAAM,UAAA,GAAa;AAAA,EAClB,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,0BAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA;AACD,CAAA;AAEA,IAAM,aAAA,GAAgB,CAAC,SAAA,EAAW,MAAA,EAAQ,SAAS,CAAA;AAEnD,IAAM,SAAA,GAAY;AAAA,EACjB,UAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACD,CAAA;AAEA,IAAM,YAAA,GAAe,CAAC,MAAA,EAAQ,OAAA,EAAS,UAAU,WAAW,CAAA;AAE5D,IAAM,UAAA,GAAa,CAAC,MAAA,EAAQ,OAAO,CAAA;AAE5B,SAAS,aAAa,UAAA,EAAkC;AAC9D,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,WAAA,EAAY,CAAE,IAAA,EAAK;AAK5C,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AACjC,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,WAAA,CAAY,GAAG,CAAA;AACtC,EAAA,MAAM,QACL,OAAA,IAAW,CAAA,IAAK,QAAA,GAAW,OAAA,GAAU,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,GAAI,MAAM,KAAA,CAAM,QAAA,GAAW,CAAC,CAAA,GAAI,OAC1F,IAAA,EAAK;AAEP,EAAA,IAAI,YAAA,CAAa,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,QAAA;AACxC,EAAA,IAAI,YAAA,CAAa,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,QAAA;AACxC,EAAA,IAAI,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,MAAA;AACtC,EAAA,IAAI,aAAA,CAAc,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,SAAA;AACzC,EAAA,IAAI,SAAA,CAAU,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,KAAA;AACrC,EAAA,IAAI,YAAA,CAAa,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,QAAA;AACxC,EAAA,IAAI,UAAA,CAAW,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,MAAA;AAGtC,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,QAAQ,CAAA,IAAK,IAAA,CAAK,WAAW,KAAK,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA;AACjF,IAAA,OAAO,MAAA;AACR,EAAA,IAAI,IAAA,CAAK,SAAS,IAAI,CAAA,IAAK,KAAK,UAAA,CAAW,MAAM,GAAG,OAAO,MAAA;AAG3D,EAAA,IACC,MAAM,QAAA,CAAS,KAAK,KACpB,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,IACtB,KAAA,CAAM,QAAA,CAAS,QAAQ,KACvB,KAAA,CAAM,QAAA,CAAS,SAAS,CAAA,IACxB,KAAA,CAAM,SAAS,SAAS,CAAA;AAExB,IAAA,OAAO,QAAA;AACR,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,QAAQ,CAAA,EAAG,OAAO,QAAA;AACzF,EAAA,IAAI,KAAA,CAAM,SAAS,MAAM,CAAA,IAAK,MAAM,QAAA,CAAS,MAAM,GAAG,OAAO,MAAA;AAC7D,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,EAAG,OAAO,SAAA;AACnC,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,KAAA;AACzF,EAAA,IAAI,KAAA,CAAM,SAAS,MAAM,CAAA,IAAK,MAAM,QAAA,CAAS,QAAQ,GAAG,OAAO,QAAA;AAC/D,EAAA,IACC,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,IACrB,MAAM,QAAA,CAAS,QAAQ,CAAA,IACvB,KAAA,CAAM,QAAA,CAAS,KAAK,CAAA,IACpB,KAAA,CAAM,SAAS,MAAM,CAAA;AAErB,IAAA,OAAO,MAAA;AAER,EAAA,OAAO,OAAA;AACR;AAEA,IAAM,WAAA,GAA4C;AAAA,EACjD,MAAA,EAAQ,eAAA;AAAA,EACR,MAAA,EAAQ,gBAAA;AAAA,EACR,IAAA,EAAM,gBAAA;AAAA,EACN,OAAA,EAAS,iBAAA;AAAA,EACT,GAAA,EAAK,eAAA;AAAA,EACL,MAAA,EAAQ,eAAA;AAAA,EACR,IAAA,EAAM,iBAAA;AAAA,EACN,KAAA,EAAO;AACR,CAAA;AAEA,IAAM,kBAAA,GAAmD;AAAA,EACxD,MAAA,EAAQ,oEAAA;AAAA,EACR,MAAA,EAAQ,wEAAA;AAAA,EACR,IAAA,EAAM,wEAAA;AAAA,EACN,OAAA,EAAS,4EAAA;AAAA,EACT,GAAA,EAAK,oEAAA;AAAA,EACL,MAAA,EAAQ,oEAAA;AAAA,EACR,IAAA,EAAM,4EAAA;AAAA,EACN,KAAA,EAAO;AACR,CAAA;AAEA,IAAM,WAAA,GAA4C;AAAA,EACjD,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQ,IAAA;AAAA,EACR,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,EAAS,KAAA;AAAA,EACT,GAAA,EAAK,KAAA;AAAA,EACL,MAAA,EAAQ,IAAA;AAAA,EACR,IAAA,EAAM,IAAA;AAAA,EACN,KAAA,EAAO;AACR,CAAA;AAEO,SAAS,UAAU,QAAA,EAAgC;AACzD,EAAA,OAAO,YAAY,QAAQ,CAAA;AAC5B;AAEO,SAAS,eAAe,QAAA,EAAgC;AAC9D,EAAA,OAAO,mBAAmB,QAAQ,CAAA;AACnC;AAEO,SAAS,UAAU,QAAA,EAAgC;AACzD,EAAA,OAAO,YAAY,QAAQ,CAAA;AAC5B;;;AC5HA,IAAM,aAAA,GAAwC;AAAA,EAC7C,QAAA,EAAU,KAAA;AAAA,EACV,OAAA,EAAS;AACV,CAAA;AAEA,IAAM,KAAA,GAAQ,EAAA;AAGd,SAAS,qBAAqB,CAAA,EAAmB;AAChD,EAAA,IAAI,MAAM,CAAA,CAAE,MAAA;AACZ,EAAA,OAAO,MAAM,CAAA,IAAK,CAAA,CAAE,WAAW,GAAA,GAAM,CAAC,MAAM,KAAA,EAAO,GAAA,EAAA;AACnD,EAAA,OAAO,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AACtB;AAGA,SAAS,iBAAiB,CAAA,EAAmB;AAC5C,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,MAAM,CAAA,CAAE,MAAA;AACZ,EAAA,OAAO,QAAQ,GAAA,IAAO,CAAA,CAAE,UAAA,CAAW,KAAK,MAAM,KAAA,EAAO,KAAA,EAAA;AACrD,EAAA,OAAO,MAAM,KAAA,IAAS,CAAA,CAAE,WAAW,GAAA,GAAM,CAAC,MAAM,KAAA,EAAO,GAAA,EAAA;AACvD,EAAA,OAAO,CAAA,CAAE,KAAA,CAAM,KAAA,EAAO,GAAG,CAAA;AAC1B;AAQO,SAAS,kBAAkB,GAAA,EAAwC;AACzE,EAAA,IAAI,CAAC,KAAK,OAAO,EAAA;AACjB,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,EAAA,IAAI,CAAC,SAAS,OAAO,EAAA;AACrB,EAAA,IAAI;AACH,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAO,CAAA;AAC3B,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,QAAA,CAAS,WAAA,EAAY;AACxC,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,QAAA,CAAS,WAAA,EAAY;AACtC,IAAA,MAAM,WAAA,GAAc,aAAA,CAAc,MAAM,CAAA,IAAK,EAAA;AAC7C,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,IAAQ,GAAA,CAAI,SAAS,WAAA,GAAc,CAAA,CAAA,EAAI,GAAA,CAAI,IAAI,CAAA,CAAA,GAAK,EAAA;AACrE,IAAA,MAAM,IAAA,GAAO,oBAAA,CAAqB,GAAA,CAAI,QAAQ,CAAA;AAC9C,IAAA,OAAO,GAAG,MAAM,CAAA,EAAA,EAAK,IAAI,CAAA,EAAG,IAAI,GAAG,IAAI,CAAA,CAAA;AAAA,EACxC,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,oBAAA,CAAqB,OAAA,CAAQ,WAAA,EAAa,CAAA;AAAA,EAClD;AACD;AAGO,SAAS,kBAAkB,QAAA,EAAiD;AAClF,EAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,IAAA,EAAK,CAAE,WAAA,EAAY;AACtC,EAAA,IAAI,CAAC,CAAA,IAAK,CAAA,KAAM,SAAA,EAAW,OAAO,IAAA;AAClC,EAAA,OAAO,CAAA;AACR;AAGA,SAAS,gBAAgB,MAAA,EAA2C;AACnE,EAAA,OAAO,gBAAA,CAAA,CAAkB,MAAA,IAAU,EAAA,EAAI,IAAA,EAAM,CAAA;AAC9C;AAEA,SAAS,gBAAgB,MAAA,EAA2C;AACnE,EAAA,OAAA,CAAQ,MAAA,IAAU,EAAA,EAAI,IAAA,EAAK,CAAE,WAAA,EAAY;AAC1C;AAOO,SAAS,sBAAsB,KAAA,EAAwC;AAC7E,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,KAAA,CAAM,QAAQ,CAAA;AACjD,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,KAAA,CAAM,MAAM,CAAA;AAC3C,EAAA,IAAI,CAAC,QAAQ,OAAO,EAAA;AAEpB,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,KAAA,CAAM,QAAQ,CAAA;AACjD,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,KAAA,CAAM,MAAM,CAAA;AAE3C,EAAA,IAAI,aAAa,OAAA,EAAS,OAAO,CAAA,MAAA,EAAS,QAAQ,IAAI,MAAM,CAAA,CAAA;AAC5D,EAAA,IAAI,QAAA,KAAa,KAAA,EAAO,OAAO,CAAA,IAAA,EAAO,MAAM,CAAA,CAAA;AAC5C,EAAA,IAAI,QAAA,KAAa,QAAQ,CAAC,QAAA,SAAiB,CAAA,GAAA,EAAM,MAAM,IAAI,MAAM,CAAA,CAAA;AACjE,EAAA,OAAO,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,QAAQ,IAAI,MAAM,CAAA,CAAA;AACzC;AAGO,SAAS,wBAAA,CACf,GACA,CAAA,EACU;AACV,EAAA,MAAM,GAAA,GAAM,sBAAsB,CAAC,CAAA;AACnC,EAAA,OAAO,GAAA,KAAQ,EAAA,IAAM,GAAA,KAAQ,qBAAA,CAAsB,CAAC,CAAA;AACrD;;;ACnHO,SAAS,aAAa,GAAA,EAAuB;AACnD,EAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AACjB,EAAA,IAAI,GAAA,YAAe,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,cAAc,OAAO,IAAA;AACrE,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,IAAI,CAAA,CAAE,IAAA,KAAS,YAAA,EAAc,OAAO,IAAA;AACpC,EAAA,IAAI,OAAO,EAAE,OAAA,KAAY,QAAA,IAAY,gBAAgB,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA,EAAG,OAAO,IAAA;AAC7E,EAAA,IAAI,EAAE,KAAA,IAAS,YAAA,CAAa,CAAA,CAAE,KAAK,GAAG,OAAO,IAAA;AAC7C,EAAA,OAAO,KAAA;AACR;AAMO,SAAS,gBAAgB,GAAA,EAA6B;AAC5D,EAAA,IAAI,YAAA,CAAa,GAAG,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,OAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AACvD;;;ACzBO,SAAS,eAAe,KAAA,EAAuB;AACrD,EAAA,IAAI,KAAA,GAAQ,GAAG,OAAO,KAAA;AACtB,EAAA,IAAI,KAAA,KAAU,GAAG,OAAO,KAAA;AAExB,EAAA,MAAM,QAAQ,CAAC,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA;AAC1C,EAAA,MAAM,IAAA,GAAO,IAAA;AACb,EAAA,MAAM,WAAW,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,KAAK,GAAA,CAAI,KAAK,CAAA,GAAI,IAAA,CAAK,IAAI,IAAI,CAAC,CAAA,EAAG,KAAA,CAAM,SAAS,CAAC,CAAA;AACxF,EAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,IAAQ,QAAA;AAG9B,EAAA,IAAI,QAAA,KAAa,CAAA,EAAG,OAAO,CAAA,EAAG,KAAK,CAAA,EAAA,CAAA;AACnC,EAAA,OAAO,CAAA,EAAG,MAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,QAAQ,CAAC,CAAA,CAAA;AAC9C;AAMO,SAAS,WAAW,SAAA,EAA2B;AACrD,EAAA,IAAI,CAAC,aAAa,SAAA,IAAa,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,EAAG,OAAO,IAAA;AAExE,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,SAAS,CAAA;AAC/B,EAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,EAAA,MAAM,SAAS,GAAA,GAAM,SAAA;AACrB,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,GAAI,CAAA;AAC5C,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,WAAA,GAAc,EAAE,CAAA;AAC/C,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,WAAA,GAAc,EAAE,CAAA;AAC7C,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,SAAA,GAAY,EAAE,CAAA;AAE1C,EAAA,IAAI,WAAA,GAAc,IAAI,OAAO,UAAA;AAC7B,EAAA,IAAI,WAAA,GAAc,EAAA,EAAI,OAAO,CAAA,EAAG,WAAW,CAAA,KAAA,CAAA;AAC3C,EAAA,IAAI,SAAA,GAAY,EAAA,EAAI,OAAO,CAAA,EAAG,SAAS,CAAA,KAAA,CAAA;AACvC,EAAA,IAAI,QAAA,GAAW,CAAA,EAAG,OAAO,CAAA,EAAG,QAAQ,CAAA,KAAA,CAAA;AAGpC,EAAA,OAAO,IAAA,CAAK,mBAAmB,MAAA,EAAW;AAAA,IACzC,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,GAAA,EAAK;AAAA,GACL,CAAA;AACF;AAMO,SAAS,iBAAiB,QAAA,EAA0B;AAC1D,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AACxC,EAAA,IAAI,OAAA,IAAW,GAAG,OAAO,EAAA;AACzB,EAAA,OAAO,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA,CAAE,WAAA,EAAY;AAC5C;AAMO,SAAS,kBAAA,CAAmB,MAAc,KAAA,EAAyB;AACzE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,CAAM,UAAS,GAAI,KAAA;AACvD;AAMO,SAAS,YAAY,KAAA,EAAwB;AACnD,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,MAAA;AAClD,EAAA,IAAI,KAAA,YAAiB,IAAA,EAAM,OAAO,KAAA,CAAM,WAAA,EAAY;AACpD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,MAAM,QAAA,EAAS;AACrD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,SAAiB,IAAA,CAAK,SAAA,CAAU,OAAO,kBAAkB,CAAA;AAC9E,EAAA,OAAO,OAAO,KAAK,CAAA;AACpB;;;ACvEA,SAAS,eAAA,CAAgB,OAAA,EAAiB,QAAA,EAAkB,QAAA,EAAkB;AAC7E,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,CAAC,OAAO,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA;AACnD,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACpC,EAAA,CAAA,CAAE,IAAA,GAAO,GAAA;AACT,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AACb,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3B,EAAA,CAAA,CAAE,KAAA,EAAM;AACR,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,CAAC,CAAA;AAC3B,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACxB;AAGA,SAAS,gBAAgB,KAAA,EAAwB;AAChD,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,EAAA;AAClD,EAAA,IAAI,KAAA,YAAiB,IAAA,EAAM,OAAO,KAAA,CAAM,WAAA,EAAY;AACpD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,MAAM,QAAA,EAAS;AACrD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,SAAiB,IAAA,CAAK,SAAA,CAAU,OAAO,kBAAkB,CAAA;AAC9E,EAAA,OAAO,OAAO,KAAK,CAAA;AACpB;AAKO,SAAS,eAAe,KAAA,EAAuB;AACrD,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,IAAK,MAAM,QAAA,CAAS,GAAG,CAAA,IAAK,KAAA,CAAM,SAAS,IAAI,CAAA,IAAK,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG;AAC/F,IAAA,OAAO,CAAA,CAAA,EAAI,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAM,IAAI,CAAC,CAAA,CAAA,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,KAAA;AACR;AAMO,SAAS,cAAA,CAAe,SAAmB,IAAA,EAAyC;AAC1F,EAAA,MAAM,SAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,CAAE,KAAK,GAAG,CAAA;AACnD,EAAA,MAAM,IAAA,GAAO,KACX,GAAA,CAAI,CAAC,QAAQ,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,KAAQ,cAAA,CAAe,eAAA,CAAgB,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA,CAAE,KAAK,GAAG,CAAC,CAAA,CACtF,IAAA,CAAK,IAAI,CAAA;AACX,EAAA,OAAO,GAAG,MAAM;AAAA,EAAK,IAAI,CAAA,CAAA;AAC1B;AAMO,SAAS,eAAA,CAAgB,SAAmB,IAAA,EAAyC;AAC3F,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC9B,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AAC1B,MAAA,MAAM,GAAA,GAAM,IAAI,GAAG,CAAA;AACnB,MAAA,IAAI,eAAe,IAAA,EAAM;AACxB,QAAA,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA,CAAI,WAAA,EAAY;AAAA,MAC5B,CAAA,MAAO;AACN,QAAA,GAAA,CAAI,GAAG,IAAI,GAAA,IAAO,IAAA;AAAA,MACnB;AAAA,IACD;AACA,IAAA,OAAO,GAAA;AAAA,EACR,CAAC,CAAA;AACD,EAAA,OAAO,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,kBAAA,EAAoB,CAAC,CAAA;AAClD;AAKO,SAAS,WAAA,CAAY,OAAA,EAAmB,IAAA,EAAiC,QAAA,EAAkB;AACjG,EAAA,eAAA;AAAA,IACC,cAAA,CAAe,SAAS,IAAI,CAAA;AAAA,IAC5B,SAAS,QAAA,CAAS,MAAM,CAAA,GAAI,QAAA,GAAW,GAAG,QAAQ,CAAA,IAAA,CAAA;AAAA,IAClD;AAAA,GACD;AACD;AAKO,SAAS,YAAA,CAAa,OAAA,EAAmB,IAAA,EAAiC,QAAA,EAAkB;AAClG,EAAA,eAAA;AAAA,IACC,eAAA,CAAgB,SAAS,IAAI,CAAA;AAAA,IAC7B,SAAS,QAAA,CAAS,OAAO,CAAA,GAAI,QAAA,GAAW,GAAG,QAAQ,CAAA,KAAA,CAAA;AAAA,IACnD;AAAA,GACD;AACD;;;AClEO,SAAS,eAAA,CAAgB,SAAsB,MAAA,EAAiC;AACtF,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,OAAO,CAAA;AAC1B,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,SAAA,KAAc,KAAA,GAAQ,CAAA,GAAI,EAAA;AAE7C,EAAA,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AAErB,IAAA,IAAI,CAAA,CAAE,MAAA,IAAU,CAAC,CAAA,CAAE,QAAQ,OAAO,EAAA;AAClC,IAAA,IAAI,CAAC,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,QAAQ,OAAO,CAAA;AAElC,IAAA,QAAQ,OAAO,KAAA;AAAO,MACrB,KAAK,MAAA;AACJ,QAAA,OAAO,GAAA,GAAM,CAAA,CAAE,IAAA,CAAK,aAAA,CAAc,CAAA,CAAE,MAAM,MAAA,EAAW,EAAE,WAAA,EAAa,MAAA,EAAQ,CAAA;AAAA,MAC7E,KAAK,MAAA;AACJ,QAAA,OAAO,GAAA,IAAO,CAAA,CAAE,IAAA,GAAO,CAAA,CAAE,IAAA,CAAA;AAAA,MAC1B,KAAK,UAAA;AACJ,QAAA,OAAO,GAAA,IAAO,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAA,CAAA;AAAA,MAC9B,KAAK,WAAA;AACJ,QAAA,OAAO,GAAA,GAAM,CAAA,CAAE,SAAA,CAAU,aAAA,CAAc,CAAA,CAAE,WAAW,MAAA,EAAW,EAAE,WAAA,EAAa,MAAA,EAAQ,CAAA;AAAA,MACvF;AACC,QAAA,OAAO,CAAA;AAAA;AACT,EACD,CAAC,CAAA;AAED,EAAA,OAAO,MAAA;AACR;AAKO,SAAS,eAAA,CAAgB,SAAqB,KAAA,EAA8B;AAClF,EAAA,IAAI,OAAA,CAAQ,UAAU,KAAA,EAAO;AAC5B,IAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,QAAQ,SAAA,KAAc,KAAA,GAAQ,SAAS,KAAA,EAAM;AAAA,EACzE;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAM;AAClC;ACZO,SAAS,kBAAkB,GAAA,EAA+B;AAChE,EAAA,MAAM,IAAI,GAAA,CAAI,WAAA,EAAY,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC9C,EAAA,IAAI,CAAA,KAAM,SAAS,OAAO,OAAA;AAC1B,EAAA,IAAI,CAAA,KAAM,cAAc,OAAO,YAAA;AAC/B,EAAA,IAAI,CAAA,KAAM,WAAW,OAAO,SAAA;AAC5B,EAAA,IAAI,CAAA,KAAM,cAAc,OAAO,YAAA;AAC/B,EAAA,IAAI,CAAA,KAAM,mBAAmB,OAAO,iBAAA;AACpC,EAAA,IAAI,CAAA,KAAM,gBAAgB,OAAO,cAAA;AACjC,EAAA,OAAO,SAAA;AACR;AAGA,IAAM,eAAA,GAAoD;AAAA,EACzD,KAAA,EAAO,gBAAA;AAAA,EACP,UAAA,EAAY,qBAAA;AAAA,EACZ,OAAA,EAAS,kBAAA;AAAA,EACT,UAAA,EAAY,qBAAA;AAAA,EACZ,eAAA,EAAiB,0BAAA;AAAA,EACjB,YAAA,EAAc;AACf,CAAA;AAYA,SAAS,cAAc,GAAA,EAAmC;AACzD,EAAA,IAAI,GAAA,CAAI,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAC3B,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA;AACtB,EAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,EAAA,MAAM,OAAA,GAAU,EAAA,CAAG,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA;AAElC,EAAA,IAAI,UAAA,GAAa,CAAA;AAGjB,EAAA,IAAA,CAAK,OAAA,GAAU,SAAA,MAAgB,CAAA,EAAG,UAAA,IAAc,CAAA;AAGhD,EAAA,MAAM,KAAA,GAAA,CAAS,UAAU,UAAA,MAAgB,CAAA;AACzC,EAAA,MAAM,KAAA,GAAA,CAAS,UAAU,UAAA,MAAgB,CAAA;AAGzC,EAAA,IAAI,OAAO,OAAA,GAAU,SAAA;AAGrB,EAAA,IAAI,IAAA,GAAO,KAAA;AACX,EAAA,IAAI,IAAA,GAAO,KAAA;AACX,EAAA,IAAI,OAAO,GAAA,EAAM;AAChB,IAAA,IAAA,GAAO,IAAA;AACP,IAAA,IAAA,GAAO,IAAA;AACP,IAAA,IAAA,IAAQ,GAAA;AAAA,EACT,CAAA,MAAA,IAAW,OAAO,GAAA,EAAM;AACvB,IAAA,IAAA,GAAO,IAAA;AACP,IAAA,IAAA,IAAQ,GAAA;AAAA,EACT,CAAA,MAAA,IAAW,OAAO,GAAA,EAAM;AACvB,IAAA,IAAA,GAAO,IAAA;AACP,IAAA,IAAA,IAAQ,GAAA;AAAA,EACT;AAEA,EAAA,MAAM,QAAQ,KAAA,IAAS,IAAA,GAAO,IAAI,CAAA,KAAM,KAAA,IAAS,OAAO,CAAA,GAAI,CAAA,CAAA;AAC5D,EAAA,MAAM,WAAA,GAAA,CAAe,IAAI,IAAA,IAAQ,CAAA;AAEjC,EAAA,OAAO,EAAE,IAAA,EAAM,EAAA,EAAI,WAAA,EAAa,YAAY,UAAA,EAAW;AACxD;AAGA,SAAS,gBAAgB,GAAA,EAA0C;AAClE,EAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,QAAQ,EAAE,IAAA;AAAM,IACf,KAAK,CAAA;AACJ,MAAA,OAAO,OAAA;AAAA,IACR,KAAK,CAAA;AACJ,MAAA,OAAO,YAAA;AAAA,IACR,KAAK,CAAA;AACJ,MAAA,OAAO,SAAA;AAAA,IACR,KAAK,CAAA;AACJ,MAAA,OAAO,YAAA;AAAA,IACR,KAAK,CAAA;AACJ,MAAA,OAAO,iBAAA;AAAA,IACR,KAAK,CAAA;AACJ,MAAA,OAAO,cAAA;AAAA,IACR;AACC,MAAA,OAAO,IAAA;AAAA;AAEV;AAWA,SAAS,SAAA,GAA2B;AACnC,EAAA,OAAO,EAAE,MAAM,QAAA,EAAU,IAAA,EAAM,UAAU,IAAA,EAAM,CAAA,QAAA,EAAW,MAAM,CAAA,QAAA,EAAU;AAC3E;AAGA,SAAS,YAAA,CAAa,CAAA,EAAkB,CAAA,EAAW,CAAA,EAAW;AAC7D,EAAA,IAAI,OAAO,KAAA,CAAM,CAAC,KAAK,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,EAAG;AACxC,EAAA,IAAI,CAAA,GAAI,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,IAAA,GAAO,CAAA;AACzB,EAAA,IAAI,CAAA,GAAI,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,IAAA,GAAO,CAAA;AACzB,EAAA,IAAI,CAAA,GAAI,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,IAAA,GAAO,CAAA;AACzB,EAAA,IAAI,CAAA,GAAI,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,IAAA,GAAO,CAAA;AAC1B;AAIA,IAAM,aAAa,IAAIC,iBAAA,CAAM,IAAA,EAAM,IAAIC,qBAAS,CAAA;AAChD,IAAM,SAAA,GAAY,IAAIC,yBAAA,CAAc,CAAA,EAAG,UAAU,CAAA;AAGjD,SAAS,aAAA,CAAc,QAAsB,SAAA,EAAwC;AACpF,EAAA,MAAM,SAAA,GAAYC,oBAAA,CAAS,EAAE,IAAA,EAAM,IAAIF,mBAAA,EAAQ,EAAG,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAQ,CAAA;AACvF,EAAA,OAAOE,oBAAA,CAAS,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,WAAW,SAAA,EAAW,CAAA,EAAG,KAAA,EAAO,SAAA,EAAW,CAAA;AACvF;AAQA,SAAS,cAAA,CAAe,MAAoB,CAAA,EAAwB;AACnE,EAAA,MAAM,IAAI,IAAA,CAAK,MAAA;AACf,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,CAAA,GAAI,CAAC,CAAA;AAErC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,GAAA,GAAM,KAAK,CAAC,CAAA;AAClB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACvB,MAAA,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,GAAI,CAAA;AAChB,MAAA,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,CAAA;AACpB,MAAA;AAAA,IACD;AACA,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,IAAI,EAAA,CAAG,UAAA,CAAW,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAC1C,IAAA,MAAM,IAAI,EAAA,CAAG,UAAA,CAAW,EAAE,UAAA,GAAa,CAAA,EAAG,EAAE,EAAE,CAAA;AAC9C,IAAA,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA,GAAI,CAAA;AAChB,IAAA,MAAA,CAAO,CAAA,GAAI,CAAA,GAAI,CAAC,CAAA,GAAI,CAAA;AACpB,IAAA,YAAA,CAAa,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,EACrB;AAEA,EAAA,OAAO,aAAA,CAAc,QAAQ,CAAC,CAAA;AAC/B;AAMA,SAAS,mBAAA,CAAoB,MAAoB,CAAA,EAAwB;AACxE,EAAA,MAAM,IAAI,IAAA,CAAK,MAAA;AACf,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,CAAA,GAAI,CAAC,CAAA;AACxC,EAAA,IAAI,WAAA,GAAc,CAAA;AAGlB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,WAAA;AACjB,IAAA,MAAM,CAAA,GAAI,aAAA,CAAc,IAAA,CAAK,CAAC,CAAC,CAAA;AAC/B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,CAAC,CAAA,CAAE,UAAA,EAAY,IAAA,CAAK,CAAC,EAAE,UAAU,CAAA;AAC9E,IAAA,MAAM,SAAS,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAC9C,IAAA,WAAA,IAAe,MAAA;AAAA,EAChB;AACA,EAAA,WAAA,CAAY,CAAC,CAAA,GAAI,WAAA;AAGjB,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,WAAA,GAAc,CAAC,CAAA;AAC/C,EAAA,IAAI,EAAA,GAAK,CAAA;AAET,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,SAAS,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAC9C,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAChC,MAAA,MAAM,CAAA,GAAI,EAAA,CAAG,UAAA,CAAW,GAAA,EAAK,EAAE,EAAE,CAAA;AACjC,MAAA,MAAM,IAAI,EAAA,CAAG,UAAA,CAAW,GAAA,GAAM,CAAA,EAAG,EAAE,EAAE,CAAA;AACrC,MAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,MAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,MAAA,YAAA,CAAa,CAAA,EAAG,GAAG,CAAC,CAAA;AACpB,MAAA,GAAA,IAAO,CAAA,CAAE,WAAA;AAAA,IACV;AAAA,EACD;AAEA,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,MAAA,EAAQ,WAAW,CAAA;AACjD,EAAA,MAAM,WAAW,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,UAAA,EAAY,SAAS,CAAC,CAAA;AAC1D,EAAA,OAAOG,oBAAA,CAAS;AAAA,IACf,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,CAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AACF;AAOA,SAAS,gBAAA,CAAiB,MAAoB,CAAA,EAAwB;AACrE,EAAA,MAAM,IAAI,IAAA,CAAK,MAAA;AACf,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,CAAA,GAAI,CAAC,CAAA;AACxC,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,WAAA,GAAc,CAAA;AAGlB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,UAAA;AACjB,IAAA,MAAM,CAAA,GAAI,aAAA,CAAc,IAAA,CAAK,CAAC,CAAC,CAAA;AAC/B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,CAAC,CAAA,CAAE,UAAA,EAAY,IAAA,CAAK,CAAC,EAAE,UAAU,CAAA;AAC9E,IAAA,MAAM,WAAW,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAChD,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,MAAA,GAAS,EAAA,CAAG,SAAA,CAAU,GAAA,EAAK,EAAE,EAAE,CAAA;AACrC,MAAA,GAAA,IAAO,CAAA,GAAI,SAAS,CAAA,CAAE,WAAA;AACtB,MAAA,WAAA,IAAe,MAAA;AACf,MAAA,UAAA,EAAA;AAAA,IACD;AAAA,EACD;AACA,EAAA,WAAA,CAAY,CAAC,CAAA,GAAI,UAAA;AAGjB,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,UAAA,GAAa,CAAC,CAAA;AACjD,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,WAAA,GAAc,CAAC,CAAA;AAC/C,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,CAAA;AAET,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,WAAW,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAChD,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,WAAA,CAAY,EAAA,EAAI,IAAI,EAAA,IAAM,CAAA;AAC1B,MAAA,MAAM,MAAA,GAAS,EAAA,CAAG,SAAA,CAAU,GAAA,EAAK,EAAE,EAAE,CAAA;AACrC,MAAA,GAAA,IAAO,CAAA;AACP,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAChC,QAAA,MAAM,CAAA,GAAI,EAAA,CAAG,UAAA,CAAW,GAAA,EAAK,EAAE,EAAE,CAAA;AACjC,QAAA,MAAM,IAAI,EAAA,CAAG,UAAA,CAAW,GAAA,GAAM,CAAA,EAAG,EAAE,EAAE,CAAA;AACrC,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,YAAA,CAAa,CAAA,EAAG,GAAG,CAAC,CAAA;AACpB,QAAA,GAAA,IAAO,CAAA,CAAE,WAAA;AAAA,MACV;AAAA,IACD;AAAA,EACD;AACA,EAAA,WAAA,CAAY,UAAU,IAAI,EAAA,IAAM,CAAA;AAEhC,EAAA,MAAM,aAAa,EAAA,IAAM,CAAA;AACzB,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,MAAA,EAAQ,UAAU,CAAA;AAEhD,EAAA,MAAM,eAAe,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,UAAA,EAAY,SAAS,CAAC,CAAA;AAC9D,EAAA,MAAM,eAAeG,oBAAA,CAAS;AAAA,IAC7B,IAAA,EAAM,YAAA;AAAA,IACN,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AAED,EAAA,MAAM,WAAW,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,OAAA,EAAS,YAAY,CAAC,CAAA;AAC1D,EAAA,OAAOG,oBAAA,CAAS;AAAA,IACf,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,CAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AACF;AAGA,SAAS,mBAAA,CAAoB,MAAoB,CAAA,EAAwB;AAGxE,EAAA,MAAM,IAAI,IAAA,CAAK,MAAA;AACf,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,CAAA,GAAI,CAAC,CAAA;AACxC,EAAA,IAAI,WAAA,GAAc,CAAA;AAGlB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,WAAA,CAAY,CAAC,CAAA,GAAI,WAAA;AACjB,IAAA,MAAM,CAAA,GAAI,aAAA,CAAc,IAAA,CAAK,CAAC,CAAC,CAAA;AAC/B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,CAAC,CAAA,CAAE,UAAA,EAAY,IAAA,CAAK,CAAC,EAAE,UAAU,CAAA;AAC9E,IAAA,WAAA,IAAe,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAAA,EAC/C;AACA,EAAA,WAAA,CAAY,CAAC,CAAA,GAAI,WAAA;AAGjB,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,WAAA,GAAc,CAAC,CAAA;AAC/C,EAAA,IAAI,EAAA,GAAK,CAAA;AAET,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,SAAS,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAC9C,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAEhC,MAAA,MAAM,MAAA,GAAS,aAAA;AAAA,QACd,IAAI,WAAW,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG;AAAA,OACtE;AACA,MAAA,IAAI,MAAA,EAAQ;AACX,QAAA,MAAM,IAAI,EAAA,CAAG,UAAA,CAAW,MAAM,MAAA,CAAO,UAAA,EAAY,OAAO,EAAE,CAAA;AAC1D,QAAA,MAAM,CAAA,GAAI,GAAG,UAAA,CAAW,GAAA,GAAM,OAAO,UAAA,GAAa,CAAA,EAAG,OAAO,EAAE,CAAA;AAC9D,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,YAAA,CAAa,CAAA,EAAG,GAAG,CAAC,CAAA;AACpB,QAAA,GAAA,IAAO,MAAA,CAAO,aAAa,MAAA,CAAO,WAAA;AAAA,MACnC,CAAA,MAAO;AACN,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,GAAA,IAAO,EAAA;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAEA,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,MAAA,EAAQ,WAAW,CAAA;AACjD,EAAA,MAAM,WAAW,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,UAAA,EAAY,SAAS,CAAC,CAAA;AAC1D,EAAA,OAAOG,oBAAA,CAAS;AAAA,IACf,IAAA,EAAM,QAAA;AAAA,IACN,MAAA,EAAQ,CAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AACF;AAMA,SAAS,wBAAA,CAAyB,MAAoB,CAAA,EAAwB;AAC7E,EAAA,MAAM,IAAI,IAAA,CAAK,MAAA;AACf,EAAA,MAAM,cAAA,GAA2B,CAAC,CAAC,CAAA;AACnC,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,WAAA,GAAc,CAAA;AAGlB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACvB,MAAA,cAAA,CAAe,KAAK,UAAU,CAAA;AAC9B,MAAA;AAAA,IACD;AACA,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,WAAW,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAChD,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,MAAA,GAAS,aAAA;AAAA,QACd,IAAI,WAAW,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG;AAAA,OACtE;AACA,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,MAAM,OAAA,GAAU,IAAI,QAAA,CAAS,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG,CAAA;AACnF,MAAA,MAAM,SAAS,OAAA,CAAQ,SAAA,CAAU,MAAA,CAAO,UAAA,EAAY,OAAO,EAAE,CAAA;AAC7D,MAAA,WAAA,IAAe,MAAA;AACf,MAAA,GAAA,IAAO,MAAA,CAAO,UAAA,GAAa,CAAA,GAAI,MAAA,GAAS,MAAA,CAAO,WAAA;AAC/C,MAAA,UAAA,EAAA;AAAA,IACD;AACA,IAAA,cAAA,CAAe,KAAK,UAAU,CAAA;AAAA,EAC/B;AAGA,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,cAAc,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,UAAA,GAAa,CAAC,CAAA;AACjD,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,WAAA,GAAc,CAAC,CAAA;AAC/C,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,CAAA;AAET,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,WAAW,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAChD,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,WAAA,CAAY,EAAA,EAAI,IAAI,EAAA,IAAM,CAAA;AAC1B,MAAA,MAAM,MAAA,GAAS,aAAA;AAAA,QACd,IAAI,WAAW,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG;AAAA,OACtE;AACA,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,MAAM,MAAA,GAAS,IAAI,QAAA,CAAS,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG,CAAA,CAAE,SAAA;AAAA,QACnF,MAAA,CAAO,UAAA;AAAA,QACP,MAAA,CAAO;AAAA,OACR;AACA,MAAA,IAAI,KAAA,GAAQ,GAAA,GAAM,MAAA,CAAO,UAAA,GAAa,CAAA;AACtC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAChC,QAAA,MAAM,CAAA,GAAI,EAAA,CAAG,UAAA,CAAW,KAAA,EAAO,OAAO,EAAE,CAAA;AACxC,QAAA,MAAM,IAAI,EAAA,CAAG,UAAA,CAAW,KAAA,GAAQ,CAAA,EAAG,OAAO,EAAE,CAAA;AAC5C,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,QAAA,YAAA,CAAa,CAAA,EAAG,GAAG,CAAC,CAAA;AACpB,QAAA,KAAA,IAAS,MAAA,CAAO,WAAA;AAAA,MACjB;AACA,MAAA,GAAA,GAAM,KAAA;AAAA,IACP;AAAA,EACD;AACA,EAAA,WAAA,CAAY,UAAU,IAAI,EAAA,IAAM,CAAA;AAEhC,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,MAAA,EAAQ,EAAA,IAAM,CAAC,CAAA;AAC7C,EAAA,MAAM,eAAe,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,UAAA,EAAY,SAAS,CAAC,CAAA;AAC9D,EAAA,MAAM,eAAeG,oBAAA,CAAS;AAAA,IAC7B,IAAA,EAAM,YAAA;AAAA,IACN,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AAED,EAAA,MAAM,gBAAgB,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,OAAA,EAAS,YAAY,CAAC,CAAA;AAC/D,EAAA,OAAOG,oBAAA,CAAS;AAAA,IACf,IAAA,EAAM,aAAA;AAAA,IACN,MAAA,EAAQ,CAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AACF;AAMA,SAAS,qBAAA,CAAsB,MAAoB,CAAA,EAAwB;AAC1E,EAAA,MAAM,IAAI,IAAA,CAAK,MAAA;AACf,EAAA,MAAM,cAAA,GAA2B,CAAC,CAAC,CAAA;AACnC,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,WAAA,GAAc,CAAA;AAGlB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACvB,MAAA,cAAA,CAAe,KAAK,UAAU,CAAA;AAC9B,MAAA;AAAA,IACD;AACA,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,WAAW,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAChD,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,MAAA,GAAS,aAAA;AAAA,QACd,IAAI,WAAW,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG;AAAA,OACtE;AACA,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,MAAM,OAAA,GAAU,IAAI,QAAA,CAAS,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG,CAAA;AACnF,MAAA,MAAM,WAAW,OAAA,CAAQ,SAAA,CAAU,MAAA,CAAO,UAAA,EAAY,OAAO,EAAE,CAAA;AAC/D,MAAA,IAAI,OAAA,GAAU,OAAO,UAAA,GAAa,CAAA;AAClC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,SAAA,CAAU,OAAA,EAAS,OAAO,EAAE,CAAA;AACnD,QAAA,OAAA,IAAW,CAAA,GAAI,SAAS,MAAA,CAAO,WAAA;AAC/B,QAAA,WAAA,IAAe,MAAA;AACf,QAAA,UAAA,EAAA;AAAA,MACD;AACA,MAAA,GAAA,IAAO,OAAA;AACP,MAAA,UAAA,EAAA;AAAA,IACD;AACA,IAAA,cAAA,CAAe,KAAK,UAAU,CAAA;AAAA,EAC/B;AAGA,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,cAAc,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,UAAA,GAAa,CAAC,CAAA;AACjD,EAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,UAAA,GAAa,CAAC,CAAA;AACjD,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa,WAAA,GAAc,CAAC,CAAA;AAC/C,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,CAAA;AAET,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,MAAM,CAAA,GAAI,cAAc,GAAG,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,GAAA,CAAI,UAAA,EAAY,IAAI,UAAU,CAAA;AAClE,IAAA,MAAM,WAAW,EAAA,CAAG,SAAA,CAAU,CAAA,CAAE,UAAA,EAAY,EAAE,EAAE,CAAA;AAChD,IAAA,IAAI,GAAA,GAAM,EAAE,UAAA,GAAa,CAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,WAAA,CAAY,IAAI,CAAA,GAAI,EAAA;AACpB,MAAA,MAAM,MAAA,GAAS,aAAA;AAAA,QACd,IAAI,WAAW,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG;AAAA,OACtE;AACA,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,MAAM,OAAA,GAAU,IAAI,QAAA,CAAS,GAAA,CAAI,MAAA,EAAQ,IAAI,UAAA,GAAa,GAAA,EAAK,GAAA,CAAI,UAAA,GAAa,GAAG,CAAA;AACnF,MAAA,MAAM,WAAW,OAAA,CAAQ,SAAA,CAAU,MAAA,CAAO,UAAA,EAAY,OAAO,EAAE,CAAA;AAC/D,MAAA,IAAI,OAAA,GAAU,GAAA,GAAM,MAAA,CAAO,UAAA,GAAa,CAAA;AACxC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,QAAA,WAAA,CAAY,EAAA,EAAI,IAAI,EAAA,IAAM,CAAA;AAC1B,QAAA,MAAM,MAAA,GAAS,EAAA,CAAG,SAAA,CAAU,OAAA,EAAS,OAAO,EAAE,CAAA;AAC9C,QAAA,OAAA,IAAW,CAAA;AACX,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAChC,UAAA,MAAM,CAAA,GAAI,EAAA,CAAG,UAAA,CAAW,OAAA,EAAS,OAAO,EAAE,CAAA;AAC1C,UAAA,MAAM,IAAI,EAAA,CAAG,UAAA,CAAW,OAAA,GAAU,CAAA,EAAG,OAAO,EAAE,CAAA;AAC9C,UAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,UAAA,MAAA,CAAO,IAAI,CAAA,GAAI,CAAA;AACf,UAAA,YAAA,CAAa,CAAA,EAAG,GAAG,CAAC,CAAA;AACpB,UAAA,OAAA,IAAW,MAAA,CAAO,WAAA;AAAA,QACnB;AAAA,MACD;AACA,MAAA,GAAA,GAAM,OAAA;AAAA,IACP;AAAA,EACD;AACA,EAAA,WAAA,CAAY,UAAU,CAAA,GAAI,EAAA;AAC1B,EAAA,WAAA,CAAY,UAAU,IAAI,EAAA,IAAM,CAAA;AAEhC,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,MAAA,EAAQ,EAAA,IAAM,CAAC,CAAA;AAE7C,EAAA,MAAM,eAAe,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,UAAA,EAAY,SAAS,CAAC,CAAA;AAC9D,EAAA,MAAM,eAAeG,oBAAA,CAAS;AAAA,IAC7B,IAAA,EAAM,YAAA;AAAA,IACN,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AAED,EAAA,MAAM,eAAe,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,OAAA,EAAS,YAAY,CAAC,CAAA;AAC9D,EAAA,MAAM,eAAeG,oBAAA,CAAS;AAAA,IAC7B,IAAA,EAAM,YAAA;AAAA,IACN,MAAA,EAAQ,UAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AAED,EAAA,MAAM,gBAAgB,IAAIC,gBAAA,CAAK,IAAIJ,iBAAA,CAAM,UAAA,EAAY,YAAY,CAAC,CAAA;AAClE,EAAA,OAAOG,oBAAA,CAAS;AAAA,IACf,IAAA,EAAM,aAAA;AAAA,IACN,MAAA,EAAQ,CAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,YAAA,EAAc,WAAA;AAAA,IACd,KAAA,EAAO;AAAA,GACP,CAAA;AACF;AAKA,SAAS,qBAAA,CACR,SACA,UAAA,EACoC;AACpC,EAAA,MAAM,IAAI,OAAA,CAAQ,MAAA;AAClB,EAAA,MAAM,SAAkB,EAAC;AACzB,EAAA,MAAM,UAAkB,EAAC;AAEzB,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,UAAA,EAAY;AACrC,IAAA,MAAM,EAAE,QAAO,GAAI,GAAA;AAGnB,IAAA,IAAI,SAAA,GAAY,IAAA;AAChB,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAG,CAAA;AACjC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,EAAW,CAAA,EAAA,EAAK;AACnC,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,IAAK,IAAA,IAAQ,OAAO,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,KAAM,QAAA,EAAU;AACzE,QAAA,SAAA,GAAY,KAAA;AACZ,QAAA;AAAA,MACD;AAAA,IACD;AAEA,IAAA,IAAI,SAAA,EAAW;AACd,MAAA,MAAM,GAAA,GAAM,IAAI,YAAA,CAAa,CAAC,CAAA;AAC9B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK,GAAA,CAAI,CAAC,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,IAAK,GAAA;AAC3D,MAAA,MAAM,IAAA,GAAOA,oBAAA,CAAS,EAAE,IAAA,EAAM,IAAIF,mBAAA,EAAQ,EAAG,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,GAAA,EAAK,CAAA;AACnE,MAAA,MAAA,CAAO,IAAA,CAAK,IAAID,iBAAA,CAAM,IAAA,EAAM,IAAIC,mBAAA,EAAQ,EAAG,IAAI,CAAC,CAAA;AAChD,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IAClB,CAAA,MAAO;AACN,MAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,MAAA,MAAM,OAAA,GAAU,IAAI,UAAA,CAAW,CAAA,GAAI,CAAC,CAAA;AACpC,MAAA,IAAI,UAAA,GAAa,CAAA;AAGjB,MAAA,MAAM,WAAyB,EAAC;AAChC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,QAAA,OAAA,CAAQ,CAAC,CAAA,GAAI,UAAA;AACb,QAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAC,CAAA,IAAK,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,GAAI,EAAA;AACpE,QAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA;AAChC,QAAA,QAAA,CAAS,KAAK,OAAO,CAAA;AACrB,QAAA,UAAA,IAAc,OAAA,CAAQ,MAAA;AAAA,MACvB;AACA,MAAA,OAAA,CAAQ,CAAC,CAAA,GAAI,UAAA;AAEb,MAAA,MAAM,WAAA,GAAc,IAAI,UAAA,CAAW,UAAU,CAAA;AAC7C,MAAA,IAAI,GAAA,GAAM,CAAA;AACV,MAAA,KAAA,MAAW,MAAM,QAAA,EAAU;AAC1B,QAAA,WAAA,CAAY,GAAA,CAAI,IAAI,GAAG,CAAA;AACvB,QAAA,GAAA,IAAO,EAAA,CAAG,MAAA;AAAA,MACX;AAEA,MAAA,MAAM,OAAOE,oBAAA,CAAS;AAAA,QACrB,IAAA,EAAM,IAAIE,gBAAA,EAAK;AAAA,QACf,MAAA,EAAQ,CAAA;AAAA,QACR,YAAA,EAAc,OAAA;AAAA,QACd,IAAA,EAAM;AAAA,OACN,CAAA;AACD,MAAA,MAAA,CAAO,IAAA,CAAK,IAAIL,iBAAA,CAAM,IAAA,EAAM,IAAIK,gBAAA,EAAK,EAAG,IAAI,CAAC,CAAA;AAC7C,MAAA,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,IAClB;AAAA,EACD;AAEA,EAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAQ;AAChC;AAGA,SAAS,gBAAA,CACR,QAAA,EACA,IAAA,EACA,OAAA,EACA,YACA,CAAA,EACiB;AACjB,EAAA,MAAM,IAAI,IAAA,CAAK,MAAA;AAEf,EAAA,IAAI,QAAA;AACJ,EAAA,QAAQ,QAAA;AAAU,IACjB,KAAK,OAAA;AACJ,MAAA,QAAA,GAAW,cAAA,CAAe,MAAM,CAAC,CAAA;AACjC,MAAA;AAAA,IACD,KAAK,YAAA;AACJ,MAAA,QAAA,GAAW,mBAAA,CAAoB,MAAM,CAAC,CAAA;AACtC,MAAA;AAAA,IACD,KAAK,SAAA;AACJ,MAAA,QAAA,GAAW,gBAAA,CAAiB,MAAM,CAAC,CAAA;AACnC,MAAA;AAAA,IACD,KAAK,YAAA;AACJ,MAAA,QAAA,GAAW,mBAAA,CAAoB,MAAM,CAAC,CAAA;AACtC,MAAA;AAAA,IACD,KAAK,iBAAA;AACJ,MAAA,QAAA,GAAW,wBAAA,CAAyB,MAAM,CAAC,CAAA;AAC3C,MAAA;AAAA,IACD,KAAK,cAAA;AACJ,MAAA,QAAA,GAAW,qBAAA,CAAsB,MAAM,CAAC,CAAA;AACxC,MAAA;AAAA;AAGF,EAAA,MAAM,aAAA,GAAgB,gBAAgB,QAAQ,CAAA;AAC9C,EAAA,MAAM,YAAA,uBAAmB,GAAA,CAAoB;AAAA,IAC5C,CAAC,wBAAwB,aAAa,CAAA;AAAA,IACtC;AAAA,MACC,0BAAA;AAAA,MACA,KAAK,SAAA,CAAU;AAAA,QACd,GAAA,EAAK;AAAA,UACJ,IAAA,EAAM,MAAA;AAAA,UACN,UAAA,EAAY,EAAE,IAAA,EAAM,+BAAA;AAAgC;AACrD,OACA;AAAA;AACF,GACA,CAAA;AAED,EAAA,MAAM,YAAY,IAAIL,iBAAA,CAAM,YAAY,QAAA,CAAS,IAAA,EAAM,OAAO,YAAY,CAAA;AAC1E,EAAA,MAAM,QAAA,GAAW,qBAAA,CAAsB,OAAA,EAAS,UAAU,CAAA;AAE1D,EAAA,MAAM,MAAA,GAAkB,CAAC,SAAA,EAAW,GAAG,SAAS,MAAM,CAAA;AACtD,EAAA,MAAM,YAAA,GAAuB,CAAC,QAAA,EAAU,GAAG,SAAS,IAAI,CAAA;AAExD,EAAA,MAAM,WAAA,GAAc,IAAIM,kBAAA,CAAO,MAAM,CAAA;AACrC,EAAA,MAAM,UAAA,GAAa,IAAIC,kBAAA,CAAO,MAAM,CAAA;AACpC,EAAA,MAAM,aAAaJ,oBAAA,CAAS;AAAA,IAC3B,IAAA,EAAM,UAAA;AAAA,IACN,MAAA,EAAQ,CAAA;AAAA,IACR,SAAA,EAAW,CAAA;AAAA,IACX,QAAA,EAAU;AAAA,GACV,CAAA;AACD,EAAA,MAAM,KAAA,GAAQ,IAAIK,uBAAA,CAAY,WAAA,EAAa,UAAU,CAAA;AACrD,EAAA,MAAM,KAAA,GAAQ,IAAIC,iBAAA,CAAM,WAAA,EAAa,KAAK,CAAA;AAE1C,EAAA,OAAO;AAAA,IACN,KAAA;AAAA,IACA,YAAA,EAAc,QAAA;AAAA,IACd,MAAA,EAAQ,CAAC,CAAA,CAAE,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,IAAI,CAAA;AAAA,IACvC,aAAA,EAAe;AAAA,GAChB;AACD;AAYO,SAAS,mBAAA,CACf,SAAA,EACA,UAAA,EACA,aAAA,EACmB;AACnB,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAGpC,EAAA,IAAI,aAAA,EAAe;AAClB,IAAA,MAAMC,gBAAe,SAAA,EAAU;AAC/B,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,SAAA,CAAU,MAAA,EAAO,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM,CAAC,CAAA;AACpE,IAAA,MAAM,SAAS,gBAAA,CAAiB,aAAA,EAAe,SAAA,EAAW,OAAA,EAAS,YAAYA,aAAY,CAAA;AAC3F,IAAA,OAAO,CAAC,MAAM,CAAA;AAAA,EACf;AAGA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAiE;AAEpF,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,SAAA,CAAU,CAAC,CAAC,CAAA;AAC7C,IAAA,IAAI,CAAC,QAAA,EAAU;AAEf,IAAA,IAAI,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,QAAQ,CAAA;AAC/B,IAAA,IAAI,CAAC,KAAA,EAAO;AACX,MAAA,KAAA,GAAQ,EAAE,IAAA,EAAM,EAAC,EAAG,OAAA,EAAS,EAAC,EAAE;AAChC,MAAA,MAAA,CAAO,GAAA,CAAI,UAAU,KAAK,CAAA;AAAA,IAC3B;AACA,IAAA,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA;AAC5B,IAAA,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACrB;AAEA,EAAA,IAAI,MAAA,CAAO,IAAA,KAAS,CAAA,EAAG,OAAO,EAAC;AAE/B,EAAA,MAAM,eAAe,SAAA,EAAU;AAC/B,EAAA,MAAM,UAA4B,EAAC;AAEnC,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,EAAE,MAAM,OAAA,EAAS,KAAK,MAAA,EAAQ;AACnD,IAAA,MAAM,SAAS,gBAAA,CAAiB,QAAA,EAAU,IAAA,EAAM,OAAA,EAAS,YAAY,YAAY,CAAA;AACjF,IAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,EACpB;AAGA,EAAA,MAAM,YAAA,GAAiD;AAAA,IACtD,YAAA,CAAa,IAAA;AAAA,IACb,YAAA,CAAa,IAAA;AAAA,IACb,YAAA,CAAa,IAAA;AAAA,IACb,YAAA,CAAa;AAAA,GACd;AACA,EAAA,KAAA,MAAW,CAAA,IAAK,OAAA,EAAS,CAAA,CAAE,MAAA,GAAS,YAAA;AAEpC,EAAA,OAAO,OAAA;AACR;;;ACrvBA,IAAM,eAAA,GAAkB,wCAAA;AAMjB,SAAS,qBAAqB,OAAA,EAAsD;AAC1F,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAE,UAAA,EAAY,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,WAAA,EAAa,IAAA,EAAK;AACzF,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,eAAe,CAAA;AAC3C,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAE,UAAA,EAAY,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,WAAA,EAAa,IAAA,EAAK;AACvF,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,CAAC,CAAA,EAAG,MAAK,IAAK,IAAA;AACnC,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,WAAA,EAAa,IAAA,EAAK;AACvF,EAAA,OAAO;AAAA,IACN,UAAA,EAAY,IAAA;AAAA,IACZ,MAAA,EAAQ,IAAA;AAAA,IACR,MAAA;AAAA,IACA,WAAA,EAAa,UAAA,CAAW,MAAM,CAAA,GAAI,IAAA,GAAO;AAAA,GAC1C;AACD;AAGO,SAAS,WAAW,GAAA,EAAyC;AACnE,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,EAAA,IAAI,OAAA,KAAY,WAAA,IAAe,OAAA,KAAY,WAAA,EAAa,OAAO,IAAA;AAC/D,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,CAAM,eAAe,CAAA;AAC/C,EAAA,IAAI,SAAA,IAAa,YAAY,GAAA,CAAI,MAAA,CAAO,UAAU,CAAC,CAAC,CAAC,CAAA,EAAG,OAAO,IAAA;AAC/D,EAAA,OAAO,KAAA;AACR;AAUO,SAAS,kBAAA,CACf,SAAA,EACA,UAAA,EACA,SAAA,EACA,SAAA,EACS;AACT,EAAA,MAAM,IAAA,GAAO,qBAAqB,UAAU,CAAA;AAC5C,EAAA,IAAI,KAAK,MAAA,EAAQ;AAChB,IAAA,OAAO,CAAA,aAAA,EAAgB,SAAS,CAAA,GAAA,EAAM,SAAS,CAAA,EAAA,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,CAAA,aAAA,EAAgB,SAAS,CAAA,GAAA,EAAM,SAAS,OAAO,SAAS,CAAA,EAAA,CAAA;AAChE;AAWO,SAAS,cAAA,CAAe,SAAiB,SAAA,EAA8C;AAC7F,EAAA,IAAI,CAAC,SAAA,EAAW,OAAO,CAAA,eAAA,EAAkB,OAAO,CAAA,CAAA,CAAA;AAChD,EAAA,OAAO,CAAA,yBAAA,EAA4B,OAAO,CAAA,IAAA,EAAO,SAAS,CAAA,EAAA,CAAA;AAC3D;;;ACnFO,SAAS,eAAA,CAAgB,IAAA,EAAkB,WAAA,GAAc,EAAA,EAAc;AAC7E,EAAA,MAAM,OAAiB,EAAC;AAExB,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,KAAK,WAAA,EAAa;AAClD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAI,WAAW,CAAA;AAC3C,IAAA,MAAM,SAAS,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AAE7C,IAAA,MAAM,MAAgB,EAAC;AACvB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAAK;AACrC,MAAA,IAAI,CAAA,GAAI,MAAM,MAAA,EAAQ;AACrB,QAAA,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,MAChD,CAAA,MAAO;AACN,QAAA,GAAA,CAAI,KAAK,IAAI,CAAA;AAAA,MACd;AAAA,IACD;AAEA,IAAA,IAAI,KAAA,GAAQ,EAAA;AACZ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,MAAA,KAAA,IAAS,QAAQ,EAAA,IAAQ,IAAA,IAAQ,MAAO,MAAA,CAAO,YAAA,CAAa,IAAI,CAAA,GAAI,GAAA;AAAA,IACrE;AAEA,IAAA,IAAA,CAAK,IAAA,CAAK,EAAE,MAAA,EAAQ,GAAA,EAAK,OAAO,CAAA;AAAA,EACjC;AAEA,EAAA,OAAO,IAAA;AACR;;;ACeO,SAAS,iBAAA,GAAkC;AACjD,EAAA,OAAO,EAAE,UAAU,IAAA,EAAM,MAAA,EAAQ,MAAM,aAAA,EAAe,KAAA,EAAO,UAAU,IAAA,EAAK;AAC7E;AAOO,SAAS,8BAA8B,IAAA,EAAgD;AAC7F,EAAA,MAAM,OAAQ,IAAA,CAAkD,eAAA;AAChE,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,GAAG,OAAO,IAAA;AACjC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACvB,IAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC7B,IAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,mCAAmC,CAAA,EAAG;AACxD,IAAA,MAAM,OAAA,GAAU,GAAA,CAAI,QAAA,CAAS,cAAc,CAAA,GAAI,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,CAAC,cAAA,CAAe,MAAM,CAAA,GAAI,GAAA;AACtF,IAAA,MAAM,OAAO,OAAA,CAAQ,KAAA,CAAM,QAAQ,WAAA,CAAY,GAAG,IAAI,CAAC,CAAA;AACvD,IAAA,MAAM,OAAA,GAAU,KAAK,UAAA,CAAW,GAAG,IAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,GAAI,IAAA;AACvD,IAAA,IAAI,OAAA,KAAY,OAAA,IAAW,OAAA,KAAY,OAAA,EAAS,OAAO,OAAA;AAGvD,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAClC,IAAA,IAAI,KAAA,KAAU,KAAK,OAAO,OAAA;AAC1B,IAAA,IAAI,KAAA,KAAU,KAAK,OAAO,OAAA;AAAA,EAC3B;AACA,EAAA,OAAO,IAAA;AACR;AAYO,SAAS,mBAAA,CAAoB,MAAgB,QAAA,EAAiC;AACpF,EAAA,MAAM,OAAA,GAAU,8BAA8B,IAAI,CAAA;AAClD,EAAA,IAAI,OAAA,KAAY,OAAA,EAAS,OAAO,cAAA,CAAe,MAAM,QAAQ,CAAA;AAC7D,EAAA,IAAI,OAAA,KAAY,OAAA,EAAS,OAAO,cAAA,CAAe,MAAM,QAAQ,CAAA;AAC7D,EAAA,OAAO,iBAAA,EAAkB;AAC1B;AAIA,SAAS,cAAA,CAAe,MAAgB,QAAA,EAAiC;AACxE,EAAA,MAAM,KAAA,GAAS,IAAA,CAAK,UAAA,IAAc,EAAC;AACnC,EAAA,MAAM,KAAA,GACL,QAAA,IAAY,IAAA,CAAK,MAAA,IAAW,IAAA,CAAK,MAAA,CAAmC,QAAQ,CAAA,GACvE,IAAA,CAAK,MAAA,CAAmC,QAAQ,CAAA,GAClD,IAAA;AAEJ,EAAA,MAAM,WAAA,GAAc,gBAAgB,CAAC,KAAA,GAAQ,kBAAkB,CAAA,EAAG,KAAA,CAAM,kBAAkB,CAAC,CAAC,CAAA;AAC5F,EAAA,MAAM,MAAA,GAAS,gBAAgB,CAAC,KAAA,GAAQ,gBAAgB,CAAA,EAAG,KAAA,CAAM,gBAAgB,CAAC,CAAC,CAAA;AACnF,EAAA,MAAM,gBAAgB,gBAAA,CAAiB;AAAA,IACtC,QAAQ,wBAAwB,CAAA;AAAA,IAChC,MAAM,wBAAwB;AAAA,GAC9B,CAAA;AAED,EAAA,OAAO;AAAA,IACN,QAAA,EAAU,WAAA,GAAc,WAAA,CAAY,WAAA,EAAY,GAAI,IAAA;AAAA,IACpD,QAAQ,MAAA,IAAU,IAAA;AAAA,IAClB,eAAe,aAAA,KAAkB,IAAA;AAAA,IACjC,QAAA,EAAU;AAAA,GACX;AACD;AAYA,SAAS,cAAA,CAAe,MAAgB,QAAA,EAAiC;AACxE,EAAA,MAAM,KAAA,GAAS,IAAA,CAAK,UAAA,IAAc,EAAC;AACnC,EAAA,MAAM,OAAA,GAAW,KAAA,CAAM,iBAAiB,CAAA,IAAK,EAAC;AAC9C,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,SAAiB,iBAAA,EAAkB;AAEtE,EAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,IAAA,EAAM,QAAQ,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,OAAA,EAAS,IAAI,CAAA;AAC5C,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,iBAAA,EAAkB;AAEtC,EAAA,MAAM,YAAY,OAAO,MAAA,CAAO,IAAA,KAAS,QAAA,GAAW,OAAO,IAAA,GAAO,EAAA;AAClE,EAAA,MAAM,WAAW,OAAO,MAAA,CAAO,QAAA,KAAa,QAAA,GAAW,OAAO,QAAA,GAAW,IAAA;AACzE,EAAA,MAAM,SAAS,OAAO,MAAA,CAAO,MAAA,KAAW,QAAA,GAAW,OAAO,MAAA,GAAS,IAAA;AACnE,EAAA,MAAM,aAAA,GAAgB,OAAO,cAAA,KAAmB,IAAA;AAEhD,EAAA,IAAI,QAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,cAAc,WAAA,EAAa;AAG9B,IAAA,IAAI,OAAO,MAAA,CAAO,QAAA,KAAa,QAAA,IAAY,MAAA,CAAO,QAAA,IAAY,CAAC,MAAA,CAAO,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG;AAC7F,MAAA,QAAA,GAAW,MAAA,CAAO,QAAA;AAAA,IACnB,WAAW,QAAA,IAAY,CAAC,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG;AAC/C,MAAA,QAAA,GAAW,QAAA;AAAA,IACZ;AAAA,EACD;AAEA,EAAA,OAAO;AAAA,IACN,QAAA,EAAU,QAAA,GAAW,QAAA,CAAS,WAAA,EAAY,GAAI,IAAA;AAAA,IAC9C,MAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACD;AACD;AAEA,SAAS,gBAAA,CAAiB,MAAgB,QAAA,EAA6B;AACtE,EAAA,MAAM,MAAA,GAAU,IAAA,CAAK,MAAA,IAAU,EAAC;AAChC,EAAA,IAAI,QAAA,EAAU;AACb,IAAA,MAAM,CAAA,GAAI,OAAO,QAAQ,CAAA;AACzB,IAAA,MAAM,IAAA,GAAO,IAAI,cAAc,CAAA;AAC/B,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,QAAQ,CAAA;AACrF,IAAA,OAAO,EAAC;AAAA,EACT;AACA,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,EAAG;AACtC,IAAA,IAAI,CAAC,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,EAAU;AACjC,IAAA,MAAM,IAAA,GAAQ,EAA8B,cAAc,CAAA;AAC1D,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,MAAM,IAAI,OAAO,MAAM,QAAA,EAAU,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,EAC5D;AACA,EAAA,OAAO,GAAA;AACR;AAEA,SAAS,eAAA,CAAgB,SAAmC,IAAA,EAAiC;AAC5F,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACrB,IAAA,MAAM,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnB,IAAA,IAAI,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAAA,EACxC;AACA,EAAA,OAAO,IAAA;AACR;AAIA,SAAS,gBAAgB,UAAA,EAAsC;AAC9D,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC3B,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,MAAA,GAAS,GAAG,OAAO,CAAA;AAAA,EACnD;AACA,EAAA,OAAO,IAAA;AACR;AAEA,SAAS,iBAAiB,UAAA,EAAuC;AAChE,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC3B,IAAA,IAAI,OAAO,CAAA,KAAM,SAAA,EAAW,OAAO,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,IAAA;AACR;AAgBO,SAAS,6BAAA,CACf,MACA,KAAA,EACI;AACJ,EAAA,MAAM,GAAA,GAAS,EAAE,GAAG,IAAA,EAAK;AACzB,EAAA,IAAI,KAAA,CAAM,MAAA,IAAU,CAAC,GAAA,CAAI,MAAA,EAAQ;AAChC,IAAC,GAAA,CAA4B,SAAS,KAAA,CAAM,MAAA;AAAA,EAC7C;AACA,EAAA,IAAI,KAAA,CAAM,QAAA,IAAY,CAAC,GAAA,CAAI,QAAA,EAAU;AACpC,IAAC,GAAA,CAA8B,WAAW,KAAA,CAAM,QAAA;AAAA,EACjD;AACA,EAAA,OAAO,GAAA;AACR;;;AChLA,SAAS,cAAA,GAA+E;AACvF,EAAA,MAAM,MAAoE,EAAC;AAC3E,EAAA,KAAA,MAAW,CAAC,EAAA,EAAI,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,EAAG;AAClD,IAAA,KAAA,MAAW,MAAA,IAAU,IAAI,OAAA,EAAS;AACjC,MAAA,MAAM,GAAA,GAAM,GAAG,MAAM,CAAA,GAAA,CAAA;AACrB,MAAA,GAAA,CAAI,GAAG,CAAA,GAAI,EAAE,UAAU,EAAA,EAAI,KAAA,EAAO,IAAI,MAAA,EAAO;AAAA,IAC9C;AAAA,EACD;AAEA,EAAA,GAAA,CAAI,UAAU,CAAA,GAAI,EAAE,QAAA,EAAU,SAAA,EAAW,OAAO,CAAA,EAAE;AAClD,EAAA,OAAO,GAAA;AACR;AAGA,IAAM,aAAa,cAAA,EAAe;AAElC,IAAMC,MAAAA,GAAQ,EAAA;AAGd,SAASC,sBAAqB,CAAA,EAAmB;AAChD,EAAA,IAAI,MAAM,CAAA,CAAE,MAAA;AACZ,EAAA,OAAO,MAAM,CAAA,IAAK,CAAA,CAAE,WAAW,GAAA,GAAM,CAAC,MAAMD,MAAAA,EAAO,GAAA,EAAA;AACnD,EAAA,OAAO,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AACtB;AAGA,SAASE,kBAAiB,CAAA,EAAmB;AAC5C,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,IAAI,MAAM,CAAA,CAAE,MAAA;AACZ,EAAA,OAAO,QAAQ,GAAA,IAAO,CAAA,CAAE,UAAA,CAAW,KAAK,MAAMF,MAAAA,EAAO,KAAA,EAAA;AACrD,EAAA,OAAO,MAAM,KAAA,IAAS,CAAA,CAAE,WAAW,GAAA,GAAM,CAAC,MAAMA,MAAAA,EAAO,GAAA,EAAA;AACvD,EAAA,OAAO,CAAA,CAAE,KAAA,CAAM,KAAA,EAAO,GAAG,CAAA;AAC1B;AAMA,IAAM,YAAA,GAAe,4CAAA;AACrB,IAAM,WAAA,GAAc,sCAAA;AACpB,IAAM,eAAA,GAAkB,kBAAA;AACxB,IAAM,KAAA,GAAQ,2CAAA;AACd,IAAM,eAAA,GAAkB,wBAAA;AACxB,IAAM,YAAA,GAAe,kCAAA;AACrB,IAAM,WAAA,GAAc,+CAAA;AACpB,IAAM,UAAA,GAAa,yCAAA;AACnB,IAAM,SAAA,GAAY,oCAAA;AAClB,IAAM,QAAA,GAAW,4CAAA;AACjB,IAAM,YAAA,GAAe,gCAAA;AACrB,IAAM,MAAA,GAAS,yCAAA;AACf,IAAM,MAAA,GAAS,0CAAA;AACf,IAAM,WAAA,GAAc,yBAAA;AACpB,IAAM,UAAA,GAAa,oCAAA;AACnB,IAAM,UAAA,GAAa,wCAAA;AACnB,IAAM,eAAA,GAAkB,0CAAA;AACxB,IAAM,cAAA,GAAiB,oCAAA;AACvB,IAAM,MAAA,GAAS,gDAAA;AACf,IAAM,aAAA,GAAgB,yCAAA;AACtB,IAAM,gBAAA,GAAmB,6CAAA;AACzB,IAAM,aAAA,GAAgB,0CAAA;AAEtB,SAAS,gBAAgB,IAAA,EAAuB;AAC/C,EAAA,OACC,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,IACrB,SAAS,WAAA,IACT,IAAA,KAAS,WAAA,IACT,IAAA,CAAK,UAAA,CAAW,UAAU,CAAA,IAC1B,IAAA,CAAK,WAAW,KAAK,CAAA;AAEvB;AAGO,IAAM,gBAAA,GAAmB;AAMzB,SAAS,kBAAkB,IAAA,EAAuB;AACxD,EAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAClB,EAAA,IAAI,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACnC,EAAA,IAAI,IAAA,KAAS,iBAAiB,OAAO,IAAA;AACrC,EAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAC7B,EAAA,IAAI,IAAA,KAAS,iBAAiB,OAAO,IAAA;AACrC,EAAA,IAAI,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACnC,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,IAAI,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,IAAI,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,IAAI,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,IAAI,IAAA,KAAS,aAAa,OAAO,IAAA;AACjC,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACvC,EAAA,IAAI,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACtC,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,IAAI,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACrC,EAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACxC,EAAA,IAAI,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACrC,EAAA,IAAI,eAAA,CAAgB,IAAI,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,OAAO,KAAA;AACR;AAQA,SAAS,cAAc,QAAA,EAAsC;AAC5D,EAAA,OAAO;AAAA,IACN,MAAA,EAAQ,EAAA;AAAA,IACR,MAAA,EAAQ,SAAS,MAAA,IAAU,WAAA;AAAA,IAC3B,QAAA,EAAU,SAAS,QAAA,IAAY,EAAA;AAAA,IAC/B,QAAA,EAAU,SAAS,QAAA,IAAY,IAAA;AAAA,IAC/B,MAAA,EAAQ;AAAA,GACT;AACD;AAEA,SAAS,kBAAkB,IAAA,EAAkD;AAC5E,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AACjC,EAAA,IAAI,YAAY,CAAA,EAAG;AAClB,IAAA,OAAO;AAAA,MACN,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,QAAQ,CAAA;AAAA,MAC9B,QAAQC,qBAAAA,CAAqB,IAAA,CAAK,KAAA,CAAM,QAAA,GAAW,CAAC,CAAC;AAAA,KACtD;AAAA,EACD;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAG;AACnC;AAKO,SAAS,eAAA,CAAgB,KAAA,EAAe,QAAA,GAAqB,EAAC,EAAqB;AACzF,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAG3B,EAAA,MAAM,KAAA,GAAQ,QAAQ,WAAA,EAAY;AAClC,EAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,EAAE,QAAA,EAAU,KAAA,EAAO,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAAG;AACvE,IAAA,IAAI,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,EAAG;AAC7B,MAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA;AAChC,MAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,kBAAkB,IAAI,CAAA;AACjD,MAAA,OAAO;AAAA,QACN,MAAA;AAAA,QACA,MAAA,EAAQ,SAAS,MAAA,IAAU,WAAA;AAAA,QAC3B,QAAA,EAAU,SAAS,QAAA,IAAY,EAAA;AAAA,QAC/B,QAAA;AAAA,QACA;AAAA,OACD;AAAA,IACD;AAAA,EACD;AAGA,EAAA,IAAI,MAAM,UAAA,CAAW,SAAS,KAAK,KAAA,CAAM,UAAA,CAAW,UAAU,CAAA,EAAG;AAChE,IAAA,IAAI;AACH,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAO,CAAA;AAC3B,MAAA,MAAM,OAAO,GAAA,CAAI,QAAA;AACjB,MAAA,MAAM,SAAA,GAAY,GAAA,CAAI,QAAA,CAAS,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA;AAK3E,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,YAAY,CAAA;AACxC,MAAA,IAAI,QAAA,EAAU;AACb,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,IAAA;AAAA,UACV,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,SAC3B;AAAA,MACD;AAGA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA;AACtC,MAAA,IAAI,OAAA,IAAW,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACpC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,UACjB,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,IAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAGA,MAAA,IAAI,IAAA,KAAS,eAAA,IAAmB,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACrD,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,WAAA;AAAA,UAC3B,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,IAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAChC,MAAA,IAAI,OAAA,IAAW,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACpC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,MAAA;AAAA,UACR,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,IAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,IAAI,IAAA,KAAS,eAAA,IAAmB,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACrD,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,IAAA;AAAA,UAC3B,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,KAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAGA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,YAAY,CAAA;AACxC,MAAA,IAAI,QAAA,EAAU;AACb,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,MAAA,EAAQ,SAAS,MAAA,IAAU,IAAA;AAAA,UAC3B,QAAA,EAAU,EAAA;AAAA,UACV,QAAA,EAAU,KAAA;AAAA,UACV,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,SAC3B;AAAA,MACD;AAIA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA;AACtC,MAAA,IAAI,OAAA,EAAS;AACZ,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,UACjB,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,UACjB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,OAAA,CAAQ,CAAC,CAAC,CAAA,uBAAA,CAAA;AAAA,UACxC,QAAA,EAAU,cAAA;AAAA,UACV,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,SAC3B;AAAA,MACD;AAGA,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AACpC,MAAA,IAAI,MAAA,IAAU,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACnC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,UAChB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,cAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACxC,MAAA,IAAI,WAAA,IAAe,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACxC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,YAAY,CAAC,CAAA;AAAA,UACrB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,QAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA;AAChC,MAAA,IAAI,IAAA,EAAM;AACT,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,KAAK,CAAC,CAAA;AAAA,UACd,MAAA,EAAQ,KAAK,CAAC,CAAA;AAAA,UACd,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,KAAA,EAAQ,IAAA,CAAK,CAAC,CAAC,CAAA,gBAAA,CAAA;AAAA,UACxC,QAAA,EAAU,IAAA;AAAA,UACV,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,SAC3B;AAAA,MACD;AAGA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,YAAY,CAAA;AACxC,MAAA,IAAI,YAAY,SAAA,CAAU,CAAC,MAAM,MAAA,IAAU,SAAA,CAAU,SAAS,CAAA,EAAG;AAChE,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,aAAA;AAAA,UAC3B,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,IAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAClC,MAAA,IAAI,QAAA,EAAU;AACb,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,QAAA,CAAS,CAAC,CAAC,CAAA,aAAA,CAAA;AAAA,UACzC,QAAA,EAAU,IAAA;AAAA,UACV,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,SAC3B;AAAA,MACD;AAIA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAClC,MAAA,IAAI,QAAA,EAAU;AACb,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,MAAA,EAAS,QAAA,CAAS,CAAC,CAAC,CAAA,aAAA,CAAA;AAAA,UAC7C,QAAA,EAAU,IAAA;AAAA,UACV,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,SAC3B;AAAA,MACD;AAIA,MAAA,IAAI,IAAA,KAAS,WAAA,IAAe,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACjD,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,aAAA;AAAA,UAC3B,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,IAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AAC1C,MAAA,IAAI,YAAA,IAAgB,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACzC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,aAAa,CAAC,CAAA;AAAA,UACtB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,SAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AAC1C,MAAA,IAAI,YAAA,IAAgB,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACzC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,aAAa,CAAC,CAAA;AAAA,UACtB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,SAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,eAAe,CAAA;AAC9C,MAAA,IAAI,WAAA,EAAa;AAChB,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,YAAY,CAAC,CAAA;AAAA,UACrB,MAAA,EAAQ,YAAY,CAAC,CAAA;AAAA,UACrB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,WAAA,CAAY,CAAC,CAAC,CAAA,kBAAA,CAAA;AAAA,UAC5C,QAAA,EAAU,QAAA;AAAA,UACV,MAAA,EAAQ,SAAA,CAAU,IAAA,CAAK,GAAG;AAAA,SAC3B;AAAA,MACD;AACA,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,cAAc,CAAA;AAC5C,MAAA,IAAI,UAAA,IAAc,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACvC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,WAAW,CAAC,CAAA;AAAA,UACpB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,QAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAClC,MAAA,IAAI,QAAA,IAAY,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACrC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,UAClB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,UAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,IAAI,eAAA,CAAgB,IAAI,CAAA,IAAK,SAAA,CAAU,SAAS,CAAA,EAAG;AAClD,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,WAAA;AAAA,UAC3B,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,OAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,aAAa,CAAA;AAC1C,MAAA,IAAI,SAAA,IAAa,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACtC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,EAAA;AAAA,UAC3B,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,OAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAIA,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,gBAAgB,CAAA;AAChD,MAAA,IAAI,YAAA,IAAgB,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AACzC,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,YAAA,CAAa,CAAC,CAAA,IAAK,SAAS,MAAA,IAAU,KAAA;AAAA,UAC9C,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAAA,UACtC,QAAA,EAAU,OAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAGA,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,aAAa,CAAA;AAC1C,MAAA,IAAI,SAAA,IAAa,SAAA,CAAU,MAAA,IAAU,CAAA,KAAM,SAAA,CAAU,CAAC,CAAA,KAAM,KAAA,IAAS,SAAA,CAAU,CAAC,CAAA,KAAM,GAAA,CAAA,EAAM;AAC3F,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAA,CAAU,CAAC,CAAA,IAAK,SAAS,MAAA,IAAU,KAAA;AAAA,UAC3C,QAAA,EAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,KAAK,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA,EAAI,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA;AAAA,UACtE,QAAA,EAAU,OAAA;AAAA,UACV,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAOA,MAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAA,EAAG;AACxC,QAAA,OAAO;AAAA,UACN,GAAG,cAAc,QAAQ,CAAA;AAAA,UACzB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA;AAAA,SACvC;AAAA,MACD;AAGA,MAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACzB,QAAA,MAAM,WAAW,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA,CAAA;AAC7C,QAAA,OAAO;AAAA,UACN,MAAA,EAAQ,UAAU,CAAC,CAAA;AAAA,UACnB,MAAA,EAAQ,SAAS,MAAA,IAAU,WAAA;AAAA,UAC3B,QAAA;AAAA,UACA,QAAA,EAAU,SAAS,QAAA,IAAY,IAAA;AAAA,UAC/B,QAAQ,SAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAE,KAAK,GAAG;AAAA,SACpC;AAAA,MACD;AAGA,MAAA,OAAO;AAAA,QACN,GAAG,cAAc,QAAQ,CAAA;AAAA,QACzB,UAAU,CAAA,EAAG,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK,IAAI,IAAI,CAAA;AAAA,OACvC;AAAA,IACD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACD;AAGA,EAAA,MAAM,OAAA,GAAUC,kBAAiB,OAAO,CAAA;AACxC,EAAA,OAAO;AAAA,IACN,MAAA,EAAQ,OAAA;AAAA,IACR,MAAA,EAAQ,SAAS,MAAA,IAAU,WAAA;AAAA,IAC3B,QAAA,EAAU,SAAS,QAAA,IAAY,EAAA;AAAA,IAC/B,QAAA,EAAU,SAAS,QAAA,IAAY,IAAA;AAAA,IAC/B,MAAA,EAAQ;AAAA,GACT;AACD;AAMO,SAAS,aAAa,KAAA,EAAwB;AACpD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,EAAK,CAAE,WAAA,EAAY;AACvC,EAAA,IAAI,KAAA,CAAM,WAAW,SAAS,CAAA,IAAK,MAAM,UAAA,CAAW,UAAU,GAAG,OAAO,IAAA;AACxE,EAAA,KAAA,MAAW,MAAA,IAAU,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,EAAG;AAC7C,IAAA,IAAI,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,EAAG,OAAO,IAAA;AAAA,EACtC;AACA,EAAA,OAAO,KAAA;AACR;AAKO,SAAS,oBAAoB,MAAA,EAAkC;AACrE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,OAAO,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,QAAA,EAAW,MAAA,CAAO,MAAM,CAAA,CAAA,CAAG,CAAA;AACzD,EAAA,IAAI,OAAO,QAAA,EAAU,KAAA,CAAM,KAAK,CAAA,UAAA,EAAa,MAAA,CAAO,QAAQ,CAAA,CAAA,CAAG,CAAA;AAC/D,EAAA,IAAI,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,WAAA,QAAmB,IAAA,CAAK,CAAA,QAAA,EAAW,MAAA,CAAO,MAAM,CAAA,CAAA,CAAG,CAAA;AAC1F,EAAA,IAAI,MAAA,CAAO,aAAa,IAAA,EAAM,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,MAAA,CAAO,QAAQ,CAAA,CAAE,CAAA;AACtE,EAAA,IAAI,OAAO,MAAA,EAAQ,KAAA,CAAM,KAAK,CAAA,QAAA,EAAW,MAAA,CAAO,MAAM,CAAA,CAAA,CAAG,CAAA;AACzD,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,UAAA,EAAa,MAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GAAK,EAAA;AAC7D;AAaO,SAAS,YAAY,KAAA,EAAkC;AAC7D,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,EAAA,MAAM,KAAA,GAAQ,QAAQ,WAAA,EAAY;AAElC,EAAA,KAAA,MAAW,MAAA,IAAU,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,EAAG;AAC7C,IAAA,IAAI,KAAA,CAAM,UAAA,CAAW,MAAM,CAAA,EAAG;AAC7B,MAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,eAAA,CAAgB,OAAO,CAAA,EAAE;AAAA,IAC3D;AAAA,EACD;AAEA,EAAA,IAAI,MAAM,UAAA,CAAW,SAAS,KAAK,KAAA,CAAM,UAAA,CAAW,UAAU,CAAA,EAAG;AAChE,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI;AACH,MAAA,GAAA,GAAM,IAAI,IAAI,OAAO,CAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AACP,MAAA,OAAO;AAAA,QACN,IAAA,EAAM,aAAA;AAAA,QACN,GAAA,EAAK,IAAI,GAAA,CAAI,CAAA,QAAA,EAAW,QAAQ,OAAA,CAAQ,eAAA,EAAiB,EAAE,CAAC,CAAA,CAAE;AAAA,OAC/D;AAAA,IACD;AACA,IAAA,MAAM,MAAA,GAAS,gBAAgB,OAAO,CAAA;AACtC,IAAA,IAAI,MAAA,CAAO,MAAA,IAAU,iBAAA,CAAkB,GAAA,CAAI,QAAQ,CAAA,EAAG;AACrD,MAAA,OAAO,EAAE,IAAA,EAAM,gBAAA,EAAkB,MAAA,EAAO;AAAA,IACzC;AACA,IAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAA,EAAG;AACxC,MAAA,OAAO,EAAE,IAAA,EAAM,UAAA,EAAY,GAAA,EAAI;AAAA,IAChC;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,GAAA,EAAI;AAAA,EACnC;AAEA,EAAA,IAAI;AACH,IAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,KAAK,IAAI,GAAA,CAAI,OAAO,CAAA,EAAE;AAAA,EACrD,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,EAAE,MAAM,aAAA,EAAe,GAAA,EAAK,IAAI,GAAA,CAAI,CAAA,QAAA,EAAW,OAAO,CAAA,CAAE,CAAA,EAAE;AAAA,EAClE;AACD;;;ACjlBA,SAAS,kBAAkB,QAAA,EAA0B;AAEpD,EAAA,IAAI,KAAA,GAAQ,QAAA,CAAS,OAAA,CAAQ,iBAAA,EAAmB,GAAG,CAAA;AAEnD,EAAA,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAE/B,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,KAAU,GAAA,EAAK,OAAO,EAAA;AAEpC,EAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,GAAG,GAAG,KAAA,IAAS,GAAA;AACnC,EAAA,OAAO,KAAA;AACR;AAKA,SAAS,cAAA,CACR,QAAA,EACA,QAAA,EACA,MAAA,EACA,MAAA,EACS;AACT,EAAA,OAAO,oBAAA;AAAA,IACL,QAAA,KAAa,YAAY,IAAA,GAAO,QAAA;AAAA,IACjC,QAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA,IAAU;AAAA,GACX;AACD;AAOA,SAAS,YAAA,CACR,MAAA,EACA,IAAA,EACA,UAAA,EACsB;AACtB,EAAA,IAAI,CAAC,MAAA,CAAO,MAAA,IAAU,CAAC,iBAAA,CAAkB,IAAI,GAAG,OAAO,IAAA;AACvD,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,KAAa,SAAA,GAAY,OAAO,MAAA,CAAO,QAAA;AAC/D,EAAA,OAAO;AAAA,IACN,QAAA;AAAA,IACA,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,UAAA;AAAA,IACA,SAAA,EAAW,eAAe,MAAA,CAAO,QAAA,EAAU,OAAO,QAAA,EAAU,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,MAAM;AAAA,GACzF;AACD;AAMO,SAAS,gBAAA,GAAwC;AACvD,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,IAAA;AAE1C,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,MAAA,CAAO,SAAS,IAAI,CAAA;AAGxC,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;AAC3C,EAAA,IAAI,QAAA,EAAU;AACb,IAAA,IAAI;AACH,MAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,QAAQ,CAAA;AACjC,MAAA,MAAMC,OAAAA,GAAS,gBAAgB,QAAQ,CAAA;AACvC,MAAA,MAAM,IAAA,GAAO,YAAA,CAAaA,OAAAA,EAAQ,QAAA,CAAS,UAAU,EAAE,CAAA;AACvD,MAAA,IAAI,MAAM,OAAO,IAAA;AAAA,IAClB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACD;AAMA,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA;AACnD,EAAA,IAAI,CAAC,OAAO,MAAA,IAAU,CAAC,kBAAkB,GAAA,CAAI,QAAQ,GAAG,OAAO,IAAA;AAI/D,EAAA,MAAM,aAAa,MAAA,CAAO,MAAA,GAAS,CAAA,CAAA,EAAI,MAAA,CAAO,MAAM,CAAA,CAAA,GAAK,EAAA;AACzD,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,UAAA,IAAc,GAAG,CAAA;AAEtD,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,QAAA,KAAa,SAAA,GAAY,OAAO,MAAA,CAAO,QAAA;AAC/D,EAAA,OAAO;AAAA,IACN,QAAA;AAAA,IACA,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,UAAU,MAAA,CAAO,QAAA;AAAA,IACjB,UAAA;AAAA,IACA,SAAA,EAAW,eAAe,MAAA,CAAO,QAAA,EAAU,OAAO,QAAA,EAAU,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,MAAM;AAAA,GACzF;AACD;AAmBO,SAAS,yBAAA,CACf,OACA,IAAA,EACI;AACJ,EAAA,MAAM,KAAA,GAAQ,oBAAoB,IAAI,CAAA;AACtC,EAAA,MAAM,MAAA,GAAS,6BAAA,CAA8B,KAAA,EAAO,KAAK,CAAA;AAIzD,EAAA,IAAI,WAAiB,GAAA,KAAQ,KAAA,CAAM,UAAU,KAAA,CAAM,QAAA,IAAY,MAAM,aAAA,CAAA,EAAgB;AACpF,IAAA,OAAA,CAAQ,KAAA,CAAM,+CAA+C,KAAK,CAAA;AAAA,EACnE;AACA,EAAA,OAAO,MAAA;AACR;;;AC/IO,SAAS,eAAA,CAAmB,KAAa,YAAA,EAAoB;AACnE,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,YAAA;AAC1C,EAAA,IAAI;AACH,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,CAAQ,GAAG,CAAA;AACpC,IAAA,IAAI,GAAA,EAAK,OAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,YAAA;AACR;AAMO,SAAS,gBAAA,CAAiB,KAAa,KAAA,EAAsB;AACnE,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACnC,EAAA,IAAI;AACH,IAAA,YAAA,CAAa,OAAA,CAAQ,GAAA,EAAK,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AAAA,EAChD,CAAA,CAAA,MAAQ;AAAA,EAER;AACD;;;AChBO,IAAM,WAAN,MAAqB;AAAA,EACnB,GAAA,uBAAU,GAAA,EAAU;AAAA,EACnB,GAAA;AAAA,EACD,OAAA;AAAA,EAER,YAAY,IAAA,EAA6B;AACxC,IAAA,IAAI,KAAK,GAAA,IAAO,CAAA,EAAG,MAAM,IAAI,MAAM,2BAA2B,CAAA;AAC9D,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAChB,IAAA,IAAA,CAAK,UAAU,IAAA,CAAK,OAAA;AAAA,EACrB;AAAA,EAEA,IAAI,IAAA,GAAe;AAClB,IAAA,OAAO,KAAK,GAAA,CAAI,IAAA;AAAA,EACjB;AAAA,EAEA,IAAI,GAAA,EAAiB;AACpB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAAA,EACxB;AAAA,EAEA,IAAI,GAAA,EAAuB;AAC1B,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,IAAA,IAAI,CAAA,KAAM,QAAW,OAAO,MAAA;AAE5B,IAAA,IAAA,CAAK,GAAA,CAAI,OAAO,GAAG,CAAA;AACnB,IAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,CAAC,CAAA;AACnB,IAAA,OAAO,CAAA;AAAA,EACR;AAAA,EAEA,GAAA,CAAI,KAAQ,KAAA,EAAgB;AAC3B,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,EAAG;AACtB,MAAA,IAAA,CAAK,GAAA,CAAI,OAAO,GAAG,CAAA;AAAA,IACpB;AACA,IAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AACvB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,GAAA,EAAK;AAChC,MAAA,MAAM,SAAS,IAAA,CAAK,GAAA,CAAI,IAAA,EAAK,CAAE,MAAK,CAAE,KAAA;AACtC,MAAA,IAAI,WAAW,MAAA,EAAW;AAC1B,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA;AACnC,MAAA,IAAA,CAAK,GAAA,CAAI,OAAO,MAAM,CAAA;AACtB,MAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAO,CAAA;AAAA,IAC/B;AAAA,EACD;AAAA,EAEA,OAAO,GAAA,EAAiB;AACvB,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,IAAA,IAAI,CAAA,KAAM,QAAW,OAAO,KAAA;AAC5B,IAAA,IAAA,CAAK,GAAA,CAAI,OAAO,GAAG,CAAA;AACnB,IAAA,IAAA,CAAK,OAAA,GAAU,KAAK,CAAC,CAAA;AACrB,IAAA,OAAO,IAAA;AAAA,EACR;AAAA,EAEA,KAAA,GAAc;AACb,IAAA,IAAI,KAAK,OAAA,EAAS;AACjB,MAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,KAAK,GAAA,EAAK,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAA;AAAA,IACjD;AACA,IAAA,IAAA,CAAK,IAAI,KAAA,EAAM;AAAA,EAChB;AACD;;;ACZO,SAAS,qBACf,GAAA,EACA,EAAE,KAAA,EAAO,OAAA,EAAS,UAAS,EACd;AACb,EAAA,IAAI,MAAA,GAAiC,IAAA;AACrC,EAAA,IAAI,QAAA,GAAW,KAAA;AAEf,EAAA,MAAM,OAAA,GAAoC,CAAC,KAAA,KAAU;AACpD,IAAA,IAAI,QAAA,EAAU;AAKd,IAAA,IAAI,MAAA,SAAe,KAAA,EAAM;AACzB,IAAA,MAAM,IAAA,GAAO,IAAI,eAAA,EAAgB;AACjC,IAAA,MAAA,GAAS,IAAA;AACT,IAAA,OAAA,EAAQ;AACR,IAAA,KAAA,CAAM,YAAY;AACjB,MAAA,IAAI,OAAA,GAAoB,IAAA;AACxB,MAAA,IAAI;AACH,QAAA,OAAA,GAAU,MAAM,KAAA,CAAM;AAAA,UACrB,GAAA,EAAK,MAAM,MAAA,CAAO,GAAA;AAAA,UAClB,GAAA,EAAK,MAAM,MAAA,CAAO,GAAA;AAAA,UAClB,QAAQ,IAAA,CAAK;AAAA,SACb,CAAA;AAAA,MACF,SAAS,GAAA,EAAK;AAKb,QAAA,IAAI,aAAA,CAAc,GAAA,EAAK,IAAA,CAAK,MAAM,CAAA,EAAG;AACrC,QAAA,OAAA,GAAU,IAAA;AAAA,MACX;AACA,MAAA,IAAI,IAAA,CAAK,MAAA,CAAO,OAAA,IAAW,MAAA,KAAW,IAAA,EAAM;AAG3C,QAAA;AAAA,MACD;AACA,MAAA,IAAI,MAAA,KAAW,MAAM,MAAA,GAAS,IAAA;AAC9B,MAAA,QAAA,CAAS,OAAO,CAAA;AAAA,IACjB,CAAA,GAAG;AAAA,EACJ,CAAA;AAEA,EAAA,GAAA,CAAI,EAAA,CAAG,SAAS,OAAO,CAAA;AAEvB,EAAA,OAAO,SAAS,MAAA,GAAe;AAC9B,IAAA,IAAI,QAAA,EAAU;AACd,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,GAAA,CAAI,GAAA,CAAI,SAAS,OAAO,CAAA;AACxB,IAAA,IAAI,MAAA,EAAQ;AACX,MAAA,MAAA,CAAO,KAAA,EAAM;AACb,MAAA,MAAA,GAAS,IAAA;AAAA,IACV;AAAA,EACD,CAAA;AACD;AAEA,SAAS,aAAA,CAAc,KAAc,MAAA,EAA8B;AAClE,EAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,OAAO,KAAA;AAC5B,EAAA,IAAI,GAAA,YAAe,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,cAAc,OAAO,IAAA;AACrE,EAAA,IAAI,OAAO,OAAO,GAAA,KAAQ,QAAA,IAAa,GAAA,CAA0B,SAAS,YAAA,EAAc;AACvF,IAAA,OAAO,IAAA;AAAA,EACR;AACA,EAAA,OAAO,KAAA;AACR;;;ACvGA,eAAsB,sBAAsB,QAAA,EAAmD;AAC9F,EAAA,IAAI,cAAmC,EAAC;AACxC,EAAA,IAAI,OAAA,GAAU,QAAA;AAEd,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,KAAA,CAAM,yBAAyB,CAAA;AACxD,EAAA,IAAI,OAAA,EAAS;AACZ,IAAA,IAAI;AACH,MAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAK,GAAI,MAAM,OAAO,MAAM,CAAA;AAC7C,MAAA,WAAA,GAAc,KAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,KAAK,EAAC;AAAA,IAC1C,CAAA,CAAA,MAAQ;AAAA,IAER;AACA,IAAA,OAAA,GAAU,QAAA,CAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,EAAE,MAAM,CAAA;AAAA,EAC3C;AAGA,EAAA,MAAM,YAAwB,EAAC;AAC/B,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,IAAI,CAAA;AAChC,EAAA,IAAI,CAAA,GAAI,CAAA;AAER,EAAA,OAAO,CAAA,GAAI,MAAM,MAAA,EAAQ;AACxB,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,0BAA0B,CAAA;AAEnD,IAAA,IAAI,KAAA,EAAO;AACV,MAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,MAAA,MAAM,SAAA,GAAY,CAAA;AAClB,MAAA,MAAM,WAAqB,EAAC;AAC5B,MAAA,CAAA,EAAA;AAEA,MAAA,OAAO,IAAI,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,CAAC,MAAM,KAAA,EAAO;AAC9C,QAAA,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AACtB,QAAA,CAAA,EAAA;AAAA,MACD;AAEA,MAAA,SAAA,CAAU,IAAA,CAAK;AAAA,QACd,IAAA;AAAA,QACA,GAAA,EAAK,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAAA,QACvB,SAAA;AAAA,QACA,OAAA,EAAS;AAAA,OACT,CAAA;AAAA,IACF;AACA,IAAA,CAAA,EAAA;AAAA,EACD;AAEA,EAAA,OAAO,EAAE,WAAA,EAAa,OAAA,EAAS,SAAA,EAAU;AAC1C;AAMO,SAAS,oBAAA,CACf,MACA,YAAA,EACS;AACT,EAAA,OAAO,KAAK,OAAA,CAAQ,kCAAA,EAAoC,CAAC,KAAA,EAAO,SAAA,EAAW,QAAQ,OAAA,KAAY;AAC9F,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,GAAA,CAAI,SAAS,CAAA;AACvC,IAAA,IAAI,CAAC,MAAM,OAAO,KAAA;AAClB,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,EAAE,CAAC,CAAA;AACrC,IAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AACjB,IAAA,MAAM,KAAA,GAAQ,IAAI,OAAO,CAAA;AACzB,IAAA,OAAO,KAAA,KAAU,MAAA,GAAY,MAAA,CAAO,KAAK,CAAA,GAAI,KAAA;AAAA,EAC9C,CAAC,CAAA;AACF;AAMO,SAAS,cAAc,OAAA,EAAyB;AACtD,EAAA,OAAO,OAAA,CAAQ,OAAA;AAAA,IACd,8CAAA;AAAA,IACA,CAAC,CAAA,EAAG,IAAA,KAAS,CAAA,qBAAA,EAAwB,IAAI,CAAA,QAAA;AAAA,GAC1C;AACD;;;ACxFO,IAAM,qBAAN,MAAyB;AAAA,EACvB,MAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA,uBAAc,GAAA,EAAkE;AAAA,EAExF,WAAA,CAAY,MAAA,EAAqB,MAAA,EAAgB,MAAA,GAAS,EAAA,EAAI;AAC7D,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EACf;AAAA;AAAA,EAGA,MAAM,UAAA,CAAW,GAAA,EAAa,SAAA,EAAmD;AAChF,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,cAAA,CAAe,GAAG,CAAA;AAC9C,IAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAO,KAAA,CAAM,IAAA,CAAK,QAAQ,cAAc,CAAA;AAClE,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,IAAQ,EAAC;AAC7B,IAAA,IAAA,CAAK,QAAQ,GAAA,CAAI,SAAA,EAAW,EAAE,MAAA,EAAQ,MAAM,CAAA;AAC5C,IAAA,OAAO,IAAA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,GAAA,EAAqB;AAC3C,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,IAAA,CAAK,QAAQ,OAAO,GAAA;AACzC,IAAA,OAAO,IAAI,OAAA,CAAQ,oDAAA,EAAsD,CAAC,KAAA,EAAO,IAAI,IAAA,KAAS;AAC7F,MAAA,IAAI,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AAChF,QAAA,OAAO,KAAA;AAAA,MACR;AACA,MAAA,MAAM,QAAA,GAAW,CAAA,KAAA,EAAQ,IAAA,CAAK,MAAM,IAAI,IAAI,CAAA,CAAA;AAC5C,MAAA,OAAO,CAAA,EAAG,EAAE,CAAA,EAAA,EAAK,QAAQ,CAAA,EAAA,CAAA;AAAA,IAC1B,CAAC,CAAA;AAAA,EACF;AAAA,EAEA,UAAU,SAAA,EAAmB;AAC5B,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AAAA,EAClC;AAAA,EAEA,aAAA,GAAoD;AACnD,IAAA,MAAM,GAAA,uBAAU,GAAA,EAAmC;AACnD,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,EAAE,MAAM,CAAA,IAAK,KAAK,OAAA,EAAS;AAC5C,MAAA,GAAA,CAAI,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,IACnB;AACA,IAAA,OAAO,GAAA;AAAA,EACR;AAAA,EAEA,WAAW,SAAA,EAA6B;AACvC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AACxC,IAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AACpB,IAAA,OAAO,MAAM,MAAA,CAAO,OAAA;AAAA,EACrB;AACD;;;ACvDA,IAAM,MAAA,GAAS,KAAA;AAIf,SAAS,EAAA,CAAG,GAAA,EAAa,UAAA,GAAuB,EAAC,EAAgB;AAChE,EAAA,MAAM,CAAA,GAAI,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACpC,EAAA,IAAI,UAAA,CAAW,MAAA,EAAQ,CAAA,CAAE,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,MAAA,GAAS,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAC/E,EAAA,OAAO,CAAA;AACR;AAEA,SAAS,WAAW,GAAA,EAAqB;AACxC,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA;AAC7E;AAEA,SAAS,SAAS,IAAA,EAAiC;AAClD,EAAA,IAAI,MAAM,OAAA,CAAQ,IAAI,GAAG,OAAO,IAAA,CAAK,KAAK,EAAE,CAAA;AAC5C,EAAA,OAAO,IAAA,IAAQ,EAAA;AAChB;AAiDA,IAAM,aAAA,GAAgB,CAAC,WAAA,EAAa,YAAA,EAAc,aAAa,YAAY,CAAA;AAE3E,SAAS,WAAA,CAAY,QAAgB,IAAA,EAAsC;AAC1E,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,KAAA,EAAO,CAAC,cAAc,CAAC,CAAA;AACtC,EAAC,GAAA,CAAyB,GAAA,GAAM,CAAA,KAAA,EAAQ,MAAM,CAAA,QAAA,EAAW,QAAA,CAAS,IAAI,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,CAAA;AAC1F,EAAA,OAAO,GAAA;AACR;AAEA,SAAS,iBAAA,CAAkB,QAAmB,MAAA,EAAqC;AAElF,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAChB,MAAA,CAAO,OAAO,IAAI,CAAA,IAAK,OAAO,IAAI,CAAA;AAGnC,EAAA,KAAA,MAAW,OAAO,aAAA,EAAe;AAChC,IAAA,MAAM,CAAA,GAAI,QAAQ,GAAG,CAAA;AACrB,IAAA,IAAI,CAAA,EAAG,OAAO,WAAA,CAAY,GAAA,EAAK,CAAC,CAAA;AAAA,EACjC;AAEA,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,eAAe,CAAA,IAAK,QAAQ,cAAc,CAAA;AAC9D,EAAA,IAAI,GAAA,EAAK;AACR,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,KAAA,EAAO,CAAC,YAAY,CAAC,CAAA;AACxC,IAAA,OAAA,CAAQ,SAAA,GAAY,SAAS,GAAG,CAAA;AAChC,IAAA,OAAO,OAAA;AAAA,EACR;AAEA,EAAA,MAAM,IAAA,GAAO,QAAQ,WAAW,CAAA;AAChC,EAAA,IAAI,IAAA,EAAM;AACT,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,KAAA,EAAO,CAAC,aAAa,CAAC,CAAA;AACzC,IAAA,OAAA,CAAQ,SAAA,GAAY,SAAS,IAAI,CAAA;AACjC,IAAA,OAAO,OAAA;AAAA,EACR;AAEA,EAAA,MAAM,EAAA,GAAK,QAAQ,eAAe,CAAA;AAClC,EAAA,IAAI,EAAA,EAAI;AACP,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,KAAA,EAAO,CAAC,aAAa,CAAC,CAAA;AACzC,IAAA,OAAA,CAAQ,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,QAAA,CAAS,EAAE,CAAC,CAAA;AAChD,IAAA,OAAO,OAAA;AAAA,EACR;AAEA,EAAA,MAAM,KAAA,GAAQ,QAAQ,YAAY,CAAA;AAClC,EAAA,IAAI,KAAA,EAAO;AACV,IAAA,MAAM,OAAA,GAAU,EAAA,CAAG,KAAA,EAAO,CAAC,cAAc,CAAC,CAAA;AAC1C,IAAA,OAAA,CAAQ,WAAA,GAAc,SAAS,KAAK,CAAA;AACpC,IAAA,OAAO,OAAA;AAAA,EACR;AAEA,EAAA,MAAM,KAAA,GAAQ,QAAQ,YAAY,CAAA;AAClC,EAAA,IAAI,KAAA,EAAO;AACV,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,KAAA,EAAO,CAAC,aAAa,CAAC,CAAA;AACrC,IAAA,GAAA,CAAI,YAAY,MAAA,CAAO,IAAA,CAAK,WAAW,QAAA,CAAS,KAAK,CAAC,CAAC,CAAA;AACvD,IAAA,OAAO,GAAA;AAAA,EACR;AAEA,EAAA,OAAO,EAAA,CAAG,KAAA,EAAO,CAAC,cAAc,CAAC,CAAA;AAClC;AAEA,SAAS,YAAA,CAAa,QAAmB,MAAA,EAAqC;AAC7E,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,IAAA,IAAQ,QAAA;AACnD,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,KAAA,EAAO,CAAC,UAAU,CAAC,CAAA;AAClC,EAAA,GAAA,CAAI,SAAA,GAAY,OAAO,IAAA,CAAK,UAAA,CAAW,SAAS,MAAA,CAAO,IAAA,IAAQ,EAAE,CAAC,CAAC,CAAA;AACnE,EAAA,OAAO,GAAA;AACR;AAEA,SAAS,WAAA,CAAY,QAAmB,MAAA,EAAqC;AAC5E,EAAA,MAAM,GAAA,GAAM,EAAA,CAAG,KAAA,EAAO,CAAC,OAAO,CAAC,CAAA;AAC/B,EAAA,MAAM,OAAO,MAAA,CAAO,SAAA,IAAa,EAAC,EAAG,KAAK,IAAI,CAAA;AAC9C,EAAA,GAAA,CAAI,SAAA,GAAY,MAAA,CAAO,IAAA,CAAK,UAAA,CAAW,GAAG,CAAC,CAAA;AAC3C,EAAA,OAAO,GAAA;AACR;AAIA,SAAS,gBAAgB,OAAA,EAAmC;AAC3D,EAAA,IAAI,CAAC,OAAA,CAAQ,MAAA,EAAQ,OAAO,OAAA;AAC5B,EAAA,MAAM,SAAsB,CAAC,EAAE,GAAG,OAAA,CAAQ,CAAC,GAAG,CAAA;AAC9C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,MAAM,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnB,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AACrC,IAAA,IACC,CAAA,CAAE,WAAA,KAAgB,QAAA,IAClB,IAAA,CAAK,WAAA,KAAgB,QAAA,IAAA,CACpB,CAAA,CAAE,MAAA,IAAU,CAAA,CAAE,IAAA,OAAW,IAAA,CAAK,MAAA,IAAU,KAAK,IAAA,CAAA,EAC7C;AAED,MAAA,MAAM,QAAA,GAAW,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA,CAAK,IAAA,GAAO,CAAC,IAAA,CAAK,IAAA,IAAQ,EAAE,CAAA;AACxE,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA,GAAI,CAAA,CAAE,IAAA,GAAO,CAAC,CAAA,CAAE,IAAA,IAAQ,EAAE,CAAA;AAC5D,MAAA,IAAA,CAAK,IAAA,GAAO,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA;AAAA,IAClC,CAAA,MAAO;AACN,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,GAAG,CAAA,EAAG,CAAA;AAAA,IACrB;AAAA,EACD;AACA,EAAA,OAAO,MAAA;AACR;AAIA,SAAS,cAAA,CAAe,IAAA,EAAe,IAAA,EAAc,MAAA,EAAqC;AACzF,EAAA,MAAM,SAAS,EAAA,CAAG,KAAA,EAAO,CAAC,MAAA,EAAQ,WAAW,CAAC,CAAA;AAG9C,EAAA,MAAM,SAAS,QAAA,CAAS,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,SAAS,EAAE,CAAA;AACvD,EAAA,IAAI,MAAA,EAAQ;AACX,IAAA,MAAM,MAAA,GAAS,EAAA,CAAG,KAAA,EAAO,CAAC,OAAO,CAAC,CAAA;AAClC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,aAAA,IAAiB,IAAA,CAAK,eAAA;AACvC,IAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,GAAM,EAAA,EAAI;AACxC,MAAA,MAAA,CAAO,YAAA,CAAa,oBAAA,EAAsB,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,IACtD;AACA,IAAA,MAAM,GAAA,GAAM,GAAG,KAAK,CAAA;AACpB,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,MAAM,CAAA;AAC1C,IAAA,IAAA,CAAK,YAAA,CAAa,iBAAiB,IAAI,CAAA;AACvC,IAAA,IAAA,CAAK,SAAA,GAAY,QAAQ,IAAI,CAAA,CAAA;AAC7B,IAAA,IAAA,CAAK,YAAY,MAAA,CAAO,WAAA,CAAY,UAAA,CAAW,MAAM,GAAG,IAAI,CAAA;AAC5D,IAAA,GAAA,CAAI,YAAY,IAAI,CAAA;AACpB,IAAA,MAAA,CAAO,YAAY,GAAG,CAAA;AACtB,IAAA,MAAA,CAAO,YAAY,MAAM,CAAA;AAAA,EAC1B;AAGA,EAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,IAAA,CAAK,OAAA,IAAW,EAAE,CAAA;AACrD,EAAA,KAAA,MAAW,UAAU,UAAA,EAAY;AAChC,IAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,KAAA,EAAO,CAAC,QAAQ,CAAC,CAAA;AAClC,IAAA,IAAI,KAAA;AACJ,IAAA,QAAQ,OAAO,WAAA;AAAa,MAC3B,KAAK,cAAA;AAAA,MACL,KAAK,gBAAA;AAAA,MACL,KAAK,OAAA;AACJ,QAAA,KAAA,GAAQ,iBAAA,CAAkB,QAAQ,MAAM,CAAA;AACxC,QAAA;AAAA,MACD,KAAK,QAAA;AACJ,QAAA,KAAA,GAAQ,YAAA,CAAa,QAAQ,MAAM,CAAA;AACnC,QAAA;AAAA,MACD,KAAK,OAAA;AAAA,MACL,KAAK,OAAA;AACJ,QAAA,KAAA,GAAQ,WAAA,CAAY,QAAQ,MAAM,CAAA;AAClC,QAAA;AAAA,MACD;AACC,QAAA,KAAA,GAAQ,EAAA,CAAG,KAAA,EAAO,CAAC,cAAc,CAAC,CAAA;AAAA;AAEpC,IAAA,KAAA,CAAM,YAAY,KAAK,CAAA;AACvB,IAAA,MAAA,CAAO,YAAY,KAAK,CAAA;AAAA,EACzB;AAEA,EAAA,OAAO,MAAA;AACR;AAEA,SAAS,kBAAA,CAAmB,MAAe,MAAA,EAAqC;AAC/E,EAAA,MAAM,SAAS,EAAA,CAAG,KAAA,EAAO,CAAC,MAAA,EAAQ,eAAe,CAAC,CAAA;AAClD,EAAA,MAAM,SAAS,QAAA,CAAS,IAAA,CAAK,MAAA,IAAU,IAAA,CAAK,SAAS,EAAE,CAAA;AACvD,EAAA,MAAA,CAAO,SAAA,GAAY,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA;AACzC,EAAA,OAAO,MAAA;AACR;AAEA,SAAS,kBAAkB,IAAA,EAA4B;AACtD,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,KAAK,KAAA,IAAS,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA;AACtD,EAAA,MAAM,OAAA,GAAU,GAAG,CAAA,CAAA,EAAI,KAAK,IAAI,CAAC,MAAA,EAAQ,cAAc,CAAC,CAAA;AACxD,EAAA,OAAA,CAAQ,SAAA,GAAY,WAAW,QAAA,CAAS,IAAA,CAAK,UAAU,IAAA,CAAK,KAAA,IAAS,EAAE,CAAC,CAAA;AACxE,EAAA,OAAO,OAAA;AACR;AAEA,SAAS,cAAc,IAAA,EAA4B;AAClD,EAAA,MAAM,SAAS,EAAA,CAAG,KAAA,EAAO,CAAC,MAAA,EAAQ,UAAU,CAAC,CAAA;AAC7C,EAAA,MAAA,CAAO,SAAA,GAAY,WAAW,QAAA,CAAS,IAAA,CAAK,UAAU,IAAA,CAAK,KAAA,IAAS,EAAE,CAAC,CAAA;AACvE,EAAA,OAAO,MAAA;AACR;AAcO,SAAS,cAAA,CACf,KACA,MAAA,EAC+C;AAC/C,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,QAAA,IAAY,EAAC;AAC9B,EAAA,MAAM,IAAA,GAAO,KAAK,UAAA,EAAY,QAAA,IAAY,KAAK,aAAA,EAAe,IAAA,IAAQ,KAAK,QAAA,IAAY,QAAA;AACvF,EAAA,MAAM,aAAa,IAAA,CAAK,UAAA,EAAY,YAAA,IAAgB,IAAA,CAAK,eAAe,IAAA,IAAQ,EAAA;AAGhF,EAAA,IAAI,WAAsB,EAAC;AAC3B,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG;AAC7B,IAAA,QAAA,GAAW,GAAA,CAAI,KAAA;AAAA,EAChB,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA,EAAG;AACzC,IAAA,KAAA,MAAW,EAAA,IAAM,IAAI,UAAA,EAAY;AAChC,MAAA,IAAI,KAAA,CAAM,QAAQ,EAAA,CAAG,KAAK,GAAG,QAAA,CAAS,IAAA,CAAK,GAAG,EAAA,CAAG,KAAK,CAAA;AAAA,IACvD;AAAA,EACD;AAEA,EAAA,MAAM,QAAA,GAAW,EAAA,CAAG,KAAA,EAAO,CAAC,UAAU,CAAC,CAAA;AAEvC,EAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC5B,IAAA,IAAI,QAAA;AACJ,IAAA,QAAQ,KAAK,SAAA;AAAW,MACvB,KAAK,MAAA;AACJ,QAAA,QAAA,GAAW,cAAA,CAAe,IAAA,EAAM,IAAA,CAAK,QAAA,IAAY,MAAM,MAAM,CAAA;AAC7D,QAAA;AAAA,MACD,KAAK,UAAA;AACJ,QAAA,QAAA,GAAW,kBAAA,CAAmB,MAAM,MAAM,CAAA;AAC1C,QAAA;AAAA,MACD,KAAK,SAAA;AACJ,QAAA,QAAA,GAAW,kBAAkB,IAAI,CAAA;AACjC,QAAA;AAAA,MACD,KAAK,KAAA;AACJ,QAAA,QAAA,GAAW,cAAc,IAAI,CAAA;AAC7B,QAAA;AAAA,MACD;AACC,QAAA,QAAA,GAAW,cAAc,IAAI,CAAA;AAAA;AAE/B,IAAA,QAAA,CAAS,YAAY,QAAQ,CAAA;AAAA,EAC9B;AAEA,EAAA,OAAO;AAAA,IACN,OAAA,EAAS,QAAA;AAAA,IACT,MAAM,EAAE,UAAA,EAAY,UAAU,IAAA,EAAM,SAAA,EAAW,SAAS,MAAA;AAAO,GAChE;AACD;;;ACvPA,SAAS,eAAe,GAAA,EAAkB;AACzC,EAAA,MAAM,KAAK,GAAA,CAAI,YAAA;AACf,EAAA,IAAI,EAAA,EAAI;AAEP,IAAA,IAAI,GAAG,IAAA,KAAS,UAAA,IAAc,EAAA,CAAG,IAAA,KAAS,aAAa,OAAO,UAAA;AAE9D,IAAA,IAAI,GAAG,IAAA,KAAS,QAAA,IAAY,EAAA,CAAG,IAAA,KAAS,QAAQ,OAAO,SAAA;AACvD,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,MAAA,EAAQ,OAAO,MAAA;AAC/B,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,MAAA,EAAQ,OAAO,MAAA;AAC/B,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,MAAA,EAAQ,OAAO,SAAA;AAE/B,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,KAAA,IAAS,EAAA,CAAG,SAAS,SAAA,EAAW;AAC/C,MAAA,MAAM,IAAA,GAAO,GAAG,QAAA,IAAY,EAAA;AAC5B,MAAA,MAAM,MAAA,GAAS,GAAG,QAAA,KAAa,KAAA;AAC/B,MAAA,IAAI,IAAA,IAAQ,CAAA,EAAG,OAAO,MAAA,GAAS,SAAA,GAAY,UAAA;AAC3C,MAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAO,MAAA,GAAS,UAAA,GAAa,WAAA;AAC7C,MAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAO,MAAA,GAAS,SAAA,GAAY,UAAA;AAC5C,MAAA,OAAO,SAAS,QAAA,GAAW,SAAA;AAAA,IAC5B;AAEA,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,SAAA,EAAW,OAAO,CAAA,QAAA,EAAW,EAAA,CAAG,SAAA,IAAa,EAAE,CAAA,CAAA,EAAI,EAAA,CAAG,KAAA,IAAS,CAAC,CAAA,CAAA,CAAA;AAEhF,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,MAAA,EAAQ,OAAO,MAAA;AAC/B,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,MAAA,EAAQ,OAAO,MAAA;AAC/B,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,WAAA,EAAa,OAAO,WAAA;AAEpC,IAAA,IAAI,EAAA,CAAG,IAAA,KAAS,MAAA,EAAQ,OAAO,MAAA;AAAA,EAChC;AAGA,EAAA,MAAM,KAAK,GAAA,CAAI,cAAA;AACf,EAAA,IAAI,EAAA,KAAO,QAAQ,OAAO,SAAA;AAC1B,EAAA,IAAI,EAAA,KAAO,QAAQ,OAAO,MAAA;AAC1B,EAAA,IAAI,EAAA,KAAO,QAAQ,OAAO,MAAA;AAC1B,EAAA,IAAI,EAAA,KAAO,kBAAA,IAAsB,EAAA,KAAO,kBAAA,EAAoB,OAAO,WAAA;AACnE,EAAA,IAAI,EAAA,KAAO,SAAA,EAAW,OAAO,CAAA,QAAA,EAAW,GAAA,CAAI,aAAa,EAAE,CAAA,CAAA,EAAI,GAAA,CAAI,KAAA,IAAS,CAAC,CAAA,CAAA,CAAA;AAC7E,EAAA,IAAI,EAAA,KAAO,SAAS,OAAO,SAAA;AAC3B,EAAA,IAAI,EAAA,KAAO,UAAU,OAAO,UAAA;AAC5B,EAAA,IAAI,EAAA,KAAO,UAAU,OAAO,SAAA;AAC5B,EAAA,IAAI,EAAA,KAAO,UAAU,OAAO,QAAA;AAC5B,EAAA,IAAI,EAAA,KAAO,UAAU,OAAO,UAAA;AAC5B,EAAA,IAAI,EAAA,KAAO,WAAW,OAAO,WAAA;AAC7B,EAAA,IAAI,EAAA,KAAO,WAAW,OAAO,UAAA;AAC7B,EAAA,IAAI,EAAA,KAAO,WAAW,OAAO,SAAA;AAE7B,EAAA,MAAM,KAAK,GAAA,CAAI,IAAA;AACf,EAAA,IAAI,EAAA,KAAO,WAAW,OAAO,SAAA;AAC7B,EAAA,IAAI,EAAA,KAAO,SAAS,OAAO,SAAA;AAC3B,EAAA,IAAI,EAAA,KAAO,SAAS,OAAO,QAAA;AAC3B,EAAA,IAAI,EAAA,KAAO,SAAS,OAAO,WAAA;AAC3B,EAAA,IAAI,EAAA,KAAO,SAAS,OAAO,OAAA;AAC3B,EAAA,IAAI,EAAA,KAAO,UAAU,OAAO,QAAA;AAC5B,EAAA,IAAI,EAAA,KAAO,cAAc,OAAO,MAAA;AAChC,EAAA,IAAI,EAAA,KAAO,wBAAwB,OAAO,MAAA;AAE1C,EAAA,OAAO,SAAA;AACR;AAMA,eAAsB,oBAAoB,GAAA,EAA2C;AACpF,EAAA,MAAM,EAAE,oBAAA,EAAsB,kBAAA,EAAmB,GAAI,MAAM,OAAO,WAAW,CAAA;AAE7E,EAAA,MAAM,IAAA,GAAO,MAAM,kBAAA,CAAmB,EAAE,KAAK,CAAA;AAC7C,EAAA,MAAM,QAAA,GAAW,MAAM,oBAAA,CAAqB,IAAI,CAAA;AAGhD,EAAA,MAAM,QAAA,GAAW,SAAS,UAAA,CAAW,MAAA;AAAA,IACpC,CAAC,GAAA,EAAa,EAAA,KAAY,GAAA,GAAM,MAAA,CAAO,GAAG,QAAQ,CAAA;AAAA,IAClD;AAAA,GACD;AAGA,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,MAAA,CACtB,KAAA,CAAM,CAAC,CAAA,CACP,MAAA,CAAO,CAAC,GAAA,KAAa,IAAI,YAAA,KAAiB,MAAS,CAAA,CACnD,GAAA,CAAI,CAAC,GAAA,MAAc;AAAA,IACnB,MAAM,GAAA,CAAI,IAAA;AAAA,IACV,IAAA,EAAM,eAAe,GAAG;AAAA,GACzB,CAAE,CAAA;AAKH,EAAA,MAAM,kBAA4B,EAAC;AACnC,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA;AAC9B,EAAA,MAAM,YAAA,GAAe,MAAM,YAAA,IAAgB,CAAA;AAC3C,EAAA,IAAI,MAAA,GAAS,CAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,GAAI,YAAA,IAAgB,SAAS,QAAA,CAAS,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACzE,IAAA,MAAMC,GAAAA,GAAK,QAAA,CAAS,MAAA,CAAO,MAAM,CAAA;AACjC,IAAA,IAAIA,GAAAA,EAAI,IAAA,EAAM,eAAA,CAAgB,IAAA,CAAKA,IAAG,IAAI,CAAA;AAC1C,IAAA,MAAA,IAAU,YAAA,CAAa,QAAA,CAAS,MAAA,EAAQ,MAAM,CAAA;AAAA,EAC/C;AAGA,EAAA,IAAI,GAAA,GAA6B,IAAA;AACjC,EAAA,IAAI,gBAAA,GAAmB,KAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,SAAS,kBAAA,EAAoB,IAAA,CAAK,CAAC,EAAA,KAAY,EAAA,CAAG,QAAQ,KAAK,CAAA;AAC7E,EAAA,IAAI,KAAA,EAAO;AACV,IAAA,IAAI;AACH,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,SAAS,EAAE,CAAA;AAM5C,MAAA,IAAI,OAAA,CAAQ,cAAA,IAAkB,CAAC,OAAA,CAAQ,OAAA,EAAS;AAC/C,QAAA,gBAAA,GAAmB,IAAA;AAAA,MACpB;AAEA,MAAA,GAAA,GAAM;AAAA,QACL,aAAA,EAAe,QAAQ,cAAA,IAAkB,UAAA;AAAA,QACzC,SAAS;AAAC,OACX;AACA,MAAA,IAAI,QAAQ,OAAA,EAAS;AACpB,QAAA,KAAA,MAAW,CAAC,SAAS,OAAO,CAAA,IAAK,OAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,CAAA,EAAsB;AACpF,UAAA,GAAA,CAAI,OAAA,CAAQ,OAAO,CAAA,GAAI;AAAA,YACtB,QAAA,EAAU,QAAQ,QAAA,IAAY,KAAA;AAAA,YAC9B,aAAA,EAAe,OAAA,CAAQ,cAAA,IAAkB,EAAC;AAAA,YAC1C,GAAA,EAAK,QAAQ,GAAA,IAAO,IAAA;AAAA,YACpB,MAAM,OAAA,CAAQ;AAAA,WACf;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACD;AAGA,EAAA,MAAM,SAAA,GAAY,SAAS,UAAA,IAAc,IAAA;AAGzC,EAAA,MAAM,YAAA,GAAe,SAAS,UAAA,CAAW,MAAA;AAGzC,EAAA,IAAI,WAAA,GAA6B,IAAA;AACjC,EAAA,IAAI,eAAe,CAAA,IAAK,QAAA,CAAS,UAAA,CAAW,CAAC,EAAE,OAAA,EAAS;AACvD,IAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,IAAA,KAAA,MAAW,GAAA,IAAO,QAAA,CAAS,UAAA,CAAW,CAAC,EAAE,OAAA,EAAS;AACjD,MAAA,MAAM,KAAA,GAAQ,IAAI,SAAA,EAAW,KAAA;AAC7B,MAAA,IAAI,KAAA,EAAO,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,IAC5B;AACA,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACtB,MAAA,WAAA,GAAc,CAAC,GAAG,MAAM,CAAA,CAAE,CAAC,CAAA;AAAA,IAC5B,CAAA,MAAA,IAAW,MAAA,CAAO,IAAA,GAAO,CAAA,EAAG;AAC3B,MAAA,WAAA,GAAc,CAAC,GAAG,MAAM,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,IACpC;AAAA,EACD;AAEA,EAAA,OAAO;AAAA,IACN,QAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA;AAAA,IACA,GAAA;AAAA,IACA,gBAAA;AAAA,IACA,SAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACD;AACD;AAGA,SAAS,YAAA,CAAa,QAAe,KAAA,EAAuB;AAC3D,EAAA,MAAMA,GAAAA,GAAK,OAAO,KAAK,CAAA;AACvB,EAAA,IAAI,CAACA,KAAI,OAAO,CAAA;AAChB,EAAA,MAAM,CAAA,GAAIA,IAAG,YAAA,IAAgB,CAAA;AAC7B,EAAA,IAAI,SAAS,KAAA,GAAQ,CAAA;AACrB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAA,IAAU,YAAA,CAAa,QAAQ,MAAM,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,MAAA,GAAS,KAAA;AACjB;AAMO,SAAS,uBAAuB,GAAA,EAAoC;AAC1E,EAAA,MAAM,UAAA,GAAa,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAChD,EAAA,IAAI,CAAC,UAAA,EAAY,GAAA,EAAK,OAAO,IAAA;AAE7B,EAAA,MAAM,MAAM,UAAA,CAAW,GAAA;AAGvB,EAAA,IAAI,GAAA,CAAI,SAAS,MAAA,IAAU,GAAA,CAAI,YAAY,IAAA,EAAM,QAAA,CAAS,OAAO,CAAA,EAAG,OAAO,IAAA;AAG3E,EAAA,IAAI,GAAA,CAAI,EAAA,EAAI,SAAA,KAAc,MAAA,EAAQ;AACjC,IAAA,MAAM,IAAA,GAAO,IAAI,EAAA,CAAG,IAAA;AACpB,IAAA,IAAI,WAAA,CAAY,GAAA,CAAI,IAAI,CAAA,EAAG,OAAO,IAAA;AAClC,IAAA,OAAO,QAAQ,IAAI,CAAA,CAAA;AAAA,EACpB;AAEA,EAAA,OAAO,IAAA;AACR;AAMO,SAAS,qBAAqB,GAAA,EAAyC;AAC7E,EAAA,MAAM,UAAA,GAAa,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAChD,EAAA,IAAI,CAAC,UAAA,EAAY,aAAA,EAAe,MAAA,SAAe,EAAC;AAEhD,EAAA,MAAM,OAAA,GAA4C;AAAA,IACjD,KAAA,EAAO,OAAA;AAAA,IACP,UAAA,EAAY,YAAA;AAAA,IACZ,OAAA,EAAS,SAAA;AAAA,IACT,UAAA,EAAY,YAAA;AAAA,IACZ,eAAA,EAAiB,iBAAA;AAAA,IACjB,YAAA,EAAc;AAAA,GACf;AAEA,EAAA,MAAM,QAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,GAAA,IAAO,WAAW,aAAA,EAAe;AAE3C,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,KAAA,CAAM,GAAG,EAAE,CAAC,CAAA;AAC7B,IAAA,MAAM,MAAA,GAAS,QAAQ,IAAI,CAAA;AAC3B,IAAA,IAAI,MAAA,IAAU,CAAC,KAAA,CAAM,QAAA,CAAS,MAAM,CAAA,EAAG,KAAA,CAAM,KAAK,MAAM,CAAA;AAAA,EACzD;AACA,EAAA,OAAO,KAAA;AACR;AAMO,SAAS,cAAc,GAAA,EAA8D;AAC3F,EAAA,MAAM,UAAA,GAAa,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,aAAa,CAAA;AAChD,EAAA,IAAI,CAAC,UAAA,EAAY,IAAA,IAAQ,WAAW,IAAA,CAAK,MAAA,GAAS,GAAG,OAAO,IAAA;AAC5D,EAAA,OAAO,CAAC,UAAA,CAAW,IAAA,CAAK,CAAC,CAAA,EAAG,WAAW,IAAA,CAAK,CAAC,CAAA,EAAG,UAAA,CAAW,KAAK,CAAC,CAAA,EAAG,UAAA,CAAW,IAAA,CAAK,CAAC,CAAC,CAAA;AACvF;;;ACnOA,IAAM,eAAA,GAAkB,CAAC,WAAA,EAAa,UAAA,EAAY,QAAQ,CAAA;AAE1D,IAAM,iBAAiB,CAAC,WAAA,EAAa,SAAA,EAAW,UAAA,EAAY,oBAAoB,QAAQ,CAAA;AAaxF,IAAM,qBAAA,GAAwB,mDAAA;AAE9B,SAAS,yBAAyB,KAAA,EAAmC;AAIpE,EAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,OAAO,IAAA;AACxB,EAAA,OAAO,qBAAA,CAAsB,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC7C;AAEA,SAAS,qBAAqB,IAAA,EAA+B;AAC5D,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAC/B,EAAA,KAAA,MAAW,QAAQ,eAAA,EAAiB;AACnC,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,MAAM,CAAA,EAAG;AAC1C,MAAA,IACC,KAAA,CAAM,OAAA,CAAQ,KAAA,EAAO,KAAK,KAC1B,KAAA,CAAM,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,IACzB,KAAA,CAAM,IAAA,IACN,wBAAA,CAAyB,KAAK,CAAA,EAC7B;AACD,QAAA,OAAO,KAAA,CAAM,IAAA;AAAA,MACd;AAAA,IACD;AAAA,EACD;AACA,EAAA,KAAA,MAAW,OAAO,cAAA,EAAgB;AACjC,IAAA,MAAM,KAAA,GAAQ,OAAO,GAAG,CAAA;AACxB,IAAA,IAAI,OAAO,IAAA,IAAQ,wBAAA,CAAyB,KAAK,CAAA,SAAU,KAAA,CAAM,IAAA;AAAA,EAClE;AACA,EAAA,OAAO,IAAA;AACR;AAEA,SAAS,kBAAkB,IAAA,EAA0B;AACpD,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,EAAA,KAAA,MAAW,SAAS,MAAA,CAAO,MAAA,CAAO,KAAK,MAAA,IAAU,EAAE,CAAA,EAAG;AACrD,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAA,EAAO,KAAK,CAAA,EAAG;AAChC,MAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,KAAA,EAAO;AAC/B,QAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,GAAA,CAAI,IAAI,IAAI,CAAA;AAAA,MAC3C;AAAA,IACD;AAAA,EACD;AACA,EAAA,OAAO,CAAC,GAAG,GAAG,CAAA,CAAE,IAAA,EAAK;AACtB;AAEA,SAAS,UAAA,CAAW,OAAgC,GAAA,EAA4B;AAC/E,EAAA,MAAM,CAAA,GAAI,MAAM,GAAG,CAAA;AACnB,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,QAAA,CAAS,CAAC,GAAG,OAAO,CAAA;AACxD,EAAA,IAAI,OAAO,MAAM,QAAA,EAAU;AAC1B,IAAA,MAAM,CAAA,GAAI,OAAO,CAAC,CAAA;AAClB,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EACjC;AACA,EAAA,OAAO,IAAA;AACR;AAEA,SAAS,UAAA,CAAW,OAAgC,GAAA,EAA4B;AAC/E,EAAA,MAAM,CAAA,GAAI,MAAM,GAAG,CAAA;AACnB,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,CAAE,MAAA,GAAS,IAAI,CAAA,GAAI,IAAA;AACpD;AAEA,SAAS,eAAA,CAAgB,OAAgC,GAAA,EAAuB;AAC/E,EAAA,MAAM,CAAA,GAAI,MAAM,GAAG,CAAA;AACnB,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,SAAU,EAAC;AAC/B,EAAA,OAAO,EAAE,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA;AAC1D;AAGO,SAAS,gBAAgB,IAAA,EAA8B;AAC7D,EAAA,MAAM,KAAA,GAAS,IAAA,CAAK,UAAA,IAAc,EAAC;AACnC,EAAA,MAAM,IAAA,GACL,MAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,MAAA,IAAU,CAAA,GAC5C;AAAA,IACD,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,IACnB,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,IACnB,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,IACnB,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,CAAC;AAAA,GACpB,GACC,IAAA;AACJ,EAAA,OAAO;AAAA,IACN,EAAA,EAAI,MAAA,CAAO,IAAA,CAAK,EAAA,IAAM,EAAE,CAAA;AAAA,IACxB,YAAY,OAAO,IAAA,CAAK,UAAA,KAAe,QAAA,GAAW,KAAK,UAAA,GAAa,IAAA;AAAA,IACpE,IAAA;AAAA,IACA,UAAU,UAAA,CAAW,KAAA,EAAO,UAAU,CAAA,IAAK,UAAA,CAAW,OAAO,gBAAgB,CAAA;AAAA,IAC7E,WAAA,EAAa,UAAA,CAAW,KAAA,EAAO,cAAc,CAAA;AAAA,IAC7C,UAAA,EAAY,UAAA,CAAW,KAAA,EAAO,gBAAgB,CAAA;AAAA,IAC9C,GAAA,EAAK,UAAA,CAAW,KAAA,EAAO,KAAK,CAAA;AAAA,IAC5B,QAAA,EAAU,UAAA,CAAW,KAAA,EAAO,UAAU,CAAA;AAAA,IACtC,aAAA,EAAe,UAAA,CAAW,KAAA,EAAO,eAAe,CAAA;AAAA,IAChD,WAAA,EAAa,eAAA,CAAgB,KAAA,EAAO,aAAa,CAAA;AAAA,IACjD,IAAA,EAAM,UAAA,CAAW,KAAA,EAAO,WAAW,CAAA;AAAA,IACnC,aAAA,EAAe,qBAAqB,IAAI,CAAA;AAAA,IACxC,UAAA,EAAY,kBAAkB,IAAI,CAAA;AAAA,IAClC,GAAA,EAAK;AAAA,GACN;AACD;AA4EO,IAAM,2BAAA,GAA8B;AAGpC,IAAM,uBAAA,GAA0B;AAEvC,IAAM,UAAA,GAAa,KAAA;AACnB,IAAM,cAAc,UAAA,GAAa,MAAA;AAWjC,IAAM,cAAA,GAAsC,CAAC,YAAA,EAAc,KAAK,CAAA;AAChE,IAAM,WAAA,GAAgC;AAAA,EACrC,YAAA;AAAA,EACA,UAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA;AACD,CAAA;AAEA,SAAS,iBAAA,CAAkB,OAAuB,KAAA,EAA+C;AAChG,EAAA,IAAI,MAAM,MAAA,CAAO,iBAAA;AACjB,EAAA,IAAI,MAAM,MAAA,CAAO,iBAAA;AACjB,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACtB,IAAA,MAAM,KAAA,GAAQ,EAAE,KAAK,CAAA;AACrB,IAAA,IAAI,SAAS,IAAA,IAAQ,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC9C,IAAA,IAAI,KAAA,GAAQ,KAAK,GAAA,GAAM,KAAA;AACvB,IAAA,IAAI,KAAA,GAAQ,KAAK,GAAA,GAAM,KAAA;AACvB,IAAA,KAAA,EAAA;AAAA,EACD;AACA,EAAA,IAAI,KAAA,KAAU,CAAA,IAAK,GAAA,KAAQ,GAAA,EAAK,OAAO,IAAA;AACvC,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,GAAA,EAAK,KAAK,KAAA,EAAM;AAClD;AAEA,SAAS,cAAA,CAAe,OAAuB,KAAA,EAAyC;AACvF,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACtB,IAAA,MAAM,GAAA,GAAM,EAAE,KAAK,CAAA;AACnB,IAAA,IAAI,OAAO,IAAA,EAAM;AACjB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACvB,MAAA,KAAA,MAAW,IAAA,IAAQ,GAAA,EAAK,MAAA,CAAO,GAAA,CAAI,IAAA,EAAA,CAAO,OAAO,GAAA,CAAI,IAAI,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAAA,IACrE,WAAW,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,CAAI,SAAS,CAAA,EAAG;AACrD,MAAA,MAAA,CAAO,IAAI,GAAA,EAAA,CAAM,MAAA,CAAO,IAAI,GAAG,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,IAC3C;AAAA,EACD;AACA,EAAA,IAAI,MAAA,CAAO,IAAA,GAAO,CAAA,EAAG,OAAO,IAAA;AAC5B,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,MAAA,CAAO,OAAA,EAAS,CAAA,CACjC,GAAA,CAAI,CAAC,CAAC,KAAA,EAAO,KAAK,OAAO,EAAE,KAAA,EAAO,KAAA,EAAM,CAAE,CAAA,CAC1C,IAAA,CAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,KAAA,CAAM,aAAA,CAAc,CAAA,CAAE,KAAK,CAAC,CAAA;AACpE,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,MAAA,EAAO;AACtC;AAQO,SAAS,gBAAgB,MAAA,EAAqC;AACpE,EAAA,IAAI,MAAA,IAAU,EAAA,GAAK,UAAA,EAAY,OAAO,KAAA;AACtC,EAAA,IAAI,MAAA,IAAU,CAAA,GAAI,WAAA,EAAa,OAAO,MAAA;AACtC,EAAA,IAAI,MAAA,IAAU,EAAA,GAAK,WAAA,EAAa,OAAO,OAAA;AACvC,EAAA,OAAO,MAAA;AACR;AAGA,SAAS,YAAY,CAAA,EAAmB;AACvC,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,CAAC,CAAA;AACpB,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,cAAA,EAAe,EAAG,EAAE,WAAA,EAAY,EAAG,CAAA,CAAE,UAAA,EAAY,CAAA;AACpE;AAGA,SAAS,aAAa,CAAA,EAAmB;AACxC,EAAA,MAAM,QAAA,GAAW,YAAY,CAAC,CAAA;AAE9B,EAAA,MAAM,GAAA,GAAM,IAAI,IAAA,CAAK,QAAQ,EAAE,SAAA,EAAU;AACzC,EAAA,MAAM,UAAA,GAAA,CAAc,MAAM,CAAA,IAAK,CAAA;AAC/B,EAAA,OAAO,WAAW,UAAA,GAAa,UAAA;AAChC;AAGA,SAAS,cAAc,CAAA,EAAmB;AACzC,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,CAAC,CAAA;AACpB,EAAA,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,cAAA,IAAkB,CAAA,CAAE,WAAA,IAAe,CAAC,CAAA;AACvD;AAGA,SAAS,aAAa,CAAA,EAAmB;AACxC,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,CAAC,CAAA;AACpB,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,CAAE,cAAA,EAAe,EAAG,GAAG,CAAC,CAAA;AACzC;AAEA,SAAS,QAAA,CAAS,GAAW,CAAA,EAAgC;AAC5D,EAAA,QAAQ,CAAA;AAAG,IACV,KAAK,KAAA;AACJ,MAAA,OAAO,YAAY,CAAC,CAAA;AAAA,IACrB,KAAK,MAAA;AACJ,MAAA,OAAO,aAAa,CAAC,CAAA;AAAA,IACtB,KAAK,OAAA;AACJ,MAAA,OAAO,cAAc,CAAC,CAAA;AAAA,IACvB,KAAK,MAAA;AACJ,MAAA,OAAO,aAAa,CAAC,CAAA;AAAA;AAExB;AAGA,SAAS,OAAA,CAAQ,GAAW,CAAA,EAAgC;AAC3D,EAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,CAAC,CAAA;AACpB,EAAA,QAAQ,CAAA;AAAG,IACV,KAAK,KAAA;AACJ,MAAA,OAAO,CAAA,GAAI,UAAA;AAAA,IACZ,KAAK,MAAA;AACJ,MAAA,OAAO,IAAI,CAAA,GAAI,UAAA;AAAA,IAChB,KAAK,OAAA;AACJ,MAAA,OAAO,IAAA,CAAK,IAAI,CAAA,CAAE,cAAA,IAAkB,CAAA,CAAE,WAAA,EAAY,GAAI,CAAA,EAAG,CAAC,CAAA;AAAA,IAC3D,KAAK,MAAA;AACJ,MAAA,OAAO,KAAK,GAAA,CAAI,CAAA,CAAE,gBAAe,GAAI,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA;AAE/C;AAEA,SAAS,mBAAmB,KAAA,EAA6C;AACxE,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACtB,IAAA,IAAI,CAAC,EAAE,QAAA,EAAU;AACjB,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,QAAQ,CAAA;AAC/B,IAAA,IAAI,OAAO,QAAA,CAAS,CAAC,CAAA,EAAG,UAAA,CAAW,KAAK,CAAC,CAAA;AAAA,EAC1C;AACA,EAAA,IAAI,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,IAAI,GAAA,GAAM,WAAW,CAAC,CAAA;AACtB,EAAA,IAAI,GAAA,GAAM,WAAW,CAAC,CAAA;AACtB,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC3B,IAAA,IAAI,CAAA,GAAI,KAAK,GAAA,GAAM,CAAA;AACnB,IAAA,IAAI,CAAA,GAAI,KAAK,GAAA,GAAM,CAAA;AAAA,EACpB;AACA,EAAA,IAAI,GAAA,KAAQ,KAAK,OAAO,IAAA;AAExB,EAAA,IAAI,WAAA,GAAc,eAAA,CAAgB,GAAA,GAAM,GAAG,CAAA;AAC3C,EAAA,IAAI,QAAA,GAAW,eAAA,CAAgB,GAAA,EAAK,GAAA,EAAK,WAAW,CAAA;AAKpD,EAAA,OAAO,QAAA,CAAS,MAAA,GAAS,2BAAA,IAA+B,WAAA,KAAgB,MAAA,EAAQ;AAC/E,IAAA,WAAA,GAAc,mBAAmB,WAAW,CAAA;AAC5C,IAAA,QAAA,GAAW,eAAA,CAAgB,GAAA,EAAK,GAAA,EAAK,WAAW,CAAA;AAAA,EACjD;AAEA,EAAA,MAAM,OAAO,IAAI,KAAA,CAAc,SAAS,MAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AACtD,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC3B,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,QAAA,EAAU,CAAC,CAAA;AACpC,IAAA,IAAA,CAAK,GAAG,CAAA,EAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACN,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,UAAA;AAAA,IACP,GAAA,EAAK,IAAI,IAAA,CAAK,GAAG,EAAE,WAAA,EAAY;AAAA,IAC/B,GAAA,EAAK,IAAI,IAAA,CAAK,GAAG,EAAE,WAAA,EAAY;AAAA,IAC/B,OAAO,UAAA,CAAW,MAAA;AAAA,IAClB,IAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACD;AACD;AAEA,SAAS,mBAAmB,CAAA,EAA6C;AACxE,EAAA,QAAQ,CAAA;AAAG,IACV,KAAK,KAAA;AACJ,MAAA,OAAO,MAAA;AAAA,IACR,KAAK,MAAA;AACJ,MAAA,OAAO,OAAA;AAAA,IACR,KAAK,OAAA;AAAA,IACL,KAAK,MAAA;AACJ,MAAA,OAAO,MAAA;AAAA;AAEV;AAGA,SAAS,eAAA,CAAgB,GAAA,EAAa,GAAA,EAAa,CAAA,EAAkC;AACpF,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,MAAA,GAAS,QAAA,CAAS,GAAA,EAAK,CAAC,CAAA;AAC5B,EAAA,MAAM,IAAA,GAAO,GAAA;AAGb,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,8BAA8B,CAAA,IAAK,MAAA,IAAU,MAAM,CAAA,EAAA,EAAK;AAC3E,IAAA,KAAA,CAAM,KAAK,MAAM,CAAA;AACjB,IAAA,MAAA,GAAS,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAAA,EAC3B;AACA,EAAA,OAAO,KAAA;AACR;AAMA,SAAS,YAAA,CAAa,OAAiB,CAAA,EAAmB;AACzD,EAAA,IAAI,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA,EAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,CAAA,IAAK,MAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,EAAG,OAAO,MAAM,MAAA,GAAS,CAAA;AACxD,EAAA,IAAI,EAAA,GAAK,CAAA;AACT,EAAA,IAAI,EAAA,GAAK,MAAM,MAAA,GAAS,CAAA;AACxB,EAAA,OAAO,KAAK,EAAA,EAAI;AACf,IAAA,MAAM,GAAA,GAAO,EAAA,GAAK,EAAA,GAAK,CAAA,KAAO,CAAA;AAC9B,IAAA,IAAI,KAAA,CAAM,GAAG,CAAA,IAAK,CAAA,EAAG,EAAA,GAAK,GAAA;AAAA,cAChB,GAAA,GAAM,CAAA;AAAA,EACjB;AACA,EAAA,OAAO,EAAA;AACR;AAaO,SAAS,YAAY,KAAA,EAAiC;AAC5D,EAAA,MAAM,UAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AACnC,IAAA,MAAM,CAAA,GAAI,iBAAA,CAAkB,KAAA,EAAO,KAAK,CAAA;AACxC,IAAA,IAAI,CAAA,EAAG,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA;AAAA,EACtB;AACA,EAAA,MAAM,QAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,SAAS,WAAA,EAAa;AAChC,IAAA,MAAM,CAAA,GAAI,cAAA,CAAe,KAAA,EAAO,KAAK,CAAA;AACrC,IAAA,IAAI,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA;AAAA,EACpB;AACA,EAAA,OAAO;AAAA,IACN,QAAA,EAAU,mBAAmB,KAAK,CAAA;AAAA,IAClC,OAAA;AAAA,IACA,KAAA;AAAA,IACA,OAAO,KAAA,CAAM;AAAA,GACd;AACD;AAgBA,SAAS,cAAA,CAAe,OAAsB,KAAA,EAAgD;AAC7F,EAAA,IAAI,SAAS,IAAA,IAAQ,CAAC,OAAO,QAAA,CAAS,KAAK,GAAG,OAAO,KAAA;AACrD,EAAA,IAAI,MAAM,GAAA,IAAO,IAAA,IAAQ,KAAA,GAAQ,KAAA,CAAM,KAAK,OAAO,KAAA;AACnD,EAAA,IAAI,MAAM,GAAA,IAAO,IAAA,IAAQ,KAAA,GAAQ,KAAA,CAAM,KAAK,OAAO,KAAA;AACnD,EAAA,OAAO,IAAA;AACR;AAEA,SAAS,SAAA,CAAU,OAAiC,KAAA,EAA0B;AAC7E,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAC/B,EAAA,IAAI,KAAA,IAAS,MAAM,OAAO,KAAA;AAC1B,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,KAAA,CAAM,QAAA,CAAS,CAAC,CAAC,CAAA;AACpE,EAAA,OAAO,KAAA,CAAM,SAAS,KAAK,CAAA;AAC5B;AAEA,SAAS,eAAA,CAAgB,OAAsB,KAAA,EAAgD;AAC9F,EAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAC1B,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,GAAG,OAAO,KAAA;AAChC,EAAA,IAAI,MAAM,GAAA,EAAK;AACd,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC9B,IAAA,IAAI,OAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,GAAI,GAAG,OAAO,KAAA;AAAA,EACzC;AACA,EAAA,IAAI,MAAM,GAAA,EAAK;AACd,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC9B,IAAA,IAAI,OAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,GAAI,GAAG,OAAO,KAAA;AAAA,EACzC;AACA,EAAA,OAAO,IAAA;AACR;AAOO,SAAS,WAAA,CACf,OACA,KAAA,EACiB;AACjB,EAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,EAAA,MAAM,KAAK,KAAA,CAAM,QAAA;AACjB,EAAA,MAAM,MAAM,KAAA,CAAM,OAAA;AAClB,EAAA,MAAM,QAAQ,KAAA,CAAM,KAAA;AACpB,EAAA,MAAM,WAAA,GAAc,EAAA,KAAO,EAAA,CAAG,GAAA,IAAO,EAAA,CAAG,GAAA,CAAA;AACxC,EAAA,MAAM,UAAA,GAAa,GAAA,IAAO,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,MAAM,CAAA,CAAE,GAAA,IAAO,IAAA,IAAQ,CAAA,CAAE,OAAO,IAAA,CAAK,CAAA;AAC9F,EAAA,MAAM,QAAA,GAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,KAAM,MAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,SAAS,CAAC,CAAA;AAC3F,EAAA,IAAI,CAAC,WAAA,IAAe,CAAC,UAAA,IAAc,CAAC,UAAU,OAAO,KAAA;AAErD,EAAA,OAAO,KAAA,CAAM,MAAA,CAAO,CAAC,IAAA,KAAS;AAC7B,IAAA,IAAI,WAAA,IAAe,MAAM,CAAC,eAAA,CAAgB,KAAK,QAAA,EAAU,EAAE,GAAG,OAAO,KAAA;AACrE,IAAA,IAAI,cAAc,GAAA,EAAK;AACtB,MAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AACnC,QAAA,MAAM,KAAA,GAAQ,IAAI,KAAK,CAAA;AACvB,QAAA,IAAI,CAAC,KAAA,IAAU,KAAA,CAAM,OAAO,IAAA,IAAQ,KAAA,CAAM,OAAO,IAAA,EAAO;AACxD,QAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,KAAK,CAAA,EAAG,KAAK,GAAG,OAAO,KAAA;AAAA,MACjD;AAAA,IACD;AACA,IAAA,IAAI,YAAY,KAAA,EAAO;AACtB,MAAA,KAAA,MAAW,SAAS,WAAA,EAAa;AAChC,QAAA,MAAM,KAAA,GAAQ,MAAM,KAAK,CAAA;AACzB,QAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,WAAW,CAAA,EAAG;AACjD,QAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,KAAK,CAAA,EAA+B,KAAK,GAAG,OAAO,KAAA;AAAA,MACxE;AAAA,IACD;AACA,IAAA,OAAO,IAAA;AAAA,EACR,CAAC,CAAA;AACF;AAkBO,SAAS,SAAA,CAAU,OAAuB,IAAA,EAAiC;AACjF,EAAA,MAAM,GAAA,GAAM,MAAM,KAAA,EAAM;AACxB,EAAA,MAAM,GAAA,GAAM,cAAc,IAAI,CAAA;AAC9B,EAAA,GAAA,CAAI,KAAK,GAAG,CAAA;AACZ,EAAA,OAAO,GAAA;AACR;AAEA,SAAS,cAAc,IAAA,EAA+D;AACrF,EAAA,QAAQ,IAAA;AAAM,IACb,KAAK,eAAA;AACJ,MAAA,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,qBAAA,CAAsB,SAAA,CAAU,CAAA,CAAE,QAAQ,CAAA,EAAG,SAAA,CAAU,CAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,IACpF,KAAK,cAAA;AACJ,MAAA,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,qBAAA,CAAsB,SAAA,CAAU,CAAA,CAAE,QAAQ,CAAA,EAAG,SAAA,CAAU,CAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,IACpF,KAAK,WAAA;AACJ,MAAA,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,sBAAsB,CAAA,CAAE,UAAA,EAAY,EAAE,UAAU,CAAA;AAAA,IAClE,KAAK,YAAA;AACJ,MAAA,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,sBAAsB,CAAA,CAAE,UAAA,EAAY,EAAE,UAAU,CAAA;AAAA,IAClE,KAAK,SAAA;AACJ,MAAA,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,sBAAsB,CAAA,CAAE,GAAA,EAAK,EAAE,GAAG,CAAA;AAAA,IACpD,KAAK,UAAA;AACJ,MAAA,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,sBAAsB,CAAA,CAAE,GAAA,EAAK,EAAE,GAAG,CAAA;AAAA,IACpD,KAAK,QAAA;AACJ,MAAA,OAAO,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,EAAA,CAAG,aAAA,CAAc,EAAE,EAAE,CAAA;AAAA;AAE3C;AAEA,SAAS,UAAU,CAAA,EAAiC;AACnD,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACtB,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,GAAI,CAAA,GAAI,IAAA;AACjC;AAEA,SAAS,qBAAA,CAAsB,GAAkB,CAAA,EAA0B;AAC1E,EAAA,MAAM,WAAW,CAAA,IAAK,IAAA,IAAQ,CAAC,MAAA,CAAO,SAAS,CAAC,CAAA;AAChD,EAAA,MAAM,WAAW,CAAA,IAAK,IAAA,IAAQ,CAAC,MAAA,CAAO,SAAS,CAAC,CAAA;AAChD,EAAA,IAAI,QAAA,IAAY,UAAU,OAAO,CAAA;AACjC,EAAA,IAAI,UAAU,OAAO,CAAA;AACrB,EAAA,IAAI,UAAU,OAAO,EAAA;AACrB,EAAA,OAAQ,CAAA,GAAgB,CAAA;AACzB;AAKO,SAAS,iBAAiB,KAAA,EAA+C;AAC/E,EAAA,IAAI,CAAC,OAAO,OAAO,KAAA;AACnB,EAAA,IAAI,KAAA,CAAM,aAAa,KAAA,CAAM,QAAA,CAAS,OAAO,KAAA,CAAM,QAAA,CAAS,MAAM,OAAO,IAAA;AACzE,EAAA,IAAI,MAAM,OAAA,EAAS;AAClB,IAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,EAAG;AAC7C,MAAA,IAAI,MAAM,CAAA,CAAE,GAAA,IAAO,QAAQ,CAAA,CAAE,GAAA,IAAO,OAAO,OAAO,IAAA;AAAA,IACnD;AAAA,EACD;AACA,EAAA,IAAI,MAAM,KAAA,EAAO;AAChB,IAAA,KAAA,MAAW,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,EAAG;AAC3C,MAAA,IAAI,MAAM,OAAA,CAAQ,CAAC,KAAK,CAAA,CAAE,MAAA,GAAS,GAAG,OAAO,IAAA;AAAA,IAC9C;AAAA,EACD;AACA,EAAA,OAAO,KAAA;AACR;AAGO,SAAS,eAAA,GAA8B;AAC7C,EAAA,OAAO,EAAC;AACT;;;ACnlBA,SAAS,mBAAmB,KAAA,EAAyB;AACpD,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,KAAA;AAClD,EAAA,MAAM,IAAI,OAAO,KAAA;AACjB,EAAA,IAAI,CAAA,KAAM,YAAY,CAAA,KAAM,QAAA,IAAY,MAAM,SAAA,IAAa,CAAA,KAAM,UAAU,OAAO,KAAA;AAClF,EAAA,IAAI,iBAAiB,UAAA,IAAc,KAAA,YAAiB,eAAe,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA,EAAG;AAC7F,IAAA,OAAO,KAAA;AAAA,EACR;AACA,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,kBAAkB,CAAA;AAC7D,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,IAAI,OAAO,GAAA,CAAI,MAAA,KAAW,UAAA,EAAY;AACrC,IAAA,OAAO,kBAAA,CAAmB,GAAA,CAAI,MAAA,EAAQ,CAAA;AAAA,EACvC;AACA,EAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,UAAA,EAAY;AACtC,IAAA,OAAO,GAAA,CAAI,OAAA,EAAQ,CAAE,GAAA,CAAI,kBAAkB,CAAA;AAAA,EAC5C;AACA,EAAA,IAAI,MAAM,QAAA,EAAU;AACnB,IAAA,MAAM,MAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AACtE,MAAA,GAAA,CAAI,CAAC,CAAA,GAAI,kBAAA,CAAmB,CAAC,CAAA;AAAA,IAC9B;AACA,IAAA,OAAO,GAAA;AAAA,EACR;AACA,EAAA,OAAO,KAAA;AACR;AAqBO,IAAM,gCAAA,GAAmC;AAAA,EAC/C,cAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA;AACD;AASO,SAAS,uBAAuB,MAAA,EAA+C;AACrF,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,MAAM,KAAK,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,KAAA;AAC1D,EAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,MAAA,CAAO,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAC/C,EAAA,OAAO,iCAAiC,KAAA,CAAM,CAAC,MAAM,KAAA,CAAM,GAAA,CAAI,CAAC,CAAC,CAAA;AAClE;AASO,SAAS,gBACf,IAAA,EAC0C;AAC1C,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACxB,IAAA,IAAI,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAC5B,IAAA,MAAM,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA,GAAI,IAAA;AACjC,IAAA,IAAI,CAAC,CAAC,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA,CAAE,KAAA,CAAM,CAAC,MAAM,MAAA,CAAO,QAAA,CAAS,CAAC,CAAC,GAAG,OAAO,IAAA;AACvE,IAAA,OAAO,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AAAA,EAC/B;AACA,EAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC7B,IAAA,MAAM,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,MAAK,GAAI,IAAA;AACnC,IAAA,IAAI,CAAC,CAAC,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA,CAAE,KAAA,CAAM,CAAC,MAAM,MAAA,CAAO,QAAA,CAAS,CAAC,CAAC,GAAG,OAAO,IAAA;AACvE,IAAA,OAAO,CAAC,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,IAAA;AACR;AAQO,SAAS,oBAAA,CAAqB,MAAc,OAAA,EAAyB;AAC3E,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,IAAI,2BAAA,CAA4B,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AACnD,EAAA,IAAI;AACH,IAAA,OAAO,IAAI,GAAA,CAAI,IAAA,EAAM,OAAO,EAAE,QAAA,EAAS;AAAA,EACxC,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,IAAA;AAAA,EACR;AACD;AASO,SAAS,oBAAA,CACf,QACA,aAAA,EAC2C;AAC3C,EAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,UAAU,OAAO,IAAA;AAClD,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,MAAA;AAAA,IACtC,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,IAAK,OAAO,CAAA,KAAM,QAAA,IAAY,OAAQ,CAAA,CAAgB,IAAA,KAAS;AAAA,GAC3E;AACA,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAEjC,EAAA,IAAI,aAAA,EAAe;AAClB,IAAA,KAAA,MAAW,OAAO,aAAA,EAAe;AAChC,MAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,KAAM,MAAM,GAAG,CAAA;AAC7C,MAAA,IAAI,KAAA,EAAO,OAAO,EAAE,GAAA,EAAK,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,EAAO,KAAA,CAAM,CAAC,CAAA,EAAE;AAAA,IACpD;AAAA,EACD;AACA,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,KAAM,MAAM,MAAM,CAAA;AAC/C,EAAA,IAAI,IAAA,EAAM,OAAO,EAAE,GAAA,EAAK,IAAA,CAAK,CAAC,CAAA,EAAG,KAAA,EAAO,IAAA,CAAK,CAAC,CAAA,EAAE;AAEhD,EAAA,MAAM,SAAS,OAAA,CAAQ,IAAA,CAAK,CAAC,GAAG,CAAC,CAAA,KAAM,KAAA,CAAM,OAAA,CAAQ,EAAE,KAAK,CAAA,IAAK,EAAE,KAAA,CAAM,QAAA,CAAS,MAAM,CAAC,CAAA;AACzF,EAAA,IAAI,MAAA,EAAQ,OAAO,EAAE,GAAA,EAAK,MAAA,CAAO,CAAC,CAAA,EAAG,KAAA,EAAO,MAAA,CAAO,CAAC,CAAA,EAAE;AAEtD,EAAA,OAAO,EAAE,GAAA,EAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,KAAA,EAAO,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAC,CAAA,EAAE;AACnD;AAUA,SAAS,oBAAA,CACR,OACA,OAAA,EACwC;AACxC,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,MAAA;AAChD,EAAA,MAAM,MAAiC,EAAC;AACxC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAgC,CAAA,EAAG;AAC1E,IAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACrC,IAAA,MAAM,KAAA,GAAQ,GAAA;AACd,IAAA,IAAI,OAAO,KAAA,CAAM,IAAA,KAAS,QAAA,IAAY,CAAC,MAAM,IAAA,EAAM;AACnD,IAAA,GAAA,CAAI,GAAG,CAAA,GAAI;AAAA,MACV,GAAG,KAAA;AAAA,MACH,IAAA,EAAM,oBAAA,CAAqB,KAAA,CAAM,IAAA,EAAM,OAAO;AAAA,KAC/C;AAAA,EACD;AACA,EAAA,OAAO,OAAO,IAAA,CAAK,GAAG,CAAA,CAAE,MAAA,GAAS,IAAI,GAAA,GAAM,MAAA;AAC5C;AAaA,SAAS,oBAAoB,KAAA,EAAoC;AAChE,EAAA,IAAI,KAAA,IAAS,MAAM,OAAO,MAAA;AAC1B,EAAA,IAAI,iBAAiB,IAAA,EAAM;AAC1B,IAAA,MAAM,EAAA,GAAK,MAAM,OAAA,EAAQ;AACzB,IAAA,OAAO,MAAA,CAAO,SAAS,EAAE,CAAA,GAAI,IAAI,IAAA,CAAK,EAAE,CAAA,CAAE,WAAA,EAAY,GAAI,MAAA;AAAA,EAC3D;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAE9B,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,KAAA,GAAQ,KAAK,CAAA;AAC/B,IAAA,OAAO,MAAA,CAAO,SAAS,EAAE,CAAA,GAAI,IAAI,IAAA,CAAK,EAAE,CAAA,CAAE,WAAA,EAAY,GAAI,MAAA;AAAA,EAC3D;AACA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAExD,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,GAAI,CAAA,GAAI,KAAA;AAC/D,IAAA,OAAO,IAAI,IAAA,CAAK,EAAE,CAAA,CAAE,WAAA,EAAY;AAAA,EACjC;AACA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC9B,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAC1B,IAAA,OAAO,MAAA,CAAO,SAAS,CAAC,CAAA,GAAI,IAAI,IAAA,CAAK,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,MAAA;AAAA,EACzD;AACA,EAAA,OAAO,MAAA;AACR;AAGA,SAAS,mBAAA,CAAoB,OAAgB,OAAA,EAAyC;AACrF,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,MAAA;AAClC,EAAA,MAAM,QAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACrC,IAAA,MAAM,IAAA,GAAO,GAAA;AACb,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,YAAY,OAAO,IAAA,CAAK,QAAQ,QAAA,EAAU;AACnE,IAAA,KAAA,CAAM,IAAA,CAAK,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,qBAAqB,IAAA,CAAK,IAAA,EAAM,OAAO,CAAA,EAAG,CAAA;AAAA,EACvE;AACA,EAAA,OAAO,KAAA,CAAM,MAAA,GAAS,CAAA,GAAI,KAAA,GAAQ,MAAA;AACnC;AAYO,SAAS,aAAA,CACf,GAAA,EACA,OAAA,EACA,IAAA,GAA6B,EAAC,EACnB;AACX,EAAA,MAAM,EAAE,SAAA,EAAW,SAAA,GAAY,UAAA,EAAY,cAAA,GAAiB,YAAW,GAAI,IAAA;AAM3E,EAAA,KAAA,MAAW,OAAO,CAAC,MAAA,EAAQ,UAAU,OAAA,EAAS,OAAA,EAAS,iBAAiB,CAAA,EAAY;AACnF,IAAA,IAAI,IAAI,GAAG,CAAA,KAAM,UAAa,GAAA,CAAI,GAAG,MAAM,IAAA,EAAM;AAChD,MAAC,IAAgC,GAAG,CAAA,GAAI,kBAAA,CAAmB,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,IACpE;AAAA,EACD;AAEA,EAAA,IAAI,QAAA,GAAoB,IAAI,cAAc,CAAA;AAC1C,EAAA,IAAI,CAAC,QAAA,EAAU;AACd,IAAA,MAAM,GAAA,GAAM,IAAI,SAAS,CAAA;AACzB,IAAA,IAAI,OAAO,SAAA,EAAW;AACrB,MAAA,MAAM,KAAA,GAAQ,GAAA,YAAe,UAAA,GAAa,GAAA,GAAM,aAAa,GAAG,CAAA;AAChE,MAAA,IAAI,KAAA,EAAO;AACV,QAAA,IAAI;AACH,UAAA,QAAA,GAAW,SAAA,CAAU,KAAK,CAAA,IAAK,KAAA,CAAA;AAAA,QAChC,CAAA,CAAA,MAAQ;AACP,UAAA,QAAA,GAAW,MAAA;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAEA,EAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,GAAA,CAAI,IAA6C,CAAA,IAAK,MAAA;AACnF,EAAA,MAAM,MAAA,GAAS,oBAAA,CAAqB,GAAA,CAAI,MAAA,EAAQ,OAAO,CAAA;AACvD,EAAA,MAAM,KAAA,GAAQ,mBAAA,CAAoB,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;AAEpD,EAAA,MAAM,aAAsC,EAAC;AAE7C,EAAA,MAAM,gBAAA,uBAAuB,GAAA,CAAI;AAAA,IAChC,KAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,aAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACA,CAAA;AACD,EAAA,MAAM,mBAAA,uBAA0B,GAAA,CAAI;AAAA,IACnC,UAAA;AAAA,IACA,gBAAA;AAAA,IACA,cAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACA,CAAA;AACD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,EAAG;AAC/C,IAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW;AAC3C,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,OAAO,CAAA,IAAK,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,IAAK,GAAA,CAAI,UAAA,CAAW,KAAK,CAAA,EAAG;AAClF,MAAA,UAAA,CAAW,GAAG,CAAA,GAAI,KAAA;AAClB,MAAA;AAAA,IACD;AACA,IAAA,IAAI,mBAAA,CAAoB,GAAA,CAAI,GAAG,CAAA,EAAG;AACjC,MAAA,MAAM,GAAA,GAAM,oBAAoB,KAAK,CAAA;AACrC,MAAA,IAAI,GAAA,EAAK,UAAA,CAAW,GAAG,CAAA,GAAI,GAAA;AAC3B,MAAA;AAAA,IACD;AACA,IAAA,IAAI,gBAAA,CAAiB,GAAA,CAAI,GAAG,CAAA,EAAG;AAC9B,MAAA,UAAA,CAAW,GAAG,CAAA,GAAI,KAAA;AAClB,MAAA;AAAA,IACD;AACA,IAAA,IAAI,QAAQ,OAAA,EAAS;AACpB,MAAA,UAAA,CAAW,KAAA,GAAQ,KAAA;AAAA,IACpB;AAAA,EACD;AAEA,EAAA,MAAM,IAAA,GAAiB;AAAA,IACtB,IAAA,EAAM,SAAA;AAAA,IACN,cAAc,OAAO,GAAA,CAAI,YAAA,KAAiB,QAAA,GAAW,IAAI,YAAA,GAAe,OAAA;AAAA,IACxE,EAAA,EAAI,OAAO,GAAA,CAAI,EAAA,KAAO,QAAA,GAAW,IAAI,EAAA,GAAK,MAAA,CAAO,GAAA,CAAI,EAAA,IAAM,EAAE,CAAA;AAAA,IAC7D;AAAA,GACD;AACA,EAAA,IAAI,OAAO,GAAA,CAAI,UAAA,KAAe,QAAA,EAAU,IAAA,CAAK,aAAa,GAAA,CAAI,UAAA;AAC9D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA,EAAG;AACvC,IAAC,IAAA,CAAmD,kBAAkB,GAAA,CAAI,eAAA;AAAA,EAC3E;AACA,EAAA,IAAI,IAAA,OAAW,IAAA,GAAO,IAAA;AACtB,EAAA,IAAI,QAAA,OAAe,QAAA,GAAW,QAAA;AAC9B,EAAA,IAAI,MAAA,OAAa,MAAA,GAAS,MAAA;AAC1B,EAAA,IAAI,KAAA,OAAY,KAAA,GAAQ,KAAA;AAExB,EAAA,OAAO,IAAA;AACR;AAGA,SAAS,aAAa,KAAA,EAAmC;AACxD,EAAA,IAAI,KAAA,YAAiB,YAAY,OAAO,KAAA;AACxC,EAAA,IAAI,KAAA,YAAiB,WAAA,EAAa,OAAO,IAAI,WAAW,KAAK,CAAA;AAC7D,EAAA,IAAI,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAA,GAAO,KAAA;AACb,IAAA,OAAO,IAAI,UAAA,CAAW,IAAA,CAAK,QAAQ,IAAA,CAAK,UAAA,EAAY,KAAK,UAAU,CAAA;AAAA,EACpE;AACA,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,IAAI,WAAW,KAAiB,CAAA;AACjE,EAAA,OAAO,IAAA;AACR;;;AC5SA,eAAsB,gBAAA,CACrB,IAAA,EACA,QAAA,EACA,OAAA,EACA,IAAA,EACyB;AACzB,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,GAAA;AAC5B,EAAA,MAAM,WAAA,GAAc,KAAK,WAAA,IAAe,EAAA;AACxC,EAAA,MAAM,gBAAA,GAAmB,KAAK,gBAAA,IAAoB,IAAA;AAClD,EAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,EAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AAEtB,EAAA,MAAM,QAAoB,EAAC;AAC3B,EAAA,IAAI,SAAA,GAAY,KAAA;AAEhB,EAAA,MAAM,IAAA,GAAO,CAAC,KAAA,KAAsB;AACnC,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACxB,IAAA,KAAA,CAAM,IAAA,CAAK,GAAG,KAAK,CAAA;AACnB,IAAA,IAAA,CAAK,UAAU,KAAK,CAAA;AACpB,IAAA,IAAA,CAAK,UAAA,GAAa,KAAA,CAAM,MAAA,EAAQ,MAAS,CAAA;AAAA,EAC1C,CAAA;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,MAAA,EAAQ;AACzB,IAAA,IAAA,CAAK,CAAC,oBAAA,CAAqB,IAAA,CAAK,IAAA,EAAM,QAAQ,CAAC,CAAC,CAAA;AAChD,IAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,cAAc,QAAA,EAAS;AAAA,EAC1D;AAEA,EAAA,IAAI,IAAA,CAAK,SAAS,iBAAA,EAAmB;AACpC,IAAA,MAAM,wBAAA,CAAyB,IAAA,CAAK,EAAA,EAAI,QAAA,EAAU,OAAA,EAAS;AAAA,MAC1D,MAAA;AAAA,MACA,WAAA;AAAA,MACA,KAAA;AAAA,MACA,gBAAA;AAAA,MACA,QAAA;AAAA,MACA,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,QAAA,EAAU,CAAC,KAAA,KAAU,IAAA,CAAK,KAAK,CAAA;AAAA,MAC/B,SAAA,EAAW,MAAM,KAAA,CAAM,MAAA,IAAU,KAAA;AAAA,MACjC,YAAY,MAAM;AACjB,QAAA,SAAA,GAAY,IAAA;AAAA,MACb;AAAA,KACA,CAAA;AACD,IAAA,OAAO,EAAE,OAAO,KAAA,CAAM,KAAA,CAAM,GAAG,KAAK,CAAA,EAAG,SAAA,EAAW,YAAA,EAAc,QAAA,EAAS;AAAA,EAC1E;AAEA,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,YAAA,IAAgB,IAAA,CAAK,SAAS,SAAA,EAAW;AAC1D,IAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AACzD,IAAA,MAAM,UAAA,GACL,IAAA,CAAK,IAAA,KAAS,SAAA,IAAa,SAAA,CAAU,MAAA,KAAW,CAAA,GAC7C,iBAAA,CAAkB,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA,GACxC,EAAC;AAML,IAAA,MAAM,aAAA,GACL,SAAA,CAAU,MAAA,KAAW,CAAA,GAAI,oBAAA,CAAqB,KAAK,OAAA,EAAS,QAAA,EAAU,IAAA,CAAK,UAAU,CAAA,GAAI,IAAA;AAE1F,IAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACzB,MAAA,MAAM,UAAA,CAAW,SAAA,EAAW,OAAA,EAAS,QAAA,EAAU;AAAA,QAC9C,MAAA;AAAA,QACA,WAAA;AAAA,QACA,QAAA;AAAA,QACA,OAAA,EAAS,CAAC,KAAA,KAAU,IAAA,CAAK,KAAK,CAAA;AAAA,QAC9B,SAAA,EAAW,MAAM,KAAA,CAAM,MAAA,IAAU,KAAA;AAAA,QACjC,YAAY,MAAM;AACjB,UAAA,SAAA,GAAY,IAAA;AAAA,QACb;AAAA,OACA,CAAA;AAAA,IACF,WAAW,aAAA,EAAe;AACzB,MAAA,IAAI;AACH,QAAA,MAAM,OAAO,MAAM,SAAA,CAAU,SAAS,aAAA,EAAe,QAAA,EAAU,QAAQ,QAAQ,CAAA;AAC/E,QAAA,IAAI,uBAAA,CAAwB,IAAI,CAAA,EAAG;AAClC,UAAA,MAAM,wBAAA,CAAyB,IAAA,EAAM,aAAA,EAAe,OAAA,EAAS;AAAA,YAC5D,MAAA;AAAA,YACA,WAAA;AAAA,YACA,KAAA;AAAA,YACA,gBAAA;AAAA,YACA,QAAA;AAAA,YACA,YAAY,IAAA,CAAK,UAAA;AAAA,YACjB,QAAA,EAAU,CAAC,KAAA,KAAU,IAAA,CAAK,KAAK,CAAA;AAAA,YAC/B,SAAA,EAAW,MAAM,KAAA,CAAM,MAAA,IAAU,KAAA;AAAA,YACjC,YAAY,MAAM;AACjB,cAAA,SAAA,GAAY,IAAA;AAAA,YACb;AAAA,WACA,CAAA;AAAA,QACF;AAAA,MACD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACD;AAEA,IAAA,IAAI,CAAC,SAAA,IAAa,KAAA,CAAM,SAAS,KAAA,IAAS,UAAA,CAAW,SAAS,CAAA,EAAG;AAChE,MAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,UAAU,CAAA;AAC5B,MAAA,MAAM,SAAA,GAAY,MAAM,KAAA,CAAM,MAAA,IAAU,SAAS,MAAA,CAAO,OAAA;AACxD,MAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,WAAA,EAAa,MAAM,MAAM,CAAA;AACtD,MAAA,MAAM,UAA2B,EAAC;AAClC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAAK;AACrC,QAAA,OAAA,CAAQ,IAAA;AAAA,UAAA,CACN,YAAY;AACZ,YAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACxB,cAAA,IAAI,WAAU,EAAG;AAChB,gBAAA,IAAI,KAAA,CAAM,MAAA,IAAU,KAAA,EAAO,SAAA,GAAY,IAAA;AACvC,gBAAA,KAAA,CAAM,MAAA,GAAS,CAAA;AACf,gBAAA;AAAA,cACD;AACA,cAAA,MAAM,SAAA,GAAY,MAAM,KAAA,EAAM;AAC9B,cAAA,IAAI,CAAC,SAAA,EAAW;AAChB,cAAA,IAAI;AACH,gBAAA,MAAM,YAAY,MAAM,SAAA,CAAU,SAAS,SAAA,EAAW,QAAA,EAAU,QAAQ,QAAQ,CAAA;AAChF,gBAAA,IAAI,WAAU,EAAG;AAChB,kBAAA,IAAI,KAAA,CAAM,MAAA,IAAU,KAAA,EAAO,SAAA,GAAY,IAAA;AACvC,kBAAA,KAAA,CAAM,MAAA,GAAS,CAAA;AACf,kBAAA;AAAA,gBACD;AACA,gBAAA,MAAM,SAAA,GAAY,oBAAoB,SAAS,CAAA;AAC/C,gBAAA,IAAI,SAAA,CAAU,SAAS,MAAA,EAAQ;AAC/B,gBAAA,MAAM,GAAA,GAAM,MAAM,gBAAA,CAAiB,SAAA,EAAW,WAAW,OAAA,EAAS;AAAA,kBACjE,GAAG,IAAA;AAAA,kBACH,KAAA,EAAO,QAAQ,KAAA,CAAM,MAAA;AAAA,kBACrB,OAAA,EAAS,CAAC,KAAA,KAAU,IAAA,CAAK,KAAK,CAAA;AAAA,kBAC9B,UAAA,EAAY,KAAA;AAAA,iBACZ,CAAA;AACD,gBAAA,IAAI,GAAA,CAAI,WAAW,SAAA,GAAY,IAAA;AAAA,cAChC,CAAA,CAAA,MAAQ;AAAA,cAER;AAAA,YACD;AAAA,UACD,CAAA;AAAG,SACJ;AAAA,MACD;AACA,MAAA,MAAM,OAAA,CAAQ,IAAI,OAAO,CAAA;AAAA,IAC1B;AAEA,IAAA,OAAO,EAAE,OAAO,KAAA,CAAM,KAAA,CAAM,GAAG,KAAK,CAAA,EAAG,SAAA,EAAW,YAAA,EAAc,QAAA,EAAS;AAAA,EAC1E;AAEA,EAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,cAAc,QAAA,EAAS;AAC1D;AAIA,SAAS,gBAAA,CAAiB,SAAuC,QAAA,EAA4B;AAC5F,EAAA,OAAA,CAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC,EACxB,MAAA,CAAO,CAAC,CAAA,KAAqB,CAAC,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,SAAS,QAAA,IAAY,CAAA,CAAE,GAAA,KAAQ,MAAM,CAAA,CAClF,GAAA,CAAI,CAAC,CAAA,KAAM,cAAA,CAAe,CAAA,CAAE,IAAA,EAAM,QAAQ,CAAC,CAAA;AAC9C;AAEA,SAAS,iBAAA,CAAkB,SAAuC,QAAA,EAA4B;AAC7F,EAAA,OAAA,CAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC,EACxB,MAAA,CAAO,CAAC,CAAA,KAAqB,CAAC,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,SAAS,QAAA,IAAY,CAAA,CAAE,GAAA,KAAQ,OAAO,CAAA,CACnF,GAAA,CAAI,CAAC,CAAA,KAAM,cAAA,CAAe,CAAA,CAAE,IAAA,EAAM,QAAQ,CAAC,CAAA;AAC9C;AAOO,SAAS,qBAAqB,OAAA,EAAgD;AACpF,EAAA,OAAA,CAAQ,QAAQ,KAAA,IAAS,EAAC,EAAG,IAAA,CAAK,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,IAAY,CAAA,CAAE,QAAQ,OAAO,CAAA;AAChG;AAEA,SAAS,oBAAA,CACR,OAAA,EACA,QAAA,EACA,KAAA,EACgB;AAChB,EAAA,MAAM,IAAA,GAAA,CAAQ,OAAA,CAAQ,KAAA,IAAS,EAAC,EAAG,IAAA;AAAA,IAClC,CAAC,CAAA,KAAqB,CAAC,CAAC,CAAA,IAAK,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,IAAY,CAAA,CAAE,GAAA,KAAQ;AAAA,GACtE;AACA,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,OAAO,gBAAgB,cAAA,CAAe,IAAA,CAAK,IAAA,EAAM,QAAQ,GAAG,KAAK,CAAA;AAClE;AAQA,SAAS,eAAA,CAAgB,UAAkB,KAAA,EAA2C;AACrF,EAAA,IAAI,CAAC,OAAO,OAAO,QAAA;AACnB,EAAA,IAAI;AACH,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,QAAQ,CAAA;AAC5B,IAAA,IAAI,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,CAAA,IAAK,CAAC,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA,EAAG;AAC3E,MAAA,GAAA,CAAI,aAAa,GAAA,CAAI,MAAA,EAAQ,MAAM,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,IAClD;AACA,IAAA,IAAI,MAAM,QAAA,IAAY,CAAC,IAAI,YAAA,CAAa,GAAA,CAAI,UAAU,CAAA,EAAG;AACxD,MAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,UAAA,EAAY,KAAA,CAAM,QAAQ,CAAA;AAAA,IAChD;AACA,IAAA,IAAI,OAAO,KAAA,CAAM,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,KAAA,GAAQ,CAAA,IAAK,CAAC,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA,EAAG;AACzF,MAAA,GAAA,CAAI,YAAA,CAAa,IAAI,OAAA,EAAS,MAAA,CAAO,KAAK,KAAA,CAAM,KAAA,CAAM,KAAK,CAAC,CAAC,CAAA;AAAA,IAC9D;AAKA,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,KAAA,CAAA,IAAa,KAAA,CAAM,MAAA,KAAW,IAAA,IAAQ,CAAC,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC3F,MAAA,IAAI;AACH,QAAA,GAAA,CAAI,aAAa,GAAA,CAAI,QAAA,EAAU,KAAK,SAAA,CAAU,KAAA,CAAM,MAAM,CAAC,CAAA;AAC3D,QAAA,IAAI,CAAC,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,aAAa,CAAA,EAAG;AACzC,UAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,aAAA,EAAe,WAAW,CAAA;AAAA,QAChD;AAAA,MACD,CAAA,CAAA,MAAQ;AAAA,MAGR;AAAA,IACD;AACA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACrB,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,QAAA;AAAA,EACR;AACD;AAEA,eAAe,wBAAA,CACd,EAAA,EACA,QAAA,EACA,OAAA,EACA,GAAA,EAWgB;AAChB,EAAA,MAAM,QAAA,GAAW,EAAA,CAAG,QAAA,CAClB,MAAA,CAAO,UAAU,CAAA,CACjB,GAAA,CAAI,CAAC,IAAA,KAAS,oBAAA,CAAqB,IAAA,EAAM,QAAQ,CAAC,CAAA;AACpD,EAAA,GAAA,CAAI,SAAS,QAAQ,CAAA;AACrB,EAAA,IAAI,GAAA,CAAI,WAAU,EAAG;AACpB,IAAA,GAAA,CAAI,UAAA,EAAW;AACf,IAAA;AAAA,EACD;AAEA,EAAA,IAAI,CAAC,IAAI,gBAAA,EAAkB;AAC3B,EAAA,MAAM,IAAA,GAAA,CAAQ,EAAA,CAAG,KAAA,IAAS,IAAI,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,IAAK,EAAE,GAAA,KAAQ,MAAA,IAAU,OAAO,CAAA,CAAE,SAAS,QAAQ,CAAA;AAC7F,EAAA,IAAI,CAAC,IAAA,EAAM;AAEX,EAAA,MAAM,QAAA,GAAW,gBAAgB,cAAA,CAAe,IAAA,CAAK,MAAM,QAAQ,CAAA,EAAG,IAAI,UAAU,CAAA;AACpF,EAAA,IAAI,GAAA,CAAI,OAAO,OAAA,EAAS;AACxB,EAAA,IAAI;AACH,IAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,OAAA,EAAS,UAAU,QAAA,EAAU,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,QAAQ,CAAA;AAClF,IAAA,IAAI,CAAC,uBAAA,CAAwB,IAAI,CAAA,EAAG;AACpC,IAAA,MAAM,wBAAA,CAAyB,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,GAAG,CAAA;AAAA,EAC5D,CAAA,CAAA,MAAQ;AAAA,EAER;AACD;AAEA,eAAe,UAAA,CACd,KAAA,EACA,OAAA,EACA,QAAA,EACA,GAAA,EAQgB;AAChB,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,KAAK,CAAA;AACvB,EAAA,MAAM,UAA2B,EAAC;AAClC,EAAA,MAAM,cAAc,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa,MAAM,MAAM,CAAA;AAE1D,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,EAAa,CAAA,EAAA,EAAK;AACrC,IAAA,OAAA,CAAQ,IAAA;AAAA,MAAA,CACN,YAAY;AACZ,QAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACxB,UAAA,IAAI,GAAA,CAAI,OAAO,OAAA,EAAS;AACxB,UAAA,IAAI,GAAA,CAAI,WAAU,EAAG;AACpB,YAAA,GAAA,CAAI,UAAA,EAAW;AACf,YAAA,KAAA,CAAM,MAAA,GAAS,CAAA;AACf,YAAA;AAAA,UACD;AACA,UAAA,MAAM,IAAA,GAAO,MAAM,KAAA,EAAM;AACzB,UAAA,IAAI,CAAC,IAAA,EAAM;AACX,UAAA,IAAI;AACH,YAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,OAAA,EAAS,MAAM,QAAA,EAAU,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,QAAQ,CAAA;AAC9E,YAAA,IAAI,UAAA,CAAW,IAAI,CAAA,EAAG,GAAA,CAAI,OAAA,CAAQ,CAAC,oBAAA,CAAqB,IAAA,EAAM,IAAI,CAAC,CAAC,CAAA;AAAA,UACrE,CAAA,CAAA,MAAQ;AAAA,UAER;AAAA,QACD;AAAA,MACD,CAAA;AAAG,KACJ;AAAA,EACD;AAEA,EAAA,MAAM,OAAA,CAAQ,IAAI,OAAO,CAAA;AAC1B;AAEA,eAAe,SAAA,CACd,OAAA,EACA,IAAA,EACA,SAAA,EACA,QACA,QAAA,EACmB;AAKnB,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAG;AAC3B,IAAA,MAAM,MAAA,GAAS,QAAA,GAAW,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA;AAC3C,IAAA,IAAI,WAAW,IAAA,EAAM;AACpB,MAAA,MAAMC,OAAM,MAAM,OAAA,CAAQ,KAAK,MAAA,EAAQ,MAAA,EAAW,QAAW,MAAM,CAAA;AACnE,MAAA,OAAO,KAAK,KAAA,CAAM,IAAI,aAAY,CAAE,MAAA,CAAOA,IAAG,CAAC,CAAA;AAAA,IAChD;AACA,IAAA,MAAM,MAAM,MAAM,KAAA,CAAM,IAAA,EAAM,EAAE,QAAQ,CAAA;AACxC,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAE,CAAA;AAC7D,IAAA,OAAO,MAAM,IAAI,IAAA,EAAK;AAAA,EACvB;AACA,EAAA,MAAM,MAAM,MAAM,OAAA,CAAQ,KAAK,IAAA,EAAM,MAAA,EAAW,QAAW,MAAM,CAAA;AACjE,EAAA,OAAO,KAAK,KAAA,CAAM,IAAI,aAAY,CAAE,MAAA,CAAO,GAAG,CAAC,CAAA;AAChD;AAEA,SAAS,oBAAoB,IAAA,EAAiC;AAC7D,EAAA,IAAI,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,IAAA,EAAK;AACxD,EAAA,IAAI,uBAAA,CAAwB,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAI,IAAA,EAAK;AAC9E,EAAA,IAAI,gBAAA,CAAiB,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,YAAA,EAAc,SAAS,IAAA,EAAK;AACvE,EAAA,IAAI,aAAA,CAAc,IAAI,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,SAAS,IAAA,EAAK;AACjE,EAAA,OAAO,EAAE,MAAM,MAAA,EAAO;AACvB;AAMO,SAAS,cAAA,CAAe,MAAc,QAAA,EAA0B;AACtE,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,IAAK,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,IAAK,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAClF,EAAA,IAAI;AACH,IAAA,OAAO,IAAI,GAAA,CAAI,IAAA,EAAM,QAAQ,EAAE,QAAA,EAAS;AAAA,EACzC,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,IAAA;AAAA,EACR;AACD;AAQA,SAAS,oBAAA,CAAqB,MAAgB,QAAA,EAA4B;AACzE,EAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,MAAM,WAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,IAAI,KAAA,EAAO,IAAA,IAAQ,OAAO,KAAA,CAAM,SAAS,QAAA,EAAU;AAClD,MAAA,MAAM,GAAA,GAAM,cAAA,CAAe,KAAA,CAAM,IAAA,EAAM,QAAQ,CAAA;AAC/C,MAAA,IAAI,GAAA,KAAQ,KAAA,CAAM,IAAA,EAAM,OAAA,GAAU,IAAA;AAClC,MAAA,QAAA,CAAS,GAAG,CAAA,GAAI,EAAE,GAAG,KAAA,EAAO,MAAM,GAAA,EAAI;AAAA,IACvC,CAAA,MAAO;AACN,MAAA,QAAA,CAAS,GAAG,CAAA,GAAI,KAAA;AAAA,IACjB;AAAA,EACD;AACA,EAAA,OAAO,UAAU,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,UAAS,GAAI,IAAA;AAClD;;;ACtYA,IAAM,sBAAA,GAAmF;AAAA,EACxF;AAAA,IACC,GAAA,EAAK,MAAA;AAAA,IACL,QAAA,EAAU,CAAC,oCAAA,EAAsC,0BAA0B;AAAA,GAC5E;AAAA,EACA;AAAA,IACC,GAAA,EAAK,UAAA;AAAA,IACL,QAAA,EAAU,CAAC,oCAAA,EAAsC,0BAA0B;AAAA,GAC5E;AAAA,EACA;AAAA,IACC,GAAA,EAAK,aAAA;AAAA,IACL,QAAA,EAAU,CAAC,0BAA0B;AAAA,GACtC;AAAA,EACA;AAAA,IACC,GAAA,EAAK,MAAA;AAAA,IACL,QAAA,EAAU,CAAC,oCAAA,EAAsC,8BAAA,EAAgC,YAAY;AAAA,GAC9F;AAAA,EACA;AAAA,IACC,GAAA,EAAK,YAAA;AAAA,IACL,QAAA,EAAU,CAAC,wCAAA,EAA0C,oCAAoC;AAAA;AAE3F,CAAA;AASO,SAAS,qBAAqB,UAAA,EAA0C;AAC9E,EAAA,MAAM,IAAA,GAA4B;AAAA,IACjC,IAAA,EAAM,KAAA;AAAA,IACN,QAAA,EAAU,KAAA;AAAA,IACV,WAAA,EAAa,KAAA;AAAA,IACb,IAAA,EAAM,KAAA;AAAA,IACN,UAAA,EAAY;AAAA,GACb;AACA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,UAAU,GAAG,OAAO,IAAA;AACvC,EAAA,MAAM,aAAa,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA;AAC9E,EAAA,KAAA,MAAW,OAAO,sBAAA,EAAwB;AACzC,IAAA,IAAI,UAAA,CAAW,IAAA,CAAK,CAAC,GAAA,KAAQ,IAAI,QAAA,CAAS,IAAA,CAAK,CAAC,EAAA,KAAO,EAAA,CAAG,IAAA,CAAK,GAAG,CAAC,CAAC,CAAA,EAAG;AACtE,MAAA,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,GAAI,IAAA;AAAA,IACjB;AAAA,EACD;AACA,EAAA,OAAO,IAAA;AACR;AAkCO,SAAS,aAAA,CACf,KAAA,EACA,IAAA,EACA,IAAA,GAA6B,EAAC,EACZ;AAClB,EAAA,MAAM,MAAuB,EAAC;AAC9B,EAAA,IAAI,KAAK,IAAA,IAAQ,IAAA,CAAK,IAAA,EAAM,GAAA,CAAI,OAAO,IAAA,CAAK,IAAA;AAC5C,EAAA,IAAI,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,IAAY,IAAA,CAAK,KAAA,GAAQ,CAAA,EAAG,GAAA,CAAI,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA;AACvF,EAAA,IAAI,CAAC,OAAO,OAAO,GAAA;AAEnB,EAAA,IAAI,IAAA,CAAK,YAAY,KAAA,CAAM,QAAA,KAAa,MAAM,QAAA,CAAS,GAAA,IAAO,KAAA,CAAM,QAAA,CAAS,GAAA,CAAA,EAAM;AAClF,IAAA,GAAA,CAAI,WAAW,sBAAA,CAAuB,KAAA,CAAM,SAAS,GAAA,EAAK,KAAA,CAAM,SAAS,GAAG,CAAA;AAAA,EAC7E;AAEA,EAAA,IAAI,IAAA,CAAK,WAAA,IAAe,KAAA,CAAM,KAAA,EAAO,YAAY,MAAA,EAAQ;AACxD,IAAA,GAAA,CAAI,WAAA,GAAc,CAAC,GAAG,KAAA,CAAM,MAAM,UAAU,CAAA;AAAA,EAC7C;AAEA,EAAA,IAAI,KAAK,IAAA,EAAM;AACd,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,KAAA,EAAO,IAAI,CAAA;AACvC,IAAA,IAAI,MAAA,EAAQ;AACX,MAAA,GAAA,CAAI,MAAA,GAAS,MAAA;AACb,MAAA,GAAA,CAAI,aAAa,CAAA,GAAI,WAAA;AAAA,IACtB;AAAA,EACD;AAEA,EAAA,OAAO,GAAA;AACR;AAMA,SAAS,sBAAA,CAAuB,KAAc,GAAA,EAAsB;AACnE,EAAA,MAAM,KAAK,GAAA,IAAO,IAAA;AAClB,EAAA,MAAM,KAAK,GAAA,IAAO,IAAA;AAClB,EAAA,IAAI,EAAA,KAAO,IAAA,IAAQ,EAAA,KAAO,IAAA,EAAM,OAAO,IAAA;AACvC,EAAA,IAAI,EAAA,KAAO,IAAI,OAAO,EAAA;AACtB,EAAA,OAAO,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA;AACnB;AA6BO,SAAS,YAAA,CACf,OACA,IAAA,EACkB;AAClB,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,MAAM,UAAsB,EAAC;AAE7B,EAAA,IAAI,MAAM,OAAA,EAAS;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,OAAA;AAChB,IAAA,WAAA,CAAY,OAAA,EAAS,gBAAA,EAAkB,CAAA,CAAE,UAAU,CAAA;AACnD,IAAA,WAAA,CAAY,OAAA,EAAS,KAAA,EAAO,CAAA,CAAE,GAAG,CAAA;AAAA,EAClC;AAEA,EAAA,IAAI,MAAM,KAAA,EAAO;AAChB,IAAA,MAAM,IAAI,KAAA,CAAM,KAAA;AAChB,IAAA,MAAA,CAAO,OAAA,EAAS,UAAA,EAAY,CAAA,CAAE,QAAQ,CAAA;AACtC,IAAA,MAAA,CAAO,OAAA,EAAS,eAAA,EAAiB,CAAA,CAAE,aAAa,CAAA;AAChD,IAAA,WAAA,CAAY,OAAA,EAAS,aAAA,EAAe,CAAA,CAAE,WAAW,CAAA;AACjD,IAAA,IAAI,CAAC,IAAA,CAAK,WAAA,SAAoB,OAAA,EAAS,YAAA,EAAc,EAAE,UAAU,CAAA;AAAA,EAClE;AAEA,EAAA,IAAI,CAAC,IAAA,CAAK,QAAA,IAAY,KAAA,CAAM,QAAA,KAAa,MAAM,QAAA,CAAS,GAAA,IAAO,KAAA,CAAM,QAAA,CAAS,GAAA,CAAA,EAAM;AACnF,IAAA,MAAM,EAAA,GAAK,MAAM,QAAA,CAAS,GAAA;AAC1B,IAAA,MAAM,EAAA,GAAK,MAAM,QAAA,CAAS,GAAA;AAC1B,IAAA,IAAI,MAAM,EAAA,EAAI;AACb,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACZ,EAAA,EAAI,cAAA;AAAA,QACJ,IAAA,EAAM,CAAC,EAAE,QAAA,EAAU,UAAA,EAAW,EAAG,EAAE,QAAA,EAAU,CAAC,EAAA,EAAI,EAAE,CAAA,EAAG;AAAA,OACvD,CAAA;AAAA,IACF,WAAW,EAAA,EAAI;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,MAAM,CAAC,EAAE,QAAA,EAAU,UAAA,IAAc,EAAE,SAAA,EAAW,EAAA,EAAI,GAAG,CAAA;AAAA,IAC/E,WAAW,EAAA,EAAI;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,MAAM,CAAC,EAAE,QAAA,EAAU,UAAA,IAAc,EAAE,SAAA,EAAW,EAAA,EAAI,GAAG,CAAA;AAAA,IAC/E;AAAA,EACD;AAEA,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,QAAQ,CAAC,CAAA;AAC1C,EAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,IAAA,EAAM,OAAA,EAAQ;AACnC;AAEA,SAAS,WAAA,CACR,GAAA,EACA,QAAA,EACA,KAAA,EACO;AACP,EAAA,IAAI,CAAC,KAAA,EAAO;AACZ,EAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAI,GAAI,KAAA;AACrB,EAAA,IAAI,GAAA,IAAO,IAAA,IAAQ,GAAA,IAAO,IAAA,EAAM;AAChC,EAAA,IAAI,GAAA,IAAO,IAAA,IAAQ,GAAA,IAAO,IAAA,EAAM;AAC/B,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,SAAA,EAAW,MAAM,CAAC,EAAE,QAAA,EAAS,EAAG,CAAC,GAAA,EAAK,GAAG,CAAC,GAAG,CAAA;AAC5D,IAAA;AAAA,EACD;AACA,EAAA,IAAI,GAAA,IAAO,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,CAAC,EAAE,QAAA,EAAS,EAAG,GAAG,GAAG,CAAA;AACjE,EAAA,IAAI,GAAA,IAAO,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,CAAC,EAAE,QAAA,EAAS,EAAG,GAAG,GAAG,CAAA;AAClE;AAEA,SAAS,MAAA,CAAO,GAAA,EAAiB,QAAA,EAAkB,MAAA,EAAoC;AACtF,EAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AACpC,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACxB,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,GAAA,EAAK,IAAA,EAAM,CAAC,EAAE,QAAA,EAAS,EAAG,MAAA,CAAO,CAAC,CAAC,GAAG,CAAA;AACrD,IAAA;AAAA,EACD;AACA,EAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,CAAC,EAAE,QAAA,EAAS,EAAG,MAAM,CAAA,EAAG,CAAA;AACpD;AAEA,SAAS,WAAA,CAAY,GAAA,EAAiB,QAAA,EAAkB,MAAA,EAAoC;AAC3F,EAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AACpC,EAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,YAAA,EAAc,IAAA,EAAM,CAAC,EAAE,QAAA,EAAS,EAAG,MAAM,CAAA,EAAG,CAAA;AAC5D;AAWO,SAAS,aAAA,CACf,OACA,IAAA,EACa;AACb,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AACpB,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,IAAI,KAAA,CAAM,QAAA,IAAY,CAAC,IAAA,CAAK,QAAA,IAAY,CAAC,IAAA,CAAK,IAAA,EAAM,GAAA,CAAI,QAAA,GAAW,KAAA,CAAM,QAAA;AAAA,OAAA,IAChE,KAAA,CAAM,QAAA,KAAa,IAAA,CAAK,QAAA,IAAY,KAAK,IAAA,CAAA,EAAO;AAGzD,EAAA,IAAI,MAAM,OAAA,EAAS;AAClB,IAAA,MAAM,YAAmC,EAAC;AAC1C,IAAA,KAAA,MAAW,CAAC,OAAO,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA,EAAG;AAC3D,MAAA,IAAI,CAAC,KAAA,EAAO;AACZ,MAAA,IAAI,KAAK,IAAA,EAAM;AACf,MAAA,SAAA,CAAU,KAA+B,CAAA,GAAI,KAAA;AAAA,IAC9C;AACA,IAAA,IAAI,OAAO,IAAA,CAAK,SAAS,EAAE,MAAA,GAAS,CAAA,MAAO,OAAA,GAAU,SAAA;AAAA,EACtD;AACA,EAAA,IAAI,MAAM,KAAA,EAAO;AAChB,IAAA,MAAM,YAAiC,EAAC;AACxC,IAAA,KAAA,MAAW,CAAC,OAAO,MAAM,CAAA,IAAK,OAAO,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAG;AAC1D,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,IAAK,MAAA,CAAO,WAAW,CAAA,EAAG;AACnD,MAAA,IAAI,KAAA,KAAU,YAAA,IAAgB,IAAA,CAAK,WAAA,EAAa;AAChD,MAAA,IACC,KAAK,IAAA,KACJ,KAAA,KAAU,cAAc,KAAA,KAAU,eAAA,IAAmB,UAAU,aAAA,CAAA,EAC/D;AACD,QAAA;AAAA,MACD;AACA,MAAA,SAAA,CAAU,KAA+B,CAAA,GAAI,MAAA;AAAA,IAC9C;AACA,IAAA,IAAI,OAAO,IAAA,CAAK,SAAS,EAAE,MAAA,GAAS,CAAA,MAAO,KAAA,GAAQ,SAAA;AAAA,EACpD;AACA,EAAA,OAAO,GAAA;AACR;;;AC7MO,SAAS,aAAA,GAAoD;AACnE,EAAA,OAAO;AAAA,IACN,IAAA,EAAM,KAAA;AAAA,IACN,QAAA,EAAU,KAAA;AAAA,IACV,UAAA,EAAY,KAAA;AAAA,IACZ,UAAA,EAAY,KAAA;AAAA,IACZ,GAAA,EAAK,KAAA;AAAA,IACL,IAAA,EAAM,KAAA;AAAA,IACN,QAAA,EAAU,KAAA;AAAA,IACV,aAAA,EAAe,KAAA;AAAA,IACf,WAAA,EAAa,KAAA;AAAA,IACb,UAAA,EAAY;AAAA,GACb;AACD;;;ACjEA,SAAS,aAAA,CAAc,MAA8B,QAAA,EAAkC;AACtF,EAAA,IAAI,CAAC,IAAA,EAAM,OAAO,EAAC;AACnB,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,IAAI,KAAK,QAAA,IAAY,CAAC,SAAS,QAAA,EAAU,GAAA,CAAI,WAAW,IAAA,CAAK,QAAA;AAC7D,EAAA,IAAI,KAAK,OAAA,EAAS;AACjB,IAAA,MAAM,OAA2C,EAAC;AAClD,IAAA,MAAM,eAAA,GAAkB,QAAA,CAAS,OAAA,IAAW,EAAC;AAC7C,IAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,EAAG;AAClD,MAAA,IAAI,CAAC,CAAA,EAAG;AACR,MAAA,IAAI,eAAA,CAAgB,CAAiC,CAAA,EAAG;AACxD,MAAA,IAAA,CAAK,CAAsB,CAAA,GAAI,CAAA;AAAA,IAChC;AACA,IAAA,IAAI,OAAO,IAAA,CAAK,IAAI,EAAE,MAAA,GAAS,CAAA,MAAO,OAAA,GAAU,IAAA;AAAA,EACjD;AACA,EAAA,IAAI,KAAK,KAAA,EAAO;AACf,IAAA,MAAM,OAAyC,EAAC;AAChD,IAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,KAAA,IAAS,EAAC;AACzC,IAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG;AAChD,MAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAA,CAAE,WAAW,CAAA,EAAG;AACzC,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,aAAA,CAAc,CAA+B,CAAC,CAAA,EAAG;AACnE,MAAA,IAAA,CAAK,CAAsB,CAAA,GAAI,CAAA;AAAA,IAChC;AACA,IAAA,IAAI,OAAO,IAAA,CAAK,IAAI,EAAE,MAAA,GAAS,CAAA,MAAO,KAAA,GAAQ,IAAA;AAAA,EAC/C;AACA,EAAA,OAAO,GAAA;AACR;AAQA,SAAS,uBAAuB,EAAA,EAA4D;AAC3F,EAAA,IAAI,CAAC,IAAI,OAAO,MAAA;AAChB,EAAA,MAAM,KAAK,EAAA,CAAG,GAAA;AACd,EAAA,MAAM,KAAK,EAAA,CAAG,GAAA;AACd,EAAA,IAAI,CAAC,EAAA,IAAM,CAAC,EAAA,EAAI,OAAO,MAAA;AACvB,EAAA,IAAI,EAAA,IAAM,IAAI,OAAO,EAAA,KAAO,KAAK,EAAA,GAAK,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA;AACjD,EAAA,IAAI,EAAA,EAAI,OAAO,CAAA,EAAG,EAAE,CAAA,GAAA,CAAA;AACpB,EAAA,OAAO,MAAM,EAAE,CAAA,CAAA;AAChB;AAaO,SAAS,eAAA,CAAgB,MAAwB,IAAA,EAAqC;AAC5F,EAAA,MAAM,YAAA,GAAuC;AAAA,IAC5C,IAAA,EAAM,KAAA;AAAA,IACN,KAAA,EAAO,UAAA;AAAA,IACP,cAAA,EAAgB,KAAA;AAAA,IAChB,SAAA,EAAW,IAAA;AAAA,IACX,QAAA,EAAU;AAAA,MACT,GAAG,aAAA,EAAc;AAAA,MACjB,IAAA,EAAM,IAAA;AAAA,MACN,QAAA,EAAU,IAAA;AAAA,MACV,UAAA,EAAY,IAAA;AAAA,MACZ,UAAA,EAAY,IAAA;AAAA,MACZ,GAAA,EAAK,IAAA;AAAA,MACL,QAAA,EAAU,IAAA;AAAA,MACV,aAAA,EAAe,IAAA;AAAA,MACf,WAAA,EAAa;AAAA;AACd,GACD;AAIA,EAAA,IAAI,WAAA,GAAmD,IAAA;AACvD,EAAA,MAAM,OAAA,GAAU,CAAC,MAAA,KAAsD;AACtE,IAAA,IAAI,CAAC,WAAA,EAAa;AACjB,MAAA,WAAA,GAAc,wBAAwB,IAAA,EAAM,IAAA,EAAM,MAAM,CAAA,CAAE,KAAA,CAAM,MAAM,YAAY,CAAA;AAAA,IACnF;AACA,IAAA,OAAO,WAAA;AAAA,EACR,CAAA;AAEA,EAAA,OAAO;AAAA,IACN,YAAA;AAAA,IACA,MAAM,GAAA,EAAwD;AAC7D,MAAA,OAAO,gBAAA,CAAiB,IAAA,EAAM,IAAA,EAAM,GAAA,EAAK,OAAO,CAAA;AAAA,IACjD;AAAA,GACD;AACD;AAOA,IAAM,YAAA,GAAoC;AAAA,EACzC,IAAA,EAAM,IAAA;AAAA,EACN,QAAA,EAAU,IAAA;AAAA,EACV,WAAA,EAAa,KAAA;AAAA,EACb,IAAA,EAAM,KAAA;AAAA,EACN,UAAA,EAAY;AACb,CAAA;AAYA,eAAe,uBAAA,CACd,IAAA,EACA,IAAA,EACA,MAAA,EAC+B;AAC/B,EAAA,MAAM,MAAA,GAAS,eAAe,IAAI,CAAA;AAClC,EAAA,IAAI,UAAU,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,qBAAqB,MAAM,CAAA;AAInE,EAAA,MAAM,IAAA,GAAO,MAAM,aAAA,CAAc,IAAA,EAAM,MAAM,CAAA;AAC7C,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACrC,IAAA,MAAM,aAAc,IAAA,CAAkC,UAAA;AACtD,IAAA,IAAI,MAAM,OAAA,CAAQ,UAAU,CAAA,EAAG,OAAO,qBAAqB,UAAU,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,YAAA;AACR;AAEA,SAAS,eAAe,IAAA,EAA0C;AACjE,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,SAAA,IAAa,IAAA,CAAK,SAAS,YAAA,EAAc;AAC1D,IAAA,MAAM,EAAA,GAAM,KAAK,OAAA,CAAqC,UAAA;AACtD,IAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,EAAE,CAAA,GAAI,EAAA,GAAK,IAAA;AAAA,EACjC;AACA,EAAA,IAAI,IAAA,CAAK,SAAS,iBAAA,EAAmB;AACpC,IAAA,MAAM,EAAA,GAAM,KAAK,EAAA,CAAgC,UAAA;AACjD,IAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,EAAE,CAAA,GAAI,EAAA,GAAK,IAAA;AAAA,EACjC;AACA,EAAA,OAAO,IAAA;AACR;AAEA,eAAe,aAAA,CAAc,MAAyB,MAAA,EAAuC;AAC5F,EAAA,MAAM,OAAO,IAAA,CAAK,QAAA;AAClB,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAG;AAC3B,IAAA,MAAM,SAAS,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,GAAI,IAAA;AACrD,IAAA,IAAI,WAAW,IAAA,EAAM;AACpB,MAAA,MAAMA,IAAAA,GAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAK,MAAA,EAAQ,MAAA,EAAW,QAAW,MAAM,CAAA;AACxE,MAAA,OAAO,KAAK,KAAA,CAAM,IAAI,aAAY,CAAE,MAAA,CAAOA,IAAG,CAAC,CAAA;AAAA,IAChD;AACA,IAAA,MAAM,MAAM,MAAM,KAAA,CAAM,IAAA,EAAM,EAAE,QAAQ,CAAA;AACxC,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,KAAA,EAAQ,GAAA,CAAI,MAAM,CAAA,KAAA,EAAQ,IAAI,CAAA,CAAE,CAAA;AAC7D,IAAA,OAAO,MAAM,IAAI,IAAA,EAAK;AAAA,EACvB;AACA,EAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAK,IAAA,EAAM,MAAA,EAAW,QAAW,MAAM,CAAA;AACtE,EAAA,OAAO,KAAK,KAAA,CAAM,IAAI,aAAY,CAAE,MAAA,CAAO,GAAG,CAAC,CAAA;AAChD;AAQA,gBAAgB,gBAAA,CACf,IAAA,EACA,IAAA,EACA,GAAA,EACA,OAAA,EACiC;AACjC,EAAA,IAAI,IAAI,MAAA,CAAO,OAAA,QAAe,IAAI,YAAA,CAAa,WAAW,YAAY,CAAA;AAEtE,EAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA;AACrC,EAAA,IAAI,IAAI,MAAA,CAAO,OAAA,QAAe,IAAI,YAAA,CAAa,WAAW,YAAY,CAAA;AAItE,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAM;AAAA,IAC9C,MAAM,GAAA,CAAI,IAAA;AAAA,IACV,KAAA,EAAO,GAAA,CAAI,QAAA,IAAY,GAAA,CAAI;AAAA,GAC3B,CAAA;AAMD,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA,IAAY,sBAAA,CAAuB,GAAA,CAAI,OAAO,QAAQ,CAAA;AAC9E,EAAA,MAAM,UAAA,GAA6B;AAAA,IAClC,IAAA,EAAM,MAAA,CAAO,IAAA,IAAQ,GAAA,CAAI,IAAA;AAAA,IACzB,QAAA;AAAA,IACA,KAAA,EAAO,MAAA,CAAO,KAAA,IAAS,GAAA,CAAI,YAAY,GAAA,CAAI,KAAA;AAAA,IAC3C,QAAQ,MAAA,CAAO;AAAA,GAChB;AAIA,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAC/C,EAAA,MAAM,UAAA,GAAa,aAAA,CAAc,GAAA,CAAI,MAAA,EAAQ,QAAQ,CAAA;AAOrD,EAAA,IAAI,CAAC,KAAK,IAAA,EAAM;AAEf,IAAA,UAAA,CAAW,MAAA,GAAS,MAAA;AAAA,EACrB,CAAA,MAAA,IAAW,UAAA,CAAW,MAAA,KAAW,MAAA,EAAW;AAC3C,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AACzC,IAAA,IAAI,GAAA,aAAgB,MAAA,GAAS,GAAA;AAAA,EAC9B;AAOA,EAAA,MAAM,SAAuB,EAAC;AAC9B,EAAA,IAAI,cAAA,GAAmD,IAAA;AAEvD,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAkB;AAC/B,IAAA,IAAI,cAAA,EAAgB;AACnB,MAAA,MAAM,CAAA,GAAI,cAAA;AACV,MAAA,cAAA,GAAiB,IAAA;AACjB,MAAA,CAAA,CAAE,CAAC,CAAA;AAAA,IACJ,CAAA,MAAO;AACN,MAAA,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IACd;AAAA,EACD,CAAA;AAEA,EAAA,MAAM,OAAO,MAA2B;AACvC,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG,OAAO,QAAQ,OAAA,CAAQ,MAAA,CAAO,OAAQ,CAAA;AAC7D,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC/B,MAAA,cAAA,GAAiB,OAAA;AAAA,IAClB,CAAC,CAAA;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,IAAI,YAAA,CAAa,SAAA,EAAW,YAAY,CAAA,EAAG,CAAA;AAC9F,EAAA,GAAA,CAAI,OAAO,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAI5D,EAAA,KAAA,CAAM,YAAY;AACjB,IAAA,IAAI;AACH,MAAA,MAAM,gBAAA,CAAiB,IAAA,EAAM,IAAA,CAAK,QAAA,EAAU,KAAK,OAAA,EAAS;AAAA,QACzD,QAAQ,GAAA,CAAI,MAAA;AAAA,QACZ,WAAA,EAAa,KAAK,WAAA,IAAe,EAAA;AAAA,QACjC,OAAO,GAAA,CAAI,KAAA;AAAA,QACX,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,UAAA;AAAA,QACA,OAAA,EAAS,CAAC,KAAA,KAAU;AACnB,UAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AAAA,QACpD;AAAA,OACA,CAAA;AACD,MAAA,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACb,MAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,KAAK,CAAA;AAAA,IACnC;AAAA,EACD,CAAA,GAAG;AAEH,EAAA,IAAI;AACH,IAAA,OAAO,IAAA,EAAM;AACZ,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,EAAK;AACzB,MAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC3B,QAAA,MAAM;AAAA,UACL,OAAO,KAAA,CAAM,KAAA;AAAA,UACb,UAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA,EAAM;AAAA,SACP;AACA,QAAA;AAAA,MACD;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AAC1B,QAAA,MAAM;AAAA,UACL,OAAO,EAAC;AAAA,UACR,UAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA,EAAM;AAAA,SACP;AACA,QAAA;AAAA,MACD;AACA,MAAA,MAAM,KAAA,CAAM,KAAA;AAAA,IACb;AAAA,EACD,CAAA,SAAE;AACD,IAAA,GAAA,CAAI,MAAA,CAAO,mBAAA,CAAoB,OAAA,EAAS,OAAO,CAAA;AAAA,EAChD;AACD;;;ACnTO,SAAS,kBAAA,CAAmB,MAAwB,IAAA,EAAwC;AAClG,EAAA,MAAM,YAAA,GAAuC;AAAA,IAC5C,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,gBAAA;AAAA,IACP,cAAA,EAAgB,KAAA;AAAA,IAChB,SAAA,EAAW,IAAA;AAAA,IACX,QAAA,EAAU,EAAE,GAAG,aAAA,EAAc;AAAE,GAChC;AAEA,EAAA,OAAO;AAAA,IACN,YAAA;AAAA,IACA,MAAM,GAAA,EAAwD;AAC7D,MAAA,OAAO,mBAAA,CAAoB,IAAA,EAAM,IAAA,EAAM,GAAG,CAAA;AAAA,IAC3C;AAAA,GACD;AACD;AAEA,gBAAgB,mBAAA,CACf,IAAA,EACA,IAAA,EACA,GAAA,EACiC;AACjC,EAAA,IAAI,IAAI,MAAA,CAAO,OAAA,QAAe,IAAI,YAAA,CAAa,WAAW,YAAY,CAAA;AAGtE,EAAA,MAAM,aAAyB,EAAC;AAChC,EAAA,MAAM,WAAuB,GAAA,CAAI,MAAA;AAOjC,EAAA,MAAM,SAAuB,EAAC;AAC9B,EAAA,IAAI,cAAA,GAAmD,IAAA;AAEvD,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAkB;AAC/B,IAAA,IAAI,cAAA,EAAgB;AACnB,MAAA,MAAM,CAAA,GAAI,cAAA;AACV,MAAA,cAAA,GAAiB,IAAA;AACjB,MAAA,CAAA,CAAE,CAAC,CAAA;AAAA,IACJ,CAAA,MAAO;AACN,MAAA,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IACd;AAAA,EACD,CAAA;AAEA,EAAA,MAAM,OAAO,MAA2B;AACvC,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG,OAAO,QAAQ,OAAA,CAAQ,MAAA,CAAO,OAAQ,CAAA;AAC7D,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC/B,MAAA,cAAA,GAAiB,OAAA;AAAA,IAClB,CAAC,CAAA;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,IAAI,YAAA,CAAa,SAAA,EAAW,YAAY,CAAA,EAAG,CAAA;AAC9F,EAAA,GAAA,CAAI,OAAO,gBAAA,CAAiB,OAAA,EAAS,SAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAE5D,EAAA,KAAA,CAAM,YAAY;AACjB,IAAA,IAAI;AACH,MAAA,MAAM,gBAAA,CAAiB,IAAA,EAAM,IAAA,CAAK,QAAA,EAAU,KAAK,OAAA,EAAS;AAAA,QACzD,QAAQ,GAAA,CAAI,MAAA;AAAA,QACZ,WAAA,EAAa,KAAK,WAAA,IAAe,EAAA;AAAA,QACjC,OAAO,GAAA,CAAI,KAAA;AAAA,QACX,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,OAAA,EAAS,CAAC,KAAA,KAAU;AACnB,UAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AAAA,QACpD;AAAA,OACA,CAAA;AACD,MAAA,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACb,MAAA,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,KAAK,CAAA;AAAA,IACnC;AAAA,EACD,CAAA,GAAG;AAEH,EAAA,IAAI;AACH,IAAA,OAAO,IAAA,EAAM;AACZ,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,EAAK;AACzB,MAAA,IAAI,KAAA,CAAM,SAAS,OAAA,EAAS;AAC3B,QAAA,MAAM;AAAA,UACL,OAAO,KAAA,CAAM,KAAA;AAAA,UACb,UAAA;AAAA,UACA,QAAA;AAAA,UACA,IAAA,EAAM;AAAA,SACP;AACA,QAAA;AAAA,MACD;AACA,MAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AAC1B,QAAA,MAAM,EAAE,KAAA,EAAO,IAAI,UAAA,EAAY,QAAA,EAAU,MAAM,IAAA,EAAK;AACpD,QAAA;AAAA,MACD;AACA,MAAA,MAAM,KAAA,CAAM,KAAA;AAAA,IACb;AAAA,EACD,CAAA,SAAE;AACD,IAAA,GAAA,CAAI,MAAA,CAAO,mBAAA,CAAoB,OAAA,EAAS,OAAO,CAAA;AAAA,EAChD;AACD;;;AChGA,eAAsB,aAAA,CAAc,MAAc,MAAA,EAAgD;AACjG,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACH,IAAA,QAAA,GAAW,MAAM,MAAM,IAAA,EAAM;AAAA,MAC5B,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS,EAAE,KAAA,EAAO,WAAA,EAAY;AAAA,MAC9B,MAAA;AAAA,MACA,QAAA,EAAU;AAAA,KACV,CAAA;AAAA,EACF,SAAS,GAAA,EAAK;AACb,IAAA,IAAI,GAAA,YAAe,YAAA,IAAgB,GAAA,CAAI,IAAA,KAAS,cAAc,MAAM,GAAA;AACpE,IAAA,MAAMC,UAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC9D,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,QAAAA,OAAAA,EAAO;AAAA,EAC1C;AACA,EAAA,IAAI,QAAA,CAAS,EAAA,IAAM,QAAA,CAAS,MAAA,KAAW,GAAA,EAAK;AAC3C,IAAA,MAAM,QAAA,CAAS,IAAA,EAAM,MAAA,EAAO,CAAE,MAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAC5C,IAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,EACnB;AACA,EAAA,MAAM,MAAA,GAAS,GAAG,QAAA,CAAS,MAAM,IAAI,QAAA,CAAS,UAAA,IAAc,EAAE,CAAA,CAAA,CAAG,IAAA,EAAK;AACtE,EAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,QAAA,CAAS,QAAQ,MAAA,EAAO;AACrD;;;AC5BA,IAAM,SAAA,GAAY,CAAA;AAClB,IAAM,cAAA,GAAiB,CAAA;AACvB,IAAM,WAAA,GAAc,CAAA;AACpB,IAAM,cAAA,GAAiB,CAAA;AACvB,IAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAM,gBAAA,GAAmB,CAAA;AAGzB,IAAM,WAAA,GAAc,UAAA;AACpB,IAAM,WAAA,GAAc,UAAA;AACpB,IAAM,cAAA,GAAiB,SAAA;AAOhB,SAAS,SAAS,KAAA,EAAmC;AAC3D,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,IAAA;AAClD,EAAA,IAAI,KAAA,YAAiB,YAAY,OAAO,KAAA;AACxC,EAAA,IAAI,KAAA,YAAiB,WAAA,EAAa,OAAO,IAAI,WAAW,KAAK,CAAA;AAC7D,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,IAAK,KAAA,CAAM,MAAA,GAAS,CAAA,IAAK,OAAO,KAAA,CAAM,CAAC,CAAA,KAAM,QAAA,EAAU;AAC7E,IAAA,OAAO,IAAI,WAAW,KAAK,CAAA;AAAA,EAC5B;AACA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,gBAAA,CAAiB,IAAA,CAAK,KAAK,CAAA,IAAK,KAAA,CAAM,MAAA,GAAS,CAAA,KAAM,CAAA,EAAG;AACxF,IAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,KAAA,CAAM,SAAS,CAAC,CAAA;AAC7C,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,KAAK,CAAA,EAAG;AACzC,MAAA,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA,GAAI,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,EAAG,CAAA,GAAI,CAAC,CAAA,EAAG,EAAE,CAAA;AAAA,IACtD;AACA,IAAA,OAAO,KAAA;AAAA,EACR;AAEA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACvD,IAAA,MAAM,GAAA,GAAM,KAAA;AACZ,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAC5B,IAAA,IAAI,KAAK,MAAA,GAAS,CAAA,IAAK,OAAO,GAAA,CAAI,GAAG,MAAM,QAAA,EAAU;AACpD,MAAA,MAAM,GAAA,GAAM,IAAI,UAAA,CAAW,IAAA,CAAK,MAAM,CAAA;AACtC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,EAAQ,KAAK,GAAA,CAAI,CAAC,CAAA,GAAI,GAAA,CAAI,CAAC,CAAA;AACpD,MAAA,OAAO,GAAA;AAAA,IACR;AAAA,EACD;AACA,EAAA,OAAO,IAAA;AACR;AAKO,SAAS,SAAS,IAAA,EAAyC;AACjE,EAAA,IAAI,IAAA,CAAK,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAC5B,EAAA,IAAI;AACH,IAAA,OAAO,YAAA,CAAa,IAAI,QAAA,CAAS,IAAA,CAAK,MAAA,EAAQ,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,UAAU,CAAA,EAAG,CAAC,CAAA,CAAE,QAAA;AAAA,EACrF,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,IAAA;AAAA,EACR;AACD;AAEA,SAAS,YAAA,CACR,MACA,MAAA,EAC+C;AAC/C,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,KAAM,CAAA;AACrC,EAAA,MAAA,IAAU,CAAA;AAEV,EAAA,IAAI,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,EAAE,CAAA;AACvC,EAAA,MAAA,IAAU,CAAA;AAGV,EAAA,MAAM,IAAA,GAAA,CACJ,OAAA,GAAU,WAAA,MAAiB,CAAA,IAC3B,UAAU,GAAA,IAAS,GAAA,IAAQ,OAAA,GAAU,GAAA,GAAQ,GAAA,IAC7C,OAAA,GAAU,GAAA,IAAS,GAAA,IAAQ,UAAU,GAAA,GAAQ,GAAA;AAC/C,EAAA,MAAM,IAAA,GAAA,CACJ,OAAA,GAAU,WAAA,MAAiB,CAAA,IAC3B,UAAU,GAAA,IAAS,GAAA,IAAQ,OAAA,GAAU,GAAA,GAAQ,GAAA,IAC7C,OAAA,GAAU,GAAA,IAAS,GAAA,IAAQ,UAAU,GAAA,GAAQ,GAAA;AAG/C,EAAA,IAAI,OAAA,GAAU,gBAAgB,MAAA,IAAU,CAAA;AAGxC,EAAA,OAAA,GAAA,CAAW,UAAU,KAAA,IAAc,GAAA;AAEnC,EAAA,MAAM,SAAA,GAAA,CAAa,IAAA,GAAO,CAAA,GAAI,CAAA,KAAM,OAAO,CAAA,GAAI,CAAA,CAAA;AAC/C,EAAA,MAAM,KAAK,CAAC,CAAA,KAAc,IAAA,CAAK,UAAA,CAAW,GAAG,EAAE,CAAA;AAC/C,EAAA,MAAM,KAAK,CAAC,CAAA,KAAc,IAAA,CAAK,SAAA,CAAU,GAAG,EAAE,CAAA;AAE9C,EAAA,SAAS,UAAU,GAAA,EAAmD;AACrE,IAAA,MAAM,CAAA,GAAI,GAAG,GAAG,CAAA;AAChB,IAAA,MAAM,CAAA,GAAI,EAAA,CAAG,GAAA,GAAM,CAAC,CAAA;AACpB,IAAA,OAAO,EAAE,MAAA,EAAQ,CAAC,CAAA,EAAG,CAAC,GAAG,MAAA,EAAQ,GAAA,GAAM,EAAA,GAAK,SAAA,GAAY,CAAA,EAAE;AAAA,EAC3D;AAEA,EAAA,SAAS,eAAe,GAAA,EAAqD;AAC5E,IAAA,MAAM,CAAA,GAAI,GAAG,GAAG,CAAA;AAChB,IAAA,GAAA,IAAO,CAAA;AACP,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,MAAA,MAAM,EAAA,GAAK,UAAU,GAAG,CAAA;AACxB,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,MAAM,CAAA;AACrB,MAAA,GAAA,GAAM,EAAA,CAAG,MAAA;AAAA,IACV;AACA,IAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAQ,GAAA,EAAI;AAAA,EAC9B;AAEA,EAAA,SAAS,YAAY,GAAA,EAAuD;AAC3E,IAAA,MAAM,CAAA,GAAI,GAAG,GAAG,CAAA;AAChB,IAAA,GAAA,IAAO,CAAA;AACP,IAAA,MAAM,SAAuB,EAAC;AAC9B,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,MAAA,MAAM,IAAA,GAAO,eAAe,GAAG,CAAA;AAC/B,MAAA,MAAA,CAAO,IAAA,CAAK,KAAK,MAAM,CAAA;AACvB,MAAA,GAAA,GAAM,IAAA,CAAK,MAAA;AAAA,IACZ;AACA,IAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAQ,GAAA,EAAI;AAAA,EAC9B;AAEA,EAAA,QAAQ,OAAA;AAAS,IAChB,KAAK,SAAA,EAAW;AACf,MAAA,MAAM,EAAA,GAAK,UAAU,MAAM,CAAA;AAC3B,MAAA,OAAO,EAAE,QAAA,EAAU,EAAE,IAAA,EAAM,OAAA,EAAS,WAAA,EAAa,EAAA,CAAG,MAAA,EAAO,EAAG,MAAA,EAAQ,EAAA,CAAG,MAAA,EAAO;AAAA,IACjF;AAAA,IACA,KAAK,cAAA,EAAgB;AACpB,MAAA,MAAM,EAAA,GAAK,eAAe,MAAM,CAAA;AAChC,MAAA,OAAO,EAAE,QAAA,EAAU,EAAE,IAAA,EAAM,YAAA,EAAc,WAAA,EAAa,EAAA,CAAG,MAAA,EAAO,EAAG,MAAA,EAAQ,EAAA,CAAG,MAAA,EAAO;AAAA,IACtF;AAAA,IACA,KAAK,WAAA,EAAa;AACjB,MAAA,MAAM,EAAA,GAAK,YAAY,MAAM,CAAA;AAC7B,MAAA,OAAO,EAAE,QAAA,EAAU,EAAE,IAAA,EAAM,SAAA,EAAW,WAAA,EAAa,EAAA,CAAG,MAAA,EAAO,EAAG,MAAA,EAAQ,EAAA,CAAG,MAAA,EAAO;AAAA,IACnF;AAAA,IACA,KAAK,cAAA,EAAgB;AACpB,MAAA,MAAM,CAAA,GAAI,GAAG,MAAM,CAAA;AACnB,MAAA,MAAA,IAAU,CAAA;AACV,MAAA,MAAM,SAAqB,EAAC;AAC5B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,QAAA,MAAM,CAAA,GAAI,YAAA,CAAa,IAAA,EAAM,MAAM,CAAA;AACnC,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,QAAA,CAAS,WAAuB,CAAA;AAC9C,QAAA,MAAA,GAAS,CAAA,CAAE,MAAA;AAAA,MACZ;AACA,MAAA,OAAO,EAAE,UAAU,EAAE,IAAA,EAAM,cAAc,WAAA,EAAa,MAAA,IAAU,MAAA,EAAO;AAAA,IACxE;AAAA,IACA,KAAK,mBAAA,EAAqB;AACzB,MAAA,MAAM,CAAA,GAAI,GAAG,MAAM,CAAA;AACnB,MAAA,MAAA,IAAU,CAAA;AACV,MAAA,MAAM,SAAuB,EAAC;AAC9B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,QAAA,MAAM,CAAA,GAAI,YAAA,CAAa,IAAA,EAAM,MAAM,CAAA;AACnC,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,QAAA,CAAS,WAAyB,CAAA;AAChD,QAAA,MAAA,GAAS,CAAA,CAAE,MAAA;AAAA,MACZ;AACA,MAAA,OAAO,EAAE,UAAU,EAAE,IAAA,EAAM,mBAAmB,WAAA,EAAa,MAAA,IAAU,MAAA,EAAO;AAAA,IAC7E;AAAA,IACA,KAAK,gBAAA,EAAkB;AACtB,MAAA,MAAM,CAAA,GAAI,GAAG,MAAM,CAAA;AACnB,MAAA,MAAA,IAAU,CAAA;AACV,MAAA,MAAM,SAAyB,EAAC;AAChC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,QAAA,MAAM,CAAA,GAAI,YAAA,CAAa,IAAA,EAAM,MAAM,CAAA;AACnC,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,QAAA,CAAS,WAA2B,CAAA;AAClD,QAAA,MAAA,GAAS,CAAA,CAAE,MAAA;AAAA,MACZ;AACA,MAAA,OAAO,EAAE,UAAU,EAAE,IAAA,EAAM,gBAAgB,WAAA,EAAa,MAAA,IAAU,MAAA,EAAO;AAAA,IAC1E;AAAA,IACA;AACC,MAAA,OAAO,EAAE,UAAU,EAAE,IAAA,EAAM,WAAW,WAAA,EAAa,EAAC,EAAE,EAAG,MAAA,EAAO;AAAA;AAEnE;AAOA,IAAM,SAAA,GAAY;AAAA,EACjB,UAAA;AAAA,EACA,MAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA;AACD,CAAA;AAGA,IAAM,iBAAA,GAAoB;AAAA,EACzB,UAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA;AAAA,EACA,oBAAA;AAAA,EACA;AACD,CAAA;AAQA,IAAM,cAAA,GAAiB,CAAC,MAAA,EAAQ,UAAA,EAAY,OAAO,KAAA,EAAO,OAAA,EAAS,WAAW,KAAK,CAAA;AAGnF,SAAS,mBAAmB,IAAA,EAAwB;AACnD,EAAA,OAAO,IAAA,CACL,OAAA,CAAQ,iBAAA,EAAmB,OAAO,EAClC,OAAA,CAAQ,iBAAA,EAAmB,OAAO,CAAA,CAClC,aAAY,CACZ,KAAA,CAAM,YAAY,CAAA,CAClB,OAAO,OAAO,CAAA;AACjB;AAGA,IAAM,aAAA,GAAgB;AAAA,EACrB,OAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACD,CAAA;AAGA,SAAS,kBAAkB,KAAA,EAAkE;AAC5F,EAAA,IAAI,OAAO,UAAU,QAAA,IAAY,KAAA,KAAU,QAAQ,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,KAAA;AAChF,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,OACC,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,IAAY,aAAA,CAAc,SAAS,GAAA,CAAI,IAAI,CAAA,IAAK,GAAA,CAAI,WAAA,IAAe,IAAA;AAEzF;AAYO,SAAS,cAAc,MAAA,EAAyD;AAItF,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACvB,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,WAAA,EAAY;AAC7B,IAAA,IAAI,CAAA,CAAE,UAAA,CAAW,QAAQ,CAAA,IAAK,CAAA,CAAE,UAAA,CAAW,KAAK,CAAA,IAAK,CAAA,CAAE,UAAA,CAAW,MAAM,CAAA,EAAG;AAC3E,IAAA,IAAI,iBAAA,CAAkB,IAAA,CAAK,CAAC,EAAA,KAAO,CAAA,CAAE,SAAS,EAAE,CAAC,CAAA,EAAG,OAAO,CAAA,CAAE,IAAA;AAAA,EAC9D;AAGA,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACvB,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,WAAA,EAAY;AAC7B,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,WAAA,EAAY;AAC7B,IAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,CAAS,MAAM,CAAA,IAAK,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAA,IAAK,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA;AACjF,IAAA,IAAI,UAAU,QAAA,CAAS,CAAC,CAAA,IAAK,QAAA,SAAiB,CAAA,CAAE,IAAA;AAAA,EACjD;AAGA,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACvB,IAAA,IAAI,SAAA,CAAU,SAAS,CAAA,CAAE,IAAA,CAAK,aAAa,CAAA,SAAU,CAAA,CAAE,IAAA;AAAA,EACxD;AAGA,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACvB,IAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,CAAA,CAAE,IAAI,CAAA;AACxC,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,WAAA,EAAY;AAC7B,IAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,CAAS,MAAM,CAAA,IAAK,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAA,IAAK,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA;AACjF,IAAA,IAAI,QAAA,IAAY,MAAA,CAAO,IAAA,CAAK,CAAC,GAAA,KAAQ,cAAA,CAAe,QAAA,CAAS,GAAG,CAAC,CAAA,EAAG,OAAO,CAAA,CAAE,IAAA;AAAA,EAC9E;AAGA,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACvB,IAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,CAAA,CAAE,IAAI,CAAA;AACxC,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,CAAC,GAAA,KAAQ,cAAA,CAAe,SAAS,GAAG,CAAC,CAAA,EAAG,OAAO,CAAA,CAAE,IAAA;AAAA,EAClE;AAEA,EAAA,OAAO,IAAA;AACR;AAOA,SAAS,aAAa,KAAA,EAAyB;AAC9C,EAAA,MAAM,KAAA,GAAQ,SAAS,KAAK,CAAA;AAC5B,EAAA,IAAI,CAAC,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,GAAG,OAAO,KAAA;AAEvC,EAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,EAAA,IAAI,GAAA,KAAQ,CAAA,IAAQ,GAAA,KAAQ,CAAA,EAAM,OAAO,KAAA;AAEzC,EAAA,MAAM,KAAK,GAAA,KAAQ,CAAA;AACnB,EAAA,MAAM,IAAA,GAAO,IAAI,QAAA,CAAS,KAAA,CAAM,QAAQ,KAAA,CAAM,UAAA,EAAY,MAAM,UAAU,CAAA;AAC1E,EAAA,IAAI,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,EAAE,CAAA;AAGlC,EAAA,OAAA,GAAA,CAAW,UAAU,KAAA,IAAc,GAAA;AAGnC,EAAA,OAAO,OAAA,IAAW,KAAK,OAAA,IAAW,CAAA;AACnC;AAOO,SAAS,qBAAA,CACf,MACA,MAAA,EACgB;AAChB,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAE9B,EAAA,MAAM,MAAA,GAAS,KAAK,CAAC,CAAA;AAGrB,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACvB,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,IAAA,CAAK,WAAA,EAAY;AAC7B,IAAA,MAAM,QAAA,GAAW,CAAA,CAAE,QAAA,CAAS,MAAM,CAAA,IAAK,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAA,IAAK,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA;AACjF,IAAA,IAAI,QAAA,IAAY,aAAa,MAAA,CAAO,CAAA,CAAE,IAAI,CAAC,CAAA,SAAU,CAAA,CAAE,IAAA;AAAA,EACxD;AAGA,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,EAAG;AAClD,IAAA,IAAI,KAAA,YAAiB,UAAA,IAAc,KAAA,YAAiB,WAAA,EAAa;AAChE,MAAA,IAAI,YAAA,CAAa,KAAK,CAAA,EAAG,OAAO,GAAA;AAAA,IACjC;AACA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAE9B,MAAA,IAAI,gBAAA,CAAiB,KAAK,KAAK,CAAA,IAAK,MAAM,MAAA,IAAU,EAAA,IAAM,YAAA,CAAa,KAAK,CAAA,EAAG;AAC9E,QAAA,OAAO,GAAA;AAAA,MACR;AAEA,MAAA,IAAI,KAAA,CAAM,KAAK,CAAA,EAAG,OAAO,GAAA;AAAA,IAC1B;AAEA,IAAA,IAAI,iBAAA,CAAkB,KAAK,CAAA,EAAG,OAAO,GAAA;AAErC,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,EAAG;AACvD,MAAA,IAAI;AACH,QAAA,IAAI,kBAAkB,IAAA,CAAK,KAAA,CAAM,KAAK,CAAC,GAAG,OAAO,GAAA;AAAA,MAClD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACD;AAAA,EACD;AAEA,EAAA,OAAO,IAAA;AACR;AAMA,IAAM,SAAA,GAAY;AAAA,EACjB,OAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACD,CAAA;AAGA,SAAS,MAAM,KAAA,EAAiC;AAC/C,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAO,KAAA;AACtC,EAAA,MAAM,CAAA,GAAI,KAAA,CAAM,SAAA,EAAU,CAAE,WAAA,EAAY;AACxC,EAAA,OAAO,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,UAAA,CAAW,CAAC,CAAA,IAAK,CAAA,CAAE,UAAA,CAAW,CAAA,KAAA,EAAQ,CAAC,EAAE,CAAC,CAAA;AAC1E","file":"index.cjs","sourcesContent":["/**\n * Shared constants used across the application.\n * Centralizes magic strings, numbers, and sets to prevent duplication.\n */\n\n// ── localStorage keys ──\n\nexport const STORAGE_KEYS = {\n\tSETTINGS: 'obstore-explore-settings',\n\tCONNECTIONS: 'obstore-explore-connections',\n\tQUERY_HISTORY: 'obstore-explore-query-history'\n} as const;\n\n// ── Geo / CRS constants ──\n\n/** EPSG codes considered WGS84 (no reprojection needed). */\nexport const WGS84_CODES = new Set([4326, 4979]);\n\n/**\n * Default target CRS for ST_Transform. Uses OGC:CRS84 (longitude, latitude)\n * to match GeoParquet 1.1+ spec and DuckDB v1.5's canonical form.\n * Functionally equivalent to EPSG:4326 under `geometry_always_xy = true`.\n */\nexport const DEFAULT_TARGET_CRS = 'OGC:CRS84';\n\n// ── Query engine constants ──\n\n/** DuckDB-WASM initialization timeout in ms. */\nexport const DUCKDB_INIT_TIMEOUT_MS = 30_000;\n\n/** Maximum entries kept in query history. */\nexport const MAX_QUERY_HISTORY_ENTRIES = 200;\n\n/** SQL preview truncation length (characters). */\nexport const SQL_PREVIEW_LENGTH = 120;\n\n// ── File browser constants ──\n\n/** Extensions that represent \"virtual files\" — directories that open as viewers. */\nexport const VIEWER_DIR_EXTENSIONS = new Set(['zarr', 'zr3']);\n\n// ── PMTiles ──\n\n/**\n * Golden-angle-based hue multiplier for evenly distributing layer colors.\n * 137 ≈ 360 × (1 − 1/φ) where φ is the golden ratio.\n */\nexport const LAYER_HUE_MULTIPLIER = 137;\n\n// ── Clipboard ──\n\n/** Duration (ms) to show \"Copied!\" feedback before resetting. */\nexport const COPY_FEEDBACK_MS = 2000;\n","/**\n * Centralized file type detection module.\n *\n * Single source of truth for extension → icon, color, label, category,\n * viewer, DuckDB read function, MIME type, and queryability.\n *\n * Used by: FileTreeSidebar, ViewerRouter, TableViewer, WasmQueryEngine, etc.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type FileCategory =\n\t| 'data'\n\t| 'geo'\n\t| 'code'\n\t| 'document'\n\t| 'config'\n\t| 'image'\n\t| 'video'\n\t| 'audio'\n\t| 'archive'\n\t| 'database'\n\t| '3d'\n\t| 'other';\n\nexport type ViewerKind =\n\t| 'table'\n\t| 'image'\n\t| 'video'\n\t| 'audio'\n\t| 'markdown'\n\t| 'code'\n\t| 'cog'\n\t| 'pmtiles'\n\t| 'flatgeobuf'\n\t| 'pdf'\n\t| '3d'\n\t| 'archive'\n\t| 'database'\n\t| 'zarr'\n\t| 'copc'\n\t| 'notebook'\n\t| 'raw';\n\nexport type DuckDbReadFn = 'read_parquet' | 'read_csv' | 'read_json' | 'ST_Read';\n\nexport interface FileTypeInfo {\n\t/** Lucide icon name */\n\ticon: string;\n\t/** Tailwind color classes (light + dark) */\n\tcolor: string;\n\t/** Human-readable type label, e.g. \"Apache Parquet\" */\n\tlabel: string;\n\t/** High-level category */\n\tcategory: FileCategory;\n\t/** Which viewer component to use */\n\tviewer: ViewerKind;\n\t/** Whether this file can be queried with DuckDB */\n\tqueryable: boolean;\n\t/** DuckDB read function (null if not queryable) */\n\tduckdbReadFn: DuckDbReadFn | null;\n\t/** MIME type */\n\tmimeType: string;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_INFO: FileTypeInfo = {\n\ticon: 'File',\n\tcolor: 'text-zinc-400 dark:text-zinc-500',\n\tlabel: 'File',\n\tcategory: 'other',\n\tviewer: 'raw',\n\tqueryable: false,\n\tduckdbReadFn: null,\n\tmimeType: 'application/octet-stream'\n};\n\nconst FOLDER_INFO: FileTypeInfo = {\n\ticon: 'Folder',\n\tcolor: 'text-blue-500 dark:text-blue-400',\n\tlabel: 'Folder',\n\tcategory: 'other',\n\tviewer: 'raw',\n\tqueryable: false,\n\tduckdbReadFn: null,\n\tmimeType: 'inode/directory'\n};\n\n// ---------------------------------------------------------------------------\n// Extension registry\n// ---------------------------------------------------------------------------\n\nconst EXTENSIONS: Record<string, FileTypeInfo> = {\n\t// ── Data / Tabular ──────────────────────────────────────────────────\n\t'.parquet': {\n\t\ticon: 'Columns3',\n\t\tcolor: 'text-purple-600 dark:text-purple-400',\n\t\tlabel: 'Apache Parquet',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.geoparquet': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'GeoParquet',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.gpq': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'GeoParquet',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.gparquet': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'GeoParquet',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_parquet',\n\t\tmimeType: 'application/vnd.apache.parquet'\n\t},\n\t'.csv': {\n\t\ticon: 'Table',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'CSV',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_csv',\n\t\tmimeType: 'text/csv'\n\t},\n\t'.tsv': {\n\t\ticon: 'Table',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'TSV',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_csv',\n\t\tmimeType: 'text/tab-separated-values'\n\t},\n\t'.json': {\n\t\ticon: 'Braces',\n\t\tcolor: 'text-yellow-600 dark:text-yellow-400',\n\t\tlabel: 'JSON',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/json'\n\t},\n\t'.jsonl': {\n\t\ticon: 'Braces',\n\t\tcolor: 'text-yellow-500 dark:text-yellow-400',\n\t\tlabel: 'JSON Lines',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_json',\n\t\tmimeType: 'application/x-jsonlines'\n\t},\n\t'.ndjson': {\n\t\ticon: 'Braces',\n\t\tcolor: 'text-yellow-500 dark:text-yellow-400',\n\t\tlabel: 'NDJSON',\n\t\tcategory: 'data',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_json',\n\t\tmimeType: 'application/x-ndjson'\n\t},\n\t'.geojson': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-emerald-600 dark:text-emerald-400',\n\t\tlabel: 'GeoJSON',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'read_json',\n\t\tmimeType: 'application/geo+json'\n\t},\n\t'.arrow': {\n\t\ticon: 'Zap',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Apache Arrow',\n\t\tcategory: 'data',\n\t\tviewer: 'raw',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.apache.arrow.file'\n\t},\n\t'.feather': {\n\t\ticon: 'Zap',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Feather',\n\t\tcategory: 'data',\n\t\tviewer: 'raw',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.apache.arrow.file'\n\t},\n\t'.ipc': {\n\t\ticon: 'Zap',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Arrow IPC',\n\t\tcategory: 'data',\n\t\tviewer: 'raw',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.apache.arrow.stream'\n\t},\n\n\t// ── Images ──────────────────────────────────────────────────────────\n\t'.png': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'PNG Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/png'\n\t},\n\t'.jpg': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'JPEG Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/jpeg'\n\t},\n\t'.jpeg': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'JPEG Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/jpeg'\n\t},\n\t'.gif': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'GIF Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/gif'\n\t},\n\t'.webp': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'WebP Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/webp'\n\t},\n\t'.avif': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'AVIF Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/avif'\n\t},\n\t'.svg': {\n\t\ticon: 'Palette',\n\t\tcolor: 'text-pink-600 dark:text-pink-400',\n\t\tlabel: 'SVG',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/svg+xml'\n\t},\n\t'.bmp': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'BMP Image',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/bmp'\n\t},\n\t'.ico': {\n\t\ticon: 'Image',\n\t\tcolor: 'text-pink-500 dark:text-pink-400',\n\t\tlabel: 'Icon',\n\t\tcategory: 'image',\n\t\tviewer: 'image',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/x-icon'\n\t},\n\n\t// ── Video ───────────────────────────────────────────────────────────\n\t'.mp4': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'MP4 Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/mp4'\n\t},\n\t'.webm': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'WebM Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/webm'\n\t},\n\t'.mov': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'MOV Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/quicktime'\n\t},\n\t'.avi': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'AVI Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/x-msvideo'\n\t},\n\t'.mkv': {\n\t\ticon: 'Film',\n\t\tcolor: 'text-violet-500 dark:text-violet-400',\n\t\tlabel: 'MKV Video',\n\t\tcategory: 'video',\n\t\tviewer: 'video',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'video/x-matroska'\n\t},\n\n\t// ── Audio ───────────────────────────────────────────────────────────\n\t'.mp3': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'MP3 Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/mpeg'\n\t},\n\t'.wav': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'WAV Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/wav'\n\t},\n\t'.ogg': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'OGG Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/ogg'\n\t},\n\t'.flac': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'FLAC Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/flac'\n\t},\n\t'.aac': {\n\t\ticon: 'Music',\n\t\tcolor: 'text-rose-500 dark:text-rose-400',\n\t\tlabel: 'AAC Audio',\n\t\tcategory: 'audio',\n\t\tviewer: 'audio',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'audio/aac'\n\t},\n\n\t// ── Code ────────────────────────────────────────────────────────────\n\t'.py': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-sky-600 dark:text-sky-400',\n\t\tlabel: 'Python',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-python'\n\t},\n\t'.ts': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-600 dark:text-blue-400',\n\t\tlabel: 'TypeScript',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/typescript'\n\t},\n\t'.js': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-yellow-500 dark:text-yellow-400',\n\t\tlabel: 'JavaScript',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/javascript'\n\t},\n\t'.rs': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-700 dark:text-orange-400',\n\t\tlabel: 'Rust',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-rust'\n\t},\n\t'.go': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-cyan-600 dark:text-cyan-400',\n\t\tlabel: 'Go',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-go'\n\t},\n\t'.java': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-red-600 dark:text-red-400',\n\t\tlabel: 'Java',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-java'\n\t},\n\t'.c': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c'\n\t},\n\t'.cpp': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C++',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c++'\n\t},\n\t'.h': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C Header',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c'\n\t},\n\t'.hpp': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'C++ Header',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-c++'\n\t},\n\t'.rb': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-red-500 dark:text-red-400',\n\t\tlabel: 'Ruby',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-ruby'\n\t},\n\t'.php': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-indigo-500 dark:text-indigo-400',\n\t\tlabel: 'PHP',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-php'\n\t},\n\t'.swift': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'Swift',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-swift'\n\t},\n\t'.kt': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'Kotlin',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-kotlin'\n\t},\n\t'.scala': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-red-600 dark:text-red-400',\n\t\tlabel: 'Scala',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-scala'\n\t},\n\t'.r': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-600 dark:text-blue-400',\n\t\tlabel: 'R',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-r'\n\t},\n\t'.lua': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-800 dark:text-blue-400',\n\t\tlabel: 'Lua',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-lua'\n\t},\n\t'.html': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-orange-600 dark:text-orange-400',\n\t\tlabel: 'HTML',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/html'\n\t},\n\t'.css': {\n\t\ticon: 'Paintbrush',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'CSS',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/css'\n\t},\n\t'.sql': {\n\t\ticon: 'DatabaseZap',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'SQL',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-sql'\n\t},\n\t'.sh': {\n\t\ticon: 'Terminal',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'Shell Script',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-shellscript'\n\t},\n\t'.bash': {\n\t\ticon: 'Terminal',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'Bash Script',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/x-shellscript'\n\t},\n\t'.vim': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-green-700 dark:text-green-400',\n\t\tlabel: 'Vim Script',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.dockerfile': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-blue-600 dark:text-blue-400',\n\t\tlabel: 'Dockerfile',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.makefile': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-600 dark:text-orange-400',\n\t\tlabel: 'Makefile',\n\t\tcategory: 'code',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\n\t// ── Documents ───────────────────────────────────────────────────────\n\t'.md': {\n\t\ticon: 'BookText',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'Markdown',\n\t\tcategory: 'document',\n\t\tviewer: 'markdown',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/markdown'\n\t},\n\t'.markdown': {\n\t\ticon: 'BookText',\n\t\tcolor: 'text-blue-500 dark:text-blue-400',\n\t\tlabel: 'Markdown',\n\t\tcategory: 'document',\n\t\tviewer: 'markdown',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/markdown'\n\t},\n\t'.pdf': {\n\t\ticon: 'FileText',\n\t\tcolor: 'text-red-600 dark:text-red-400',\n\t\tlabel: 'PDF',\n\t\tcategory: 'document',\n\t\tviewer: 'pdf',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/pdf'\n\t},\n\t'.txt': {\n\t\ticon: 'FileText',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Text',\n\t\tcategory: 'document',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.log': {\n\t\ticon: 'FileText',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Log File',\n\t\tcategory: 'document',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\n\t// ── Config ──────────────────────────────────────────────────────────\n\t'.xml': {\n\t\ticon: 'FileCode',\n\t\tcolor: 'text-orange-500 dark:text-orange-400',\n\t\tlabel: 'XML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/xml'\n\t},\n\t'.yaml': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'YAML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/yaml'\n\t},\n\t'.yml': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'YAML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/yaml'\n\t},\n\t'.toml': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'TOML',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.ini': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'INI',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.cfg': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Config',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.conf': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Config',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.env': {\n\t\ticon: 'Settings',\n\t\tcolor: 'text-zinc-500 dark:text-zinc-400',\n\t\tlabel: 'Environment',\n\t\tcategory: 'config',\n\t\tviewer: 'code',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\n\t// ── Archives ────────────────────────────────────────────────────────\n\t'.zip': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'ZIP Archive',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/zip'\n\t},\n\t'.tar': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'TAR Archive',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-tar'\n\t},\n\t'.gz': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'GZIP',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/gzip'\n\t},\n\t'.tgz': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'TGZ Archive',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/gzip'\n\t},\n\t'.7z': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: '7-Zip',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-7z-compressed'\n\t},\n\t'.rar': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'RAR',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/vnd.rar'\n\t},\n\t'.bz2': {\n\t\ticon: 'Archive',\n\t\tcolor: 'text-amber-600 dark:text-amber-400',\n\t\tlabel: 'BZIP2',\n\t\tcategory: 'archive',\n\t\tviewer: 'archive',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-bzip2'\n\t},\n\n\t// ── Geo / Map ───────────────────────────────────────────────────────\n\t'.tif': {\n\t\ticon: 'Map',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'GeoTIFF',\n\t\tcategory: 'geo',\n\t\tviewer: 'cog',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/tiff'\n\t},\n\t'.tiff': {\n\t\ticon: 'Map',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'GeoTIFF',\n\t\tcategory: 'geo',\n\t\tviewer: 'cog',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'image/tiff'\n\t},\n\t'.pmtiles': {\n\t\ticon: 'Layers',\n\t\tcolor: 'text-teal-600 dark:text-teal-400',\n\t\tlabel: 'PMTiles',\n\t\tcategory: 'geo',\n\t\tviewer: 'pmtiles',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.fgb': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-teal-500 dark:text-teal-400',\n\t\tlabel: 'FlatGeobuf',\n\t\tcategory: 'geo',\n\t\tviewer: 'flatgeobuf',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.shp': {\n\t\ticon: 'Globe',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'Shapefile',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'ST_Read',\n\t\tmimeType: 'application/x-esri-shape'\n\t},\n\t'.gpkg': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-green-600 dark:text-green-400',\n\t\tlabel: 'GeoPackage',\n\t\tcategory: 'geo',\n\t\tviewer: 'table',\n\t\tqueryable: true,\n\t\tduckdbReadFn: 'ST_Read',\n\t\tmimeType: 'application/geopackage+sqlite3'\n\t},\n\n\t// ── Database ────────────────────────────────────────────────────────\n\t'.duckdb': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-yellow-600 dark:text-yellow-400',\n\t\tlabel: 'DuckDB',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: true,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.ducklake': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-teal-600 dark:text-teal-400',\n\t\tlabel: 'DuckLake',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: true,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.sqlite': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-sky-600 dark:text-sky-400',\n\t\tlabel: 'SQLite',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-sqlite3'\n\t},\n\t'.db': {\n\t\ticon: 'Database',\n\t\tcolor: 'text-amber-500 dark:text-amber-400',\n\t\tlabel: 'Database',\n\t\tcategory: 'database',\n\t\tviewer: 'database',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\n\t// ── 3D Models ───────────────────────────────────────────────────────\n\t'.glb': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'GLB Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'model/gltf-binary'\n\t},\n\t'.gltf': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'glTF Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'model/gltf+json'\n\t},\n\t'.obj': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'OBJ Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'text/plain'\n\t},\n\t'.stl': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'STL Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'model/stl'\n\t},\n\t'.fbx': {\n\t\ticon: 'Box',\n\t\tcolor: 'text-violet-600 dark:text-violet-400',\n\t\tlabel: 'FBX Model',\n\t\tcategory: '3d',\n\t\tviewer: '3d',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\n\t// ── Notebooks ───────────────────────────────────────────────────────\n\t'.ipynb': {\n\t\ticon: 'BookOpen',\n\t\tcolor: 'text-orange-600 dark:text-orange-400',\n\t\tlabel: 'Jupyter Notebook',\n\t\tcategory: 'code',\n\t\tviewer: 'notebook',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/x-ipynb+json'\n\t},\n\n\t// ── Special ─────────────────────────────────────────────────────────\n\t'.zarr': {\n\t\ticon: 'Layers',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'Zarr',\n\t\tcategory: 'data',\n\t\tviewer: 'zarr',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.zr3': {\n\t\ticon: 'Layers',\n\t\tcolor: 'text-purple-500 dark:text-purple-400',\n\t\tlabel: 'Zarr',\n\t\tcategory: 'data',\n\t\tviewer: 'zarr',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\n\t// ── Point Cloud ─────────────────────────────────────────────────────\n\t'.laz': {\n\t\ticon: 'Orbit',\n\t\tcolor: 'text-cyan-600 dark:text-cyan-400',\n\t\tlabel: 'COPC / LAZ',\n\t\tcategory: 'geo',\n\t\tviewer: 'copc',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t},\n\t'.las': {\n\t\ticon: 'Orbit',\n\t\tcolor: 'text-cyan-600 dark:text-cyan-400',\n\t\tlabel: 'LAS Point Cloud',\n\t\tcategory: 'geo',\n\t\tviewer: 'copc',\n\t\tqueryable: false,\n\t\tduckdbReadFn: null,\n\t\tmimeType: 'application/octet-stream'\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Returns full file type information for a given extension.\n * Extension may be with or without leading dot: \".parquet\" or \"parquet\".\n */\nexport function getFileTypeInfo(extension: string, isDir = false): FileTypeInfo {\n\tif (isDir && extension) {\n\t\tconst ext = extension.startsWith('.') ? extension.toLowerCase() : `.${extension.toLowerCase()}`;\n\t\tconst found = EXTENSIONS[ext];\n\t\tif (found) return found;\n\t}\n\tif (isDir) return FOLDER_INFO;\n\tconst ext = extension.startsWith('.') ? extension.toLowerCase() : `.${extension.toLowerCase()}`;\n\treturn EXTENSIONS[ext] ?? DEFAULT_INFO;\n}\n\n/** Returns the DuckDB read function name for a file path. Falls back to read_parquet. */\nexport function getDuckDbReadFn(pathOrExt: string): string {\n\tconst ext = pathOrExt.includes('.') ? `.${pathOrExt.split('.').pop()!.toLowerCase()}` : '';\n\treturn EXTENSIONS[ext]?.duckdbReadFn ?? 'read_parquet';\n}\n\n/**\n * Returns a DuckDB FROM-clause expression for a file.\n *\n * For GeoJSON files the raw `read_json_auto` returns a single row with the\n * FeatureCollection structure (`type`, `features`, `bbox`). This helper\n * unnests the features array so each feature becomes its own row with\n * property columns + a geometry column.\n */\nexport function buildDuckDbSource(pathOrExt: string, url: string): string {\n\tconst ext = pathOrExt.includes('.') ? `.${pathOrExt.split('.').pop()!.toLowerCase()}` : '';\n\tif (ext === '.geojson') {\n\t\treturn `(SELECT unnest(feature.properties), to_json(feature.geometry)::VARCHAR AS geometry FROM (SELECT unnest(features) AS feature FROM read_json_auto('${url}', maximum_object_size=1073741824, ignore_errors=true)))`;\n\t}\n\tconst readFn = EXTENSIONS[ext]?.duckdbReadFn ?? 'read_parquet';\n\treturn `${readFn}('${url}')`;\n}\n\n/**\n * Cloud-native formats that DuckDB can query via range requests — metadata\n * reads (schema, row count) are cheap and don't download the full file.\n *\n * Other cloud-native formats (.fgb, .pmtiles, .zarr) also support range\n * requests but have dedicated viewers and don't go through DuckDB/TableViewer.\n */\nconst CLOUD_NATIVE_EXTS = new Set(['.parquet', '.geoparquet', '.gpq', '.gparquet', '.ducklake']);\n\nexport function isCloudNativeFormat(pathOrExt: string): boolean {\n\tconst ext = pathOrExt.includes('.') ? `.${pathOrExt.split('.').pop()!.toLowerCase()}` : '';\n\treturn CLOUD_NATIVE_EXTS.has(ext);\n}\n\n/** Returns the viewer kind for a given extension. */\nexport function getViewerKind(extension: string): ViewerKind {\n\treturn getFileTypeInfo(extension).viewer;\n}\n\n/** Returns whether a file can be queried with DuckDB. */\nexport function isQueryable(extension: string): boolean {\n\treturn getFileTypeInfo(extension).queryable;\n}\n\n/** Returns the MIME type for a file extension. */\nexport function getMimeType(extension: string): string {\n\treturn getFileTypeInfo(extension).mimeType;\n}\n\n/** Re-export folder info for components that need it directly. */\nexport { DEFAULT_INFO, FOLDER_INFO };\n","export class QueryCancelledError extends Error {\n\tconstructor() {\n\t\tsuper('Query cancelled');\n\t\tthis.name = 'QueryCancelledError';\n\t}\n}\n\nexport interface QueryHandle {\n\tresult: Promise<QueryResult>;\n\tcancel: () => Promise<boolean>;\n}\n\nexport interface MapQueryHandle {\n\tresult: Promise<MapQueryResult>;\n\tcancel: () => Promise<boolean>;\n}\n\nexport interface QueryResult {\n\tcolumns: string[];\n\ttypes: string[];\n\trowCount: number;\n\t/** Pre-parsed rows — avoids Arrow version mismatch in WASM engine */\n\trows: Record<string, any>[];\n}\n\n/** Raw column data for map rendering (bypasses toJSON serialization). */\nexport interface MapQueryResult {\n\t/** Geometry column as raw WKB binary arrays */\n\twkbArrays: Uint8Array[];\n\t/** Geometry type from ST_GeometryType (e.g., 'POLYGON') */\n\tgeometryType: string;\n\t/** Non-geometry attribute columns: name → JS values */\n\tattributes: Map<string, { values: any[]; type: string }>;\n\t/** Number of rows */\n\trowCount: number;\n}\n\nexport interface SchemaField {\n\tname: string;\n\ttype: string;\n\tnullable: boolean;\n}\n\n/**\n * Abstraction over a DuckDB query source. Decouples schema / CRS / count\n * helpers from assuming a file-backed path. `ref` is the FROM-clause target\n * inserted into generated SQL (e.g. `read_parquet('url')` for files, or\n * `attached_db.\"schema\".\"table\"` for attached databases). `filePath` is\n * optional and only used as a shortcut for Parquet file-level metadata\n * queries (`parquet_kv_metadata`, `parquet_file_metadata`), not for SQL.\n */\nexport interface QuerySource {\n\tref: string;\n\tfilePath?: string;\n}\n\nexport interface QueryEngine {\n\tquery(connId: string, sql: string): Promise<QueryResult>;\n\tqueryForMap(\n\t\tconnId: string,\n\t\tsql: string,\n\t\tgeomCol: string,\n\t\tgeomColType: string,\n\t\tsourceCrs?: string | null\n\t): Promise<MapQueryResult>;\n\tgetSchema(connId: string, source: QuerySource): Promise<SchemaField[]>;\n\tgetRowCount(connId: string, source: QuerySource): Promise<number>;\n\t/** Detect CRS from GeoParquet metadata. Returns e.g. 'EPSG:27700' or null if WGS84/unknown. */\n\tdetectCrs(connId: string, source: QuerySource, geomCol: string): Promise<string | null>;\n\t/** Combined schema + CRS detection in a single connection (fewer web worker round-trips). */\n\tgetSchemaAndCrs?(\n\t\tconnId: string,\n\t\tsource: QuerySource,\n\t\tfindGeoCol: (schema: SchemaField[]) => string | null\n\t): Promise<{ schema: SchemaField[]; geomCol: string | null; crs: string | null }>;\n\tqueryCancellable?(connId: string, sql: string): QueryHandle;\n\t/**\n\t * Streaming variant of `queryCancellable`. Yields one `QueryResult`-shaped\n\t * chunk per Arrow RecordBatch instead of materializing the full row set\n\t * before returning. Peak memory tracks one batch (~64 KiB rows) rather\n\t * than the full result, which avoids DuckDB-WASM OOMs on large parquet\n\t * scans. The first chunk carries the schema (`columns` / `types`); later\n\t * chunks repeat them so consumers don't need to track first-batch state.\n\t * Cancellation aborts the inner DuckDB cursor.\n\t */\n\tqueryStream?(connId: string, sql: string, signal?: AbortSignal): AsyncIterable<QueryResult>;\n\tqueryForMapCancellable?(\n\t\tconnId: string,\n\t\tsql: string,\n\t\tgeomCol: string,\n\t\tgeomColType: string,\n\t\tsourceCrs?: string | null\n\t): MapQueryHandle;\n\tforceCancel?(): Promise<void>;\n\t/** Register a file buffer in DuckDB-WASM's virtual filesystem for ATTACH. */\n\tregisterFileBuffer?(name: string, buffer: Uint8Array): Promise<void>;\n\t/** Drop a previously registered file from DuckDB-WASM's virtual filesystem. */\n\tdropFile?(name: string): Promise<void>;\n\treleaseMemory(): Promise<void>;\n\tdispose(): Promise<void>;\n}\n","/**\n * Provider registry — single source of truth for all cloud storage providers.\n *\n * Centralizes endpoint patterns, regions, auth methods, and UI metadata.\n * Used by ConnectionDialog, browser-cloud adapter, host-detection, url-state, etc.\n */\n\n// ---------------------------------------------------------------------------\n// Provider type — the canonical union used by Connection, ConnectionConfig, etc.\n// ---------------------------------------------------------------------------\n\nexport type ProviderId =\n\t| 's3'\n\t| 'gcs'\n\t| 'r2'\n\t| 'minio'\n\t| 'azure'\n\t| 'storj'\n\t| 'b2'\n\t| 'digitalocean'\n\t| 'wasabi'\n\t| 'contabo'\n\t| 'hetzner'\n\t| 'linode'\n\t| 'ovhcloud';\n\n// ---------------------------------------------------------------------------\n// Region definition\n// ---------------------------------------------------------------------------\n\nexport interface ProviderRegion {\n\tcode: string;\n\tlabel: string;\n}\n\n// ---------------------------------------------------------------------------\n// Provider definition\n// ---------------------------------------------------------------------------\n\nexport interface ProviderDef {\n\t/** Display label in the UI. */\n\tlabel: string;\n\t/** Short description shown as helper text. */\n\tdescription: string;\n\t/** Auth method used by this provider. */\n\tauthMethod: 'sigv4' | 'sas-token';\n\t/** Whether the region field is relevant for this provider. */\n\tneedsRegion: boolean;\n\t/** Whether the endpoint field is required. */\n\tneedsEndpoint: boolean;\n\t/** Default region when creating a new connection. */\n\tdefaultRegion: string;\n\t/**\n\t * Endpoint template with `{region}` placeholder.\n\t * If null, the user must provide a custom endpoint (e.g. MinIO).\n\t * If a fixed string (no `{region}`), it's always the same (e.g. GCS).\n\t */\n\tendpointTemplate: string | null;\n\t/** Known regions with labels. Empty = free-form region input. */\n\tregions: ProviderRegion[];\n\t/** Bucket label override (e.g. Azure uses \"Container\"). */\n\tbucketLabel?: string;\n\t/** Default endpoint placeholder shown in the input. */\n\tendpointPlaceholder: string;\n\t/** URI schemes that map to this provider (lowercase, without \"://\"). */\n\tschemes: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nexport const PROVIDERS: Record<ProviderId, ProviderDef> = {\n\ts3: {\n\t\tlabel: 'AWS S3',\n\t\tdescription: 'Amazon S3 or any S3-compatible service',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: null,\n\t\tregions: [\n\t\t\t{ code: 'us-east-1', label: 'US East (N. Virginia)' },\n\t\t\t{ code: 'us-east-2', label: 'US East (Ohio)' },\n\t\t\t{ code: 'us-west-1', label: 'US West (N. California)' },\n\t\t\t{ code: 'us-west-2', label: 'US West (Oregon)' },\n\t\t\t{ code: 'eu-west-1', label: 'EU (Ireland)' },\n\t\t\t{ code: 'eu-west-2', label: 'EU (London)' },\n\t\t\t{ code: 'eu-west-3', label: 'EU (Paris)' },\n\t\t\t{ code: 'eu-central-1', label: 'EU (Frankfurt)' },\n\t\t\t{ code: 'eu-central-2', label: 'EU (Zurich)' },\n\t\t\t{ code: 'eu-north-1', label: 'EU (Stockholm)' },\n\t\t\t{ code: 'eu-south-1', label: 'EU (Milan)' },\n\t\t\t{ code: 'eu-south-2', label: 'EU (Spain)' },\n\t\t\t{ code: 'ap-northeast-1', label: 'Asia Pacific (Tokyo)' },\n\t\t\t{ code: 'ap-northeast-2', label: 'Asia Pacific (Seoul)' },\n\t\t\t{ code: 'ap-northeast-3', label: 'Asia Pacific (Osaka)' },\n\t\t\t{ code: 'ap-southeast-1', label: 'Asia Pacific (Singapore)' },\n\t\t\t{ code: 'ap-southeast-2', label: 'Asia Pacific (Sydney)' },\n\t\t\t{ code: 'ap-southeast-3', label: 'Asia Pacific (Jakarta)' },\n\t\t\t{ code: 'ap-south-1', label: 'Asia Pacific (Mumbai)' },\n\t\t\t{ code: 'ap-south-2', label: 'Asia Pacific (Hyderabad)' },\n\t\t\t{ code: 'ap-east-1', label: 'Asia Pacific (Hong Kong)' },\n\t\t\t{ code: 'sa-east-1', label: 'South America (São Paulo)' },\n\t\t\t{ code: 'ca-central-1', label: 'Canada (Central)' },\n\t\t\t{ code: 'ca-west-1', label: 'Canada (Calgary)' },\n\t\t\t{ code: 'me-south-1', label: 'Middle East (Bahrain)' },\n\t\t\t{ code: 'me-central-1', label: 'Middle East (UAE)' },\n\t\t\t{ code: 'af-south-1', label: 'Africa (Cape Town)' },\n\t\t\t{ code: 'il-central-1', label: 'Israel (Tel Aviv)' }\n\t\t],\n\t\tendpointPlaceholder: 'Leave empty for AWS, or enter custom S3 endpoint',\n\t\tschemes: ['s3', 's3a', 's3n', 'aws']\n\t},\n\n\tgcs: {\n\t\tlabel: 'Google Cloud',\n\t\tdescription: 'Google Cloud Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'auto',\n\t\tendpointTemplate: 'https://storage.googleapis.com',\n\t\tregions: [],\n\t\tendpointPlaceholder: 'https://storage.googleapis.com',\n\t\tschemes: ['gs', 'gcs']\n\t},\n\n\tr2: {\n\t\tlabel: 'Cloudflare R2',\n\t\tdescription: 'Cloudflare R2 Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: true,\n\t\tdefaultRegion: 'auto',\n\t\tendpointTemplate: null,\n\t\tregions: [],\n\t\tendpointPlaceholder: 'https://<account-id>.r2.cloudflarestorage.com',\n\t\tschemes: ['r2']\n\t},\n\n\tazure: {\n\t\tlabel: 'Azure',\n\t\tdescription: 'Azure Blob Storage',\n\t\tauthMethod: 'sas-token',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: true,\n\t\tdefaultRegion: '',\n\t\tendpointTemplate: null,\n\t\tregions: [],\n\t\tbucketLabel: 'Container',\n\t\tendpointPlaceholder: 'https://<account>.blob.core.windows.net',\n\t\tschemes: ['azure', 'az', 'abfs', 'abfss', 'wasbs', 'adl']\n\t},\n\n\tminio: {\n\t\tlabel: 'MinIO / RustFS / Custom',\n\t\tdescription: 'MinIO, RustFS, or any custom S3-compatible endpoint',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: true,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: null,\n\t\tregions: [],\n\t\tendpointPlaceholder: 'https://s3.example.com or http://localhost:9000',\n\t\tschemes: []\n\t},\n\n\tstorj: {\n\t\tlabel: 'Storj',\n\t\tdescription: 'Storj Decentralized Cloud',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: false,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us1',\n\t\tendpointTemplate: 'https://gateway.storjshare.io',\n\t\tregions: [\n\t\t\t{ code: 'us1', label: 'US1' },\n\t\t\t{ code: 'eu1', label: 'EU1' },\n\t\t\t{ code: 'ap1', label: 'AP1' }\n\t\t],\n\t\tendpointPlaceholder: 'https://gateway.storjshare.io',\n\t\tschemes: ['storj', 'sj']\n\t},\n\n\tb2: {\n\t\tlabel: 'Backblaze B2',\n\t\tdescription: 'Backblaze B2 Cloud Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-west-004',\n\t\tendpointTemplate: 'https://s3.{region}.backblazeb2.com',\n\t\tregions: [\n\t\t\t{ code: 'us-west-000', label: 'US West (Sacramento)' },\n\t\t\t{ code: 'us-west-001', label: 'US West (Stockton)' },\n\t\t\t{ code: 'us-west-002', label: 'US West (Phoenix)' },\n\t\t\t{ code: 'us-west-004', label: 'US West' },\n\t\t\t{ code: 'us-east-005', label: 'US East (Reston)' },\n\t\t\t{ code: 'eu-central-003', label: 'EU Central (Amsterdam)' },\n\t\t\t{ code: 'ca-central-001', label: 'Canada (Toronto)' }\n\t\t],\n\t\tendpointPlaceholder: 'https://s3.us-west-004.backblazeb2.com',\n\t\tschemes: []\n\t},\n\n\tdigitalocean: {\n\t\tlabel: 'DigitalOcean',\n\t\tdescription: 'DigitalOcean Spaces',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'nyc3',\n\t\tendpointTemplate: 'https://{region}.digitaloceanspaces.com',\n\t\tregions: [\n\t\t\t{ code: 'nyc3', label: 'New York 3' },\n\t\t\t{ code: 'sfo3', label: 'San Francisco 3' },\n\t\t\t{ code: 'ams3', label: 'Amsterdam 3' },\n\t\t\t{ code: 'sgp1', label: 'Singapore 1' },\n\t\t\t{ code: 'lon1', label: 'London 1' },\n\t\t\t{ code: 'fra1', label: 'Frankfurt 1' },\n\t\t\t{ code: 'tor1', label: 'Toronto 1' },\n\t\t\t{ code: 'blr1', label: 'Bangalore 1' },\n\t\t\t{ code: 'syd1', label: 'Sydney 1' }\n\t\t],\n\t\tendpointPlaceholder: 'https://nyc3.digitaloceanspaces.com',\n\t\tschemes: []\n\t},\n\n\twasabi: {\n\t\tlabel: 'Wasabi',\n\t\tdescription: 'Wasabi Hot Cloud Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: 'https://s3.{region}.wasabisys.com',\n\t\tregions: [\n\t\t\t{ code: 'us-east-1', label: 'US East 1 (Virginia)' },\n\t\t\t{ code: 'us-east-2', label: 'US East 2 (Virginia)' },\n\t\t\t{ code: 'us-central-1', label: 'US Central 1 (Texas)' },\n\t\t\t{ code: 'us-west-1', label: 'US West 1 (Oregon)' },\n\t\t\t{ code: 'eu-central-1', label: 'EU Central 1 (Amsterdam)' },\n\t\t\t{ code: 'eu-central-2', label: 'EU Central 2 (Frankfurt)' },\n\t\t\t{ code: 'eu-west-1', label: 'EU West 1 (London)' },\n\t\t\t{ code: 'eu-west-2', label: 'EU West 2 (Paris)' },\n\t\t\t{ code: 'ap-northeast-1', label: 'AP Northeast 1 (Tokyo)' },\n\t\t\t{ code: 'ap-northeast-2', label: 'AP Northeast 2 (Osaka)' },\n\t\t\t{ code: 'ap-southeast-1', label: 'AP Southeast 1 (Singapore)' },\n\t\t\t{ code: 'ap-southeast-2', label: 'AP Southeast 2 (Sydney)' },\n\t\t\t{ code: 'ca-central-1', label: 'Canada (Toronto)' }\n\t\t],\n\t\tendpointPlaceholder: 'https://s3.us-east-1.wasabisys.com',\n\t\tschemes: []\n\t},\n\n\tcontabo: {\n\t\tlabel: 'Contabo',\n\t\tdescription: 'Contabo Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'eu2',\n\t\tendpointTemplate: 'https://{region}.contabostorage.com',\n\t\tregions: [\n\t\t\t{ code: 'eu2', label: 'European Union' },\n\t\t\t{ code: 'usc1', label: 'US Central' },\n\t\t\t{ code: 'sin1', label: 'Singapore' }\n\t\t],\n\t\tendpointPlaceholder: 'https://eu2.contabostorage.com',\n\t\tschemes: []\n\t},\n\n\thetzner: {\n\t\tlabel: 'Hetzner',\n\t\tdescription: 'Hetzner Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'fsn1',\n\t\tendpointTemplate: 'https://{region}.your-objectstorage.com',\n\t\tregions: [\n\t\t\t{ code: 'fsn1', label: 'Falkenstein, DE' },\n\t\t\t{ code: 'nbg1', label: 'Nuremberg, DE' },\n\t\t\t{ code: 'hel1', label: 'Helsinki, FI' }\n\t\t],\n\t\tendpointPlaceholder: 'https://fsn1.your-objectstorage.com',\n\t\tschemes: []\n\t},\n\n\tlinode: {\n\t\tlabel: 'Linode / Akamai',\n\t\tdescription: 'Akamai / Linode Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'us-east-1',\n\t\tendpointTemplate: 'https://{region}.linodeobjects.com',\n\t\tregions: [\n\t\t\t{ code: 'us-east-1', label: 'Newark, NJ' },\n\t\t\t{ code: 'us-southeast-1', label: 'Atlanta, GA' },\n\t\t\t{ code: 'us-ord-1', label: 'Chicago, IL' },\n\t\t\t{ code: 'us-iad-1', label: 'Washington, DC' },\n\t\t\t{ code: 'us-lax-1', label: 'Los Angeles, CA' },\n\t\t\t{ code: 'us-sea-1', label: 'Seattle, WA' },\n\t\t\t{ code: 'us-mia-1', label: 'Miami, FL' },\n\t\t\t{ code: 'eu-central-1', label: 'Frankfurt, DE' },\n\t\t\t{ code: 'nl-ams-1', label: 'Amsterdam, NL' },\n\t\t\t{ code: 'gb-lon-1', label: 'London, UK' },\n\t\t\t{ code: 'fr-par-1', label: 'Paris, FR' },\n\t\t\t{ code: 'ap-south-1', label: 'Singapore' },\n\t\t\t{ code: 'jp-osa-1', label: 'Osaka, JP' },\n\t\t\t{ code: 'au-mel-1', label: 'Melbourne, AU' },\n\t\t\t{ code: 'br-gru-1', label: 'São Paulo, BR' },\n\t\t\t{ code: 'in-maa-1', label: 'Chennai, IN' },\n\t\t\t{ code: 'id-cgk-1', label: 'Jakarta, ID' },\n\t\t\t{ code: 'it-mil-1', label: 'Milan, IT' },\n\t\t\t{ code: 'se-sto-1', label: 'Stockholm, SE' }\n\t\t],\n\t\tendpointPlaceholder: 'https://us-east-1.linodeobjects.com',\n\t\tschemes: []\n\t},\n\n\tovhcloud: {\n\t\tlabel: 'OVHcloud',\n\t\tdescription: 'OVHcloud Object Storage',\n\t\tauthMethod: 'sigv4',\n\t\tneedsRegion: true,\n\t\tneedsEndpoint: false,\n\t\tdefaultRegion: 'gra',\n\t\tendpointTemplate: 'https://s3.{region}.io.cloud.ovh.net',\n\t\tregions: [\n\t\t\t{ code: 'gra', label: 'Gravelines, FR' },\n\t\t\t{ code: 'sbg', label: 'Strasbourg, FR' },\n\t\t\t{ code: 'bhs', label: 'Beauharnois, CA' },\n\t\t\t{ code: 'de', label: 'Frankfurt, DE' },\n\t\t\t{ code: 'uk', label: 'London, UK' },\n\t\t\t{ code: 'waw', label: 'Warsaw, PL' }\n\t\t],\n\t\tendpointPlaceholder: 'https://s3.gra.io.cloud.ovh.net',\n\t\tschemes: []\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// CORS help — provider-specific browser access guidance\n// ---------------------------------------------------------------------------\n\nexport interface CorsHelp {\n\t/** True if the provider returns CORS headers by default. */\n\tdefaultEnabled: boolean;\n\t/** Official CORS configuration docs URL. */\n\tdocsUrl?: string;\n\t/** Brief note shown in the UI. */\n\tnote?: string;\n\t/** CLI steps when no console UI or docs are insufficient. */\n\tcliSteps?: string[];\n}\n\nexport const CORS_HELP: Record<ProviderId, CorsHelp> = {\n\ts3: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html',\n\t\tnote: 'Enable via S3 Console: Bucket > Permissions > CORS, or use the AWS CLI.'\n\t},\n\tgcs: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://cloud.google.com/storage/docs/using-cors',\n\t\tnote: 'Use the gcloud CLI. GCS `responseHeader` is dual-purpose (Access-Control-Expose-Headers AND Access-Control-Allow-Headers), so every request header the browser sends must be listed or the preflight fails silently. For private buckets signed with HMAC, include the AWS SigV4 headers (Authorization, x-amz-date, x-amz-content-sha256). For DuckDB httpfs partial reads, also include Range and the conditional If-* headers.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n[\\n {\\n \"origin\": [\"*\"],\\n \"method\": [\"GET\", \"HEAD\"],\\n \"responseHeader\": [\\n \"Content-Type\",\\n \"Content-Length\",\\n \"Content-Range\",\\n \"Accept-Ranges\",\\n \"Range\",\\n \"If-Match\",\\n \"If-Modified-Since\",\\n \"If-None-Match\",\\n \"If-Unmodified-Since\",\\n \"ETag\",\\n \"Authorization\",\\n \"x-amz-content-sha256\",\\n \"x-amz-date\",\\n \"x-amz-*\",\\n \"x-goog-*\"\\n ],\\n \"maxAgeSeconds\": 3600\\n }\\n]',\n\t\t\t'gcloud storage buckets update gs://BUCKET --cors-file=cors.json'\n\t\t]\n\t},\n\tr2: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://developers.cloudflare.com/r2/buckets/cors/',\n\t\tnote: 'Enable via R2 Dashboard: Bucket > Settings > CORS Policy.'\n\t},\n\tazure: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl:\n\t\t\t'https://learn.microsoft.com/en-us/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services',\n\t\tnote: 'Enable via Azure Portal: Storage Account > Blob Service > CORS, or use the Azure CLI.',\n\t\tcliSteps: [\n\t\t\t'az storage cors add --services b --methods GET HEAD \\\\\\n --origins \"*\" --allowed-headers \"*\" \\\\\\n --exposed-headers \"*\" --max-age 3600 \\\\\\n --account-name ACCOUNT'\n\t\t]\n\t},\n\tminio: {\n\t\tdefaultEnabled: true,\n\t\tdocsUrl: 'https://docs.min.io/enterprise/aistor-object-store/reference/cli/mc-cors/',\n\t\tnote: 'MinIO allows all origins by default (for custom rules use mc cors set). For RustFS or any other custom S3 service, set a CORS policy on the server that allows this origin.'\n\t},\n\tstorj: {\n\t\tdefaultEnabled: true,\n\t\tnote: 'Storj S3 gateway returns CORS headers by default.'\n\t},\n\tb2: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://www.backblaze.com/docs/cloud-storage-cross-origin-resource-sharing-rules',\n\t\tnote: 'Enable via B2 Console: Bucket Settings > CORS Rules, or use the B2 CLI.',\n\t\tcliSteps: [\n\t\t\t'b2 bucket update --cors-rules \\'[{\\n \"corsRuleName\": \"allow-all\",\\n \"allowedOrigins\": [\"*\"],\\n \"allowedOperations\": [\"s3_head\", \"s3_get\"],\\n \"allowedHeaders\": [\"*\"],\\n \"maxAgeSeconds\": 3600\\n}]\\' BUCKET allPublic'\n\t\t]\n\t},\n\tdigitalocean: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://docs.digitalocean.com/products/spaces/how-to/configure-cors/',\n\t\tnote: 'Enable via Control Panel: Space > Settings > CORS Configurations.'\n\t},\n\twasabi: {\n\t\tdefaultEnabled: true,\n\t\tdocsUrl: 'https://docs.wasabi.com/docs/bucket-policy',\n\t\tnote: 'Wasabi returns CORS headers by default for all buckets.'\n\t},\n\tcontabo: {\n\t\tdefaultEnabled: false,\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://REGION.contaboobj.com'\n\t\t]\n\t},\n\thetzner: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://docs.hetzner.com/storage/object-storage/howto-protect-objects/cors/',\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://REGION.your-objectstorage.com \\\\\\n --region REGION'\n\t\t]\n\t},\n\tlinode: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl: 'https://www.linode.com/docs/guides/working-with-cors-linode-object-storage/',\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://REGION.linodeobjects.com'\n\t\t]\n\t},\n\tovhcloud: {\n\t\tdefaultEnabled: false,\n\t\tdocsUrl:\n\t\t\t'https://help.ovhcloud.com/csm/en-public-cloud-storage-s3-cors?id=kb_article_view&sysparm_article=KB0058291',\n\t\tnote: 'S3-compatible CORS via the AWS CLI.',\n\t\tcliSteps: [\n\t\t\t'Create a cors.json file:\\n{\\n \"CORSRules\": [{\\n \"AllowedOrigins\": [\"*\"],\\n \"AllowedMethods\": [\"GET\", \"HEAD\"],\\n \"AllowedHeaders\": [\"*\"],\\n \"ExposeHeaders\": [\"ETag\", \"Content-Length\", \"Content-Type\", \"Content-Range\", \"Accept-Ranges\"],\\n \"MaxAgeSeconds\": 3600\\n }]\\n}',\n\t\t\t'aws s3api put-bucket-cors --bucket BUCKET \\\\\\n --cors-configuration file://cors.json \\\\\\n --endpoint-url https://s3.REGION.io.cloud.ovh.net'\n\t\t]\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// Read-only access help — provider-specific bucket policy guidance\n// ---------------------------------------------------------------------------\n\nexport interface ReadOnlyHelp {\n\t/** Brief note shown in the UI. */\n\tnote: string;\n\t/** Official docs URL. */\n\tdocsUrl?: string;\n\t/** CLI steps to apply a read-only bucket policy. */\n\tcliSteps?: string[];\n}\n\nexport const READ_ONLY_HELP: Partial<Record<ProviderId, ReadOnlyHelp>> = {\n\ts3: {\n\t\tnote: 'Use IAM policies to create a read-only user, or apply a bucket policy that allows only s3:GetObject and s3:ListBucket.',\n\t\tdocsUrl: 'https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-policies-s3.html'\n\t},\n\tgcs: {\n\t\tnote: 'Assign the Storage Object Viewer role (roles/storage.objectViewer) to the service account.',\n\t\tdocsUrl: 'https://cloud.google.com/storage/docs/access-control/iam-roles'\n\t},\n\tr2: {\n\t\tnote: 'Create an API token with Object Read permissions in the R2 dashboard.',\n\t\tdocsUrl: 'https://developers.cloudflare.com/r2/api/tokens/'\n\t},\n\tazure: {\n\t\tnote: 'Generate a SAS token with Read and List permissions only. Avoid granting Write or Delete.',\n\t\tdocsUrl: 'https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview'\n\t},\n\tb2: {\n\t\tnote: 'Create an application key with readFiles and listBuckets capabilities only.',\n\t\tdocsUrl: 'https://www.backblaze.com/docs/cloud-storage-application-keys'\n\t},\n\thetzner: {\n\t\tnote: 'Keys have full read/write by default. Use a bucket policy with the correct ARN format to deny write and policy actions. To undo, generate a new admin key from the Hetzner Console.',\n\t\tdocsUrl:\n\t\t\t'https://docs.hetzner.com/storage/object-storage/faq/s3-credentials/#how-do-i-restrict-access-per-key',\n\t\tcliSteps: [\n\t\t\t'Find your project ID from the Hetzner Console URL:\\nhttps://console.hetzner.com/projects/<PROJECT_ID>/servers',\n\t\t\t'Create a policy.json file:\\n{\\n \"Version\": \"2012-10-17\",\\n \"Statement\": [\\n {\\n \"Sid\": \"DenyWrites\",\\n \"Effect\": \"Deny\",\\n \"Principal\": {\\n \"AWS\": \"arn:aws:iam:::user/p<PROJECT_ID>:<ACCESS_KEY>\"\\n },\\n \"Action\": [\\n \"s3:PutObject\",\\n \"s3:DeleteObject\",\\n \"s3:AbortMultipartUpload\",\\n \"s3:PutBucketPolicy\",\\n \"s3:DeleteBucketPolicy\"\\n ],\\n \"Resource\": [\\n \"arn:aws:s3:::BUCKET\",\\n \"arn:aws:s3:::BUCKET/*\"\\n ]\\n }\\n ]\\n}',\n\t\t\t'aws s3api put-bucket-policy --bucket BUCKET \\\\\\n --policy file://policy.json \\\\\\n --endpoint-url https://REGION.your-objectstorage.com \\\\\\n --region REGION',\n\t\t\t'Note: This key can no longer modify the policy.\\nTo restore write access, generate a new key in the\\nHetzner Console and use it to delete the policy.'\n\t\t]\n\t},\n\tminio: {\n\t\tnote: 'For MinIO, create a read-only policy with mc admin policy or use the built-in readonly canned policy. For RustFS or any other custom S3 service, attach a read-only bucket policy on the server.',\n\t\tdocsUrl: 'https://docs.min.io/enterprise/aistor-object-store/administration/iam/access/'\n\t},\n\tdigitalocean: {\n\t\tnote: 'Spaces keys are project-wide. Use a bucket policy to restrict write actions for a specific key.',\n\t\tdocsUrl: 'https://docs.digitalocean.com/products/spaces/how-to/manage-access/'\n\t},\n\twasabi: {\n\t\tnote: 'Create a sub-user with a read-only policy in the Wasabi Console.',\n\t\tdocsUrl: 'https://docs.wasabi.com/docs/creating-a-user-account-and-access-key'\n\t},\n\tcontabo: {\n\t\tnote: 'S3-compatible bucket policies. Use a Deny policy for write actions with the key ARN.',\n\t\tcliSteps: [\n\t\t\t'Create a policy.json with a Deny statement for s3:PutObject and s3:DeleteObject.',\n\t\t\t'aws s3api put-bucket-policy --bucket BUCKET \\\\\\n --policy file://policy.json \\\\\\n --endpoint-url https://REGION.contaboobj.com'\n\t\t]\n\t}\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** All provider IDs, ordered for the UI. */\nexport const PROVIDER_IDS: ProviderId[] = [\n\t's3',\n\t'gcs',\n\t'r2',\n\t'azure',\n\t'b2',\n\t'digitalocean',\n\t'wasabi',\n\t'storj',\n\t'hetzner',\n\t'contabo',\n\t'linode',\n\t'ovhcloud',\n\t'minio'\n];\n\n/** Get provider def, falling back to S3 for unknown. */\nexport function getProvider(id: string): ProviderDef {\n\treturn PROVIDERS[id as ProviderId] ?? PROVIDERS.s3;\n}\n\n/** Build endpoint URL from template + region. */\nexport function buildEndpointFromTemplate(id: ProviderId, region: string): string {\n\tconst def = PROVIDERS[id];\n\tif (!def?.endpointTemplate) return '';\n\treturn def.endpointTemplate.replace('{region}', region);\n}\n\n/**\n * Resolve an endpoint URL for a provider using its registered template,\n * falling back to the provider's default region when none is supplied.\n * Returns '' when the provider has no template (e.g. plain S3 or MinIO).\n */\nexport function resolveProviderEndpoint(provider: string, region?: string): string {\n\tconst def = PROVIDERS[provider as ProviderId];\n\tif (!def?.endpointTemplate) return '';\n\treturn buildEndpointFromTemplate(provider as ProviderId, region || def.defaultRegion);\n}\n\n/**\n * Build the base URL for API requests (endpoint + bucket).\n * Used by browser-cloud adapter and url-state.\n */\nexport function buildProviderBaseUrl(\n\tprovider: ProviderId,\n\tendpoint: string,\n\tbucket: string,\n\tregion: string\n): string {\n\tif (endpoint) {\n\t\treturn `${endpoint.replace(/\\/$/, '')}/${bucket}`;\n\t}\n\tconst def = PROVIDERS[provider];\n\tif (def?.endpointTemplate) {\n\t\tconst resolved = def.endpointTemplate.replace('{region}', region || def.defaultRegion);\n\t\treturn `${resolved}/${bucket}`;\n\t}\n\t// Fallback: AWS S3 path-style\n\treturn `https://s3.${region || 'us-east-1'}.amazonaws.com/${bucket}`;\n}\n\n/** Check if a provider uses the GCS JSON API (not S3 XML). */\nexport function isGcsProvider(provider: string, endpoint: string): boolean {\n\treturn provider === 'gcs' || (!!endpoint && /storage\\.googleapis\\.com/i.test(endpoint));\n}\n\n// ---------------------------------------------------------------------------\n// Access mode — single source of truth for how any HTTP client (DuckDB httpfs,\n// COG/Zarr/PMTiles libraries, fetch, img, video) can read files for a given\n// connection. Used by url.ts (URL construction), query/wasm.ts (S3 config\n// short-circuit), canStreamDirectly (viewer routing).\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal connection shape needed to decide access mode.\n * Kept loose so callers don't need to import the full Connection type.\n */\nexport interface AccessModeInput {\n\tprovider: string;\n\tanonymous?: boolean;\n\tendpoint?: string;\n}\n\n/**\n * How a connection's files can be read by the browser:\n *\n * - `public-https`: plain HTTPS via any HTTP client. No auth, no signing.\n * Covers anonymous AWS/GCS/R2/Storj/Wasabi/etc.\n * - `sas-https`: HTTPS with SAS token embedded in the URL. Still works with\n * any HTTP client. Azure only.\n * - `signed-s3`: requires SigV4 signing. DuckDB uses the `s3://` URI and\n * signs it via its S3 config; other viewers must go through the storage\n * adapter (which returns a blob) instead of streaming the HTTPS URL.\n */\nexport type AccessMode = 'public-https' | 'sas-https' | 'signed-s3';\n\nexport function getAccessMode(conn: AccessModeInput): AccessMode {\n\tif (conn.provider === 'azure') return 'sas-https';\n\t// Anonymous buckets: every provider serves files over plain HTTPS without\n\t// signing (AWS path/vhost, GCS, R2 public, Storj, Wasabi, DO, etc.).\n\tif (conn.anonymous) return 'public-https';\n\t// Authenticated: needs SigV4 signing.\n\treturn 'signed-s3';\n}\n\n/**\n * True when the connection's files can be fetched by any HTTP client\n * (fetch/img/video/DuckDB httpfs/COG/Zarr/etc.) without the storage adapter.\n */\nexport function isPubliclyStreamable(conn: AccessModeInput): boolean {\n\tconst mode = getAccessMode(conn);\n\treturn mode === 'public-https' || mode === 'sas-https';\n}\n","import type { FileEntry, WriteResult } from '../types.js';\nimport type { StorageAdapter } from './adapter.js';\n\n/**\n * Minimal adapter for direct HTTPS URLs (source: 'url').\n * Only supports read/head — no listing or writing.\n * The `path` parameter is the full HTTPS URL.\n */\nexport class UrlAdapter implements StorageAdapter {\n\treadonly supportsWrite = false;\n\n\tasync read(\n\t\turl: string,\n\t\toffset?: number,\n\t\tlength?: number,\n\t\tsignal?: AbortSignal\n\t): Promise<Uint8Array> {\n\t\tconst headers: Record<string, string> = {};\n\t\tif (offset !== undefined && length !== undefined) {\n\t\t\theaders.Range = `bytes=${offset}-${offset + length - 1}`;\n\t\t} else if (offset !== undefined) {\n\t\t\theaders.Range = `bytes=${offset}-`;\n\t\t}\n\n\t\tconst res = await fetch(url, { headers, signal });\n\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\treturn new Uint8Array(await res.arrayBuffer());\n\t}\n\n\tasync head(url: string, signal?: AbortSignal): Promise<FileEntry> {\n\t\tconst res = await fetch(url, { method: 'HEAD', signal });\n\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\tconst name = url.split('/').pop()?.split('?')[0] || 'file';\n\t\tconst ext = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n\t\treturn {\n\t\t\tname,\n\t\t\tpath: url,\n\t\t\tis_dir: false,\n\t\t\tsize: Number(res.headers.get('content-length') || 0),\n\t\t\tmodified: new Date(res.headers.get('last-modified') || 0).getTime(),\n\t\t\textension: ext\n\t\t};\n\t}\n\n\tasync list(): Promise<FileEntry[]> {\n\t\treturn [];\n\t}\n\n\tasync put(): Promise<WriteResult> {\n\t\tthrow new Error('Write not supported for direct URL sources');\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tthrow new Error('Delete not supported for direct URL sources');\n\t}\n\n\tasync deletePrefix(): Promise<{ deleted: number }> {\n\t\tthrow new Error('Delete not supported for direct URL sources');\n\t}\n\n\tasync copy(): Promise<WriteResult> {\n\t\tthrow new Error('Copy not supported for direct URL sources');\n\t}\n}\n","import type { Theme } from '../../../src/lib/types.js';\n\n/** A basemap option a host can offer. Consumed in Phase 2. */\nexport interface BasemapConfig {\n\tid: string;\n\tlabel: string;\n\ttype: 'vector' | 'raster';\n\turl: string;\n\tvariant?: 'light' | 'dark';\n}\n\n/** A preloaded connection definition. Never carries secrets. Consumed in Phase 2. */\nexport interface ConnectionSeed {\n\tname: string;\n\tprovider: string;\n\tbucket: string;\n\tregion?: string;\n\tendpoint?: string;\n\tanonymous?: boolean;\n\tauthMethod?: 'sigv4' | 'sas-token';\n\trootPrefix?: string;\n}\n\nexport interface AppConfigDefaults {\n\ttheme: Theme;\n\tlocale: string;\n\tfeatureLimit: number;\n\tmosaicItemLimit: number;\n}\n\nexport interface AppConfigUi {\n\tshowConnectionRail: boolean;\n\tshowFileTree: boolean;\n\tshowSettings: boolean;\n}\n\nexport interface AppConfig {\n\tdefaults: AppConfigDefaults;\n\tui: AppConfigUi;\n\tbasemaps: BasemapConfig[];\n\tdefaultBasemap: { light?: string; dark?: string };\n\tconnections: ConnectionSeed[];\n}\n\n/** Hardcoded fallback. Matches current app behaviour when no config is present. */\nexport const DEFAULT_APP_CONFIG: AppConfig = {\n\tdefaults: { theme: 'system', locale: 'en', featureLimit: 1000, mosaicItemLimit: 2000 },\n\tui: { showConnectionRail: true, showFileTree: true, showSettings: true },\n\tbasemaps: [],\n\tdefaultBasemap: {},\n\tconnections: []\n};\n\ntype JsonObject = Record<string, unknown>;\n\nfunction asObject(v: unknown): JsonObject | undefined {\n\treturn v && typeof v === 'object' && !Array.isArray(v) ? (v as JsonObject) : undefined;\n}\n\nexport function coerceTheme(v: unknown): Theme | undefined {\n\treturn v === 'light' || v === 'dark' || v === 'system' ? v : undefined;\n}\n\nexport function coerceString(v: unknown): string | undefined {\n\treturn typeof v === 'string' && v.trim().length > 0 ? v.trim() : undefined;\n}\n\nexport function coercePositiveInt(v: unknown): number | undefined {\n\treturn typeof v === 'number' && Number.isFinite(v) && v >= 1 ? Math.floor(v) : undefined;\n}\n\nexport function coerceBool(v: unknown): boolean | undefined {\n\treturn typeof v === 'boolean' ? v : undefined;\n}\n\n/** First defined (non-null, non-undefined) candidate wins. Encodes the precedence chain. */\nexport function resolveSetting<T>(...candidates: (T | null | undefined)[]): T | undefined {\n\tfor (const c of candidates) {\n\t\tif (c !== null && c !== undefined) return c;\n\t}\n\treturn undefined;\n}\n\n/** Maps the ?sidebar / ?tree visibility param to a boolean, or undefined when absent or invalid. */\nexport function parseVisibilityParam(value: string | null): boolean | undefined {\n\tif (value === 'hide') return false;\n\tif (value === 'show') return true;\n\treturn undefined;\n}\n\nfunction coerceBasemaps(v: unknown): BasemapConfig[] | undefined {\n\tif (!Array.isArray(v)) return undefined;\n\tconst out: BasemapConfig[] = [];\n\tfor (const raw of v) {\n\t\tconst o = asObject(raw);\n\t\tif (!o) continue;\n\t\tconst id = coerceString(o.id);\n\t\tconst label = coerceString(o.label);\n\t\tconst url = coerceString(o.url);\n\t\tconst type = o.type === 'vector' || o.type === 'raster' ? o.type : undefined;\n\t\tif (!id || !label || !url || !type) continue;\n\t\tconst variant = o.variant === 'light' || o.variant === 'dark' ? o.variant : undefined;\n\t\tout.push({ id, label, url, type, ...(variant ? { variant } : {}) });\n\t}\n\treturn out;\n}\n\nfunction coerceConnections(v: unknown): ConnectionSeed[] | undefined {\n\tif (!Array.isArray(v)) return undefined;\n\tconst out: ConnectionSeed[] = [];\n\tfor (const raw of v) {\n\t\tconst o = asObject(raw);\n\t\tif (!o) continue;\n\t\tconst name = coerceString(o.name);\n\t\tconst bucket = coerceString(o.bucket);\n\t\tif (!name || !bucket) continue;\n\t\tconst region = coerceString(o.region);\n\t\tconst endpoint = coerceString(o.endpoint);\n\t\tconst anonymous = coerceBool(o.anonymous);\n\t\tconst authMethod =\n\t\t\to.authMethod === 'sigv4' || o.authMethod === 'sas-token' ? o.authMethod : undefined;\n\t\tconst rootPrefix = coerceString(o.rootPrefix);\n\t\tout.push({\n\t\t\tname,\n\t\t\tbucket,\n\t\t\tprovider: coerceString(o.provider) ?? 's3',\n\t\t\t...(region !== undefined ? { region } : {}),\n\t\t\t...(endpoint !== undefined ? { endpoint } : {}),\n\t\t\t...(anonymous !== undefined ? { anonymous } : {}),\n\t\t\t...(authMethod !== undefined ? { authMethod } : {}),\n\t\t\t...(rootPrefix !== undefined ? { rootPrefix } : {})\n\t\t});\n\t}\n\treturn out;\n}\n\n/**\n * Pick the basemap a map should render. Precedence: explicit user pick (when it\n * still exists in the configured list) > the configured default for the theme\n * variant > the first basemap matching the variant > the first basemap of any\n * variant. Returns undefined when no basemaps are configured, signalling the\n * caller to fall back to its hardcoded default.\n */\nexport function resolveBasemap(\n\tconfig: AppConfig,\n\tvariant: 'light' | 'dark',\n\tuserId: string | undefined\n): BasemapConfig | undefined {\n\tconst list = config.basemaps;\n\tif (list.length === 0) return undefined;\n\tif (userId) {\n\t\tconst picked = list.find((b) => b.id === userId);\n\t\tif (picked) return picked;\n\t}\n\tconst defaultId = config.defaultBasemap[variant];\n\tif (defaultId) {\n\t\tconst byDefault = list.find((b) => b.id === defaultId);\n\t\tif (byDefault) return byDefault;\n\t}\n\treturn list.find((b) => b.variant === variant) ?? list[0];\n}\n\n/**\n * Merge an untrusted JSON value over a base config, field by field.\n * Unknown fields are ignored. Malformed values fall back to the base.\n * Never reads secrets.\n */\nexport function mergeAppConfig(base: AppConfig, override: unknown): AppConfig {\n\tconst o = asObject(override);\n\tif (!o) return base;\n\tconst d = asObject(o.defaults) ?? {};\n\tconst u = asObject(o.ui) ?? {};\n\tconst db = asObject(o.defaultBasemap) ?? {};\n\treturn {\n\t\tdefaults: {\n\t\t\ttheme: coerceTheme(d.theme) ?? base.defaults.theme,\n\t\t\tlocale: coerceString(d.locale) ?? base.defaults.locale,\n\t\t\tfeatureLimit: coercePositiveInt(d.featureLimit) ?? base.defaults.featureLimit,\n\t\t\tmosaicItemLimit: coercePositiveInt(d.mosaicItemLimit) ?? base.defaults.mosaicItemLimit\n\t\t},\n\t\tui: {\n\t\t\tshowConnectionRail: coerceBool(u.showConnectionRail) ?? base.ui.showConnectionRail,\n\t\t\tshowFileTree: coerceBool(u.showFileTree) ?? base.ui.showFileTree,\n\t\t\tshowSettings: coerceBool(u.showSettings) ?? base.ui.showSettings\n\t\t},\n\t\tbasemaps: coerceBasemaps(o.basemaps) ?? base.basemaps,\n\t\tdefaultBasemap: ((): { light?: string; dark?: string } => {\n\t\t\tconst light = coerceString(db.light) ?? base.defaultBasemap.light;\n\t\t\tconst dark = coerceString(db.dark) ?? base.defaultBasemap.dark;\n\t\t\treturn { ...(light !== undefined ? { light } : {}), ...(dark !== undefined ? { dark } : {}) };\n\t\t})(),\n\t\tconnections: coerceConnections(o.connections) ?? base.connections\n\t};\n}\n","/**\n * STAC (SpatioTemporal Asset Catalog) detection and parsing.\n *\n * Pure TypeScript helpers shared by ViewerRouter, StacMosaicViewer, and\n * MultiCogViewer. No Svelte dependency, publishable via objex-utils.\n */\n\n/** STAC Link (shared by Catalog/Collection/Item). */\nexport interface StacLink {\n\trel: string;\n\thref: string;\n\ttype?: string;\n\ttitle?: string;\n}\n\n/** STAC Item (GeoJSON Feature shape with stac_version). */\nexport interface StacItem {\n\ttype: 'Feature';\n\tstac_version: string;\n\tid: string;\n\tbbox?: [number, number, number, number];\n\tgeometry?: unknown;\n\tproperties?: Record<string, unknown>;\n\tassets?: Record<string, StacAsset>;\n\tcollection?: string;\n\tlinks?: StacLink[];\n}\n\n/** STAC FeatureCollection (collection of Items). Also used for STAC API responses. */\nexport interface StacFeatureCollection {\n\ttype: 'FeatureCollection';\n\tstac_version?: string;\n\tfeatures: StacItem[];\n\tlinks?: StacLink[];\n}\n\n/** STAC Collection (a grouping of Items with its own metadata and links). */\nexport interface StacCollection {\n\ttype: 'Collection';\n\tstac_version: string;\n\tid: string;\n\tdescription?: string;\n\textent?: { spatial?: { bbox?: number[][] }; temporal?: unknown };\n\tlinks: StacLink[];\n}\n\n/** STAC Catalog (a directory-like grouping of Catalogs/Collections/Items via links). */\nexport interface StacCatalog {\n\ttype: 'Catalog';\n\tstac_version: string;\n\tid: string;\n\tdescription?: string;\n\tlinks: StacLink[];\n}\n\n/** Single asset entry within a STAC item. */\nexport interface StacAsset {\n\thref: string;\n\ttype?: string;\n\ttitle?: string;\n\troles?: string[];\n\t/** Set when the asset carries `eo:bands`. */\n\t'eo:bands'?: { name?: string; common_name?: string }[];\n}\n\n/** Sentinel-2 band slot identifier, shared with utils/cog.ts composites. */\nexport type BandSlot = 'red' | 'green' | 'blue' | 'nir' | 'swir1' | 'swir2' | 'rededge';\n\n/** Parsed band map: slot name → HTTPS asset URL. */\nexport type BandMap = Partial<Record<BandSlot, string>>;\n\n/** Asset keys providers use for the single \"display COG\" asset, in priority order. */\nexport const STAC_COG_ASSET_KEYS = ['visual', 'image', 'data', 'rendered_preview'] as const;\n\n/** Shape-check a parsed JSON object as a STAC Item. */\nexport function isStacItem(json: unknown): json is StacItem {\n\tif (!json || typeof json !== 'object') return false;\n\tconst obj = json as Record<string, unknown>;\n\treturn obj.type === 'Feature' && typeof obj.stac_version === 'string';\n}\n\n/** Shape-check a parsed JSON object as a STAC FeatureCollection. */\nexport function isStacFeatureCollection(json: unknown): json is StacFeatureCollection {\n\tif (!json || typeof json !== 'object') return false;\n\tconst obj = json as Record<string, unknown>;\n\tif (obj.type !== 'FeatureCollection') return false;\n\tif (!Array.isArray(obj.features) || obj.features.length === 0) return false;\n\tif (typeof obj.stac_version === 'string') return true;\n\treturn isStacItem(obj.features[0]);\n}\n\n/** STAC Collection detection: `type === 'Collection'` + stac_version + links array. */\nexport function isStacCollection(json: unknown): json is StacCollection {\n\tif (!json || typeof json !== 'object') return false;\n\tconst obj = json as Record<string, unknown>;\n\treturn (\n\t\tobj.type === 'Collection' && typeof obj.stac_version === 'string' && Array.isArray(obj.links)\n\t);\n}\n\n/** STAC Catalog detection: `type === 'Catalog'` + stac_version + links array. */\nexport function isStacCatalog(json: unknown): json is StacCatalog {\n\tif (!json || typeof json !== 'object') return false;\n\tconst obj = json as Record<string, unknown>;\n\treturn obj.type === 'Catalog' && typeof obj.stac_version === 'string' && Array.isArray(obj.links);\n}\n\n/** Routing verdict for any STAC-shaped JSON payload. */\nexport type StacRoutableKind =\n\t| { kind: 'item'; item: StacItem }\n\t| { kind: 'item-collection'; fc: StacFeatureCollection }\n\t| { kind: 'collection'; payload: StacCollection }\n\t| { kind: 'catalog'; payload: StacCatalog }\n\t| { kind: 'none' };\n\n/** Classify an arbitrary parsed JSON into one of the STAC routing buckets. */\nexport function classifyStac(json: unknown): StacRoutableKind {\n\tif (isStacItem(json)) return { kind: 'item', item: json };\n\tif (isStacFeatureCollection(json)) return { kind: 'item-collection', fc: json };\n\tif (isStacCollection(json)) return { kind: 'collection', payload: json };\n\tif (isStacCatalog(json)) return { kind: 'catalog', payload: json };\n\treturn { kind: 'none' };\n}\n\n/**\n * Pick the COG-ish asset href from a STAC Item. Returns the href of the named\n * asset when `preferred` is given and present, else scans STAC_COG_ASSET_KEYS,\n * else falls back to any asset whose `type` contains \"tiff\". Returns null when\n * nothing matches.\n */\nexport function pickCogAssetHref(item: StacItem, preferred?: string): string | null {\n\tconst assets = item.assets ?? {};\n\tif (preferred && assets[preferred]?.href) return assets[preferred].href;\n\tfor (const key of STAC_COG_ASSET_KEYS) {\n\t\tif (assets[key]?.href) return assets[key].href;\n\t}\n\tfor (const asset of Object.values(assets)) {\n\t\tconst t = typeof asset?.type === 'string' ? asset.type.toLowerCase() : '';\n\t\tif (asset?.href && t.includes('tiff')) return asset.href;\n\t}\n\treturn null;\n}\n\n/** True when a single STAC Item exposes a COG-ish asset and a bbox. */\nexport function detectMosaicCapable(item: StacItem): boolean {\n\treturn stacItemBbox(item) !== null && pickCogAssetHref(item) !== null;\n}\n\n/** True when a single STAC Item exposes ≥3 single-band raster COG assets,\n * whether tagged with S2-style common names or not. The MultiCogViewer's\n * band picker fills in the gap when presets don't auto-resolve. */\nexport function detectMultiCogCapable(item: StacItem): boolean {\n\tif (hasRgbBands(extractSentinelBandAssets(item))) return true;\n\treturn hasCompositableBands(extractRasterBandAssets(item));\n}\n\n/** WGS84 bbox helper. Returns `null` if no bbox can be derived. */\nexport function stacItemBbox(item: StacItem): [number, number, number, number] | null {\n\tif (Array.isArray(item.bbox) && item.bbox.length >= 4) {\n\t\treturn [Number(item.bbox[0]), Number(item.bbox[1]), Number(item.bbox[2]), Number(item.bbox[3])];\n\t}\n\treturn null;\n}\n\n/** Normalized mosaic source entry consumed by MosaicLayer. */\nexport interface MosaicSourceMeta {\n\tid: string;\n\tbbox: [number, number, number, number];\n\thref: string;\n}\n\n/**\n * Normalize a STAC Item or a plain `{id?, bbox, href}` record into a\n * MosaicSourceMeta. Returns null when essentials (bbox / href) are missing.\n */\nexport function buildMosaicSourceMeta(\n\tinput:\n\t\t| StacItem\n\t\t| { id?: string; bbox: [number, number, number, number] | number[]; href: string },\n\tassetKey?: string\n): MosaicSourceMeta | null {\n\tif (!input || typeof input !== 'object') return null;\n\tif (isStacItem(input)) {\n\t\tconst bbox = stacItemBbox(input);\n\t\tif (!bbox) return null;\n\t\tconst href = pickCogAssetHref(input, assetKey);\n\t\tif (!href) return null;\n\t\treturn {\n\t\t\tid: String(input.id ?? href),\n\t\t\tbbox,\n\t\t\thref\n\t\t};\n\t}\n\tconst raw = input as { id?: string; bbox?: number[]; href?: string };\n\tif (Array.isArray(raw.bbox) && raw.bbox.length >= 4 && typeof raw.href === 'string') {\n\t\treturn {\n\t\t\tid: String(raw.id ?? raw.href),\n\t\t\tbbox: [Number(raw.bbox[0]), Number(raw.bbox[1]), Number(raw.bbox[2]), Number(raw.bbox[3])],\n\t\t\thref: raw.href\n\t\t};\n\t}\n\treturn null;\n}\n\n/**\n * Stable spatial cell key for an item, used to dedupe revisits when the\n * caller wants only the freshest scene per footprint. STAC providers\n * default to descending-datetime sort, so the first item per key is the\n * newest. Prefers STAC `grid:code`, then Sentinel-2 MGRS triplet, then\n * `s2:mgrs_tile`, then a rounded bbox so non-S2 providers still dedupe.\n */\nexport function spatialCellKey(item: StacItem, bbox: [number, number, number, number]): string {\n\tconst props = (item.properties ?? {}) as Record<string, unknown>;\n\tconst grid = props['grid:code'];\n\tif (typeof grid === 'string' && grid) return `g:${grid}`;\n\tconst utm = props['mgrs:utm_zone'];\n\tconst band = props['mgrs:latitude_band'];\n\tconst sq = props['mgrs:grid_square'];\n\tif (utm != null && band != null && sq != null) return `m:${utm}${band}${sq}`;\n\tconst s2 = props['s2:mgrs_tile'];\n\tif (typeof s2 === 'string' && s2) return `m:${s2}`;\n\treturn `b:${bbox[0].toFixed(3)},${bbox[1].toFixed(3)},${bbox[2].toFixed(3)},${bbox[3].toFixed(3)}`;\n}\n\n// Provider-specific asset key conventions. Each entry maps a BandSlot to the\n// asset keys providers are known to use. First match wins, so list more\n// specific keys before generic ones.\nconst BAND_KEY_FALLBACKS: Record<BandSlot, string[]> = {\n\tred: ['red', 'B04', 'B4', 'visual-red'],\n\tgreen: ['green', 'B03', 'B3', 'visual-green'],\n\tblue: ['blue', 'B02', 'B2', 'visual-blue'],\n\tnir: ['nir', 'nir08', 'B08', 'B8', 'B8A'],\n\tswir1: ['swir16', 'swir1', 'B11'],\n\tswir2: ['swir22', 'swir2', 'B12'],\n\trededge: ['rededge1', 'rededge', 'B05', 'B5']\n};\n\n/**\n * Map Sentinel-2 STAC item assets to a BandMap. Recognizes:\n * - `eo:bands[0].common_name` (preferred, stable across providers)\n * - asset key heuristics for Microsoft PC / Element 84 / AWS S2 L2A buckets\n * Returns an empty map when no bands are identifiable so callers can fall\n * back to a different viewer.\n */\nexport function extractSentinelBandAssets(item: StacItem): BandMap {\n\tconst out: BandMap = {};\n\tconst assets = item.assets ?? {};\n\tfor (const [key, asset] of Object.entries(assets)) {\n\t\tif (!asset?.href) continue;\n\t\tconst bands = asset['eo:bands'];\n\t\tif (Array.isArray(bands) && bands.length >= 1) {\n\t\t\tconst common = bands[0]?.common_name?.toLowerCase();\n\t\t\tif (common && isBandSlot(common)) {\n\t\t\t\tif (!out[common]) out[common] = asset.href;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tfor (const slot of Object.keys(BAND_KEY_FALLBACKS) as BandSlot[]) {\n\t\t\tif (BAND_KEY_FALLBACKS[slot].includes(key) && !out[slot]) {\n\t\t\t\tout[slot] = asset.href;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn out;\n}\n\nfunction isBandSlot(value: string): value is BandSlot {\n\treturn (\n\t\tvalue === 'red' ||\n\t\tvalue === 'green' ||\n\t\tvalue === 'blue' ||\n\t\tvalue === 'nir' ||\n\t\tvalue === 'swir1' ||\n\t\tvalue === 'swir2' ||\n\t\tvalue === 'rededge'\n\t);\n}\n\n/** True when the band map has enough channels for a True Color composite. */\nexport function hasRgbBands(map: BandMap): boolean {\n\treturn Boolean(map.red && map.green && map.blue);\n}\n\n/**\n * Generic raster band asset description, vendor-neutral. Carries the bits a\n * MultiCOG band picker needs to populate dropdowns and resolve presets.\n *\n * `key` is the STAC asset key as it appears in `item.assets` (`red`, `B04`,\n * `image`, `analytic`, ...). It is the natural identifier and lines up 1:1\n * with `MultiCOGLayer.sources`'s record key.\n */\nexport interface RasterBandAsset {\n\tkey: string;\n\thref: string;\n\tcommonName?: string;\n\tbandCount?: number;\n\troles?: string[];\n\tmediaType?: string;\n\ttitle?: string;\n}\n\n/**\n * Enumerate every asset on a STAC Item that looks like a single-band raster\n * COG suitable for compositing in MultiCOGLayer. Used by the band picker UI.\n *\n * Inclusion: `media_type` matches `image/tiff*` (drops JP2 mirrors, PNGs,\n * thumbnails) AND it is not a thumbnail / overview / metadata role. Pre-baked\n * multi-band visuals (`raster:bands.length > 1` or `eo:bands.length > 1`) are\n * dropped because compositing needs single-band sources, not a 3-band visual\n * COG; that asset belongs in `CogViewer`.\n *\n * `bandCount` is reported as `1` when neither tag is present and the asset\n * media type is COG-like, so vendor catalogs that omit `eo:bands` are still\n * pickable. Callers wanting to be strict can filter on `bandCount === 1`.\n */\nexport function extractRasterBandAssets(item: StacItem): RasterBandAsset[] {\n\tconst out: RasterBandAsset[] = [];\n\tconst assets = item.assets ?? {};\n\tfor (const [key, asset] of Object.entries(assets)) {\n\t\tif (!asset?.href) continue;\n\t\tconst mediaType = typeof asset.type === 'string' ? asset.type : undefined;\n\t\t// Be permissive on missing media_type (some catalogs omit it for COGs)\n\t\t// and accept image/tiff* including the cloud-optimized profile suffix.\n\t\tif (mediaType && !/^image\\/(tiff|geotiff)\\b/i.test(mediaType)) continue;\n\t\tconst roles = Array.isArray(asset.roles) ? (asset.roles as string[]) : undefined;\n\t\tif (\n\t\t\troles &&\n\t\t\t(roles.includes('thumbnail') || roles.includes('overview') || roles.includes('metadata'))\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst eoBands = Array.isArray(asset['eo:bands']) ? asset['eo:bands'] : undefined;\n\t\tconst assetExt = asset as unknown as Record<string, unknown>;\n\t\tconst rasterBands = Array.isArray(assetExt['raster:bands'])\n\t\t\t? (assetExt['raster:bands'] as unknown[])\n\t\t\t: undefined;\n\t\tconst bandCount = rasterBands?.length ?? eoBands?.length;\n\t\tif (typeof bandCount === 'number' && bandCount > 1) continue;\n\t\tconst commonName = eoBands?.[0]?.common_name?.toLowerCase();\n\t\tout.push({\n\t\t\tkey,\n\t\t\thref: asset.href,\n\t\t\tcommonName,\n\t\t\tbandCount: typeof bandCount === 'number' ? bandCount : 1,\n\t\t\troles,\n\t\t\tmediaType,\n\t\t\ttitle: typeof asset.title === 'string' ? asset.title : undefined\n\t\t});\n\t}\n\treturn out;\n}\n\n/**\n * Resolve a semantic band slot to an asset key on this Item.\n *\n * Priority:\n * 1. First asset whose `eo:bands[0].common_name` (lowercased) equals the slot.\n * 2. First asset whose key appears in `BAND_KEY_FALLBACKS[slot]` (vendor key\n * conventions: `B04`, `red-jp2`, etc.).\n *\n * Returns the asset key (NOT the href) so callers can plumb it into\n * `composite: { r, g, b }` and look it up in `extractRasterBandAssets()`.\n */\nexport function resolveBandSlotAssetKey(\n\tassets: RasterBandAsset[],\n\tslot: BandSlot\n): string | undefined {\n\tconst byCommon = assets.find((a) => a.commonName === slot);\n\tif (byCommon) return byCommon.key;\n\tconst fallbacks = BAND_KEY_FALLBACKS[slot] ?? [];\n\tconst byKey = assets.find((a) => fallbacks.includes(a.key));\n\treturn byKey?.key;\n}\n\n/**\n * Resolve a preset's R/G/B BandSlot triple into asset keys for this Item.\n * Returns null when any of the three required slots cannot be resolved, so\n * the caller can disable the preset rather than half-apply it.\n */\nexport function resolvePresetComposite(\n\tassets: RasterBandAsset[],\n\tcomposite: { r: BandSlot; g: BandSlot; b: BandSlot }\n): { r: string; g: string; b: string } | null {\n\tconst r = resolveBandSlotAssetKey(assets, composite.r);\n\tconst g = resolveBandSlotAssetKey(assets, composite.g);\n\tconst b = resolveBandSlotAssetKey(assets, composite.b);\n\tif (!r || !g || !b) return null;\n\treturn { r, g, b };\n}\n\n/** True when ≥3 single-band raster COG assets exist, so manual RGB pick is viable. */\nexport function hasCompositableBands(assets: RasterBandAsset[]): boolean {\n\treturn assets.length >= 3;\n}\n\n/**\n * Same shape as `extractRasterBandAssets`, but does NOT drop multi-band assets.\n * Used by the mosaic asset picker, where a 3-band pre-baked `visual` TCI is a\n * legitimate choice alongside the per-band single-band COGs.\n *\n * `bandCount` is reported when known (`raster:bands.length` or `eo:bands.length`),\n * else left undefined so the consuming UI can fall back to probing the COG.\n */\nexport function extractMosaicAssets(item: StacItem): RasterBandAsset[] {\n\tconst out: RasterBandAsset[] = [];\n\tconst assets = item.assets ?? {};\n\tfor (const [key, asset] of Object.entries(assets)) {\n\t\tif (!asset?.href) continue;\n\t\tconst mediaType = typeof asset.type === 'string' ? asset.type : undefined;\n\t\tif (mediaType && !/^image\\/(tiff|geotiff)\\b/i.test(mediaType)) continue;\n\t\tconst roles = Array.isArray(asset.roles) ? (asset.roles as string[]) : undefined;\n\t\tif (\n\t\t\troles &&\n\t\t\t(roles.includes('thumbnail') || roles.includes('overview') || roles.includes('metadata'))\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst eoBands = Array.isArray(asset['eo:bands']) ? asset['eo:bands'] : undefined;\n\t\tconst assetExt = asset as unknown as Record<string, unknown>;\n\t\tconst rasterBands = Array.isArray(assetExt['raster:bands'])\n\t\t\t? (assetExt['raster:bands'] as unknown[])\n\t\t\t: undefined;\n\t\tconst bandCount = rasterBands?.length ?? eoBands?.length;\n\t\tconst commonName = eoBands?.[0]?.common_name?.toLowerCase();\n\t\tout.push({\n\t\t\tkey,\n\t\t\thref: asset.href,\n\t\t\tcommonName,\n\t\t\tbandCount: typeof bandCount === 'number' ? bandCount : undefined,\n\t\t\troles,\n\t\t\tmediaType,\n\t\t\ttitle: typeof asset.title === 'string' ? asset.title : undefined\n\t\t});\n\t}\n\treturn out;\n}\n","/**\n * Preset definitions, URL round-trip, and preset application for the unified\n * RGB picker. Pure TypeScript, publishable via objex-utils.\n *\n * Presets describe a SEMANTIC band slot triple (`red`/`green`/`blue` for\n * Natural Color, `nir`/`red`/`green` for False-Color IR, ...). Resolving a\n * preset against a specific item walks `BAND_KEY_FALLBACKS` in `utils/stac.ts`\n * to map slots to actual asset keys on that item. NDVI and other single-band\n * derived presets are intentionally NOT in this list for this slice.\n */\n\nimport type { ChannelComposite, CogAsset } from './cog-asset.js';\nimport { type BandSlot, type RasterBandAsset, resolvePresetComposite } from './stac.js';\n\nexport interface PresetDef {\n\tid: string;\n\tlabelKey: string;\n\tslots: { r: BandSlot; g: BandSlot; b: BandSlot };\n}\n\nexport const PRESETS: PresetDef[] = [\n\t{\n\t\tid: 'natural-color',\n\t\tlabelKey: 'map.multiCogPreset.trueColor',\n\t\tslots: { r: 'red', g: 'green', b: 'blue' }\n\t},\n\t{\n\t\tid: 'false-color-ir',\n\t\tlabelKey: 'map.multiCogPreset.falseColorIR',\n\t\tslots: { r: 'nir', g: 'red', b: 'green' }\n\t},\n\t{\n\t\tid: 'swir',\n\t\tlabelKey: 'map.multiCogPreset.swir',\n\t\tslots: { r: 'swir2', g: 'swir1', b: 'red' }\n\t},\n\t{\n\t\tid: 'vegetation',\n\t\tlabelKey: 'map.multiCogPreset.vegetation',\n\t\tslots: { r: 'nir', g: 'swir1', b: 'red' }\n\t},\n\t{\n\t\tid: 'agriculture',\n\t\tlabelKey: 'map.multiCogPreset.agriculture',\n\t\tslots: { r: 'swir1', g: 'nir', b: 'blue' }\n\t}\n];\n\nfunction toRasterBandAssets(assets: CogAsset[]): RasterBandAsset[] {\n\treturn assets.map((a) => ({\n\t\tkey: a.key,\n\t\thref: a.href,\n\t\tcommonName: a.eoCommon[0],\n\t\tbandCount: a.bandCount,\n\t\troles: a.roles,\n\t\tmediaType: a.mediaType,\n\t\ttitle: a.title\n\t}));\n}\n\n/** Subset of PRESETS whose slot triple resolves on this item. */\nexport function availablePresets(assets: CogAsset[]): PresetDef[] {\n\tconst rba = toRasterBandAssets(assets);\n\treturn PRESETS.filter((p) => resolvePresetComposite(rba, p.slots) !== null);\n}\n\n/** Resolve a preset to a ChannelComposite for this item. Returns null when not applicable. */\nexport function applyPreset(assets: CogAsset[], preset: PresetDef): ChannelComposite | null {\n\tconst rba = toRasterBandAssets(assets);\n\tconst r = resolvePresetComposite(rba, preset.slots);\n\tif (!r) return null;\n\treturn {\n\t\tr: { assetKey: r.r, bandIndex: 0 },\n\t\tg: { assetKey: r.g, bandIndex: 0 },\n\t\tb: { assetKey: r.b, bandIndex: 0 }\n\t};\n}\n\n/** True when the preset's resolved composite still matches the user's current picks. */\nexport function presetMatchesComposite(\n\tpreset: PresetDef,\n\tc: ChannelComposite,\n\tassets: CogAsset[]\n): boolean {\n\tconst resolved = applyPreset(assets, preset);\n\tif (!resolved) return false;\n\treturn (\n\t\tresolved.r.assetKey === c.r.assetKey &&\n\t\tresolved.g.assetKey === c.g.assetKey &&\n\t\tresolved.b.assetKey === c.b.assetKey &&\n\t\tc.r.bandIndex === 0 &&\n\t\tc.g.bandIndex === 0 &&\n\t\tc.b.bandIndex === 0\n\t);\n}\n\n/**\n * Decode a `URLSearchParams` chunk into a ChannelComposite.\n *\n * Format: `r=<asset>&g=<asset>&b=<asset>&band_r=<n>&band_g=<n>&band_b=<n>` plus\n * optional `a=<asset>&band_a=<n>`. `band_*` defaults to 0 when absent so\n * legacy MultiCog URLs (`?r=red&g=green&b=blue&preset=true-color`) keep\n * round-tripping. Returns null when any required asset key is missing from\n * the current item's asset list.\n */\nexport function compositeFromUrl(\n\tparams: URLSearchParams,\n\tassets: CogAsset[]\n): ChannelComposite | null {\n\tconst r = params.get('r');\n\tconst g = params.get('g');\n\tconst b = params.get('b');\n\tif (!r || !g || !b) return null;\n\tconst known = new Map(assets.map((a) => [a.key, a]));\n\tconst ra = known.get(r);\n\tconst ga = known.get(g);\n\tconst ba = known.get(b);\n\tif (!ra || !ga || !ba) return null;\n\tconst out: ChannelComposite = {\n\t\tr: { assetKey: r, bandIndex: clampBand(params.get('band_r'), ra.bandCount) },\n\t\tg: { assetKey: g, bandIndex: clampBand(params.get('band_g'), ga.bandCount) },\n\t\tb: { assetKey: b, bandIndex: clampBand(params.get('band_b'), ba.bandCount) }\n\t};\n\tconst a = params.get('a');\n\tif (a) {\n\t\tconst aa = known.get(a);\n\t\tif (aa) out.a = { assetKey: a, bandIndex: clampBand(params.get('band_a'), aa.bandCount) };\n\t}\n\treturn out;\n}\n\n/** Encode a composite + active preset id into URLSearchParams for the hash. */\nexport function compositeToUrl(c: ChannelComposite, presetId: string | null): URLSearchParams {\n\tconst p = new URLSearchParams();\n\tp.set('r', c.r.assetKey);\n\tp.set('g', c.g.assetKey);\n\tp.set('b', c.b.assetKey);\n\tif (c.r.bandIndex !== 0) p.set('band_r', String(c.r.bandIndex));\n\tif (c.g.bandIndex !== 0) p.set('band_g', String(c.g.bandIndex));\n\tif (c.b.bandIndex !== 0) p.set('band_b', String(c.b.bandIndex));\n\tif (c.a) {\n\t\tp.set('a', c.a.assetKey);\n\t\tif (c.a.bandIndex !== 0) p.set('band_a', String(c.a.bandIndex));\n\t}\n\tif (presetId) p.set('preset', presetId);\n\treturn p;\n}\n\nfunction clampBand(raw: string | null, bandCount: number): number {\n\tif (!raw) return 0;\n\tconst n = Number(raw);\n\tif (!Number.isFinite(n)) return 0;\n\tconst i = Math.floor(n);\n\tif (i < 0) return 0;\n\tif (i >= bandCount) return Math.max(0, bandCount - 1);\n\treturn i;\n}\n","import { COPY_FEEDBACK_MS } from '../../../src/lib/constants.js';\n\n/**\n * Copy text to clipboard and run a feedback callback for COPY_FEEDBACK_MS.\n * Silently catches clipboard errors (e.g. insecure context).\n *\n * @returns true if copy succeeded, false otherwise.\n */\nexport async function copyToClipboard(\n\ttext: string,\n\tonFeedback?: (copied: boolean) => void\n): Promise<boolean> {\n\ttry {\n\t\tawait navigator.clipboard.writeText(text);\n\t\tonFeedback?.(true);\n\t\tsetTimeout(() => onFeedback?.(false), COPY_FEEDBACK_MS);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Wire click-to-copy on all elements matching `selector` inside `root`.\n * Each element must have `data-code` (URI-encoded) with the text to copy.\n * Adds/removes a `copied` CSS class for visual feedback.\n */\nexport function wireCodeCopyButtons(root: Element, selector: string): void {\n\tfor (const btn of root.querySelectorAll(selector)) {\n\t\tbtn.addEventListener('click', async () => {\n\t\t\tconst code = decodeURIComponent((btn as HTMLElement).dataset.code ?? '');\n\t\t\ttry {\n\t\t\t\tawait navigator.clipboard.writeText(code);\n\t\t\t\tbtn.classList.add('copied');\n\t\t\t\tsetTimeout(() => btn.classList.remove('copied'), COPY_FEEDBACK_MS);\n\t\t\t} catch {\n\t\t\t\t// clipboard not available\n\t\t\t}\n\t\t});\n\t}\n}\n","/**\n * Cloud storage protocol URL utilities — pure TS, no Svelte dependency.\n *\n * Converts cloud protocol URLs (s3://, gs://) to HTTPS URLs for browser access.\n * Provider-aware native scheme lookup.\n */\n\nimport {\n\tbuildProviderBaseUrl,\n\tPROVIDERS,\n\ttype ProviderId\n} from '../../../src/lib/storage/providers.js';\n\n/** AWS region pattern — matches prefixes like \"us-west-2\", \"eu-central-1\", etc. */\nconst AWS_REGION_RE =\n\t/^(us|eu|ap|sa|ca|me|af|il)-(north|south|east|west|central|northeast|southeast|northwest|southwest)-\\d+/;\n\n/**\n * Map provider to its native URI scheme prefix.\n * Derived from the registry's `schemes` array (first entry is the primary scheme).\n * Falls back to 's3' for providers without a scheme (S3-compatible).\n */\nexport function getNativeScheme(provider: string): string {\n\tconst def = PROVIDERS[provider as ProviderId];\n\tif (def?.schemes.length) return def.schemes[0];\n\treturn 's3';\n}\n\n/**\n * Safely decode a percent-encoded URI component.\n * Returns the original string if decoding fails (malformed sequences).\n */\nexport function safeDecodeURIComponent(s: string): string {\n\ttry {\n\t\treturn decodeURIComponent(s);\n\t} catch {\n\t\treturn s;\n\t}\n}\n\n/**\n * Convert a cloud storage protocol URL (s3://, gs://) to an HTTPS URL\n * for browser access. Returns the original URL if already HTTP(S) or unknown.\n *\n * Supported:\n * - `s3://bucket/key` → `https://s3.{region}.amazonaws.com/{bucket}/{key}`\n * (region auto-detected from bucket name when possible)\n * - `gs://bucket/key` → `https://storage.googleapis.com/{bucket}/{key}`\n */\nexport function resolveCloudUrl(url: string): string {\n\t// S3 / S3-compatible: s3://, s3a://, s3n://\n\tconst s3Match = url.match(/^s3[an]?:\\/\\/([^/]+)(?:\\/(.*))?$/);\n\tif (s3Match) {\n\t\tconst [, bucket, key] = s3Match;\n\t\t// Detect region from bucket name (e.g. \"us-west-2.opendata.source.coop\")\n\t\tconst regionMatch = bucket.match(AWS_REGION_RE);\n\t\tconst region = regionMatch ? regionMatch[0] : 'us-east-1';\n\t\tconst base = buildProviderBaseUrl('s3', '', bucket, region);\n\t\treturn key ? `${base}/${key}` : base;\n\t}\n\n\t// Google Cloud Storage: gs://, gcs://\n\tconst gcsMatch = url.match(/^gcs?:\\/\\/([^/]+)(?:\\/(.*))?$/);\n\tif (gcsMatch) {\n\t\tconst [, bucket, key] = gcsMatch;\n\t\tconst base = buildProviderBaseUrl('gcs', '', bucket, '');\n\t\treturn key ? `${base}/${key}` : base;\n\t}\n\n\treturn url;\n}\n","/**\n * Generic per-channel asset descriptor for the unified RGB picker.\n *\n * Pure TypeScript. No Svelte dependency. Publishable via objex-utils.\n *\n * `CogAsset` is the canonical shape every viewer (CogViewer, MultiCogViewer,\n * StacMosaicViewer) hands to the shared ChannelPicker UI. Each entry records\n * the STAC asset key (`red`, `B04`, `image`, `visual`, ... or `self` when the\n * viewer is a single bare COG file with no STAC context), the href, the band\n * count (from `raster:bands.length` when STAC populates it, lazily probed from\n * the COG header otherwise), and the optional `eo:bands` common name.\n */\n\nimport type { StacItem } from './stac.js';\n\nexport interface CogAsset {\n\t/** STAC asset key, or `self` for a single bare COG without STAC context. */\n\tkey: string;\n\t/** Absolute or relative href as it appears in the STAC item / URL. */\n\thref: string;\n\t/** Number of bands in the asset. 1 by default until probed. */\n\tbandCount: number;\n\t/** True when bandCount came from STAC metadata or a probe; false → trust default. */\n\tbandCountKnown: boolean;\n\t/** `raster:bands[0].data_type` if known. */\n\tdtype?: string;\n\t/** `eo:bands[].common_name` lowercased, aligned to bandIndex order. */\n\teoCommon: string[];\n\t/** STAC asset roles (`data`, `visual`, `reflectance`, ...). */\n\troles: string[];\n\t/** Optional human title. */\n\ttitle?: string;\n\t/** Asset media_type as advertised by STAC. */\n\tmediaType?: string;\n}\n\n/** Per-channel pixel coordinate inside a STAC item. */\nexport interface ChannelRef {\n\tassetKey: string;\n\tbandIndex: number;\n}\n\n/** RGB(A) composite expressed as `(asset, bandIndex)` per channel. */\nexport interface ChannelComposite {\n\tr: ChannelRef;\n\tg: ChannelRef;\n\tb: ChannelRef;\n\ta?: ChannelRef;\n}\n\nconst TIFF_MEDIA = /^image\\/(tiff|geotiff)\\b/i;\nconst NON_DATA_ROLES = new Set(['thumbnail', 'overview', 'metadata']);\n\n/**\n * Enumerate every TIFF/COG asset on a STAC Item, keeping multi-band assets\n * (NAIP `image`, S2 `visual` TCI) alongside single-band per-band assets.\n *\n * Reads band metadata from (in priority order):\n * 1. `asset.bands` (STAC 1.1 unified bands array)\n * 2. `asset['raster:bands']` (STAC 1.0 raster extension)\n * 3. `asset['eo:bands']` (STAC 1.0 eo extension)\n * 4. `item.properties.bands` (STAC 1.1 item-level bands, applies to all\n * assets that do not override) — covers catalogs like the Hamilton\n * NAIP-style 3-inch where each item has 4 bands but the single `data`\n * asset carries no band metadata of its own.\n *\n * `bandCount` is set when any of the above provides one; otherwise defaults\n * to 1 with `bandCountKnown: false` so callers can lazily probe on first pick.\n */\nexport function extractCogAssets(item: StacItem): CogAsset[] {\n\tconst out: CogAsset[] = [];\n\tconst assets = item.assets ?? {};\n\tconst props = (item.properties ?? {}) as Record<string, unknown>;\n\tconst itemBands = Array.isArray(props.bands)\n\t\t? (props.bands as Array<Record<string, unknown>>)\n\t\t: undefined;\n\tfor (const [key, asset] of Object.entries(assets)) {\n\t\tif (!asset?.href) continue;\n\t\tconst mediaType = typeof asset.type === 'string' ? asset.type : undefined;\n\t\tif (mediaType && !TIFF_MEDIA.test(mediaType)) continue;\n\t\tconst roles = Array.isArray(asset.roles) ? (asset.roles as string[]) : [];\n\t\tif (roles.some((r) => NON_DATA_ROLES.has(r))) continue;\n\t\tconst eoBands = Array.isArray(asset['eo:bands']) ? asset['eo:bands'] : undefined;\n\t\tconst assetExt = asset as unknown as Record<string, unknown>;\n\t\tconst rasterBands = Array.isArray(assetExt['raster:bands'])\n\t\t\t? (assetExt['raster:bands'] as Array<Record<string, unknown>>)\n\t\t\t: undefined;\n\t\tconst assetBands11 = Array.isArray(assetExt.bands)\n\t\t\t? (assetExt.bands as Array<Record<string, unknown>>)\n\t\t\t: undefined;\n\t\t// `bandCount` source priority: STAC 1.1 unified `bands` → `raster:bands`\n\t\t// → `eo:bands` → item-level `properties.bands`. Item-level `bands` is the\n\t\t// fallback that lets catalogs (Hamilton NAIP-style 4-band COGs) which\n\t\t// keep band metadata at the item-properties level expose band picks.\n\t\tconst bandCount =\n\t\t\tassetBands11?.length ?? rasterBands?.length ?? eoBands?.length ?? itemBands?.length;\n\t\tconst bandCountKnown = typeof bandCount === 'number' && bandCount > 0;\n\t\t// `eoCommon` is independent of bandCount source: prefer `eo:bands` (the\n\t\t// only field guaranteed to carry common_name pre-STAC 1.1), then the\n\t\t// STAC 1.1 unified `bands` (which may include common_name), then the\n\t\t// item-level fallback. raster:bands typically has no common_name so we\n\t\t// skip it for this lookup.\n\t\tconst commonSource = eoBands ?? assetBands11 ?? itemBands;\n\t\tconst eoCommon = commonSource\n\t\t\t? commonSource.map((b) => {\n\t\t\t\t\tconst c = (b as Record<string, unknown>)?.common_name;\n\t\t\t\t\treturn typeof c === 'string' ? c.toLowerCase() : '';\n\t\t\t\t})\n\t\t\t: [];\n\t\tconst dtypeSource = rasterBands ?? assetBands11 ?? itemBands;\n\t\tconst dtype = (dtypeSource?.[0] as Record<string, unknown> | undefined)?.data_type;\n\t\tout.push({\n\t\t\tkey,\n\t\t\thref: asset.href,\n\t\t\tbandCount: bandCountKnown ? (bandCount as number) : 1,\n\t\t\tbandCountKnown,\n\t\t\tdtype: typeof dtype === 'string' ? dtype : undefined,\n\t\t\teoCommon,\n\t\t\troles,\n\t\t\ttitle: typeof asset.title === 'string' ? asset.title : undefined,\n\t\t\tmediaType\n\t\t});\n\t}\n\treturn out;\n}\n\n/**\n * For `CogViewer` (single bare COG file, no STAC context). Returns one synthetic\n * asset with key `self` so the same ChannelPicker UI works without special-casing.\n * `bandCount` defaults to 1, set to the probed `geotiff.count` once known.\n */\nexport function syntheticSelfAsset(href: string, probedBandCount?: number): CogAsset {\n\tconst known = typeof probedBandCount === 'number' && probedBandCount > 0;\n\treturn {\n\t\tkey: 'self',\n\t\thref,\n\t\tbandCount: known ? probedBandCount : 1,\n\t\tbandCountKnown: known,\n\t\teoCommon: [],\n\t\troles: []\n\t};\n}\n\n/**\n * Pick the most natural and most performant default composite for an item.\n *\n * Priority (first match wins):\n * 1. A 3-band uint8 pre-baked visual asset (`visual` / `image` / `tci` etc):\n * all three channels bind to it, bands 0/1/2. Single COGLayer path,\n * one decoder, fastest.\n * 2. Common-name red/green/blue resolvable across separate single-band assets.\n * MultiCOGLayer path.\n * 3. Fallback: first three raster assets, band 0 each.\n *\n * Returns null when no raster assets exist.\n */\nexport function pickNaturalColorComposite(\n\tassets: CogAsset[]\n): { composite: ChannelComposite; source: 'visual-asset' | 'rgb-bands' | 'fallback' } | null {\n\tif (assets.length === 0) return null;\n\n\t// 1. Pre-baked visual: bandCount === 3 AND eoCommon ⊇ {red,green,blue} OR roles ∋ visual\n\tfor (const a of assets) {\n\t\tif (a.bandCount === 3 && (a.roles.includes('visual') || hasRgbInEoCommon(a.eoCommon))) {\n\t\t\treturn {\n\t\t\t\tcomposite: {\n\t\t\t\t\tr: { assetKey: a.key, bandIndex: indexOfCommon(a.eoCommon, 'red', 0) },\n\t\t\t\t\tg: { assetKey: a.key, bandIndex: indexOfCommon(a.eoCommon, 'green', 1) },\n\t\t\t\t\tb: { assetKey: a.key, bandIndex: indexOfCommon(a.eoCommon, 'blue', 2) }\n\t\t\t\t},\n\t\t\t\tsource: 'visual-asset'\n\t\t\t};\n\t\t}\n\t}\n\n\t// 2. Separate red/green/blue assets by common-name\n\tconst red = assets.find((a) => a.eoCommon[0] === 'red');\n\tconst green = assets.find((a) => a.eoCommon[0] === 'green');\n\tconst blue = assets.find((a) => a.eoCommon[0] === 'blue');\n\tif (red && green && blue) {\n\t\treturn {\n\t\t\tcomposite: {\n\t\t\t\tr: { assetKey: red.key, bandIndex: 0 },\n\t\t\t\tg: { assetKey: green.key, bandIndex: 0 },\n\t\t\t\tb: { assetKey: blue.key, bandIndex: 0 }\n\t\t\t},\n\t\t\tsource: 'rgb-bands'\n\t\t};\n\t}\n\n\t// 3. Fallback: first three raster assets\n\tif (assets.length >= 3) {\n\t\treturn {\n\t\t\tcomposite: {\n\t\t\t\tr: { assetKey: assets[0].key, bandIndex: 0 },\n\t\t\t\tg: { assetKey: assets[1].key, bandIndex: 0 },\n\t\t\t\tb: { assetKey: assets[2].key, bandIndex: 0 }\n\t\t\t},\n\t\t\tsource: 'fallback'\n\t\t};\n\t}\n\n\t// Single asset (e.g. CogViewer with a 1-band file): R/G/B all on band 0\n\tconst only = assets[0];\n\tconst last = Math.max(0, only.bandCount - 1);\n\treturn {\n\t\tcomposite: {\n\t\t\tr: { assetKey: only.key, bandIndex: 0 },\n\t\t\tg: { assetKey: only.key, bandIndex: Math.min(1, last) },\n\t\t\tb: { assetKey: only.key, bandIndex: Math.min(2, last) }\n\t\t},\n\t\tsource: 'fallback'\n\t};\n}\n\nfunction hasRgbInEoCommon(eo: string[]): boolean {\n\treturn eo.includes('red') && eo.includes('green') && eo.includes('blue');\n}\n\nfunction indexOfCommon(eo: string[], name: string, fallback: number): number {\n\tconst i = eo.indexOf(name);\n\treturn i >= 0 ? i : fallback;\n}\n\n/** True when all three RGB channels target the same asset key. */\nexport function isSingleAssetComposite(c: ChannelComposite): boolean {\n\treturn c.r.assetKey === c.g.assetKey && c.g.assetKey === c.b.assetKey;\n}\n\n/** True when all three channels are at band index 0 (the MultiCOGLayer-compatible case). */\nexport function allChannelsBand0(c: ChannelComposite): boolean {\n\treturn c.r.bandIndex === 0 && c.g.bandIndex === 0 && c.b.bandIndex === 0;\n}\n","// Dependency-free subset of `cog.ts` so that `@walkthru-earth/objex-utils`\n// can re-export these helpers without dragging in `@developmentseed/epsg`,\n// `@developmentseed/geotiff`, `@developmentseed/proj`, `proj4`, or\n// `maplibre-gl`. tsup preserves bare side-effect imports from externalized\n// modules even when all named bindings are tree-shaken, so the pure surface\n// MUST live in a module that has zero heavy imports.\n\n/** SampleFormat tag value → human label. */\nexport const SF_LABELS: Record<number, string> = {\n\t1: 'uint',\n\t2: 'int',\n\t3: 'float',\n\t4: 'void',\n\t5: 'complex int',\n\t6: 'complex float'\n};\n\nexport interface GeoBounds {\n\twest: number;\n\tsouth: number;\n\teast: number;\n\tnorth: number;\n}\n\nexport interface CogInfo {\n\twidth: number;\n\theight: number;\n\tbandCount: number;\n\tdataType: string;\n\tbounds: GeoBounds;\n\tdownsampled?: boolean;\n}\n\n/** Safely clamp a number to a range, treating NaN/Infinity as the fallback. */\nexport function safeClamp(v: number, lo: number, hi: number, fallback: number): number {\n\treturn Number.isFinite(v) ? Math.max(lo, Math.min(hi, v)) : fallback;\n}\n\n/** Clamp geographic bounds to valid MapLibre web-Mercator range. */\nexport function clampBounds(b: GeoBounds): GeoBounds {\n\treturn {\n\t\twest: safeClamp(b.west, -180, 180, -180),\n\t\tsouth: safeClamp(b.south, -85.051129, 85.051129, -85.051129),\n\t\teast: safeClamp(b.east, -180, 180, 180),\n\t\tnorth: safeClamp(b.north, -85.051129, 85.051129, 85.051129)\n\t};\n}\n\n/**\n * Build a data-type label from GeoTIFF sample format and bits per sample.\n * e.g. \"uint8\", \"float32\", \"int16\"\n */\nexport function buildDataTypeLabel(sampleFormat: number, bitsPerSample: number): string {\n\treturn `${SF_LABELS[sampleFormat] ?? `sf${sampleFormat}`}${bitsPerSample ?? ''}`;\n}\n","export type TypeCategory =\n\t| 'number'\n\t| 'string'\n\t| 'date'\n\t| 'boolean'\n\t| 'geo'\n\t| 'binary'\n\t| 'json'\n\t| 'other';\n\nconst NUMBER_TYPES = [\n\t'TINYINT',\n\t'SMALLINT',\n\t'INTEGER',\n\t'BIGINT',\n\t'HUGEINT',\n\t'UTINYINT',\n\t'USMALLINT',\n\t'UINTEGER',\n\t'UBIGINT',\n\t'FLOAT',\n\t'DOUBLE',\n\t'DECIMAL',\n\t'NUMERIC',\n\t'REAL',\n\t'INT',\n\t'INT1',\n\t'INT2',\n\t'INT4',\n\t'INT8',\n\t'SIGNED',\n\t'SHORT',\n\t'LONG'\n];\n\nconst STRING_TYPES = ['VARCHAR', 'TEXT', 'STRING', 'CHAR', 'BPCHAR', 'NAME', 'UUID', 'ENUM'];\n\nconst DATE_TYPES = [\n\t'DATE',\n\t'TIME',\n\t'TIMESTAMP',\n\t'TIMESTAMP_S',\n\t'TIMESTAMP_MS',\n\t'TIMESTAMP_NS',\n\t'TIMESTAMP WITH TIME ZONE',\n\t'TIMESTAMPTZ',\n\t'INTERVAL',\n\t'TIMESTAMP_TZ'\n];\n\nconst BOOLEAN_TYPES = ['BOOLEAN', 'BOOL', 'LOGICAL'];\n\nconst GEO_TYPES = [\n\t'GEOMETRY',\n\t'POINT',\n\t'LINESTRING',\n\t'POLYGON',\n\t'MULTIPOINT',\n\t'MULTILINESTRING',\n\t'MULTIPOLYGON',\n\t'GEOMETRYCOLLECTION',\n\t'WKB_GEOMETRY'\n];\n\nconst BINARY_TYPES = ['BLOB', 'BYTEA', 'BINARY', 'VARBINARY'];\n\nconst JSON_TYPES = ['JSON', 'JSONB'];\n\nexport function classifyType(duckdbType: string): TypeCategory {\n\tconst upper = duckdbType.toUpperCase().trim();\n\n\t// Handle parameterized types like DECIMAL(18,3), VARCHAR(100). Strip the\n\t// parenthesized span (first '(' to last ')') via index math instead of a\n\t// regex to avoid polynomial backtracking on '('-heavy input.\n\tconst openIdx = upper.indexOf('(');\n\tconst closeIdx = upper.lastIndexOf(')');\n\tconst base = (\n\t\topenIdx >= 0 && closeIdx > openIdx ? upper.slice(0, openIdx) + upper.slice(closeIdx + 1) : upper\n\t).trim();\n\n\tif (NUMBER_TYPES.includes(base)) return 'number';\n\tif (STRING_TYPES.includes(base)) return 'string';\n\tif (DATE_TYPES.includes(base)) return 'date';\n\tif (BOOLEAN_TYPES.includes(base)) return 'boolean';\n\tif (GEO_TYPES.includes(base)) return 'geo';\n\tif (BINARY_TYPES.includes(base)) return 'binary';\n\tif (JSON_TYPES.includes(base)) return 'json';\n\n\t// Compound types\n\tif (base.startsWith('STRUCT') || base.startsWith('MAP') || base.startsWith('UNION'))\n\t\treturn 'json';\n\tif (base.endsWith('[]') || base.startsWith('LIST')) return 'json';\n\n\t// Fallback checks\n\tif (\n\t\tupper.includes('INT') ||\n\t\tupper.includes('FLOAT') ||\n\t\tupper.includes('DOUBLE') ||\n\t\tupper.includes('DECIMAL') ||\n\t\tupper.includes('NUMERIC')\n\t)\n\t\treturn 'number';\n\tif (upper.includes('CHAR') || upper.includes('TEXT') || upper.includes('STRING')) return 'string';\n\tif (upper.includes('TIME') || upper.includes('DATE')) return 'date';\n\tif (upper.includes('BOOL')) return 'boolean';\n\tif (upper.includes('GEOMETRY') || upper.includes('GEO') || upper.includes('WKB')) return 'geo';\n\tif (upper.includes('BLOB') || upper.includes('BINARY')) return 'binary';\n\tif (\n\t\tupper.includes('JSON') ||\n\t\tupper.includes('STRUCT') ||\n\t\tupper.includes('MAP') ||\n\t\tupper.includes('LIST')\n\t)\n\t\treturn 'json';\n\n\treturn 'other';\n}\n\nconst TYPE_COLORS: Record<TypeCategory, string> = {\n\tnumber: 'text-blue-500',\n\tstring: 'text-green-500',\n\tdate: 'text-amber-500',\n\tboolean: 'text-purple-500',\n\tgeo: 'text-teal-500',\n\tbinary: 'text-zinc-500',\n\tjson: 'text-orange-500',\n\tother: 'text-zinc-400'\n};\n\nconst TYPE_BADGE_CLASSES: Record<TypeCategory, string> = {\n\tnumber: 'bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/20',\n\tstring: 'bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/20',\n\tdate: 'bg-amber-500/10 text-amber-600 dark:text-amber-400 border-amber-500/20',\n\tboolean: 'bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/20',\n\tgeo: 'bg-teal-500/10 text-teal-600 dark:text-teal-400 border-teal-500/20',\n\tbinary: 'bg-zinc-500/10 text-zinc-600 dark:text-zinc-400 border-zinc-500/20',\n\tjson: 'bg-orange-500/10 text-orange-600 dark:text-orange-400 border-orange-500/20',\n\tother: 'bg-zinc-500/10 text-zinc-500 dark:text-zinc-400 border-zinc-500/20'\n};\n\nconst TYPE_LABELS: Record<TypeCategory, string> = {\n\tnumber: '#',\n\tstring: 'Aa',\n\tdate: 'dt',\n\tboolean: 'T/F',\n\tgeo: 'geo',\n\tbinary: '01',\n\tjson: '{}',\n\tother: '?'\n};\n\nexport function typeColor(category: TypeCategory): string {\n\treturn TYPE_COLORS[category];\n}\n\nexport function typeBadgeClass(category: TypeCategory): string {\n\treturn TYPE_BADGE_CLASSES[category];\n}\n\nexport function typeLabel(category: TypeCategory): string {\n\treturn TYPE_LABELS[category];\n}\n","/**\n * Canonical connection identity.\n *\n * Single source of truth for deciding when two connection configs point at\n * the same bucket. Used by the connections store to deduplicate auto-detect,\n * manual add, and edit flows, so one physical bucket never ends up with\n * multiple competing local records.\n *\n * Identity rules, per provider:\n *\n * azure → (provider, endpoint, bucket) endpoint carries the account\n * gcs → (provider, bucket) GCS bucket names are global\n * s3 → (provider, bucket, region) AWS native: same bucket name\n * can exist in exactly one region,\n * but the region is load-bearing\n * for signing, so a paste with a\n * different region is a distinct\n * connection until the user merges\n * other → (provider, endpoint, bucket) r2, b2, minio, wasabi, storj,\n * digitalocean, contabo, hetzner,\n * linode, ovhcloud, custom\n *\n * Endpoint normalization is aggressive: scheme + host + non-default port +\n * pathname, with trailing slashes and default ports stripped, host lowercased.\n * That collapses the common trip hazards — http vs https, :443 vs empty,\n * trailing slash drift, mixed case host.\n */\n\nimport type { ProviderId } from '../../../src/lib/storage/providers.js';\n\nexport interface ConnectionIdentityInput {\n\tprovider: string;\n\tendpoint: string;\n\tbucket: string;\n\tregion: string;\n}\n\nconst DEFAULT_PORTS: Record<string, string> = {\n\t'https:': '443',\n\t'http:': '80'\n};\n\nconst SLASH = 47; // '/'.charCodeAt(0)\n\n/** Strip trailing '/' linearly (avoids the polynomial backtracking of `/\\/+$/`). */\nfunction stripTrailingSlashes(s: string): string {\n\tlet end = s.length;\n\twhile (end > 0 && s.charCodeAt(end - 1) === SLASH) end--;\n\treturn s.slice(0, end);\n}\n\n/** Strip leading and trailing '/' linearly (avoids `/^\\/+|\\/+$/g` backtracking). */\nfunction stripEdgeSlashes(s: string): string {\n\tlet start = 0;\n\tlet end = s.length;\n\twhile (start < end && s.charCodeAt(start) === SLASH) start++;\n\twhile (end > start && s.charCodeAt(end - 1) === SLASH) end--;\n\treturn s.slice(start, end);\n}\n\n/**\n * Normalize an endpoint URL to a canonical form suitable for equality checks.\n * Empty / whitespace-only input returns `''` (the \"no endpoint\" sentinel).\n * Non-URL strings are lowercased and stripped of trailing slashes as a best\n * effort so the comparison is still deterministic.\n */\nexport function normalizeEndpoint(raw: string | undefined | null): string {\n\tif (!raw) return '';\n\tconst trimmed = raw.trim();\n\tif (!trimmed) return '';\n\ttry {\n\t\tconst url = new URL(trimmed);\n\t\tconst scheme = url.protocol.toLowerCase();\n\t\tconst host = url.hostname.toLowerCase();\n\t\tconst defaultPort = DEFAULT_PORTS[scheme] ?? '';\n\t\tconst port = url.port && url.port !== defaultPort ? `:${url.port}` : '';\n\t\tconst path = stripTrailingSlashes(url.pathname);\n\t\treturn `${scheme}//${host}${port}${path}`;\n\t} catch {\n\t\treturn stripTrailingSlashes(trimmed.toLowerCase());\n\t}\n}\n\n/** Collapse unknown / empty providers to `'s3'`; otherwise lowercase. */\nexport function normalizeProvider(provider: string | undefined | null): ProviderId {\n\tif (!provider) return 's3';\n\tconst p = provider.trim().toLowerCase();\n\tif (!p || p === 'unknown') return 's3';\n\treturn p as ProviderId;\n}\n\n/** Bucket names are case-sensitive on some backends, so preserve case. */\nfunction normalizeBucket(bucket: string | undefined | null): string {\n\treturn stripEdgeSlashes((bucket ?? '').trim());\n}\n\nfunction normalizeRegion(region: string | undefined | null): string {\n\treturn (region ?? '').trim().toLowerCase();\n}\n\n/**\n * Produce a canonical key for a connection's identity. Two connection\n * configs with the same identity key point at the same physical bucket.\n * Returns `''` when the config is too incomplete to identify a bucket.\n */\nexport function connectionIdentityKey(input: ConnectionIdentityInput): string {\n\tconst provider = normalizeProvider(input.provider);\n\tconst bucket = normalizeBucket(input.bucket);\n\tif (!bucket) return '';\n\n\tconst endpoint = normalizeEndpoint(input.endpoint);\n\tconst region = normalizeRegion(input.region);\n\n\tif (provider === 'azure') return `azure|${endpoint}|${bucket}`;\n\tif (provider === 'gcs') return `gcs|${bucket}`;\n\tif (provider === 's3' && !endpoint) return `s3|${bucket}|${region}`;\n\treturn `${provider}|${endpoint}|${bucket}`;\n}\n\n/** Convenience: true when both inputs share the same non-empty identity. */\nexport function isSameConnectionIdentity(\n\ta: ConnectionIdentityInput,\n\tb: ConnectionIdentityInput\n): boolean {\n\tconst key = connectionIdentityKey(a);\n\treturn key !== '' && key === connectionIdentityKey(b);\n}\n","/**\n * Shared error handling for async viewer load operations.\n */\n\n/**\n * True for any abort cascade. Recognizes raw `DOMException(AbortError)`,\n * objects whose `.name` is `AbortError`, deck.gl's `_SourceError(\"Failed\n * to fetch\")` wrapper whose `cause` is an AbortError, and free-text errors\n * from `@developmentseed/geotiff` that mention \"aborted\". Used to silence\n * cancellation noise without swallowing real failures.\n */\nexport function isAbortError(err: unknown): boolean {\n\tif (!err) return false;\n\tif (err instanceof DOMException && err.name === 'AbortError') return true;\n\tconst e = err as { name?: string; message?: string; cause?: unknown };\n\tif (e.name === 'AbortError') return true;\n\tif (typeof e.message === 'string' && /\\baborted?\\b/i.test(e.message)) return true;\n\tif (e.cause && isAbortError(e.cause)) return true;\n\treturn false;\n}\n\n/**\n * Extract an error message from an unknown caught value.\n * Returns null for AbortError (caller should silently return).\n */\nexport function handleLoadError(err: unknown): string | null {\n\tif (isAbortError(err)) return null;\n\treturn err instanceof Error ? err.message : String(err);\n}\n","/**\n * Formats a byte count into a human-readable string.\n */\nexport function formatFileSize(bytes: number): string {\n\tif (bytes < 0) return '0 B';\n\tif (bytes === 0) return '0 B';\n\n\tconst units = ['B', 'KB', 'MB', 'GB', 'TB'];\n\tconst base = 1024;\n\tconst exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(base)), units.length - 1);\n\tconst value = bytes / base ** exponent;\n\n\t// Use integer display for bytes, one decimal for everything else\n\tif (exponent === 0) return `${bytes} B`;\n\treturn `${value.toFixed(1)} ${units[exponent]}`;\n}\n\n/**\n * Formats a unix timestamp (milliseconds) to a human-readable date string.\n * Shows relative time for recent dates, absolute for older ones.\n */\nexport function formatDate(timestamp: number): string {\n\tif (!timestamp || timestamp <= 0 || !Number.isFinite(timestamp)) return '--';\n\n\tconst date = new Date(timestamp);\n\tconst now = Date.now();\n\tconst diffMs = now - timestamp;\n\tconst diffSeconds = Math.floor(diffMs / 1000);\n\tconst diffMinutes = Math.floor(diffSeconds / 60);\n\tconst diffHours = Math.floor(diffMinutes / 60);\n\tconst diffDays = Math.floor(diffHours / 24);\n\n\tif (diffSeconds < 60) return 'Just now';\n\tif (diffMinutes < 60) return `${diffMinutes}m ago`;\n\tif (diffHours < 24) return `${diffHours}h ago`;\n\tif (diffDays < 7) return `${diffDays}d ago`;\n\n\t// For older dates, show absolute date\n\treturn date.toLocaleDateString(undefined, {\n\t\tyear: 'numeric',\n\t\tmonth: 'short',\n\t\tday: 'numeric'\n\t});\n}\n\n/**\n * Extracts the file extension from a filename, including the leading dot.\n * Returns an empty string if no extension is found.\n */\nexport function getFileExtension(filename: string): string {\n\tconst lastDot = filename.lastIndexOf('.');\n\tif (lastDot <= 0) return '';\n\treturn filename.slice(lastDot).toLowerCase();\n}\n\n/**\n * JSON replacer that converts BigInt values to strings.\n * Use with `JSON.stringify(value, jsonReplacerBigInt)`.\n */\nexport function jsonReplacerBigInt(_key: string, value: unknown): unknown {\n\treturn typeof value === 'bigint' ? value.toString() : value;\n}\n\n/**\n * Format a value for display in tables, attribute panels, and exports.\n * Handles null, undefined, Date, BigInt, and objects uniformly.\n */\nexport function formatValue(value: unknown): string {\n\tif (value === null || value === undefined) return 'NULL';\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value === 'bigint') return value.toString();\n\tif (typeof value === 'object') return JSON.stringify(value, jsonReplacerBigInt);\n\treturn String(value);\n}\n","import { jsonReplacerBigInt } from './format.js';\n\nfunction triggerDownload(content: string, filename: string, mimeType: string) {\n\tconst blob = new Blob([content], { type: mimeType });\n\tconst url = URL.createObjectURL(blob);\n\tconst a = document.createElement('a');\n\ta.href = url;\n\ta.download = filename;\n\tdocument.body.appendChild(a);\n\ta.click();\n\tdocument.body.removeChild(a);\n\tURL.revokeObjectURL(url);\n}\n\n/** Format a cell value for export (empty string for null/undefined). */\nfunction formatCellValue(value: unknown): string {\n\tif (value === null || value === undefined) return '';\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value === 'bigint') return value.toString();\n\tif (typeof value === 'object') return JSON.stringify(value, jsonReplacerBigInt);\n\treturn String(value);\n}\n\n/**\n * Escape a CSV field value per RFC 4180.\n */\nexport function escapeCsvField(value: string): string {\n\tif (value.includes(',') || value.includes('\"') || value.includes('\\n') || value.includes('\\r')) {\n\t\treturn `\"${value.replace(/\"/g, '\"\"')}\"`;\n\t}\n\treturn value;\n}\n\n/**\n * Serialize column/row data to a CSV string.\n * Pure function — no browser APIs, works in Node.js.\n */\nexport function serializeToCsv(columns: string[], rows: Record<string, unknown>[]): string {\n\tconst header = columns.map(escapeCsvField).join(',');\n\tconst body = rows\n\t\t.map((row) => columns.map((col) => escapeCsvField(formatCellValue(row[col]))).join(','))\n\t\t.join('\\n');\n\treturn `${header}\\n${body}`;\n}\n\n/**\n * Serialize column/row data to a formatted JSON string.\n * Pure function — no browser APIs, works in Node.js.\n */\nexport function serializeToJson(columns: string[], rows: Record<string, unknown>[]): string {\n\tconst data = rows.map((row) => {\n\t\tconst obj: Record<string, unknown> = {};\n\t\tfor (const col of columns) {\n\t\t\tconst val = row[col];\n\t\t\tif (val instanceof Date) {\n\t\t\t\tobj[col] = val.toISOString();\n\t\t\t} else {\n\t\t\t\tobj[col] = val ?? null;\n\t\t\t}\n\t\t}\n\t\treturn obj;\n\t});\n\treturn JSON.stringify(data, jsonReplacerBigInt, 2);\n}\n\n/**\n * Export data as CSV file (triggers browser download).\n */\nexport function exportToCsv(columns: string[], rows: Record<string, unknown>[], filename: string) {\n\ttriggerDownload(\n\t\tserializeToCsv(columns, rows),\n\t\tfilename.endsWith('.csv') ? filename : `${filename}.csv`,\n\t\t'text/csv;charset=utf-8;'\n\t);\n}\n\n/**\n * Export data as JSON file (triggers browser download).\n */\nexport function exportToJson(columns: string[], rows: Record<string, unknown>[], filename: string) {\n\ttriggerDownload(\n\t\tserializeToJson(columns, rows),\n\t\tfilename.endsWith('.json') ? filename : `${filename}.json`,\n\t\t'application/json'\n\t);\n}\n","/**\n * Pure file entry sorting — framework-agnostic, works in Node.js.\n */\n\nimport type { FileEntry } from '../../../src/lib/types.js';\n\nexport type SortField = 'name' | 'size' | 'modified' | 'extension';\nexport type SortDirection = 'asc' | 'desc';\n\nexport interface SortConfig {\n\tfield: SortField;\n\tdirection: SortDirection;\n}\n\n/**\n * Sort file entries by the given config.\n * Directories always sort before files regardless of sort field.\n * Returns a new array (does not mutate the input).\n */\nexport function sortFileEntries(entries: FileEntry[], config: SortConfig): FileEntry[] {\n\tconst sorted = [...entries];\n\tconst dir = config.direction === 'asc' ? 1 : -1;\n\n\tsorted.sort((a, b) => {\n\t\t// Directories always come first\n\t\tif (a.is_dir && !b.is_dir) return -1;\n\t\tif (!a.is_dir && b.is_dir) return 1;\n\n\t\tswitch (config.field) {\n\t\t\tcase 'name':\n\t\t\t\treturn dir * a.name.localeCompare(b.name, undefined, { sensitivity: 'base' });\n\t\t\tcase 'size':\n\t\t\t\treturn dir * (a.size - b.size);\n\t\t\tcase 'modified':\n\t\t\t\treturn dir * (a.modified - b.modified);\n\t\t\tcase 'extension':\n\t\t\t\treturn dir * a.extension.localeCompare(b.extension, undefined, { sensitivity: 'base' });\n\t\t\tdefault:\n\t\t\t\treturn 0;\n\t\t}\n\t});\n\n\treturn sorted;\n}\n\n/**\n * Toggle sort config: same field flips direction, new field starts ascending.\n */\nexport function toggleSortField(current: SortConfig, field: SortField): SortConfig {\n\tif (current.field === field) {\n\t\treturn { field, direction: current.direction === 'asc' ? 'desc' : 'asc' };\n\t}\n\treturn { field, direction: 'asc' };\n}\n","/**\n * Direct WKB → GeoArrow bridge (zero-copy).\n *\n * Reads raw WKB binary directly into pre-allocated Arrow typed arrays\n * without any intermediate JS object allocation. No parseWKB(), no GeoJSON.\n *\n * Data flow: WKB Uint8Array[] → DataView binary reads → Float64Array/Int32Array\n * → arrow.makeData() → arrow.Table with ARROW:extension:name metadata\n */\n\nimport type { Data } from 'apache-arrow';\nimport {\n\tField,\n\tFixedSizeList,\n\tFloat64,\n\tList,\n\tmakeData,\n\tRecordBatch,\n\tSchema,\n\tStruct,\n\tTable,\n\tUtf8\n} from 'apache-arrow';\n\nexport type GeoArrowGeomType =\n\t| 'point'\n\t| 'linestring'\n\t| 'polygon'\n\t| 'multipoint'\n\t| 'multilinestring'\n\t| 'multipolygon';\n\nexport interface GeoArrowResult {\n\ttable: Table;\n\tgeometryType: GeoArrowGeomType;\n\tbounds: [number, number, number, number]; // [minX, minY, maxX, maxY]\n\t/** Maps local table row index → original WKB array index (for selection lookup). */\n\tsourceIndices: number[];\n}\n\n/** Map DuckDB ST_GeometryType output to our normalized type. */\nexport function normalizeGeomType(raw: string): GeoArrowGeomType {\n\tconst s = raw.toUpperCase().replace(/\\s+/g, '');\n\tif (s === 'POINT') return 'point';\n\tif (s === 'LINESTRING') return 'linestring';\n\tif (s === 'POLYGON') return 'polygon';\n\tif (s === 'MULTIPOINT') return 'multipoint';\n\tif (s === 'MULTILINESTRING') return 'multilinestring';\n\tif (s === 'MULTIPOLYGON') return 'multipolygon';\n\treturn 'polygon'; // fallback\n}\n\n/** GeoArrow extension name for each geometry type. */\nconst EXTENSION_NAMES: Record<GeoArrowGeomType, string> = {\n\tpoint: 'geoarrow.point',\n\tlinestring: 'geoarrow.linestring',\n\tpolygon: 'geoarrow.polygon',\n\tmultipoint: 'geoarrow.multipoint',\n\tmultilinestring: 'geoarrow.multilinestring',\n\tmultipolygon: 'geoarrow.multipolygon'\n};\n\n// ─── WKB binary header reader ────────────────────────────────────────\n\ninterface WkbHeader {\n\ttype: number; // base geometry type (1–6)\n\tle: boolean; // little-endian\n\tcoordStride: number; // bytes per coordinate point (16=2D, 24=3D/M, 32=ZM)\n\tdataOffset: number; // byte offset where geometry data begins\n}\n\n/** Read WKB/EWKB header — 5 bytes + optional SRID. No allocations. */\nfunction readWkbHeader(wkb: Uint8Array): WkbHeader | null {\n\tif (wkb.length < 5) return null;\n\tconst le = wkb[0] === 1;\n\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\tconst rawType = dv.getUint32(1, le);\n\n\tlet headerSize = 5; // byte_order(1) + type(4)\n\n\t// EWKB SRID flag — 4 extra bytes after type\n\tif ((rawType & 0x20000000) !== 0) headerSize += 4;\n\n\t// EWKB dimension flags\n\tconst ewkbZ = (rawType & 0x80000000) !== 0;\n\tconst ewkbM = (rawType & 0x40000000) !== 0;\n\n\t// Strip all EWKB flags to get base type\n\tlet type = rawType & 0x0fffffff;\n\n\t// ISO Z/M ranges: 1001–1006 (Z), 2001–2006 (M), 3001–3006 (ZM)\n\tlet isoZ = false;\n\tlet isoM = false;\n\tif (type > 3000) {\n\t\tisoZ = true;\n\t\tisoM = true;\n\t\ttype -= 3000;\n\t} else if (type > 2000) {\n\t\tisoM = true;\n\t\ttype -= 2000;\n\t} else if (type > 1000) {\n\t\tisoZ = true;\n\t\ttype -= 1000;\n\t}\n\n\tconst dims = (ewkbZ || isoZ ? 1 : 0) + (ewkbM || isoM ? 1 : 0);\n\tconst coordStride = (2 + dims) * 8; // 16, 24, or 32 bytes\n\n\treturn { type, le, coordStride, dataOffset: headerSize };\n}\n\n/** Classify WKB type from first 5 bytes. No full parse. */\nfunction classifyWkbType(wkb: Uint8Array): GeoArrowGeomType | null {\n\tconst h = readWkbHeader(wkb);\n\tif (!h) return null;\n\tswitch (h.type) {\n\t\tcase 1:\n\t\t\treturn 'point';\n\t\tcase 2:\n\t\t\treturn 'linestring';\n\t\tcase 3:\n\t\t\treturn 'polygon';\n\t\tcase 4:\n\t\t\treturn 'multipoint';\n\t\tcase 5:\n\t\t\treturn 'multilinestring';\n\t\tcase 6:\n\t\t\treturn 'multipolygon';\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\n// ─── Bounds tracking ─────────────────────────────────────────────────\n\ninterface BoundsTracker {\n\tminX: number;\n\tminY: number;\n\tmaxX: number;\n\tmaxY: number;\n}\n\nfunction newBounds(): BoundsTracker {\n\treturn { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };\n}\n\n/** Update bounds, skipping NaN coordinates (EMPTY geometries, invalid data). */\nfunction expandBounds(b: BoundsTracker, x: number, y: number) {\n\tif (Number.isNaN(x) || Number.isNaN(y)) return;\n\tif (x < b.minX) b.minX = x;\n\tif (y < b.minY) b.minY = y;\n\tif (x > b.maxX) b.maxX = x;\n\tif (y > b.maxY) b.maxY = y;\n}\n\n// ─── Arrow coordinate type (shared) ─────────────────────────────────\n\nconst coordField = new Field('xy', new Float64());\nconst coordType = new FixedSizeList(2, coordField);\n\n/** Build FixedSizeList<Float64> Data from a pre-allocated Float64Array. */\nfunction makeCoordData(coords: Float64Array, numPoints: number): Data<FixedSizeList> {\n\tconst floatData = makeData({ type: new Float64(), length: coords.length, data: coords });\n\treturn makeData({ type: coordType, length: numPoints, nullCount: 0, child: floatData });\n}\n\n// ─── Direct WKB → Arrow builders (zero intermediate objects) ─────────\n\n/**\n * POINT: [byte_order:1][type:4][x:8][y:8]\n * Direct read — 2 Float64 reads per geometry. Zero parseWKB.\n */\nfunction buildPointData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst coords = new Float64Array(n * 2);\n\n\tfor (let i = 0; i < n; i++) {\n\t\tconst wkb = wkbs[i];\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 1) {\n\t\t\tcoords[i * 2] = 0;\n\t\t\tcoords[i * 2 + 1] = 0;\n\t\t\tcontinue;\n\t\t}\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst x = dv.getFloat64(h.dataOffset, h.le);\n\t\tconst y = dv.getFloat64(h.dataOffset + 8, h.le);\n\t\tcoords[i * 2] = x;\n\t\tcoords[i * 2 + 1] = y;\n\t\texpandBounds(b, x, y);\n\t}\n\n\treturn makeCoordData(coords, n);\n}\n\n/**\n * LINESTRING: [byte_order:1][type:4][num_points:4][x:8,y:8 × n]\n * Two-pass: count first to pre-allocate, then extract.\n */\nfunction buildLineStringData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsets = new Int32Array(n + 1);\n\tlet totalCoords = 0;\n\n\t// Pass 1: count coordinates\n\tfor (let i = 0; i < n; i++) {\n\t\tgeomOffsets[i] = totalCoords;\n\t\tconst h = readWkbHeader(wkbs[i]);\n\t\tif (!h || h.type !== 2) continue;\n\t\tconst dv = new DataView(wkbs[i].buffer, wkbs[i].byteOffset, wkbs[i].byteLength);\n\t\tconst numPts = dv.getUint32(h.dataOffset, h.le);\n\t\ttotalCoords += numPts;\n\t}\n\tgeomOffsets[n] = totalCoords;\n\n\t// Pass 2: extract coordinates directly from binary\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 2) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPts = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\tconst x = dv.getFloat64(off, h.le);\n\t\t\tconst y = dv.getFloat64(off + 8, h.le);\n\t\t\tcoords[ci++] = x;\n\t\t\tcoords[ci++] = y;\n\t\t\texpandBounds(b, x, y);\n\t\t\toff += h.coordStride;\n\t\t}\n\t}\n\n\tconst fslData = makeCoordData(coords, totalCoords);\n\tconst listType = new List(new Field('vertices', coordType));\n\treturn makeData({\n\t\ttype: listType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: fslData\n\t});\n}\n\n/**\n * POLYGON: [byte_order:1][type:4][num_rings:4]\n * { [num_points:4][x:8,y:8 × n] } × rings\n * Two-pass: count rings+coords first, then extract.\n */\nfunction buildPolygonData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsets = new Int32Array(n + 1);\n\tlet totalRings = 0;\n\tlet totalCoords = 0;\n\n\t// Pass 1: count rings and coordinates\n\tfor (let i = 0; i < n; i++) {\n\t\tgeomOffsets[i] = totalRings;\n\t\tconst h = readWkbHeader(wkbs[i]);\n\t\tif (!h || h.type !== 3) continue;\n\t\tconst dv = new DataView(wkbs[i].buffer, wkbs[i].byteOffset, wkbs[i].byteLength);\n\t\tconst numRings = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\tconst numPts = dv.getUint32(off, h.le);\n\t\t\toff += 4 + numPts * h.coordStride;\n\t\t\ttotalCoords += numPts;\n\t\t\ttotalRings++;\n\t\t}\n\t}\n\tgeomOffsets[n] = totalRings;\n\n\t// Pass 2: extract coordinates and ring offsets\n\tconst ringOffsets = new Int32Array(totalRings + 1);\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet ri = 0;\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 3) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numRings = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\tringOffsets[ri++] = ci >> 1; // coordIndex = ci / 2\n\t\t\tconst numPts = dv.getUint32(off, h.le);\n\t\t\toff += 4;\n\t\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t\tconst x = dv.getFloat64(off, h.le);\n\t\t\t\tconst y = dv.getFloat64(off + 8, h.le);\n\t\t\t\tcoords[ci++] = x;\n\t\t\t\tcoords[ci++] = y;\n\t\t\t\texpandBounds(b, x, y);\n\t\t\t\toff += h.coordStride;\n\t\t\t}\n\t\t}\n\t}\n\tringOffsets[totalRings] = ci >> 1;\n\n\tconst coordCount = ci >> 1;\n\tconst fslData = makeCoordData(coords, coordCount);\n\n\tconst ringListType = new List(new Field('vertices', coordType));\n\tconst ringListData = makeData({\n\t\ttype: ringListType,\n\t\tlength: totalRings,\n\t\tnullCount: 0,\n\t\tvalueOffsets: ringOffsets,\n\t\tchild: fslData\n\t});\n\n\tconst polyType = new List(new Field('rings', ringListType));\n\treturn makeData({\n\t\ttype: polyType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: ringListData\n\t});\n}\n\n/** MultiPoint has same Arrow structure as LineString: List<FixedSizeList(2)>. */\nfunction buildMultiPointData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\t// MultiPoint WKB: [header][num_points:4]{Point WKB × n}\n\t// Each inner point has its own WKB header.\n\tconst n = wkbs.length;\n\tconst geomOffsets = new Int32Array(n + 1);\n\tlet totalCoords = 0;\n\n\t// Pass 1: count\n\tfor (let i = 0; i < n; i++) {\n\t\tgeomOffsets[i] = totalCoords;\n\t\tconst h = readWkbHeader(wkbs[i]);\n\t\tif (!h || h.type !== 4) continue;\n\t\tconst dv = new DataView(wkbs[i].buffer, wkbs[i].byteOffset, wkbs[i].byteLength);\n\t\ttotalCoords += dv.getUint32(h.dataOffset, h.le);\n\t}\n\tgeomOffsets[n] = totalCoords;\n\n\t// Pass 2: extract from inner point WKBs\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 4) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPts = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t// Each inner point is a full WKB: skip its header to get coords\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (innerH) {\n\t\t\t\tconst x = dv.getFloat64(off + innerH.dataOffset, innerH.le);\n\t\t\t\tconst y = dv.getFloat64(off + innerH.dataOffset + 8, innerH.le);\n\t\t\t\tcoords[ci++] = x;\n\t\t\t\tcoords[ci++] = y;\n\t\t\t\texpandBounds(b, x, y);\n\t\t\t\toff += innerH.dataOffset + innerH.coordStride;\n\t\t\t} else {\n\t\t\t\tcoords[ci++] = 0;\n\t\t\t\tcoords[ci++] = 0;\n\t\t\t\toff += 21; // minimum point WKB size\n\t\t\t}\n\t\t}\n\t}\n\n\tconst fslData = makeCoordData(coords, totalCoords);\n\tconst listType = new List(new Field('vertices', coordType));\n\treturn makeData({\n\t\ttype: listType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: fslData\n\t});\n}\n\n/**\n * MULTILINESTRING: [header][num_lines:4]{LineString WKB × n}\n * Each inner LineString has its own WKB header.\n */\nfunction buildMultiLineStringData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsetsArr: number[] = [0];\n\tlet totalLines = 0;\n\tlet totalCoords = 0;\n\n\t// Pass 1: count lines and coordinates\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 5) {\n\t\t\tgeomOffsetsArr.push(totalLines);\n\t\t\tcontinue;\n\t\t}\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numLines = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let l = 0; l < numLines; l++) {\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst innerDv = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off);\n\t\t\tconst numPts = innerDv.getUint32(innerH.dataOffset, innerH.le);\n\t\t\ttotalCoords += numPts;\n\t\t\toff += innerH.dataOffset + 4 + numPts * innerH.coordStride;\n\t\t\ttotalLines++;\n\t\t}\n\t\tgeomOffsetsArr.push(totalLines);\n\t}\n\n\t// Pass 2: extract\n\tconst geomOffsets = new Int32Array(geomOffsetsArr);\n\tconst lineOffsets = new Int32Array(totalLines + 1);\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet li = 0;\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 5) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numLines = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let l = 0; l < numLines; l++) {\n\t\t\tlineOffsets[li++] = ci >> 1;\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst numPts = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off).getUint32(\n\t\t\t\tinnerH.dataOffset,\n\t\t\t\tinnerH.le\n\t\t\t);\n\t\t\tlet ptOff = off + innerH.dataOffset + 4;\n\t\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t\tconst x = dv.getFloat64(ptOff, innerH.le);\n\t\t\t\tconst y = dv.getFloat64(ptOff + 8, innerH.le);\n\t\t\t\tcoords[ci++] = x;\n\t\t\t\tcoords[ci++] = y;\n\t\t\t\texpandBounds(b, x, y);\n\t\t\t\tptOff += innerH.coordStride;\n\t\t\t}\n\t\t\toff = ptOff;\n\t\t}\n\t}\n\tlineOffsets[totalLines] = ci >> 1;\n\n\tconst fslData = makeCoordData(coords, ci >> 1);\n\tconst lineListType = new List(new Field('vertices', coordType));\n\tconst lineListData = makeData({\n\t\ttype: lineListType,\n\t\tlength: totalLines,\n\t\tnullCount: 0,\n\t\tvalueOffsets: lineOffsets,\n\t\tchild: fslData\n\t});\n\n\tconst multiLineType = new List(new Field('lines', lineListType));\n\treturn makeData({\n\t\ttype: multiLineType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: lineListData\n\t});\n}\n\n/**\n * MULTIPOLYGON: [header][num_polys:4]{Polygon WKB × n}\n * Each inner Polygon has its own WKB header.\n */\nfunction buildMultiPolygonData(wkbs: Uint8Array[], b: BoundsTracker): Data {\n\tconst n = wkbs.length;\n\tconst geomOffsetsArr: number[] = [0];\n\tlet totalPolys = 0;\n\tlet totalRings = 0;\n\tlet totalCoords = 0;\n\n\t// Pass 1: count polygons, rings, coordinates\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 6) {\n\t\t\tgeomOffsetsArr.push(totalPolys);\n\t\t\tcontinue;\n\t\t}\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPolys = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let p = 0; p < numPolys; p++) {\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst innerDv = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off);\n\t\t\tconst numRings = innerDv.getUint32(innerH.dataOffset, innerH.le);\n\t\t\tlet ringOff = innerH.dataOffset + 4;\n\t\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\t\tconst numPts = innerDv.getUint32(ringOff, innerH.le);\n\t\t\t\tringOff += 4 + numPts * innerH.coordStride;\n\t\t\t\ttotalCoords += numPts;\n\t\t\t\ttotalRings++;\n\t\t\t}\n\t\t\toff += ringOff;\n\t\t\ttotalPolys++;\n\t\t}\n\t\tgeomOffsetsArr.push(totalPolys);\n\t}\n\n\t// Pass 2: extract\n\tconst geomOffsets = new Int32Array(geomOffsetsArr);\n\tconst polyOffsets = new Int32Array(totalPolys + 1);\n\tconst ringOffsets = new Int32Array(totalRings + 1);\n\tconst coords = new Float64Array(totalCoords * 2);\n\tlet pi = 0;\n\tlet ri = 0;\n\tlet ci = 0;\n\n\tfor (const wkb of wkbs) {\n\t\tconst h = readWkbHeader(wkb);\n\t\tif (!h || h.type !== 6) continue;\n\t\tconst dv = new DataView(wkb.buffer, wkb.byteOffset, wkb.byteLength);\n\t\tconst numPolys = dv.getUint32(h.dataOffset, h.le);\n\t\tlet off = h.dataOffset + 4;\n\t\tfor (let p = 0; p < numPolys; p++) {\n\t\t\tpolyOffsets[pi++] = ri;\n\t\t\tconst innerH = readWkbHeader(\n\t\t\t\tnew Uint8Array(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off)\n\t\t\t);\n\t\t\tif (!innerH) break;\n\t\t\tconst innerDv = new DataView(wkb.buffer, wkb.byteOffset + off, wkb.byteLength - off);\n\t\t\tconst numRings = innerDv.getUint32(innerH.dataOffset, innerH.le);\n\t\t\tlet ringOff = off + innerH.dataOffset + 4;\n\t\t\tfor (let r = 0; r < numRings; r++) {\n\t\t\t\tringOffsets[ri++] = ci >> 1;\n\t\t\t\tconst numPts = dv.getUint32(ringOff, innerH.le);\n\t\t\t\tringOff += 4;\n\t\t\t\tfor (let j = 0; j < numPts; j++) {\n\t\t\t\t\tconst x = dv.getFloat64(ringOff, innerH.le);\n\t\t\t\t\tconst y = dv.getFloat64(ringOff + 8, innerH.le);\n\t\t\t\t\tcoords[ci++] = x;\n\t\t\t\t\tcoords[ci++] = y;\n\t\t\t\t\texpandBounds(b, x, y);\n\t\t\t\t\tringOff += innerH.coordStride;\n\t\t\t\t}\n\t\t\t}\n\t\t\toff = ringOff;\n\t\t}\n\t}\n\tpolyOffsets[totalPolys] = ri;\n\tringOffsets[totalRings] = ci >> 1;\n\n\tconst fslData = makeCoordData(coords, ci >> 1);\n\n\tconst ringListType = new List(new Field('vertices', coordType));\n\tconst ringListData = makeData({\n\t\ttype: ringListType,\n\t\tlength: totalRings,\n\t\tnullCount: 0,\n\t\tvalueOffsets: ringOffsets,\n\t\tchild: fslData\n\t});\n\n\tconst polyListType = new List(new Field('rings', ringListType));\n\tconst polyListData = makeData({\n\t\ttype: polyListType,\n\t\tlength: totalPolys,\n\t\tnullCount: 0,\n\t\tvalueOffsets: polyOffsets,\n\t\tchild: ringListData\n\t});\n\n\tconst multiPolyType = new List(new Field('polygons', polyListType));\n\treturn makeData({\n\t\ttype: multiPolyType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tvalueOffsets: geomOffsets,\n\t\tchild: polyListData\n\t});\n}\n\n// ─── Build a single GeoArrow table for one type group ────────────────\n\n/** Build attribute columns for a subset of rows identified by indices. */\nfunction buildAttributeColumns(\n\tindices: number[],\n\tattributes: Map<string, { values: any[]; type: string }>\n): { fields: Field[]; data: Data[] } {\n\tconst n = indices.length;\n\tconst fields: Field[] = [];\n\tconst dataArr: Data[] = [];\n\n\tfor (const [name, col] of attributes) {\n\t\tconst { values } = col;\n\n\t\t// Detect whether values are numeric or string\n\t\tlet isNumeric = true;\n\t\tconst sampleEnd = Math.min(n, 100);\n\t\tfor (let i = 0; i < sampleEnd; i++) {\n\t\t\tif (values[indices[i]] != null && typeof values[indices[i]] !== 'number') {\n\t\t\t\tisNumeric = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (isNumeric) {\n\t\t\tconst arr = new Float64Array(n);\n\t\t\tfor (let i = 0; i < n; i++) arr[i] = values[indices[i]] ?? NaN;\n\t\t\tconst data = makeData({ type: new Float64(), length: n, data: arr });\n\t\t\tfields.push(new Field(name, new Float64(), true));\n\t\t\tdataArr.push(data);\n\t\t} else {\n\t\t\tconst encoder = new TextEncoder();\n\t\t\tconst offsets = new Int32Array(n + 1);\n\t\t\tlet totalBytes = 0;\n\n\t\t\t// Single pass: encode directly into a growing buffer\n\t\t\tconst strParts: Uint8Array[] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\toffsets[i] = totalBytes;\n\t\t\t\tconst s = values[indices[i]] != null ? String(values[indices[i]]) : '';\n\t\t\t\tconst encoded = encoder.encode(s);\n\t\t\t\tstrParts.push(encoded);\n\t\t\t\ttotalBytes += encoded.length;\n\t\t\t}\n\t\t\toffsets[n] = totalBytes;\n\n\t\t\tconst valueBuffer = new Uint8Array(totalBytes);\n\t\t\tlet pos = 0;\n\t\t\tfor (const sv of strParts) {\n\t\t\t\tvalueBuffer.set(sv, pos);\n\t\t\t\tpos += sv.length;\n\t\t\t}\n\n\t\t\tconst data = makeData({\n\t\t\t\ttype: new Utf8(),\n\t\t\t\tlength: n,\n\t\t\t\tvalueOffsets: offsets,\n\t\t\t\tdata: valueBuffer\n\t\t\t});\n\t\t\tfields.push(new Field(name, new Utf8(), true));\n\t\t\tdataArr.push(data);\n\t\t}\n\t}\n\n\treturn { fields, data: dataArr };\n}\n\n/** Build a single GeoArrow table for one geometry type group. */\nfunction buildSingleTable(\n\tgeomType: GeoArrowGeomType,\n\twkbs: Uint8Array[],\n\tindices: number[],\n\tattributes: Map<string, { values: any[]; type: string }>,\n\tb: BoundsTracker\n): GeoArrowResult {\n\tconst n = wkbs.length;\n\n\tlet geomData: Data;\n\tswitch (geomType) {\n\t\tcase 'point':\n\t\t\tgeomData = buildPointData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'linestring':\n\t\t\tgeomData = buildLineStringData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'polygon':\n\t\t\tgeomData = buildPolygonData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'multipoint':\n\t\t\tgeomData = buildMultiPointData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'multilinestring':\n\t\t\tgeomData = buildMultiLineStringData(wkbs, b);\n\t\t\tbreak;\n\t\tcase 'multipolygon':\n\t\t\tgeomData = buildMultiPolygonData(wkbs, b);\n\t\t\tbreak;\n\t}\n\n\tconst extensionName = EXTENSION_NAMES[geomType];\n\tconst geomMetadata = new Map<string, string>([\n\t\t['ARROW:extension:name', extensionName],\n\t\t[\n\t\t\t'ARROW:extension:metadata',\n\t\t\tJSON.stringify({\n\t\t\t\tcrs: {\n\t\t\t\t\ttype: 'name',\n\t\t\t\t\tproperties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }\n\t\t\t\t}\n\t\t\t})\n\t\t]\n\t]);\n\n\tconst geomField = new Field('geometry', geomData.type, false, geomMetadata);\n\tconst attrCols = buildAttributeColumns(indices, attributes);\n\n\tconst fields: Field[] = [geomField, ...attrCols.fields];\n\tconst childrenData: Data[] = [geomData, ...attrCols.data];\n\n\tconst arrowSchema = new Schema(fields);\n\tconst structType = new Struct(fields);\n\tconst structData = makeData({\n\t\ttype: structType,\n\t\tlength: n,\n\t\tnullCount: 0,\n\t\tchildren: childrenData\n\t});\n\tconst batch = new RecordBatch(arrowSchema, structData);\n\tconst table = new Table(arrowSchema, batch);\n\n\treturn {\n\t\ttable,\n\t\tgeometryType: geomType,\n\t\tbounds: [b.minX, b.minY, b.maxX, b.maxY],\n\t\tsourceIndices: indices\n\t};\n}\n\n// ─── Main entry point ────────────────────────────────────────────────\n\n/**\n * Build GeoArrow tables from raw WKB arrays, automatically splitting by geometry type.\n * Returns one GeoArrowResult per non-empty type group, with shared merged bounds.\n *\n * @param wkbArrays Raw WKB binary arrays from DuckDB\n * @param attributes Attribute columns (non-geometry)\n * @param knownGeomType If provided (e.g. from GeoParquet metadata), skip classification\n */\nexport function buildGeoArrowTables(\n\twkbArrays: Uint8Array[],\n\tattributes: Map<string, { values: any[]; type: string }>,\n\tknownGeomType?: GeoArrowGeomType\n): GeoArrowResult[] {\n\tif (wkbArrays.length === 0) return [];\n\n\t// Fast path: known geometry type from metadata — skip classification entirely\n\tif (knownGeomType) {\n\t\tconst globalBounds = newBounds();\n\t\tconst indices = Array.from({ length: wkbArrays.length }, (_, i) => i);\n\t\tconst result = buildSingleTable(knownGeomType, wkbArrays, indices, attributes, globalBounds);\n\t\treturn [result];\n\t}\n\n\t// Classify by reading only the type bytes (5 bytes per WKB, not full parse)\n\tconst groups = new Map<GeoArrowGeomType, { wkbs: Uint8Array[]; indices: number[] }>();\n\n\tfor (let i = 0; i < wkbArrays.length; i++) {\n\t\tconst geomType = classifyWkbType(wkbArrays[i]);\n\t\tif (!geomType) continue;\n\n\t\tlet group = groups.get(geomType);\n\t\tif (!group) {\n\t\t\tgroup = { wkbs: [], indices: [] };\n\t\t\tgroups.set(geomType, group);\n\t\t}\n\t\tgroup.wkbs.push(wkbArrays[i]);\n\t\tgroup.indices.push(i);\n\t}\n\n\tif (groups.size === 0) return [];\n\n\tconst globalBounds = newBounds();\n\tconst results: GeoArrowResult[] = [];\n\n\tfor (const [geomType, { wkbs, indices }] of groups) {\n\t\tconst result = buildSingleTable(geomType, wkbs, indices, attributes, globalBounds);\n\t\tresults.push(result);\n\t}\n\n\t// Share merged bounds across all results\n\tconst mergedBounds: [number, number, number, number] = [\n\t\tglobalBounds.minX,\n\t\tglobalBounds.minY,\n\t\tglobalBounds.maxX,\n\t\tglobalBounds.maxY\n\t];\n\tfor (const r of results) r.bounds = mergedBounds;\n\n\treturn results;\n}\n","/**\n * Helpers for parsing DuckDB v1.5 parameterized GEOMETRY type strings.\n *\n * DuckDB v1.5 made GEOMETRY a core type with an optional CRS parameter:\n * GEOMETRY — no CRS attached\n * GEOMETRY('EPSG:4326') — EPSG form\n * GEOMETRY('OGC:CRS84') — OGC form (canonical for GeoParquet 1.1+)\n * GEOMETRY('EPSG:27700') — projected CRS\n *\n * Type strings may come from `DESCRIBE`, from the Arrow schema, or from a\n * legacy code path that still reports `BLOB`. Use these helpers everywhere\n * instead of ad-hoc regex so behaviour stays consistent.\n */\n\nimport { WGS84_CODES } from '../../../src/lib/constants.js';\n\nexport interface GeometryTypeInfo {\n\t/** True if the type is some form of GEOMETRY (with or without CRS). */\n\tisGeometry: boolean;\n\t/** True if the type carries a CRS parameter, e.g. GEOMETRY('EPSG:4326'). */\n\thasCrs: boolean;\n\t/** The CRS string if present, otherwise null. Raw value, including WGS84. */\n\trawCrs: string | null;\n\t/**\n\t * The CRS string if present and NOT a WGS84 variant (EPSG:4326, EPSG:4979,\n\t * OGC:CRS84). Returns null for WGS84 so callers can skip ST_Transform.\n\t */\n\tnonWgs84Crs: string | null;\n}\n\nconst GEOMETRY_PREFIX = /^GEOMETRY(\\s*\\(\\s*'?([^')]+)'?\\s*\\))?/i;\n\n/**\n * Parse a DuckDB type string and report whether it is a GEOMETRY type, and\n * whether a CRS parameter is attached.\n */\nexport function parseGeometryTypeCrs(typeStr: string | null | undefined): GeometryTypeInfo {\n\tif (!typeStr) return { isGeometry: false, hasCrs: false, rawCrs: null, nonWgs84Crs: null };\n\tconst match = typeStr.match(GEOMETRY_PREFIX);\n\tif (!match) return { isGeometry: false, hasCrs: false, rawCrs: null, nonWgs84Crs: null };\n\tconst rawCrs = match[2]?.trim() ?? null;\n\tif (!rawCrs) return { isGeometry: true, hasCrs: false, rawCrs: null, nonWgs84Crs: null };\n\treturn {\n\t\tisGeometry: true,\n\t\thasCrs: true,\n\t\trawCrs,\n\t\tnonWgs84Crs: isWgs84Crs(rawCrs) ? null : rawCrs\n\t};\n}\n\n/** True for EPSG:4326, EPSG:4979, OGC:CRS84 and equivalent strings. */\nexport function isWgs84Crs(crs: string | null | undefined): boolean {\n\tif (!crs) return true;\n\tconst trimmed = crs.trim();\n\tif (trimmed === 'OGC:CRS84' || trimmed === 'OGC:CRS83') return true;\n\tconst epsgMatch = trimmed.match(/^EPSG:(\\d+)$/i);\n\tif (epsgMatch && WGS84_CODES.has(Number(epsgMatch[1]))) return true;\n\treturn false;\n}\n\n/**\n * Build a `ST_Transform(...)` SQL expression choosing the 2-arg form when the\n * input already carries its CRS in the GEOMETRY type (DuckDB v1.5), and the\n * 3-arg form otherwise.\n *\n * `geometry_always_xy` is set globally at DB init, so no per-call `always_xy`\n * argument is needed.\n */\nexport function buildTransformExpr(\n\tinnerExpr: string,\n\tsourceType: string,\n\tsourceCrs: string,\n\ttargetCrs: string\n): string {\n\tconst info = parseGeometryTypeCrs(sourceType);\n\tif (info.hasCrs) {\n\t\treturn `ST_Transform(${innerExpr}, '${targetCrs}')`;\n\t}\n\treturn `ST_Transform(${innerExpr}, '${sourceCrs}', '${targetCrs}')`;\n}\n\n/**\n * Wrap a bare WKB expression with `ST_SetCRS(ST_GeomFromWKB(...))` so that the\n * resulting GEOMETRY value carries a CRS through the rest of the pipeline.\n * Used in the legacy GeoParquet fallback where we read the geometry column as\n * BLOB but still know the source CRS from hyparquet metadata or the GeoParquet\n * footer.\n *\n * If `sourceCrs` is null/empty, returns a plain `ST_GeomFromWKB(...)`.\n */\nexport function wrapWkbWithCrs(wkbExpr: string, sourceCrs: string | null | undefined): string {\n\tif (!sourceCrs) return `ST_GeomFromWKB(${wkbExpr})`;\n\treturn `ST_SetCRS(ST_GeomFromWKB(${wkbExpr}), '${sourceCrs}')`;\n}\n","export interface HexRow {\n\toffset: string;\n\thex: string[];\n\tascii: string;\n}\n\n/**\n * Generates a hex dump from binary data.\n * Returns rows of offset | hex bytes | ASCII representation.\n */\nexport function generateHexDump(data: Uint8Array, bytesPerRow = 16): HexRow[] {\n\tconst rows: HexRow[] = [];\n\n\tfor (let i = 0; i < data.length; i += bytesPerRow) {\n\t\tconst slice = data.slice(i, i + bytesPerRow);\n\t\tconst offset = i.toString(16).padStart(8, '0');\n\n\t\tconst hex: string[] = [];\n\t\tfor (let j = 0; j < bytesPerRow; j++) {\n\t\t\tif (j < slice.length) {\n\t\t\t\thex.push(slice[j].toString(16).padStart(2, '0'));\n\t\t\t} else {\n\t\t\t\thex.push(' ');\n\t\t\t}\n\t\t}\n\n\t\tlet ascii = '';\n\t\tfor (let j = 0; j < slice.length; j++) {\n\t\t\tconst byte = slice[j];\n\t\t\tascii += byte >= 0x20 && byte <= 0x7e ? String.fromCharCode(byte) : '.';\n\t\t}\n\n\t\trows.push({ offset, hex, ascii });\n\t}\n\n\treturn rows;\n}\n","/**\n * STAC Storage Extension parser.\n *\n * Detects the Storage Extension version on a STAC Item and extracts\n * connection-relevant hints (region, requester-pays, custom-S3 endpoint).\n *\n * Inspired by lazycogs's `_storage_ext.py`. Pure TypeScript, no fetch, no\n * Svelte dependency. Suitable for `@walkthru-earth/objex-utils` re-export.\n *\n * Supported schema URLs:\n * - https://stac-extensions.github.io/storage/v1.0.0/schema.json\n * - https://stac-extensions.github.io/storage/v2.0.0/schema.json\n *\n * v1 (item / asset properties)\n * storage:platform e.g. \"AWS\", \"GCP\", \"AZURE\"\n * storage:region\n * storage:requester_pays boolean\n * storage:tier (ignored — no obstore equivalent)\n *\n * v2 (item-level scheme map + asset-level refs)\n * properties.storage:schemes = {\n * <ref>: { type, platform, region?, requester_pays?, endpoint? }\n * }\n * asset.storage:refs = [\"primary\", ...] (first matching ref wins)\n *\n * Asset-level fields take precedence over item-level fields in v1.\n */\n\nimport type { StacItem } from './stac.js';\n\n/** Recognized Storage Extension schema versions. */\nexport type StorageExtensionVersion = '1.0.0' | '2.0.0';\n\n/**\n * Connection-relevant hints extracted from the Storage Extension. All fields\n * are nullable so callers can merge selectively into existing config without\n * clobbering user-set values.\n */\nexport interface StorageHints {\n\t/** e.g. \"AWS\", \"GCP\", \"AZURE\", \"MINIO\". Uppercased. Null when absent. */\n\tplatform: string | null;\n\t/** Region code, e.g. \"us-west-2\". Null when absent. */\n\tregion: string | null;\n\t/** True when requester-pays must be set. False when absent or false. */\n\trequesterPays: boolean;\n\t/** Concrete S3-compatible endpoint URL. Null unless v2 `custom-s3` with\n\t * a non-templated `platform` value. */\n\tendpoint: string | null;\n}\n\n/** Empty hints record. Returned when extension absent or unparseable. */\nexport function emptyStorageHints(): StorageHints {\n\treturn { platform: null, region: null, requesterPays: false, endpoint: null };\n}\n\n/**\n * Scan `item.stac_extensions[]` for the Storage Extension schema URL and\n * return its parsed version. Returns null when the extension is absent or\n * the version is not one we recognize.\n */\nexport function detectStorageExtensionVersion(item: StacItem): StorageExtensionVersion | null {\n\tconst exts = (item as unknown as { stac_extensions?: unknown }).stac_extensions;\n\tif (!Array.isArray(exts)) return null;\n\tfor (const raw of exts) {\n\t\tif (typeof raw !== 'string') continue;\n\t\tif (!raw.includes('stac-extensions.github.io/storage')) continue;\n\t\tconst trimmed = raw.endsWith('/schema.json') ? raw.slice(0, -'/schema.json'.length) : raw;\n\t\tconst last = trimmed.slice(trimmed.lastIndexOf('/') + 1);\n\t\tconst version = last.startsWith('v') ? last.slice(1) : last;\n\t\tif (version === '1.0.0' || version === '2.0.0') return version;\n\t\t// Unknown patch / minor — fall back to major-version detection so a\n\t\t// hypothetical v1.0.1 still gets parsed via the v1 path.\n\t\tconst major = version.split('.')[0];\n\t\tif (major === '1') return '1.0.0';\n\t\tif (major === '2') return '2.0.0';\n\t}\n\treturn null;\n}\n\n/**\n * Extract connection hints from a STAC Item. Dispatches on the detected\n * Storage Extension version. Returns `emptyStorageHints()` when the\n * extension is absent or fails to parse.\n *\n * `assetKey` is optional. When given:\n * - v1: that asset's overrides take precedence over item-level fields.\n * - v2: that asset's `storage:refs[0]` resolves the item scheme.\n * When omitted in v2, the first scheme found in any asset's refs wins.\n */\nexport function extractStorageHints(item: StacItem, assetKey?: string): StorageHints {\n\tconst version = detectStorageExtensionVersion(item);\n\tif (version === '1.0.0') return extractV1Hints(item, assetKey);\n\tif (version === '2.0.0') return extractV2Hints(item, assetKey);\n\treturn emptyStorageHints();\n}\n\n// --- v1 -------------------------------------------------------------------\n\nfunction extractV1Hints(item: StacItem, assetKey?: string): StorageHints {\n\tconst props = (item.properties ?? {}) as Record<string, unknown>;\n\tconst asset =\n\t\tassetKey && item.assets && (item.assets as Record<string, unknown>)[assetKey]\n\t\t\t? ((item.assets as Record<string, unknown>)[assetKey] as Record<string, unknown>)\n\t\t\t: null;\n\n\tconst platformRaw = pickFirstString([asset?.['storage:platform'], props['storage:platform']]);\n\tconst region = pickFirstString([asset?.['storage:region'], props['storage:region']]);\n\tconst requesterPays = pickFirstBoolean([\n\t\tasset?.['storage:requester_pays'],\n\t\tprops['storage:requester_pays']\n\t]);\n\n\treturn {\n\t\tplatform: platformRaw ? platformRaw.toUpperCase() : null,\n\t\tregion: region ?? null,\n\t\trequesterPays: requesterPays === true,\n\t\tendpoint: null\n\t};\n}\n\n// --- v2 -------------------------------------------------------------------\n\ninterface V2Scheme {\n\ttype?: string;\n\tplatform?: string;\n\tregion?: string;\n\trequester_pays?: boolean;\n\tendpoint?: string;\n}\n\nfunction extractV2Hints(item: StacItem, assetKey?: string): StorageHints {\n\tconst props = (item.properties ?? {}) as Record<string, unknown>;\n\tconst schemes = (props['storage:schemes'] ?? {}) as Record<string, V2Scheme>;\n\tif (!schemes || typeof schemes !== 'object') return emptyStorageHints();\n\n\tconst refs = collectAssetRefs(item, assetKey);\n\tconst scheme = pickFirstScheme(schemes, refs);\n\tif (!scheme) return emptyStorageHints();\n\n\tconst storeType = typeof scheme.type === 'string' ? scheme.type : '';\n\tconst platform = typeof scheme.platform === 'string' ? scheme.platform : null;\n\tconst region = typeof scheme.region === 'string' ? scheme.region : null;\n\tconst requesterPays = scheme.requester_pays === true;\n\n\tlet endpoint: string | null = null;\n\tif (storeType === 'custom-s3') {\n\t\t// Only treat `platform` as a concrete endpoint when it has no URI\n\t\t// template variables (e.g. `{region}`).\n\t\tif (typeof scheme.endpoint === 'string' && scheme.endpoint && !scheme.endpoint.includes('{')) {\n\t\t\tendpoint = scheme.endpoint;\n\t\t} else if (platform && !platform.includes('{')) {\n\t\t\tendpoint = platform;\n\t\t}\n\t}\n\n\treturn {\n\t\tplatform: platform ? platform.toUpperCase() : null,\n\t\tregion,\n\t\trequesterPays,\n\t\tendpoint\n\t};\n}\n\nfunction collectAssetRefs(item: StacItem, assetKey?: string): string[] {\n\tconst assets = (item.assets ?? {}) as Record<string, unknown>;\n\tif (assetKey) {\n\t\tconst a = assets[assetKey] as Record<string, unknown> | undefined;\n\t\tconst refs = a?.['storage:refs'];\n\t\tif (Array.isArray(refs)) return refs.filter((r): r is string => typeof r === 'string');\n\t\treturn [];\n\t}\n\tconst out: string[] = [];\n\tfor (const a of Object.values(assets)) {\n\t\tif (!a || typeof a !== 'object') continue;\n\t\tconst refs = (a as Record<string, unknown>)['storage:refs'];\n\t\tif (!Array.isArray(refs)) continue;\n\t\tfor (const r of refs) if (typeof r === 'string') out.push(r);\n\t}\n\treturn out;\n}\n\nfunction pickFirstScheme(schemes: Record<string, V2Scheme>, refs: string[]): V2Scheme | null {\n\tfor (const r of refs) {\n\t\tconst s = schemes[r];\n\t\tif (s && typeof s === 'object') return s;\n\t}\n\treturn null;\n}\n\n// --- helpers --------------------------------------------------------------\n\nfunction pickFirstString(candidates: unknown[]): string | null {\n\tfor (const c of candidates) {\n\t\tif (typeof c === 'string' && c.length > 0) return c;\n\t}\n\treturn null;\n}\n\nfunction pickFirstBoolean(candidates: unknown[]): boolean | null {\n\tfor (const c of candidates) {\n\t\tif (typeof c === 'boolean') return c;\n\t}\n\treturn null;\n}\n\n// --- connection wiring ----------------------------------------------------\n\n/**\n * TODO(host-detection): a future PR should call this from the connection\n * auto-fill path so a STAC Item carrying Storage Extension metadata can\n * pre-populate `region` and (for `custom-s3`) `endpoint` on a new\n * connection.\n *\n * Today this lives next to the parser so consumers can opt-in without\n * touching `host-detection.ts` or the connection store. The function is\n * intentionally generic — it takes any object with `region` / `endpoint`\n * keys and returns a shallow copy with hint fields filled only when the\n * existing value is empty.\n */\nexport function applyStorageHintsToConnection<T extends { region?: string; endpoint?: string }>(\n\tconn: T,\n\thints: StorageHints\n): T {\n\tconst out: T = { ...conn };\n\tif (hints.region && !out.region) {\n\t\t(out as { region?: string }).region = hints.region;\n\t}\n\tif (hints.endpoint && !out.endpoint) {\n\t\t(out as { endpoint?: string }).endpoint = hints.endpoint;\n\t}\n\treturn out;\n}\n","/**\n * Universal cloud storage URL / bucket parser.\n *\n * Accepts the many URI/URL formats that users commonly paste and extracts\n * the correct bucket, region, endpoint, and provider.\n *\n * Supported URI schemes:\n * s3:// s3a:// s3n:// aws:// — Amazon S3 / S3-compatible\n * r2:// — Cloudflare R2\n * gs:// gcs:// — Google Cloud Storage\n * azure:// az:// — Azure Blob Storage\n * abfs:// abfss:// — Azure Data Lake (ADLS Gen2)\n * wasbs:// — Azure Blob (Hadoop WASB driver)\n * swift:// — OpenStack Swift\n * file:// filesystem:// — Local filesystem\n *\n * Supported HTTPS URL patterns:\n * https://<bucket>.s3.<region>.amazonaws.com[/prefix] — AWS virtual-hosted\n * https://s3.<region>.amazonaws.com/<bucket>[/prefix] — AWS path-style\n * https://s3.amazonaws.com/<bucket> — AWS global\n * https://<account>.r2.cloudflarestorage.com/<bucket> — Cloudflare R2\n * https://storage.googleapis.com/<bucket> — Google Cloud Storage\n * https://<bucket>.storage.googleapis.com[/prefix] — GCS virtual-hosted\n * https://<bucket>.<region>.digitaloceanspaces.com — DigitalOcean Spaces\n * https://<region>.digitaloceanspaces.com/<bucket> — DO Spaces path-style\n * https://s3.<region>.wasabisys.com/<bucket> — Wasabi\n * https://f<id>.backblazeb2.com/file/<bucket> — Backblaze B2\n * https://<bucket>.s3.<region>.backblazeb2.com — B2 S3-compatible\n * https://<bucket>.oss-<region>.aliyuncs.com — Alibaba Cloud OSS\n * https://<bucket>.cos.<region>.myqcloud.com — Tencent COS\n * https://storage.yandexcloud.net/<bucket> — Yandex Cloud\n * https://gateway.storjshare.io/<bucket> — Storj S3 gateway\n * https://link.storjshare.io/raw/<access>/<bucket> — Storj linksharing\n * https://<custom-endpoint>/<bucket> — Generic S3-compatible\n *\n * Also handles plain bucket names (no protocol).\n */\n\nimport { PROVIDERS } from '../../../src/lib/storage/providers.js';\n\nexport type StorageProvider = string;\n\nexport interface ParsedStorageUrl {\n\tbucket: string;\n\tregion: string;\n\tendpoint: string;\n\tprovider: StorageProvider;\n\t/** Original prefix/path after bucket, if any */\n\tprefix: string;\n}\n\n/**\n * Build SCHEME_MAP from the provider registry's `schemes` arrays.\n * Each scheme like \"s3\" generates an entry `\"s3://\": { provider: \"s3\", strip: 5 }`.\n */\nfunction buildSchemeMap(): Record<string, { provider: StorageProvider; strip: number }> {\n\tconst map: Record<string, { provider: StorageProvider; strip: number }> = {};\n\tfor (const [id, def] of Object.entries(PROVIDERS)) {\n\t\tfor (const scheme of def.schemes) {\n\t\t\tconst key = `${scheme}://`;\n\t\t\tmap[key] = { provider: id, strip: key.length };\n\t\t}\n\t}\n\t// Non-registry schemes (no corresponding provider)\n\tmap['swift://'] = { provider: 'unknown', strip: 8 };\n\treturn map;\n}\n\n/** All recognized URI scheme prefixes (lowercase), derived from provider registry */\nconst SCHEME_MAP = buildSchemeMap();\n\nconst SLASH = 47; // '/'.charCodeAt(0)\n\n/** Strip trailing '/' linearly (avoids the polynomial backtracking of `/\\/+$/`). */\nfunction stripTrailingSlashes(s: string): string {\n\tlet end = s.length;\n\twhile (end > 0 && s.charCodeAt(end - 1) === SLASH) end--;\n\treturn s.slice(0, end);\n}\n\n/** Strip leading and trailing '/' linearly (avoids `/^\\/+|\\/+$/g` backtracking). */\nfunction stripEdgeSlashes(s: string): string {\n\tlet start = 0;\n\tlet end = s.length;\n\twhile (start < end && s.charCodeAt(start) === SLASH) start++;\n\twhile (end > start && s.charCodeAt(end - 1) === SLASH) end--;\n\treturn s.slice(start, end);\n}\n\n/**\n * Shared host matchers. Used by both `parseStorageUrl` and `isKnownBucketHost`\n * so provider recognition has a single source of truth.\n */\nconst AWS_VHOST_RE = /^(.+)\\.s3[.-]([a-z0-9-]+)\\.amazonaws\\.com$/;\nconst AWS_PATH_RE = /^s3[.-]([a-z0-9-]+)\\.amazonaws\\.com$/;\nconst AWS_GLOBAL_HOST = 's3.amazonaws.com';\nconst R2_RE = /^([a-z0-9]+)\\.r2\\.cloudflarestorage\\.com$/;\nconst GCS_GLOBAL_HOST = 'storage.googleapis.com';\nconst GCS_VHOST_RE = /^(.+)\\.storage\\.googleapis\\.com$/;\nconst DO_VHOST_RE = /^(.+)\\.([a-z0-9-]+)\\.digitaloceanspaces\\.com$/;\nconst DO_PATH_RE = /^([a-z0-9-]+)\\.digitaloceanspaces\\.com$/;\nconst WASABI_RE = /^s3\\.([a-z0-9-]+)\\.wasabisys\\.com$/;\nconst B2_S3_RE = /^(.+)\\.s3\\.([a-z0-9-]+)\\.backblazeb2\\.com$/;\nconst B2_NATIVE_RE = /^f[a-z0-9]+\\.backblazeb2\\.com$/;\nconst OSS_RE = /^(.+)\\.(oss-[a-z0-9-]+)\\.aliyuncs\\.com$/;\nconst COS_RE = /^(.+)\\.cos\\.([a-z0-9-]+)\\.myqcloud\\.com$/;\nconst YANDEX_HOST = 'storage.yandexcloud.net';\nconst CONTABO_RE = /^([a-z0-9]+)\\.contabostorage\\.com$/;\nconst HETZNER_RE = /^([a-z0-9]+)\\.your-objectstorage\\.com$/;\nconst LINODE_VHOST_RE = /^(.+)\\.([a-z0-9-]+)\\.linodeobjects\\.com$/;\nconst LINODE_PATH_RE = /^([a-z0-9-]+)\\.linodeobjects\\.com$/;\nconst OVH_RE = /^s3\\.([a-z0-9-]+)\\.io\\.cloud\\.ovh\\.(?:net|us)$/;\nconst AZURE_BLOB_RE = /^([a-z0-9]+)\\.blob\\.core\\.windows\\.net$/;\nconst STORJ_GATEWAY_RE = /^gateway\\.(?:([a-z0-9]+)\\.)?storjshare\\.io$/;\nconst STORJ_LINK_RE = /^link\\.(?:([a-z0-9]+)\\.)?storjshare\\.io$/;\n\nfunction isMinioLikeHost(host: string): boolean {\n\treturn (\n\t\thost.includes('minio') ||\n\t\thost === 'localhost' ||\n\t\thost === '127.0.0.1' ||\n\t\thost.startsWith('192.168.') ||\n\t\thost.startsWith('10.')\n\t);\n}\n\n/** STAC API path test, one source of truth. Tests pathname only. */\nexport const STAC_API_PATH_RE = /\\/(collections|items|catalogs|search)(\\/|\\?|$)/i;\n\n/**\n * Returns true when the host matches any of the provider host patterns\n * that `parseStorageUrl` recognizes on the HTTPS branch.\n */\nexport function isKnownBucketHost(host: string): boolean {\n\tif (!host) return false;\n\tif (AWS_VHOST_RE.test(host)) return true;\n\tif (AWS_PATH_RE.test(host)) return true;\n\tif (host === AWS_GLOBAL_HOST) return true;\n\tif (R2_RE.test(host)) return true;\n\tif (host === GCS_GLOBAL_HOST) return true;\n\tif (GCS_VHOST_RE.test(host)) return true;\n\tif (DO_VHOST_RE.test(host)) return true;\n\tif (DO_PATH_RE.test(host)) return true;\n\tif (WASABI_RE.test(host)) return true;\n\tif (B2_S3_RE.test(host)) return true;\n\tif (B2_NATIVE_RE.test(host)) return true;\n\tif (OSS_RE.test(host)) return true;\n\tif (COS_RE.test(host)) return true;\n\tif (host === YANDEX_HOST) return true;\n\tif (CONTABO_RE.test(host)) return true;\n\tif (HETZNER_RE.test(host)) return true;\n\tif (LINODE_VHOST_RE.test(host)) return true;\n\tif (LINODE_PATH_RE.test(host)) return true;\n\tif (OVH_RE.test(host)) return true;\n\tif (AZURE_BLOB_RE.test(host)) return true;\n\tif (STORJ_GATEWAY_RE.test(host)) return true;\n\tif (STORJ_LINK_RE.test(host)) return true;\n\tif (isMinioLikeHost(host)) return true;\n\treturn false;\n}\n\nexport interface Defaults {\n\tregion?: string;\n\tendpoint?: string;\n\tprovider?: StorageProvider;\n}\n\nfunction defaultResult(defaults: Defaults): ParsedStorageUrl {\n\treturn {\n\t\tbucket: '',\n\t\tregion: defaults.region || 'us-east-1',\n\t\tendpoint: defaults.endpoint || '',\n\t\tprovider: defaults.provider || 's3',\n\t\tprefix: ''\n\t};\n}\n\nfunction splitBucketPrefix(rest: string): { bucket: string; prefix: string } {\n\tconst slashIdx = rest.indexOf('/');\n\tif (slashIdx >= 0) {\n\t\treturn {\n\t\t\tbucket: rest.slice(0, slashIdx),\n\t\t\tprefix: stripTrailingSlashes(rest.slice(slashIdx + 1))\n\t\t};\n\t}\n\treturn { bucket: rest, prefix: '' };\n}\n\n/**\n * Parse a user-provided bucket/URL string into structured storage connection parts.\n */\nexport function parseStorageUrl(input: string, defaults: Defaults = {}): ParsedStorageUrl {\n\tconst trimmed = input.trim();\n\n\t// ── Custom URI schemes (s3://, gs://, r2://, az://, etc.) ──────────\n\tconst lower = trimmed.toLowerCase();\n\tfor (const [scheme, { provider, strip }] of Object.entries(SCHEME_MAP)) {\n\t\tif (lower.startsWith(scheme)) {\n\t\t\tconst rest = trimmed.slice(strip);\n\t\t\tconst { bucket, prefix } = splitBucketPrefix(rest);\n\t\t\treturn {\n\t\t\t\tbucket,\n\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\tendpoint: defaults.endpoint || '',\n\t\t\t\tprovider,\n\t\t\t\tprefix\n\t\t\t};\n\t\t}\n\t}\n\n\t// ── HTTP(S) URL ─────────────────────────────────────────────────\n\tif (lower.startsWith('http://') || lower.startsWith('https://')) {\n\t\ttry {\n\t\t\tconst url = new URL(trimmed);\n\t\t\tconst host = url.hostname;\n\t\t\tconst pathParts = url.pathname.replace(/^\\//, '').split('/').filter(Boolean);\n\n\t\t\t// --- AWS S3 ---\n\n\t\t\t// Virtual-hosted: <bucket>.s3.<region>.amazonaws.com\n\t\t\tconst awsVhost = host.match(AWS_VHOST_RE);\n\t\t\tif (awsVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: awsVhost[1],\n\t\t\t\t\tregion: awsVhost[2],\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Path-style: s3.<region>.amazonaws.com/<bucket>\n\t\t\tconst awsPath = host.match(AWS_PATH_RE);\n\t\t\tif (awsPath && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: awsPath[1],\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Global: s3.amazonaws.com/<bucket>\n\t\t\tif (host === AWS_GLOBAL_HOST && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Cloudflare R2 ---\n\t\t\t// <account>.r2.cloudflarestorage.com/<bucket>\n\t\t\tconst r2Match = host.match(R2_RE);\n\t\t\tif (r2Match && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: 'auto',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'r2',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Google Cloud Storage ---\n\t\t\t// storage.googleapis.com/<bucket>\n\t\t\tif (host === GCS_GLOBAL_HOST && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us',\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 'gcs',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// <bucket>.storage.googleapis.com\n\t\t\tconst gcsVhost = host.match(GCS_VHOST_RE);\n\t\t\tif (gcsVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: gcsVhost[1],\n\t\t\t\t\tregion: defaults.region || 'us',\n\t\t\t\t\tendpoint: '',\n\t\t\t\t\tprovider: 'gcs',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- DigitalOcean Spaces ---\n\t\t\t// <bucket>.<region>.digitaloceanspaces.com\n\t\t\tconst doVhost = host.match(DO_VHOST_RE);\n\t\t\tif (doVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: doVhost[1],\n\t\t\t\t\tregion: doVhost[2],\n\t\t\t\t\tendpoint: `${url.protocol}//${doVhost[2]}.digitaloceanspaces.com`,\n\t\t\t\t\tprovider: 'digitalocean',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// <region>.digitaloceanspaces.com/<bucket>\n\t\t\tconst doPath = host.match(DO_PATH_RE);\n\t\t\tif (doPath && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: doPath[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'digitalocean',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Wasabi ---\n\t\t\t// s3.<region>.wasabisys.com/<bucket>\n\t\t\tconst wasabiMatch = host.match(WASABI_RE);\n\t\t\tif (wasabiMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: wasabiMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'wasabi',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Backblaze B2 ---\n\t\t\t// <bucket>.s3.<region>.backblazeb2.com (S3-compatible)\n\t\t\tconst b2S3 = host.match(B2_S3_RE);\n\t\t\tif (b2S3) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: b2S3[1],\n\t\t\t\t\tregion: b2S3[2],\n\t\t\t\t\tendpoint: `${url.protocol}//s3.${b2S3[2]}.backblazeb2.com`,\n\t\t\t\t\tprovider: 'b2',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// f<id>.backblazeb2.com/file/<bucket>\n\t\t\tconst b2Native = host.match(B2_NATIVE_RE);\n\t\t\tif (b2Native && pathParts[0] === 'file' && pathParts.length > 1) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[1],\n\t\t\t\t\tregion: defaults.region || 'us-west-000',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'b2',\n\t\t\t\t\tprefix: pathParts.slice(2).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Alibaba Cloud OSS ---\n\t\t\t// <bucket>.oss-<region>.aliyuncs.com\n\t\t\tconst ossMatch = host.match(OSS_RE);\n\t\t\tif (ossMatch) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: ossMatch[1],\n\t\t\t\t\tregion: ossMatch[2],\n\t\t\t\t\tendpoint: `${url.protocol}//${ossMatch[2]}.aliyuncs.com`,\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Tencent Cloud COS ---\n\t\t\t// <bucket>.cos.<region>.myqcloud.com\n\t\t\tconst cosMatch = host.match(COS_RE);\n\t\t\tif (cosMatch) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: cosMatch[1],\n\t\t\t\t\tregion: cosMatch[2],\n\t\t\t\t\tendpoint: `${url.protocol}//cos.${cosMatch[2]}.myqcloud.com`,\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Yandex Cloud ---\n\t\t\t// storage.yandexcloud.net/<bucket>\n\t\t\tif (host === YANDEX_HOST && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'ru-central1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Contabo ---\n\t\t\t// <region>.contabostorage.com/<bucket>\n\t\t\tconst contaboMatch = host.match(CONTABO_RE);\n\t\t\tif (contaboMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: contaboMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'contabo',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Hetzner ---\n\t\t\t// <region>.your-objectstorage.com/<bucket>\n\t\t\tconst hetznerMatch = host.match(HETZNER_RE);\n\t\t\tif (hetznerMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: hetznerMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'hetzner',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Linode / Akamai ---\n\t\t\t// <bucket>.<region>.linodeobjects.com or <region>.linodeobjects.com/<bucket>\n\t\t\tconst linodeVhost = host.match(LINODE_VHOST_RE);\n\t\t\tif (linodeVhost) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: linodeVhost[1],\n\t\t\t\t\tregion: linodeVhost[2],\n\t\t\t\t\tendpoint: `${url.protocol}//${linodeVhost[2]}.linodeobjects.com`,\n\t\t\t\t\tprovider: 'linode',\n\t\t\t\t\tprefix: pathParts.join('/')\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst linodePath = host.match(LINODE_PATH_RE);\n\t\t\tif (linodePath && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: linodePath[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'linode',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- OVHcloud ---\n\t\t\t// s3.<region>.io.cloud.ovh.net/<bucket>\n\t\t\tconst ovhMatch = host.match(OVH_RE);\n\t\t\tif (ovhMatch && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: ovhMatch[1],\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'ovhcloud',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- MinIO ---\n\t\t\t// Common patterns: minio.<domain>, localhost with port\n\t\t\tif (isMinioLikeHost(host) && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'minio',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Azure Blob Storage ---\n\t\t\t// <account>.blob.core.windows.net/<container>\n\t\t\tconst azureBlob = host.match(AZURE_BLOB_RE);\n\t\t\tif (azureBlob && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || '',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'azure',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Storj ---\n\t\t\t// S3 gateway: gateway.storjshare.io/<bucket> (or gateway.<region>.storjshare.io)\n\t\t\tconst storjGateway = host.match(STORJ_GATEWAY_RE);\n\t\t\tif (storjGateway && pathParts.length > 0) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: storjGateway[1] || defaults.region || 'us1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`,\n\t\t\t\t\tprovider: 'storj',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Linksharing: link.storjshare.io/raw/<access>/<bucket>/... or /s/<access>/<bucket>/...\n\t\t\tconst storjLink = host.match(STORJ_LINK_RE);\n\t\t\tif (storjLink && pathParts.length >= 3 && (pathParts[0] === 'raw' || pathParts[0] === 's')) {\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[2],\n\t\t\t\t\tregion: storjLink[1] || defaults.region || 'us1',\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}/${pathParts[0]}/${pathParts[1]}`,\n\t\t\t\t\tprovider: 'storj',\n\t\t\t\t\tprefix: pathParts.slice(3).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- STAC API endpoints (Element 84, MPC, etc.) ---\n\t\t\t// Paths like /v1/collections/.../items/... are not S3 buckets, the\n\t\t\t// first path segment is an API version, not a bucket name. Return\n\t\t\t// no bucket so detectHostBucket() falls through and the URL opens\n\t\t\t// as a direct remote fetch.\n\t\t\tif (STAC_API_PATH_RE.test(url.pathname)) {\n\t\t\t\treturn {\n\t\t\t\t\t...defaultResult(defaults),\n\t\t\t\t\tendpoint: `${url.protocol}//${url.host}`\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// --- Generic custom endpoint with bucket in path ---\n\t\t\tif (pathParts.length > 0) {\n\t\t\t\tconst endpoint = `${url.protocol}//${url.host}`;\n\t\t\t\treturn {\n\t\t\t\t\tbucket: pathParts[0],\n\t\t\t\t\tregion: defaults.region || 'us-east-1',\n\t\t\t\t\tendpoint,\n\t\t\t\t\tprovider: defaults.provider || 's3',\n\t\t\t\t\tprefix: pathParts.slice(1).join('/')\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Just a host, no path — treat as endpoint with no bucket\n\t\t\treturn {\n\t\t\t\t...defaultResult(defaults),\n\t\t\t\tendpoint: `${url.protocol}//${url.host}`\n\t\t\t};\n\t\t} catch {\n\t\t\t// Not a valid URL, fall through to plain bucket name\n\t\t}\n\t}\n\n\t// ── Plain bucket name (no protocol) ─────────────────────────────\n\tconst cleaned = stripEdgeSlashes(trimmed);\n\treturn {\n\t\tbucket: cleaned,\n\t\tregion: defaults.region || 'us-east-1',\n\t\tendpoint: defaults.endpoint || '',\n\t\tprovider: defaults.provider || 's3',\n\t\tprefix: ''\n\t};\n}\n\n/**\n * Returns true if the input looks like a URL/URI rather than a plain bucket name.\n * Covers all recognized cloud storage URI schemes.\n */\nexport function looksLikeUrl(input: string): boolean {\n\tconst lower = input.trim().toLowerCase();\n\tif (lower.startsWith('http://') || lower.startsWith('https://')) return true;\n\tfor (const scheme of Object.keys(SCHEME_MAP)) {\n\t\tif (lower.startsWith(scheme)) return true;\n\t}\n\treturn false;\n}\n\n/**\n * Given a parsed URL result, build a human-readable summary of what was detected.\n */\nexport function describeParseResult(parsed: ParsedStorageUrl): string {\n\tconst parts: string[] = [];\n\tif (parsed.bucket) parts.push(`bucket=\"${parsed.bucket}\"`);\n\tif (parsed.endpoint) parts.push(`endpoint=\"${parsed.endpoint}\"`);\n\tif (parsed.region && parsed.region !== 'us-east-1') parts.push(`region=\"${parsed.region}\"`);\n\tif (parsed.provider !== 's3') parts.push(`provider=${parsed.provider}`);\n\tif (parsed.prefix) parts.push(`prefix=\"${parsed.prefix}\"`);\n\treturn parts.length > 0 ? `Detected: ${parts.join(', ')}` : '';\n}\n\nexport type UrlClassification =\n\t| { kind: 'scheme'; parsed: ParsedStorageUrl }\n\t| { kind: 'object-storage'; parsed: ParsedStorageUrl }\n\t| { kind: 'stac-api'; url: URL }\n\t| { kind: 'remote-file'; url: URL };\n\n/**\n * Classify a user-supplied URL/URI into one of four buckets. Unparseable or\n * plain inputs fall through to `remote-file` with a best-effort URL parse,\n * returning a synthetic `https://` URL when `new URL()` would throw.\n */\nexport function classifyUrl(input: string): UrlClassification {\n\tconst trimmed = input.trim();\n\tconst lower = trimmed.toLowerCase();\n\n\tfor (const scheme of Object.keys(SCHEME_MAP)) {\n\t\tif (lower.startsWith(scheme)) {\n\t\t\treturn { kind: 'scheme', parsed: parseStorageUrl(trimmed) };\n\t\t}\n\t}\n\n\tif (lower.startsWith('http://') || lower.startsWith('https://')) {\n\t\tlet url: URL;\n\t\ttry {\n\t\t\turl = new URL(trimmed);\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tkind: 'remote-file',\n\t\t\t\turl: new URL(`https://${trimmed.replace(/^https?:\\/\\//i, '')}`)\n\t\t\t};\n\t\t}\n\t\tconst parsed = parseStorageUrl(trimmed);\n\t\tif (parsed.bucket && isKnownBucketHost(url.hostname)) {\n\t\t\treturn { kind: 'object-storage', parsed };\n\t\t}\n\t\tif (STAC_API_PATH_RE.test(url.pathname)) {\n\t\t\treturn { kind: 'stac-api', url };\n\t\t}\n\t\treturn { kind: 'remote-file', url };\n\t}\n\n\ttry {\n\t\treturn { kind: 'remote-file', url: new URL(trimmed) };\n\t} catch {\n\t\treturn { kind: 'remote-file', url: new URL(`https://${trimmed}`) };\n\t}\n}\n","/**\n * Auto-detect hosting bucket from URL search params and window.location.\n *\n * Detection priority:\n * 1. `?url=<storage-url>` query parameter (highest priority)\n * 2. `window.location.hostname` pattern matching (fallback)\n *\n * Also extracts `rootPrefix` when the app is hosted inside a subfolder.\n */\n\nimport { buildProviderBaseUrl, type ProviderId } from '../../../src/lib/storage/providers.js';\nimport type { StacItem } from './stac.js';\nimport { applyStorageHintsToConnection, extractStorageHints } from './stac-storage-extension.js';\nimport { isKnownBucketHost, parseStorageUrl, type StorageProvider } from './storage-url.js';\n\nexport interface DetectedHost {\n\tprovider: StorageProvider;\n\tbucket: string;\n\tregion: string;\n\tendpoint: string;\n\trootPrefix: string;\n\tbucketUrl: string;\n}\n\n/**\n * Extract root prefix from pathname.\n * When hosted at `/subfolder/index.html` or `/subfolder/`, returns `subfolder/`.\n */\nfunction extractRootPrefix(pathname: string): string {\n\t// Strip trailing filename (index.html, etc.)\n\tlet clean = pathname.replace(/\\/[^/]*\\.[^/]*$/, '/');\n\t// Remove leading slash\n\tclean = clean.replace(/^\\//, '');\n\t// Empty or just '/' means no prefix\n\tif (!clean || clean === '/') return '';\n\t// Ensure trailing slash\n\tif (!clean.endsWith('/')) clean += '/';\n\treturn clean;\n}\n\n/**\n * Build a normalized API endpoint URL for a detected provider.\n */\nfunction buildBucketUrl(\n\tprovider: StorageProvider,\n\tendpoint: string,\n\tbucket: string,\n\tregion?: string\n): string {\n\treturn buildProviderBaseUrl(\n\t\t(provider === 'unknown' ? 's3' : provider) as ProviderId,\n\t\tendpoint,\n\t\tbucket,\n\t\tregion || ''\n\t);\n}\n\n/**\n * Translate a `ParsedStorageUrl` into a `DetectedHost`. Returns null when the\n * parser did not recognize a bucket or when the host is not a known provider\n * pattern (prevents arbitrary custom endpoints from being auto-connected).\n */\nfunction parsedToHost(\n\tparsed: ReturnType<typeof parseStorageUrl>,\n\thost: string,\n\trootPrefix: string\n): DetectedHost | null {\n\tif (!parsed.bucket || !isKnownBucketHost(host)) return null;\n\tconst provider = parsed.provider === 'unknown' ? 's3' : parsed.provider;\n\treturn {\n\t\tprovider,\n\t\tbucket: parsed.bucket,\n\t\tregion: parsed.region,\n\t\tendpoint: parsed.endpoint,\n\t\trootPrefix,\n\t\tbucketUrl: buildBucketUrl(parsed.provider, parsed.endpoint, parsed.bucket, parsed.region)\n\t};\n}\n\n/**\n * Detect hosting bucket from current URL.\n * Returns null when no hosting bucket can be determined.\n */\nexport function detectHostBucket(): DetectedHost | null {\n\tif (typeof window === 'undefined') return null;\n\n\tconst url = new URL(window.location.href);\n\n\t// Priority 1: ?url= query parameter\n\tconst urlParam = url.searchParams.get('url');\n\tif (urlParam) {\n\t\ttry {\n\t\t\tconst paramUrl = new URL(urlParam);\n\t\t\tconst parsed = parseStorageUrl(urlParam);\n\t\t\tconst host = parsedToHost(parsed, paramUrl.hostname, '');\n\t\t\tif (host) return host;\n\t\t} catch {\n\t\t\t// Not a parseable URL, fall through to location-based detection.\n\t\t}\n\t}\n\n\t// Priority 2: window.location pattern matching via the unified parser.\n\t// `parseStorageUrl` extracts bucket + any remaining prefix from the\n\t// current URL. The prefix is used as the in-bucket sub-folder the app\n\t// should root into when auto-connecting.\n\tconst parsed = parseStorageUrl(window.location.href);\n\tif (!parsed.bucket || !isKnownBucketHost(url.hostname)) return null;\n\n\t// `rootPrefix` is the in-bucket sub-folder, possibly trailing with an\n\t// `index.html` style filename, which `extractRootPrefix` strips.\n\tconst prefixPath = parsed.prefix ? `/${parsed.prefix}` : '';\n\tconst rootPrefix = extractRootPrefix(prefixPath || '/');\n\n\tconst provider = parsed.provider === 'unknown' ? 's3' : parsed.provider;\n\treturn {\n\t\tprovider,\n\t\tbucket: parsed.bucket,\n\t\tregion: parsed.region,\n\t\tendpoint: parsed.endpoint,\n\t\trootPrefix,\n\t\tbucketUrl: buildBucketUrl(parsed.provider, parsed.endpoint, parsed.bucket, parsed.region)\n\t};\n}\n\n/**\n * Enrich an in-progress connection-config draft with hints from a STAC Item\n * that declares the Storage Extension (`storage:region`,\n * `storage:requester_pays`, `storage:platform`, v2 `storage:schemes`).\n *\n * Modular by design, callers opt in. The existing `detectHostBucket` flow\n * does NOT know about STAC, so call sites that already hold a representative\n * `StacItem` (e.g. classification just after fetching a Catalog / Collection /\n * ItemCollection) should funnel through this helper before handing the draft\n * to `connectionStore.saveHostConnection` / `connectionStore.save`. Existing\n * non-empty fields on the draft are preserved (this never clobbers a\n * user-set value).\n *\n * Returns a shallow copy of `input` with hint fields filled in. Safe to call\n * with an unrelated item, returns `input` untouched when the extension is\n * absent or unparseable.\n */\nexport function applyStacItemStorageHints<T extends { region?: string; endpoint?: string }>(\n\tinput: T,\n\titem: StacItem\n): T {\n\tconst hints = extractStorageHints(item);\n\tconst merged = applyStorageHintsToConnection(input, hints);\n\t// Light tracing for development. Stripped from production builds via the\n\t// Vite `import.meta.env.DEV` define. Intentionally one-line so it's cheap\n\t// to leave in.\n\tif (import.meta.env?.DEV && (hints.region || hints.endpoint || hints.requesterPays)) {\n\t\tconsole.debug('[host-detection] applied STAC storage hints', hints);\n\t}\n\treturn merged;\n}\n","/**\n * Generic localStorage helpers with SSR safety.\n *\n * Used by connection, settings, and query-history stores to avoid\n * repeating the same load/persist/try-catch/SSR-guard pattern.\n */\n\n/**\n * Load a JSON value from localStorage.\n * Returns `defaultValue` on SSR, missing key, or parse error.\n */\nexport function loadFromStorage<T>(key: string, defaultValue: T): T {\n\tif (typeof window === 'undefined') return defaultValue;\n\ttry {\n\t\tconst raw = localStorage.getItem(key);\n\t\tif (raw) return JSON.parse(raw) as T;\n\t} catch {\n\t\t// ignore parse errors\n\t}\n\treturn defaultValue;\n}\n\n/**\n * Persist a JSON-serializable value to localStorage.\n * Silently no-ops on SSR or storage errors (quota, private browsing).\n */\nexport function persistToStorage(key: string, value: unknown): void {\n\tif (typeof window === 'undefined') return;\n\ttry {\n\t\tlocalStorage.setItem(key, JSON.stringify(value));\n\t} catch {\n\t\t// ignore storage errors\n\t}\n}\n","/**\n * Tiny insertion-order LRU built on top of `Map`. `get` / `has` move the entry\n * to the most-recent slot, `set` evicts the oldest (and runs `onEvict`) once\n * the cap is exceeded.\n *\n * Keeps the implementation deliberately small. Used by viewer modules that\n * cache per-source resources (GeoTIFF headers, presigned URLs) which would\n * otherwise leak across long pan / viewport-reload sessions.\n */\n\nexport interface LruCacheOptions<K, V> {\n\t/** Maximum number of entries. Must be > 0. */\n\tmax: number;\n\t/** Called when an entry is evicted (LRU overflow or `delete()`). */\n\tonEvict?: (key: K, value: V) => void;\n}\n\nexport class LruCache<K, V> {\n\tprivate map = new Map<K, V>();\n\treadonly max: number;\n\tprivate onEvict?: (key: K, value: V) => void;\n\n\tconstructor(opts: LruCacheOptions<K, V>) {\n\t\tif (opts.max <= 0) throw new Error('LruCache: max must be > 0');\n\t\tthis.max = opts.max;\n\t\tthis.onEvict = opts.onEvict;\n\t}\n\n\tget size(): number {\n\t\treturn this.map.size;\n\t}\n\n\thas(key: K): boolean {\n\t\treturn this.map.has(key);\n\t}\n\n\tget(key: K): V | undefined {\n\t\tconst v = this.map.get(key);\n\t\tif (v === undefined) return undefined;\n\t\t// Move-to-end so this entry is now most-recent.\n\t\tthis.map.delete(key);\n\t\tthis.map.set(key, v);\n\t\treturn v;\n\t}\n\n\tset(key: K, value: V): void {\n\t\tif (this.map.has(key)) {\n\t\t\tthis.map.delete(key);\n\t\t}\n\t\tthis.map.set(key, value);\n\t\twhile (this.map.size > this.max) {\n\t\t\tconst oldest = this.map.keys().next().value;\n\t\t\tif (oldest === undefined) break;\n\t\t\tconst evicted = this.map.get(oldest) as V;\n\t\t\tthis.map.delete(oldest);\n\t\t\tthis.onEvict?.(oldest, evicted);\n\t\t}\n\t}\n\n\tdelete(key: K): boolean {\n\t\tconst v = this.map.get(key);\n\t\tif (v === undefined) return false;\n\t\tthis.map.delete(key);\n\t\tthis.onEvict?.(key, v);\n\t\treturn true;\n\t}\n\n\tclear(): void {\n\t\tif (this.onEvict) {\n\t\t\tfor (const [k, v] of this.map) this.onEvict(k, v);\n\t\t}\n\t\tthis.map.clear();\n\t}\n}\n","/**\n * Framework-agnostic helper that wires a \"click on map, run a probe, surface the\n * result\" flow used by every COG-style viewer (`CogViewer`, `StacMosaicViewer`,\n * `MultiCogViewer`).\n *\n * The viewers differ in what the probe returns (a single pixel sample, a per-\n * channel fan-out, or a topmost-source bbox hit), but they share the same\n * boilerplate: subscribe to `click`, mark inspecting, await the probe, surface\n * the payload, abort the previous probe if a new click arrives mid-flight, and\n * tear the listener down on cleanup.\n *\n * No dependency on Svelte, MapLibre, or deck.gl. The `MapLike` shape captures\n * only what the helper needs from the underlying map so this can be unit-tested\n * with a tiny stub if needed.\n */\nexport interface PixelInspectClickEvent {\n\tlngLat: { lng: number; lat: number };\n}\n\nexport type PixelInspectClickHandler = (event: PixelInspectClickEvent) => void;\n\n/**\n * Minimal subset of MapLibre's map API used by the inspector. Anything that\n * dispatches a `click` event with `{lngLat}` and supports symmetric on/off\n * registration plugs in.\n */\nexport interface MapLike {\n\ton(type: 'click', handler: PixelInspectClickHandler): unknown;\n\toff(type: 'click', handler: PixelInspectClickHandler): unknown;\n}\n\nexport interface PixelInspectProbeRequest {\n\tlng: number;\n\tlat: number;\n\tsignal: AbortSignal;\n}\n\nexport type PixelInspectProbe<T> = (req: PixelInspectProbeRequest) => Promise<T | null>;\n\nexport interface PixelInspectCallbacks<T> {\n\t/** Called synchronously when a click is accepted, before the probe is awaited. */\n\tonStart(): void;\n\t/**\n\t * Called once per click after the probe settles. Receives `null` when the\n\t * probe returned `null` or threw a non-helper-driven error (including an\n\t * `AbortError` that did not originate from this helper's own controller).\n\t */\n\tonResult(result: T | null): void;\n}\n\nexport interface AttachPixelInspectorOptions<T> {\n\tprobe: PixelInspectProbe<T>;\n\tonStart: PixelInspectCallbacks<T>['onStart'];\n\tonResult: PixelInspectCallbacks<T>['onResult'];\n}\n\n/**\n * Wire a click-to-inspect probe onto `map`. Returns a `detach()` function that\n * removes the listener AND aborts any in-flight probe. Subsequent clicks abort\n * the previous probe so a fast double-click never leaves a stale result behind.\n */\nexport function attachPixelInspector<T>(\n\tmap: MapLike,\n\t{ probe, onStart, onResult }: AttachPixelInspectorOptions<T>\n): () => void {\n\tlet active: AbortController | null = null;\n\tlet detached = false;\n\n\tconst handler: PixelInspectClickHandler = (event) => {\n\t\tif (detached) return;\n\t\t// A fast second click cancels the first probe via its own controller. The\n\t\t// helper-owned signal is what `isHelperAbort()` checks below so we can\n\t\t// distinguish \"the user clicked again\" (swallow) from \"an upstream signal\n\t\t// aborted us mid-flight\" (still surface as `null`, matches old behavior).\n\t\tif (active) active.abort();\n\t\tconst ctrl = new AbortController();\n\t\tactive = ctrl;\n\t\tonStart();\n\t\tvoid (async () => {\n\t\t\tlet payload: T | null = null;\n\t\t\ttry {\n\t\t\t\tpayload = await probe({\n\t\t\t\t\tlng: event.lngLat.lng,\n\t\t\t\t\tlat: event.lngLat.lat,\n\t\t\t\t\tsignal: ctrl.signal\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\t// Swallow only this helper's own abort (a newer click superseded us).\n\t\t\t\t// Any other AbortError (viewer teardown, upstream cancel) still flows\n\t\t\t\t// through to `onResult(null)` to match the pre-refactor behavior of\n\t\t\t\t// each viewer's catch block.\n\t\t\t\tif (isHelperAbort(err, ctrl.signal)) return;\n\t\t\t\tpayload = null;\n\t\t\t}\n\t\t\tif (ctrl.signal.aborted && active === ctrl) {\n\t\t\t\t// Helper-owned abort that arrived while we were awaiting: another\n\t\t\t\t// click is already running. Don't double-emit.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (active === ctrl) active = null;\n\t\t\tonResult(payload);\n\t\t})();\n\t};\n\n\tmap.on('click', handler);\n\n\treturn function detach(): void {\n\t\tif (detached) return;\n\t\tdetached = true;\n\t\tmap.off('click', handler);\n\t\tif (active) {\n\t\t\tactive.abort();\n\t\t\tactive = null;\n\t\t}\n\t};\n}\n\nfunction isHelperAbort(err: unknown, signal: AbortSignal): boolean {\n\tif (!signal.aborted) return false;\n\tif (err instanceof DOMException && err.name === 'AbortError') return true;\n\tif (err && typeof err === 'object' && (err as { name?: string }).name === 'AbortError') {\n\t\treturn true;\n\t}\n\treturn false;\n}\n","export interface SqlBlock {\n\tname: string;\n\tsql: string;\n\tstartLine: number;\n\tendLine: number;\n}\n\nexport interface ParsedMarkdownDocument {\n\tfrontmatter: Record<string, any>;\n\tcontent: string;\n\tsqlBlocks: SqlBlock[];\n}\n\n/**\n * Parse a markdown document with YAML frontmatter and SQL code blocks.\n *\n * Evidence-compatible syntax:\n * ```sql query_name\n * SELECT * FROM table\n * ```\n */\nexport async function parseMarkdownDocument(markdown: string): Promise<ParsedMarkdownDocument> {\n\tlet frontmatter: Record<string, any> = {};\n\tlet content = markdown;\n\n\tconst fmMatch = markdown.match(/^---\\n([\\s\\S]*?)\\n---\\n/);\n\tif (fmMatch) {\n\t\ttry {\n\t\t\tconst { default: YAML } = await import('yaml');\n\t\t\tfrontmatter = YAML.parse(fmMatch[1]) || {};\n\t\t} catch {\n\t\t\t// Invalid YAML or yaml peer dep not installed, ignore frontmatter\n\t\t}\n\t\tcontent = markdown.slice(fmMatch[0].length);\n\t}\n\n\t// Extract SQL blocks\n\tconst sqlBlocks: SqlBlock[] = [];\n\tconst lines = content.split('\\n');\n\tlet i = 0;\n\n\twhile (i < lines.length) {\n\t\tconst line = lines[i];\n\t\tconst match = line.match(/^```sql\\s+(\\w[\\w-]*)\\s*$/);\n\n\t\tif (match) {\n\t\t\tconst name = match[1];\n\t\t\tconst startLine = i;\n\t\t\tconst sqlLines: string[] = [];\n\t\t\ti++;\n\n\t\t\twhile (i < lines.length && lines[i] !== '```') {\n\t\t\t\tsqlLines.push(lines[i]);\n\t\t\t\ti++;\n\t\t\t}\n\n\t\t\tsqlBlocks.push({\n\t\t\t\tname,\n\t\t\t\tsql: sqlLines.join('\\n'),\n\t\t\t\tstartLine,\n\t\t\t\tendLine: i\n\t\t\t});\n\t\t}\n\t\ti++;\n\t}\n\n\treturn { frontmatter, content, sqlBlocks };\n}\n\n/**\n * Interpolate template variables in markdown text.\n * Supports {queryName.rows[0].columnName} syntax.\n */\nexport function interpolateTemplates(\n\ttext: string,\n\tqueryResults: Map<string, Record<string, any>[]>\n): string {\n\treturn text.replace(/\\{(\\w+)\\.rows\\[(\\d+)\\]\\.(\\w+)\\}/g, (match, queryName, rowIdx, colName) => {\n\t\tconst rows = queryResults.get(queryName);\n\t\tif (!rows) return match;\n\t\tconst row = rows[parseInt(rowIdx, 10)];\n\t\tif (!row) return match;\n\t\tconst value = row[colName];\n\t\treturn value !== undefined ? String(value) : match;\n\t});\n}\n\n/**\n * Replace SQL blocks in markdown content with placeholder markers\n * that can be replaced with rendered components.\n */\nexport function markSqlBlocks(content: string): string {\n\treturn content.replace(\n\t\t/```sql[ \\t]+(\\w[\\w-]*)[ \\t]*\\n([\\s\\S]*?)```/g,\n\t\t(_, name) => `<div data-sql-block=\"${name}\"></div>`\n\t);\n}\n","import type { QueryEngine, QueryResult } from '../../../src/lib/query/engine.js';\n\n/**\n * Executes the SQL blocks parsed out of a markdown document (Evidence.dev style)\n * against an injected query engine, and caches the results by block name. Pairs\n * with `markdown-sql.ts` (the parser). Pure TypeScript, the engine is supplied by\n * the host so this module never imports DuckDB or any other heavy dependency.\n */\nexport class MarkdownSqlContext {\n\tprivate engine: QueryEngine;\n\tprivate connId: string;\n\tprivate prefix: string;\n\tprivate results = new Map<string, { result: QueryResult; rows: Record<string, any>[] }>();\n\n\tconstructor(engine: QueryEngine, connId: string, prefix = '') {\n\t\tthis.engine = engine;\n\t\tthis.connId = connId;\n\t\tthis.prefix = prefix;\n\t}\n\n\t/** Execute a SQL query and store the result under the given name. */\n\tasync executeSql(sql: string, queryName: string): Promise<Record<string, any>[]> {\n\t\tconst transformedSql = this.transformPaths(sql);\n\t\tconst result = await this.engine.query(this.connId, transformedSql);\n\t\tconst rows = result.rows ?? [];\n\t\tthis.results.set(queryName, { result, rows });\n\t\treturn rows;\n\t}\n\n\t/**\n\t * Transform relative file paths in SQL to full S3 URLs.\n\t * e.g. read_parquet('data.parquet') becomes read_parquet('s3://bucket/prefix/data.parquet').\n\t */\n\tprivate transformPaths(sql: string): string {\n\t\tif (!this.connId || !this.prefix) return sql;\n\t\treturn sql.replace(/(read_(?:parquet|csv|json|csv_auto))\\('([^']+)'\\)/g, (match, fn, path) => {\n\t\t\tif (path.startsWith('s3://') || path.startsWith('http') || path.startsWith('/')) {\n\t\t\t\treturn match;\n\t\t\t}\n\t\t\tconst fullPath = `s3://${this.prefix}/${path}`;\n\t\t\treturn `${fn}('${fullPath}')`;\n\t\t});\n\t}\n\n\tgetResult(queryName: string) {\n\t\treturn this.results.get(queryName);\n\t}\n\n\tgetAllResults(): Map<string, Record<string, any>[]> {\n\t\tconst map = new Map<string, Record<string, any>[]>();\n\t\tfor (const [name, { rows }] of this.results) {\n\t\t\tmap.set(name, rows);\n\t\t}\n\t\treturn map;\n\t}\n\n\tgetColumns(queryName: string): string[] {\n\t\tconst entry = this.results.get(queryName);\n\t\tif (!entry) return [];\n\t\treturn entry.result.columns;\n\t}\n}\n","/**\n * Lightweight browser-native Jupyter notebook renderer.\n * Replaces `notebookjs` which depends on jsdom/Buffer (Node.js only).\n * Handles nbformat 2, 3, 4, and 5.\n */\n\nconst PREFIX = 'nb-';\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction el(tag: string, classNames: string[] = []): HTMLElement {\n\tconst e = document.createElement(tag);\n\tif (classNames.length) e.className = classNames.map((c) => PREFIX + c).join(' ');\n\treturn e;\n}\n\nfunction escapeHTML(raw: string): string {\n\treturn raw.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\nfunction joinText(text: string | string[]): string {\n\tif (Array.isArray(text)) return text.join('');\n\treturn text ?? '';\n}\n\n// ── Types ────────────────────────────────────────────────────────────────────\n\nexport interface NotebookConfig {\n\tmarkdown: (md: string) => string;\n\tansi: (text: string) => string;\n\thighlighter: (code: string, lang: string) => string;\n}\n\ninterface RawNotebook {\n\tnbformat: number;\n\tnbformat_minor?: number;\n\tmetadata?: Record<string, any>;\n\tcells?: RawCell[];\n\tworksheets?: { cells: RawCell[] }[];\n}\n\ninterface RawCell {\n\tcell_type: string;\n\tsource?: string | string[];\n\tinput?: string | string[];\n\toutputs?: RawOutput[];\n\tprompt_number?: number;\n\texecution_count?: number | null;\n\tlevel?: number;\n\tlanguage?: string;\n}\n\ninterface RawOutput {\n\toutput_type: string;\n\tdata?: Record<string, string | string[]>;\n\ttext?: string | string[];\n\tstream?: string;\n\tname?: string;\n\tpng?: string;\n\tjpeg?: string;\n\tsvg?: string;\n\thtml?: string;\n\tlatex?: string;\n\ttraceback?: string[];\n\tename?: string;\n\tevalue?: string;\n\t// v3 display_data flat keys\n\t[key: string]: any;\n}\n\n// ── Display renderers ────────────────────────────────────────────────────────\n\nconst IMAGE_FORMATS = ['image/png', 'image/jpeg', 'image/gif', 'image/webp'] as const;\n\nfunction renderImage(format: string, data: string | string[]): HTMLElement {\n\tconst img = el('img', ['image-output']);\n\t(img as HTMLImageElement).src = `data:${format};base64,${joinText(data).replace(/\\n/g, '')}`;\n\treturn img;\n}\n\nfunction renderDisplayData(output: RawOutput, config: NotebookConfig): HTMLElement {\n\t// Resolve data from v4 `data` field or v3 flat fields\n\tconst getData = (mime: string): string | string[] | undefined =>\n\t\toutput.data?.[mime] ?? output[mime];\n\n\t// Priority order (richest first)\n\tfor (const fmt of IMAGE_FORMATS) {\n\t\tconst d = getData(fmt);\n\t\tif (d) return renderImage(fmt, d);\n\t}\n\n\tconst svg = getData('image/svg+xml') ?? getData('text/svg+xml');\n\tif (svg) {\n\t\tconst wrapper = el('div', ['svg-output']);\n\t\twrapper.innerHTML = joinText(svg);\n\t\treturn wrapper;\n\t}\n\n\tconst html = getData('text/html');\n\tif (html) {\n\t\tconst wrapper = el('div', ['html-output']);\n\t\twrapper.innerHTML = joinText(html);\n\t\treturn wrapper;\n\t}\n\n\tconst md = getData('text/markdown');\n\tif (md) {\n\t\tconst wrapper = el('div', ['html-output']);\n\t\twrapper.innerHTML = config.markdown(joinText(md));\n\t\treturn wrapper;\n\t}\n\n\tconst latex = getData('text/latex');\n\tif (latex) {\n\t\tconst wrapper = el('div', ['latex-output']);\n\t\twrapper.textContent = joinText(latex);\n\t\treturn wrapper;\n\t}\n\n\tconst plain = getData('text/plain');\n\tif (plain) {\n\t\tconst pre = el('pre', ['text-output']);\n\t\tpre.innerHTML = config.ansi(escapeHTML(joinText(plain)));\n\t\treturn pre;\n\t}\n\n\treturn el('div', ['empty-output']);\n}\n\nfunction renderStream(output: RawOutput, config: NotebookConfig): HTMLElement {\n\tconst streamName = output.stream ?? output.name ?? 'stdout';\n\tconst pre = el('pre', [streamName]);\n\tpre.innerHTML = config.ansi(escapeHTML(joinText(output.text ?? '')));\n\treturn pre;\n}\n\nfunction renderError(output: RawOutput, config: NotebookConfig): HTMLElement {\n\tconst pre = el('pre', ['pyerr']);\n\tconst raw = (output.traceback ?? []).join('\\n');\n\tpre.innerHTML = config.ansi(escapeHTML(raw));\n\treturn pre;\n}\n\n// ── Output coalescing (merge consecutive same-name streams) ──────────────────\n\nfunction coalesceStreams(outputs: RawOutput[]): RawOutput[] {\n\tif (!outputs.length) return outputs;\n\tconst result: RawOutput[] = [{ ...outputs[0] }];\n\tfor (let i = 1; i < outputs.length; i++) {\n\t\tconst o = outputs[i];\n\t\tconst last = result[result.length - 1];\n\t\tif (\n\t\t\to.output_type === 'stream' &&\n\t\t\tlast.output_type === 'stream' &&\n\t\t\t(o.stream ?? o.name) === (last.stream ?? last.name)\n\t\t) {\n\t\t\t// Merge text\n\t\t\tconst lastText = Array.isArray(last.text) ? last.text : [last.text ?? ''];\n\t\t\tconst oText = Array.isArray(o.text) ? o.text : [o.text ?? ''];\n\t\t\tlast.text = lastText.concat(oText);\n\t\t} else {\n\t\t\tresult.push({ ...o });\n\t\t}\n\t}\n\treturn result;\n}\n\n// ── Cell renderers ───────────────────────────────────────────────────────────\n\nfunction renderCodeCell(cell: RawCell, lang: string, config: NotebookConfig): HTMLElement {\n\tconst cellEl = el('div', ['cell', 'code-cell']);\n\n\t// Input\n\tconst source = joinText(cell.source ?? cell.input ?? '');\n\tif (source) {\n\t\tconst holder = el('div', ['input']);\n\t\tconst num = cell.prompt_number ?? cell.execution_count;\n\t\tif (typeof num === 'number' && num > -1) {\n\t\t\tholder.setAttribute('data-prompt-number', String(num));\n\t\t}\n\t\tconst pre = el('pre');\n\t\tconst code = document.createElement('code');\n\t\tcode.setAttribute('data-language', lang);\n\t\tcode.className = `lang-${lang}`;\n\t\tcode.innerHTML = config.highlighter(escapeHTML(source), lang);\n\t\tpre.appendChild(code);\n\t\tholder.appendChild(pre);\n\t\tcellEl.appendChild(holder);\n\t}\n\n\t// Outputs\n\tconst rawOutputs = coalesceStreams(cell.outputs ?? []);\n\tfor (const output of rawOutputs) {\n\t\tconst outer = el('div', ['output']);\n\t\tlet inner: HTMLElement;\n\t\tswitch (output.output_type) {\n\t\t\tcase 'display_data':\n\t\t\tcase 'execute_result':\n\t\t\tcase 'pyout':\n\t\t\t\tinner = renderDisplayData(output, config);\n\t\t\t\tbreak;\n\t\t\tcase 'stream':\n\t\t\t\tinner = renderStream(output, config);\n\t\t\t\tbreak;\n\t\t\tcase 'error':\n\t\t\tcase 'pyerr':\n\t\t\t\tinner = renderError(output, config);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tinner = el('div', ['empty-output']);\n\t\t}\n\t\touter.appendChild(inner);\n\t\tcellEl.appendChild(outer);\n\t}\n\n\treturn cellEl;\n}\n\nfunction renderMarkdownCell(cell: RawCell, config: NotebookConfig): HTMLElement {\n\tconst cellEl = el('div', ['cell', 'markdown-cell']);\n\tconst source = joinText(cell.source ?? cell.input ?? '');\n\tcellEl.innerHTML = config.markdown(source);\n\treturn cellEl;\n}\n\nfunction renderHeadingCell(cell: RawCell): HTMLElement {\n\tconst level = Math.min(Math.max(cell.level ?? 1, 1), 6);\n\tconst heading = el(`h${level}`, ['cell', 'heading-cell']);\n\theading.innerHTML = escapeHTML(joinText(cell.source ?? cell.input ?? ''));\n\treturn heading;\n}\n\nfunction renderRawCell(cell: RawCell): HTMLElement {\n\tconst cellEl = el('div', ['cell', 'raw-cell']);\n\tcellEl.innerHTML = escapeHTML(joinText(cell.source ?? cell.input ?? ''));\n\treturn cellEl;\n}\n\n// ── Main render function ─────────────────────────────────────────────────────\n\nexport interface NotebookMeta {\n\tkernelName: string;\n\tlanguage: string;\n\tcellCount: number;\n}\n\n/**\n * Parse and render a Jupyter notebook JSON to a DOM element.\n * Returns the rendered element and metadata.\n */\nexport function renderNotebook(\n\traw: RawNotebook,\n\tconfig: NotebookConfig\n): { element: HTMLElement; meta: NotebookMeta } {\n\tconst meta = raw.metadata ?? {};\n\tconst lang = meta.kernelspec?.language ?? meta.language_info?.name ?? meta.language ?? 'python';\n\tconst kernelName = meta.kernelspec?.display_name ?? meta.language_info?.name ?? '';\n\n\t// Normalize cells: v4+ has top-level `cells`, v2/v3 uses `worksheets`\n\tlet allCells: RawCell[] = [];\n\tif (Array.isArray(raw.cells)) {\n\t\tallCells = raw.cells;\n\t} else if (Array.isArray(raw.worksheets)) {\n\t\tfor (const ws of raw.worksheets) {\n\t\t\tif (Array.isArray(ws.cells)) allCells.push(...ws.cells);\n\t\t}\n\t}\n\n\tconst notebook = el('div', ['notebook']);\n\n\tfor (const cell of allCells) {\n\t\tlet rendered: HTMLElement;\n\t\tswitch (cell.cell_type) {\n\t\t\tcase 'code':\n\t\t\t\trendered = renderCodeCell(cell, cell.language ?? lang, config);\n\t\t\t\tbreak;\n\t\t\tcase 'markdown':\n\t\t\t\trendered = renderMarkdownCell(cell, config);\n\t\t\t\tbreak;\n\t\t\tcase 'heading':\n\t\t\t\trendered = renderHeadingCell(cell);\n\t\t\t\tbreak;\n\t\t\tcase 'raw':\n\t\t\t\trendered = renderRawCell(cell);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\trendered = renderRawCell(cell);\n\t\t}\n\t\tnotebook.appendChild(rendered);\n\t}\n\n\treturn {\n\t\telement: notebook,\n\t\tmeta: { kernelName, language: lang, cellCount: allCells.length }\n\t};\n}\n","/**\n * Lightweight Parquet metadata reader using hyparquet.\n *\n * Reads schema, row count, CRS, and geometry types from the Parquet footer\n * via a single HTTP range request (~512KB). No DuckDB boot needed.\n *\n * This provides instant metadata display before DuckDB-WASM finishes loading.\n */\n\nimport { WGS84_CODES } from '../../../src/lib/constants.js';\nimport type { GeoArrowGeomType } from './geoarrow.js';\n\nexport interface GeoColumnMeta {\n\tencoding: string;\n\tgeometryTypes: string[];\n\tcrs: any | null;\n\tbbox?: number[];\n}\n\nexport interface GeoParquetMeta {\n\tprimaryColumn: string;\n\tcolumns: Record<string, GeoColumnMeta>;\n}\n\nexport interface ParquetFileMetadata {\n\t/** Total number of rows across all row groups. */\n\trowCount: number;\n\t/** Column schema (name + type). Leaf columns only (structs flattened to children). */\n\tschema: { name: string; type: string }[];\n\t/**\n\t * Top-level column names as written. Includes struct/group parents (e.g.\n\t * `assets`, `bbox`) that `schema` flattens away. Required for stac-geoparquet\n\t * detection, which looks up struct columns by their parent name.\n\t */\n\ttopLevelColumns: string[];\n\t/** GeoParquet \"geo\" metadata if present. */\n\tgeo: GeoParquetMeta | null;\n\t/** True when file has legacy GeoParquet metadata (schema_version 0.x without \"version\" field). */\n\tlegacyGeoParquet: boolean;\n\t/** Tool that created the file (e.g. \"pyarrow 15.0.0\"). */\n\tcreatedBy: string | null;\n\t/** Number of row groups. */\n\tnumRowGroups: number;\n\t/** Primary compression codec (e.g. \"SNAPPY\", \"ZSTD\"). */\n\tcompression: string | null;\n}\n\n/** Map hyparquet schema element types to DuckDB-like type strings. */\nfunction mapParquetType(col: any): string {\n\tconst lt = col.logical_type;\n\tif (lt) {\n\t\t// Parquet Format 2.11+ native geometry/geography types\n\t\tif (lt.type === 'GEOMETRY' || lt.type === 'GEOGRAPHY') return 'GEOMETRY';\n\t\t// String types\n\t\tif (lt.type === 'STRING' || lt.type === 'UTF8') return 'VARCHAR';\n\t\tif (lt.type === 'JSON') return 'JSON';\n\t\tif (lt.type === 'UUID') return 'UUID';\n\t\tif (lt.type === 'ENUM') return 'VARCHAR';\n\t\t// Integer types\n\t\tif (lt.type === 'INT' || lt.type === 'INTEGER') {\n\t\t\tconst bits = lt.bitWidth ?? 32;\n\t\t\tconst signed = lt.isSigned !== false;\n\t\t\tif (bits <= 8) return signed ? 'TINYINT' : 'UTINYINT';\n\t\t\tif (bits <= 16) return signed ? 'SMALLINT' : 'USMALLINT';\n\t\t\tif (bits <= 32) return signed ? 'INTEGER' : 'UINTEGER';\n\t\t\treturn signed ? 'BIGINT' : 'UBIGINT';\n\t\t}\n\t\t// Decimal\n\t\tif (lt.type === 'DECIMAL') return `DECIMAL(${lt.precision ?? 18},${lt.scale ?? 0})`;\n\t\t// Date/Time\n\t\tif (lt.type === 'DATE') return 'DATE';\n\t\tif (lt.type === 'TIME') return 'TIME';\n\t\tif (lt.type === 'TIMESTAMP') return 'TIMESTAMP';\n\t\t// Binary\n\t\tif (lt.type === 'BSON') return 'BLOB';\n\t}\n\n\t// Fallback to physical type\n\tconst ct = col.converted_type;\n\tif (ct === 'UTF8') return 'VARCHAR';\n\tif (ct === 'JSON') return 'JSON';\n\tif (ct === 'DATE') return 'DATE';\n\tif (ct === 'TIMESTAMP_MILLIS' || ct === 'TIMESTAMP_MICROS') return 'TIMESTAMP';\n\tif (ct === 'DECIMAL') return `DECIMAL(${col.precision ?? 18},${col.scale ?? 0})`;\n\tif (ct === 'INT_8') return 'TINYINT';\n\tif (ct === 'INT_16') return 'SMALLINT';\n\tif (ct === 'INT_32') return 'INTEGER';\n\tif (ct === 'INT_64') return 'BIGINT';\n\tif (ct === 'UINT_8') return 'UTINYINT';\n\tif (ct === 'UINT_16') return 'USMALLINT';\n\tif (ct === 'UINT_32') return 'UINTEGER';\n\tif (ct === 'UINT_64') return 'UBIGINT';\n\n\tconst pt = col.type;\n\tif (pt === 'BOOLEAN') return 'BOOLEAN';\n\tif (pt === 'INT32') return 'INTEGER';\n\tif (pt === 'INT64') return 'BIGINT';\n\tif (pt === 'INT96') return 'TIMESTAMP';\n\tif (pt === 'FLOAT') return 'FLOAT';\n\tif (pt === 'DOUBLE') return 'DOUBLE';\n\tif (pt === 'BYTE_ARRAY') return 'BLOB';\n\tif (pt === 'FIXED_LEN_BYTE_ARRAY') return 'BLOB';\n\n\treturn 'VARCHAR';\n}\n\n/**\n * Read Parquet footer metadata from a remote URL using hyparquet.\n * Uses HTTP range requests — typically a single ~512KB fetch.\n */\nexport async function readParquetMetadata(url: string): Promise<ParquetFileMetadata> {\n\tconst { parquetMetadataAsync, asyncBufferFromUrl } = await import('hyparquet');\n\n\tconst file = await asyncBufferFromUrl({ url });\n\tconst metadata = await parquetMetadataAsync(file);\n\n\t// Row count from row group metadata (no data scan needed)\n\tconst rowCount = metadata.row_groups.reduce(\n\t\t(sum: number, rg: any) => sum + Number(rg.num_rows),\n\t\t0\n\t);\n\n\t// Schema from metadata (skip root element at index 0)\n\tconst schema = metadata.schema\n\t\t.slice(1)\n\t\t.filter((col: any) => col.num_children === undefined) // skip group elements\n\t\t.map((col: any) => ({\n\t\t\tname: col.name,\n\t\t\ttype: mapParquetType(col)\n\t\t}));\n\n\t// Walk depth-first to collect top-level column names (including struct parents).\n\t// hyparquet serializes the schema as a flat depth-first array where the root\n\t// carries `num_children` and each group element claims the next N siblings.\n\tconst topLevelColumns: string[] = [];\n\tconst root = metadata.schema[0];\n\tconst rootChildren = root?.num_children ?? 0;\n\tlet cursor = 1;\n\tfor (let i = 0; i < rootChildren && cursor < metadata.schema.length; i++) {\n\t\tconst el = metadata.schema[cursor];\n\t\tif (el?.name) topLevelColumns.push(el.name);\n\t\tcursor += countSubtree(metadata.schema, cursor);\n\t}\n\n\t// GeoParquet \"geo\" key-value metadata\n\tlet geo: GeoParquetMeta | null = null;\n\tlet legacyGeoParquet = false;\n\tconst geoKv = metadata.key_value_metadata?.find((kv: any) => kv.key === 'geo');\n\tif (geoKv) {\n\t\ttry {\n\t\t\tconst geoJson = JSON.parse(geoKv.value ?? '');\n\n\t\t\t// Detect legacy GeoParquet (schema_version 0.x without \"version\" field).\n\t\t\t// Early geopandas (<0.12) wrote schema_version instead of version.\n\t\t\t// DuckDB's spatial extension rejects these files with:\n\t\t\t// \"Geoparquet metadata does not have a version\"\n\t\t\tif (geoJson.schema_version && !geoJson.version) {\n\t\t\t\tlegacyGeoParquet = true;\n\t\t\t}\n\n\t\t\tgeo = {\n\t\t\t\tprimaryColumn: geoJson.primary_column ?? 'geometry',\n\t\t\t\tcolumns: {}\n\t\t\t};\n\t\t\tif (geoJson.columns) {\n\t\t\t\tfor (const [colName, colMeta] of Object.entries(geoJson.columns) as [string, any][]) {\n\t\t\t\t\tgeo.columns[colName] = {\n\t\t\t\t\t\tencoding: colMeta.encoding ?? 'WKB',\n\t\t\t\t\t\tgeometryTypes: colMeta.geometry_types ?? [],\n\t\t\t\t\t\tcrs: colMeta.crs ?? null,\n\t\t\t\t\t\tbbox: colMeta.bbox\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// malformed geo metadata — ignore\n\t\t}\n\t}\n\n\t// Created-by tool\n\tconst createdBy = metadata.created_by ?? null;\n\n\t// Row group count\n\tconst numRowGroups = metadata.row_groups.length;\n\n\t// Compression: collect unique codecs from first row group's columns\n\tlet compression: string | null = null;\n\tif (numRowGroups > 0 && metadata.row_groups[0].columns) {\n\t\tconst codecs = new Set<string>();\n\t\tfor (const col of metadata.row_groups[0].columns) {\n\t\t\tconst codec = col.meta_data?.codec;\n\t\t\tif (codec) codecs.add(codec);\n\t\t}\n\t\tif (codecs.size === 1) {\n\t\t\tcompression = [...codecs][0];\n\t\t} else if (codecs.size > 1) {\n\t\t\tcompression = [...codecs].join(', ');\n\t\t}\n\t}\n\n\treturn {\n\t\trowCount,\n\t\tschema,\n\t\ttopLevelColumns,\n\t\tgeo,\n\t\tlegacyGeoParquet,\n\t\tcreatedBy,\n\t\tnumRowGroups,\n\t\tcompression\n\t};\n}\n\n/** Count how many schema elements belong to the subtree rooted at `start` (inclusive). */\nfunction countSubtree(schema: any[], start: number): number {\n\tconst el = schema[start];\n\tif (!el) return 0;\n\tconst n = el.num_children ?? 0;\n\tlet cursor = start + 1;\n\tfor (let i = 0; i < n; i++) {\n\t\tcursor += countSubtree(schema, cursor);\n\t}\n\treturn cursor - start;\n}\n\n/**\n * Extract EPSG code from GeoParquet CRS metadata.\n * Returns null for WGS84/CRS84 (no reprojection needed).\n */\nexport function extractEpsgFromGeoMeta(geo: GeoParquetMeta): string | null {\n\tconst primaryCol = geo.columns[geo.primaryColumn];\n\tif (!primaryCol?.crs) return null;\n\n\tconst crs = primaryCol.crs;\n\n\t// OGC CRS84 is lon/lat WGS84\n\tif (crs.type === 'name' && crs.properties?.name?.includes('CRS84')) return null;\n\n\t// PROJJSON: { \"id\": { \"authority\": \"EPSG\", \"code\": 27700 } }\n\tif (crs.id?.authority === 'EPSG') {\n\t\tconst code = crs.id.code;\n\t\tif (WGS84_CODES.has(code)) return null;\n\t\treturn `EPSG:${code}`;\n\t}\n\n\treturn null;\n}\n\n/**\n * Extract normalized geometry types from GeoParquet metadata.\n * Returns the set of geometry types for the primary column.\n */\nexport function extractGeometryTypes(geo: GeoParquetMeta): GeoArrowGeomType[] {\n\tconst primaryCol = geo.columns[geo.primaryColumn];\n\tif (!primaryCol?.geometryTypes?.length) return [];\n\n\tconst typeMap: Record<string, GeoArrowGeomType> = {\n\t\tPoint: 'point',\n\t\tLineString: 'linestring',\n\t\tPolygon: 'polygon',\n\t\tMultiPoint: 'multipoint',\n\t\tMultiLineString: 'multilinestring',\n\t\tMultiPolygon: 'multipolygon'\n\t};\n\n\tconst types: GeoArrowGeomType[] = [];\n\tfor (const raw of primaryCol.geometryTypes) {\n\t\t// GeoParquet geometry_types may include Z/M suffixes like \"Polygon Z\"\n\t\tconst base = raw.split(' ')[0];\n\t\tconst mapped = typeMap[base];\n\t\tif (mapped && !types.includes(mapped)) types.push(mapped);\n\t}\n\treturn types;\n}\n\n/**\n * Extract bounds from GeoParquet metadata (bbox field).\n * Returns [minX, minY, maxX, maxY] or null.\n */\nexport function extractBounds(geo: GeoParquetMeta): [number, number, number, number] | null {\n\tconst primaryCol = geo.columns[geo.primaryColumn];\n\tif (!primaryCol?.bbox || primaryCol.bbox.length < 4) return null;\n\treturn [primaryCol.bbox[0], primaryCol.bbox[1], primaryCol.bbox[2], primaryCol.bbox[3]];\n}\n","/**\n * STAC item facets, filtering, and sorting. Pure TS, framework-agnostic.\n *\n * Inputs are STAC Items (or any subset compatible with `StacItem`). Outputs\n * are slim views, auto-detected facet descriptors, and filtered/sorted view\n * arrays. No DOM, no Svelte, no fetch, no maplibre, safe to publish via\n * `@walkthru-earth/objex-utils`.\n *\n * The flow is intentionally one-directional:\n * StacItem[] --extractItemView--> StacItemView[]\n * StacItemView[] --buildFacets--> FacetSet\n * StacItemView[] + FacetState --applyFacets--> StacItemView[]\n * StacItemView[] + FacetSort --sortViews--> StacItemView[]\n *\n * Callers (any framework) can hold the views array, derive a FacetSet on\n * change, and reactively filter / sort it without re-touching the original\n * StacItems.\n */\n\nimport type { StacItem } from './stac.js';\n\n// ─── Slim projection ────────────────────────────────────────────────\n\n/**\n * Compact, render-ready projection of a STAC Item. Keeps only the fields\n * needed for facet UI, sorting, footprint rendering, and the inspector\n * panel. The full original item is retained on `raw` for callers that need\n * to inspect arbitrary properties without a re-extract pass.\n */\nexport interface StacItemView {\n\tid: string;\n\tcollection: string | null;\n\tbbox: [number, number, number, number] | null;\n\t/** ISO 8601 datetime, or `start_datetime` when only an interval is given. */\n\tdatetime: string | null;\n\t/** End of `start_datetime` / `end_datetime` interval, when present. */\n\tendDatetime: string | null;\n\t/** `eo:cloud_cover` percent (0-100), null when absent. */\n\tcloudCover: number | null;\n\t/** Ground sample distance in meters, null when absent. */\n\tgsd: number | null;\n\tplatform: string | null;\n\tconstellation: string | null;\n\tinstruments: string[];\n\t/** EPSG code from `proj:epsg`, null when absent or non-numeric. */\n\tepsg: number | null;\n\t/** Best-effort thumbnail / overview href, null when no preview asset. */\n\tthumbnailHref: string | null;\n\t/** Asset role set across all assets on the item. */\n\tassetRoles: string[];\n\t/** Original item, retained so the inspector can show the raw JSON. */\n\traw: StacItem;\n}\n\n/** Asset roles inspected when picking a thumbnail href, in priority order. */\nconst THUMBNAIL_ROLES = ['thumbnail', 'overview', 'visual'];\n/** Asset keys inspected when no role-tagged asset is present. */\nconst THUMBNAIL_KEYS = ['thumbnail', 'preview', 'overview', 'rendered_preview', 'visual'];\n\n/**\n * MIME types `<img>` can actually decode. The `visual` role / `visual` key\n * is almost always a multi-MB COG (`image/tiff; application=geotiff;\n * profile=cloud-optimized`), and dragging that through an `<img>` element\n * just streams megabytes before the browser fails to decode it and fires\n * `onerror`. Gate every candidate asset on a browser-renderable MIME so\n * the strip never spends bandwidth on something it cannot paint.\n *\n * Trailing parameters / profile strings (`; charset=...`, `; profile=...`)\n * are matched by anchoring on the leading `image/<subtype>`.\n */\nconst BROWSER_IMAGE_MIME_RE = /^image\\/(png|jpe?g|webp|gif|avif|svg\\+xml|svg)\\b/i;\n\nfunction isBrowserRenderableAsset(asset: { type?: string }): boolean {\n\t// No `type` field at all → assume the catalog author intended a real\n\t// preview (small JPG/PNG). This is the common case for thumbnail-role\n\t// assets on hand-rolled static catalogs.\n\tif (!asset.type) return true;\n\treturn BROWSER_IMAGE_MIME_RE.test(asset.type);\n}\n\nfunction extractThumbnailHref(item: StacItem): string | null {\n\tconst assets = item.assets ?? {};\n\tfor (const role of THUMBNAIL_ROLES) {\n\t\tfor (const asset of Object.values(assets)) {\n\t\t\tif (\n\t\t\t\tArray.isArray(asset?.roles) &&\n\t\t\t\tasset.roles.includes(role) &&\n\t\t\t\tasset.href &&\n\t\t\t\tisBrowserRenderableAsset(asset)\n\t\t\t) {\n\t\t\t\treturn asset.href;\n\t\t\t}\n\t\t}\n\t}\n\tfor (const key of THUMBNAIL_KEYS) {\n\t\tconst asset = assets[key];\n\t\tif (asset?.href && isBrowserRenderableAsset(asset)) return asset.href;\n\t}\n\treturn null;\n}\n\nfunction collectAssetRoles(item: StacItem): string[] {\n\tconst out = new Set<string>();\n\tfor (const asset of Object.values(item.assets ?? {})) {\n\t\tif (Array.isArray(asset?.roles)) {\n\t\t\tfor (const role of asset.roles) {\n\t\t\t\tif (typeof role === 'string') out.add(role);\n\t\t\t}\n\t\t}\n\t}\n\treturn [...out].sort();\n}\n\nfunction readNumber(props: Record<string, unknown>, key: string): number | null {\n\tconst v = props[key];\n\tif (typeof v === 'number' && Number.isFinite(v)) return v;\n\tif (typeof v === 'string') {\n\t\tconst n = Number(v);\n\t\treturn Number.isFinite(n) ? n : null;\n\t}\n\treturn null;\n}\n\nfunction readString(props: Record<string, unknown>, key: string): string | null {\n\tconst v = props[key];\n\treturn typeof v === 'string' && v.length > 0 ? v : null;\n}\n\nfunction readStringArray(props: Record<string, unknown>, key: string): string[] {\n\tconst v = props[key];\n\tif (!Array.isArray(v)) return [];\n\treturn v.filter((x): x is string => typeof x === 'string');\n}\n\n/** Project a STAC Item into a `StacItemView`. Always succeeds. */\nexport function extractItemView(item: StacItem): StacItemView {\n\tconst props = (item.properties ?? {}) as Record<string, unknown>;\n\tconst bbox =\n\t\tArray.isArray(item.bbox) && item.bbox.length >= 4\n\t\t\t? ([\n\t\t\t\t\tNumber(item.bbox[0]),\n\t\t\t\t\tNumber(item.bbox[1]),\n\t\t\t\t\tNumber(item.bbox[2]),\n\t\t\t\t\tNumber(item.bbox[3])\n\t\t\t\t] as [number, number, number, number])\n\t\t\t: null;\n\treturn {\n\t\tid: String(item.id ?? ''),\n\t\tcollection: typeof item.collection === 'string' ? item.collection : null,\n\t\tbbox,\n\t\tdatetime: readString(props, 'datetime') ?? readString(props, 'start_datetime'),\n\t\tendDatetime: readString(props, 'end_datetime'),\n\t\tcloudCover: readNumber(props, 'eo:cloud_cover'),\n\t\tgsd: readNumber(props, 'gsd'),\n\t\tplatform: readString(props, 'platform'),\n\t\tconstellation: readString(props, 'constellation'),\n\t\tinstruments: readStringArray(props, 'instruments'),\n\t\tepsg: readNumber(props, 'proj:epsg'),\n\t\tthumbnailHref: extractThumbnailHref(item),\n\t\tassetRoles: collectAssetRoles(item),\n\t\traw: item\n\t};\n}\n\n// ─── Facet detection ────────────────────────────────────────────────\n\n/**\n * Numeric facet, e.g. cloud cover. `min`/`max` are derived from the loaded\n * views so the UI can use them as slider bounds. `count` is how many of the\n * input views had this field at all.\n */\nexport interface NumericFacet {\n\tkind: 'numeric';\n\tfield: NumericFacetField;\n\tmin: number;\n\tmax: number;\n\tcount: number;\n}\n\n/**\n * Enum facet, e.g. platform. `values` is sorted by descending count so the\n * most common values surface first in chip lists.\n */\nexport interface EnumFacet {\n\tkind: 'enum';\n\tfield: EnumFacetField;\n\tvalues: { value: string; count: number }[];\n}\n\n/**\n * Calendar-aligned bin granularity for the datetime histogram. Picked\n * automatically from the loaded items' time span so callers never see a\n * span-vs-resolution mismatch (e.g. month bins on a 30-day window or day bins\n * on a 20-year archive). See `pickGranularity` for the breakpoints.\n */\nexport type DatetimeGranularity = 'day' | 'week' | 'month' | 'year';\n\n/**\n * Datetime facet, with min/max for slider bounds and a calendar-aligned\n * histogram the UI can render under a range slider. Each bin spans one\n * `granularity` unit (UTC day, ISO week starting Monday, calendar month, or\n * calendar year). `bins[i]` is the count of items whose `datetime` falls\n * inside the bin starting at `binEdges[i]` (epoch ms, UTC). `bins.length ===\n * binEdges.length`, capped at `DATETIME_HISTOGRAM_BINS_MAX`.\n */\nexport interface DatetimeFacet {\n\tkind: 'datetime';\n\tfield: 'datetime';\n\t/** Earliest datetime, ISO 8601. */\n\tmin: string;\n\t/** Latest datetime, ISO 8601. */\n\tmax: string;\n\tcount: number;\n\t/** Per-bin counts. Length matches `binEdges.length`. */\n\tbins: number[];\n\t/** Auto-picked calendar granularity for each histogram bucket. */\n\tgranularity: DatetimeGranularity;\n\t/** Epoch ms (UTC) of each bin's start boundary. Same length as `bins`. */\n\tbinEdges: number[];\n}\n\nexport type Facet = NumericFacet | EnumFacet | DatetimeFacet;\nexport type NumericFacetField = 'cloudCover' | 'gsd';\nexport type EnumFacetField =\n\t| 'collection'\n\t| 'platform'\n\t| 'constellation'\n\t| 'instruments'\n\t| 'assetRoles';\n\n/**\n * Soft cap on histogram bin count. The actual count is derived from the span\n * + granularity (e.g. a 5-year span at month granularity emits 60 bins, a\n * 90-day span at day granularity emits 90 bins). Spans that would exceed the\n * cap are clamped here, the next coarser granularity should already have been\n * picked by `pickGranularity` so this only protects against pathological\n * inputs.\n */\nexport const DATETIME_HISTOGRAM_BINS_MAX = 64;\n\n/** @deprecated Retained for backward compatibility. Use `DATETIME_HISTOGRAM_BINS_MAX`. */\nexport const DATETIME_HISTOGRAM_BINS = 32;\n\nconst MS_PER_DAY = 86_400_000;\nconst MS_PER_YEAR = MS_PER_DAY * 365.25;\n\n/** Result of `buildFacets`: every facet that has variance in the input set. */\nexport interface FacetSet {\n\tdatetime: DatetimeFacet | null;\n\tnumeric: NumericFacet[];\n\tenums: EnumFacet[];\n\t/** Total number of views the facet set was built from. */\n\ttotal: number;\n}\n\nconst NUMERIC_FIELDS: NumericFacetField[] = ['cloudCover', 'gsd'];\nconst ENUM_FIELDS: EnumFacetField[] = [\n\t'collection',\n\t'platform',\n\t'constellation',\n\t'instruments',\n\t'assetRoles'\n];\n\nfunction buildNumericFacet(views: StacItemView[], field: NumericFacetField): NumericFacet | null {\n\tlet min = Number.POSITIVE_INFINITY;\n\tlet max = Number.NEGATIVE_INFINITY;\n\tlet count = 0;\n\tfor (const v of views) {\n\t\tconst value = v[field];\n\t\tif (value == null || !Number.isFinite(value)) continue;\n\t\tif (value < min) min = value;\n\t\tif (value > max) max = value;\n\t\tcount++;\n\t}\n\tif (count === 0 || min === max) return null;\n\treturn { kind: 'numeric', field, min, max, count };\n}\n\nfunction buildEnumFacet(views: StacItemView[], field: EnumFacetField): EnumFacet | null {\n\tconst counts = new Map<string, number>();\n\tfor (const v of views) {\n\t\tconst raw = v[field];\n\t\tif (raw == null) continue;\n\t\tif (Array.isArray(raw)) {\n\t\t\tfor (const item of raw) counts.set(item, (counts.get(item) ?? 0) + 1);\n\t\t} else if (typeof raw === 'string' && raw.length > 0) {\n\t\t\tcounts.set(raw, (counts.get(raw) ?? 0) + 1);\n\t\t}\n\t}\n\tif (counts.size < 2) return null;\n\tconst values = [...counts.entries()]\n\t\t.map(([value, count]) => ({ value, count }))\n\t\t.sort((a, b) => b.count - a.count || a.value.localeCompare(b.value));\n\treturn { kind: 'enum', field, values };\n}\n\n/**\n * Pick a calendar granularity from the time span. Inspired by lazycogs's\n * `_TemporalGrouper` family: short windows surface daily / weekly cadence,\n * long archives roll up to month / year so each bin still represents a\n * meaningful slice of data.\n */\nexport function pickGranularity(spanMs: number): DatetimeGranularity {\n\tif (spanMs <= 90 * MS_PER_DAY) return 'day';\n\tif (spanMs <= 2 * MS_PER_YEAR) return 'week';\n\tif (spanMs <= 20 * MS_PER_YEAR) return 'month';\n\treturn 'year';\n}\n\n/** Floor `t` to the start of its containing UTC day (00:00:00.000Z). */\nfunction floorUtcDay(t: number): number {\n\tconst d = new Date(t);\n\treturn Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());\n}\n\n/** Floor `t` to the Monday 00:00 UTC that starts its ISO week. */\nfunction floorIsoWeek(t: number): number {\n\tconst dayStart = floorUtcDay(t);\n\t// JS getUTCDay: Sun=0, Mon=1, ..., Sat=6. ISO weeks start on Monday.\n\tconst dow = new Date(dayStart).getUTCDay();\n\tconst offsetDays = (dow + 6) % 7; // Mon→0, Tue→1, ..., Sun→6\n\treturn dayStart - offsetDays * MS_PER_DAY;\n}\n\n/** Floor `t` to the 1st of its UTC month at 00:00. */\nfunction floorUtcMonth(t: number): number {\n\tconst d = new Date(t);\n\treturn Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1);\n}\n\n/** Floor `t` to Jan 1 of its UTC year at 00:00. */\nfunction floorUtcYear(t: number): number {\n\tconst d = new Date(t);\n\treturn Date.UTC(d.getUTCFullYear(), 0, 1);\n}\n\nfunction floorBin(t: number, g: DatetimeGranularity): number {\n\tswitch (g) {\n\t\tcase 'day':\n\t\t\treturn floorUtcDay(t);\n\t\tcase 'week':\n\t\t\treturn floorIsoWeek(t);\n\t\tcase 'month':\n\t\t\treturn floorUtcMonth(t);\n\t\tcase 'year':\n\t\t\treturn floorUtcYear(t);\n\t}\n}\n\n/** Advance `t` to the start of the next bin at granularity `g`. */\nfunction nextBin(t: number, g: DatetimeGranularity): number {\n\tconst d = new Date(t);\n\tswitch (g) {\n\t\tcase 'day':\n\t\t\treturn t + MS_PER_DAY;\n\t\tcase 'week':\n\t\t\treturn t + 7 * MS_PER_DAY;\n\t\tcase 'month':\n\t\t\treturn Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + 1, 1);\n\t\tcase 'year':\n\t\t\treturn Date.UTC(d.getUTCFullYear() + 1, 0, 1);\n\t}\n}\n\nfunction buildDatetimeFacet(views: StacItemView[]): DatetimeFacet | null {\n\tconst timestamps: number[] = [];\n\tfor (const v of views) {\n\t\tif (!v.datetime) continue;\n\t\tconst t = Date.parse(v.datetime);\n\t\tif (Number.isFinite(t)) timestamps.push(t);\n\t}\n\tif (timestamps.length < 2) return null;\n\tlet min = timestamps[0];\n\tlet max = timestamps[0];\n\tfor (const t of timestamps) {\n\t\tif (t < min) min = t;\n\t\tif (t > max) max = t;\n\t}\n\tif (min === max) return null;\n\n\tlet granularity = pickGranularity(max - min);\n\tlet binEdges = computeBinEdges(min, max, granularity);\n\n\t// Defensive clamp, if a pathological input would emit more than\n\t// `DATETIME_HISTOGRAM_BINS_MAX` bins at the picked granularity, step up\n\t// to the next coarser granularity until we fit.\n\twhile (binEdges.length > DATETIME_HISTOGRAM_BINS_MAX && granularity !== 'year') {\n\t\tgranularity = coarsenGranularity(granularity);\n\t\tbinEdges = computeBinEdges(min, max, granularity);\n\t}\n\n\tconst bins = new Array<number>(binEdges.length).fill(0);\n\tfor (const t of timestamps) {\n\t\tconst idx = findBinIndex(binEdges, t);\n\t\tbins[idx]++;\n\t}\n\n\treturn {\n\t\tkind: 'datetime',\n\t\tfield: 'datetime',\n\t\tmin: new Date(min).toISOString(),\n\t\tmax: new Date(max).toISOString(),\n\t\tcount: timestamps.length,\n\t\tbins,\n\t\tgranularity,\n\t\tbinEdges\n\t};\n}\n\nfunction coarsenGranularity(g: DatetimeGranularity): DatetimeGranularity {\n\tswitch (g) {\n\t\tcase 'day':\n\t\t\treturn 'week';\n\t\tcase 'week':\n\t\t\treturn 'month';\n\t\tcase 'month':\n\t\tcase 'year':\n\t\t\treturn 'year';\n\t}\n}\n\n/** Compute calendar-aligned bin start edges covering `[min, max]` inclusive. */\nfunction computeBinEdges(min: number, max: number, g: DatetimeGranularity): number[] {\n\tconst edges: number[] = [];\n\tlet cursor = floorBin(min, g);\n\tconst stop = max;\n\t// Hard upper-bound the loop in case of malformed input. The defensive\n\t// while loop above will coarsen and retry if we hit this.\n\tfor (let i = 0; i < DATETIME_HISTOGRAM_BINS_MAX * 4 && cursor <= stop; i++) {\n\t\tedges.push(cursor);\n\t\tcursor = nextBin(cursor, g);\n\t}\n\treturn edges;\n}\n\n/**\n * Locate the bin containing `t` via binary search on bin start edges.\n * Returns the index of the largest edge ≤ t, clamped into `[0, edges.length-1]`.\n */\nfunction findBinIndex(edges: number[], t: number): number {\n\tif (t <= edges[0]) return 0;\n\tif (t >= edges[edges.length - 1]) return edges.length - 1;\n\tlet lo = 0;\n\tlet hi = edges.length - 1;\n\twhile (lo < hi) {\n\t\tconst mid = (lo + hi + 1) >>> 1;\n\t\tif (edges[mid] <= t) lo = mid;\n\t\telse hi = mid - 1;\n\t}\n\treturn lo;\n}\n\n/**\n * Scan a list of views and emit only those facets that have meaningful\n * variance. A facet is omitted when:\n * - numeric: fewer than two distinct finite values\n * - enum: fewer than two distinct values\n * - datetime: fewer than two parseable timestamps with distinct values\n *\n * The intent is \"render only the controls that will narrow this dataset\",\n * so callers can map each returned facet to a UI component without further\n * checks.\n */\nexport function buildFacets(views: StacItemView[]): FacetSet {\n\tconst numeric: NumericFacet[] = [];\n\tfor (const field of NUMERIC_FIELDS) {\n\t\tconst f = buildNumericFacet(views, field);\n\t\tif (f) numeric.push(f);\n\t}\n\tconst enums: EnumFacet[] = [];\n\tfor (const field of ENUM_FIELDS) {\n\t\tconst f = buildEnumFacet(views, field);\n\t\tif (f) enums.push(f);\n\t}\n\treturn {\n\t\tdatetime: buildDatetimeFacet(views),\n\t\tnumeric,\n\t\tenums,\n\t\ttotal: views.length\n\t};\n}\n\n// ─── Filtering ──────────────────────────────────────────────────────\n\n/**\n * Mutable filter state, intended to be held by the UI layer. Each entry is\n * optional, omitting an entry means \"no filter on this field\". Numeric\n * ranges are inclusive on both ends. Enum sets are union-match (any value\n * in the set passes).\n */\nexport interface FacetState {\n\tdatetime?: { min?: string; max?: string };\n\tnumeric?: Partial<Record<NumericFacetField, { min?: number; max?: number }>>;\n\tenums?: Partial<Record<EnumFacetField, string[]>>;\n}\n\nfunction inNumericRange(value: number | null, range: { min?: number; max?: number }): boolean {\n\tif (value == null || !Number.isFinite(value)) return false;\n\tif (range.min != null && value < range.min) return false;\n\tif (range.max != null && value > range.max) return false;\n\treturn true;\n}\n\nfunction inEnumSet(value: string | string[] | null, allow: string[]): boolean {\n\tif (allow.length === 0) return true;\n\tif (value == null) return false;\n\tif (Array.isArray(value)) return value.some((v) => allow.includes(v));\n\treturn allow.includes(value);\n}\n\nfunction inDatetimeRange(value: string | null, range: { min?: string; max?: string }): boolean {\n\tif (!value) return false;\n\tconst t = Date.parse(value);\n\tif (!Number.isFinite(t)) return false;\n\tif (range.min) {\n\t\tconst m = Date.parse(range.min);\n\t\tif (Number.isFinite(m) && t < m) return false;\n\t}\n\tif (range.max) {\n\t\tconst m = Date.parse(range.max);\n\t\tif (Number.isFinite(m) && t > m) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Filter views by `state`. Empty / missing entries are no-ops. Returns a new\n * array, the input is never mutated. Order is preserved, run `sortViews`\n * afterwards if a different order is needed.\n */\nexport function applyFacets(\n\tviews: StacItemView[],\n\tstate: FacetState | null | undefined\n): StacItemView[] {\n\tif (!state) return views;\n\tconst dt = state.datetime;\n\tconst num = state.numeric;\n\tconst enums = state.enums;\n\tconst hasDatetime = dt && (dt.min || dt.max);\n\tconst hasNumeric = num && Object.values(num).some((r) => r && (r.min != null || r.max != null));\n\tconst hasEnums = enums && Object.values(enums).some((a) => Array.isArray(a) && a.length > 0);\n\tif (!hasDatetime && !hasNumeric && !hasEnums) return views;\n\n\treturn views.filter((view) => {\n\t\tif (hasDatetime && dt && !inDatetimeRange(view.datetime, dt)) return false;\n\t\tif (hasNumeric && num) {\n\t\t\tfor (const field of NUMERIC_FIELDS) {\n\t\t\t\tconst range = num[field];\n\t\t\t\tif (!range || (range.min == null && range.max == null)) continue;\n\t\t\t\tif (!inNumericRange(view[field], range)) return false;\n\t\t\t}\n\t\t}\n\t\tif (hasEnums && enums) {\n\t\t\tfor (const field of ENUM_FIELDS) {\n\t\t\t\tconst allow = enums[field];\n\t\t\t\tif (!Array.isArray(allow) || allow.length === 0) continue;\n\t\t\t\tif (!inEnumSet(view[field] as string | string[] | null, allow)) return false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t});\n}\n\n// ─── Sorting ────────────────────────────────────────────────────────\n\nexport type FacetSort =\n\t| 'datetime-desc'\n\t| 'datetime-asc'\n\t| 'cloud-asc'\n\t| 'cloud-desc'\n\t| 'gsd-asc'\n\t| 'gsd-desc'\n\t| 'id-asc';\n\n/**\n * Sort views by one of a fixed set of strategies. Items missing the sort\n * field always sink to the bottom (regardless of asc/desc) so a `cloud-asc`\n * sort never surfaces \"items with no cloud cover\" above the cleanest scenes.\n */\nexport function sortViews(views: StacItemView[], sort: FacetSort): StacItemView[] {\n\tconst arr = views.slice();\n\tconst cmp = getComparator(sort);\n\tarr.sort(cmp);\n\treturn arr;\n}\n\nfunction getComparator(sort: FacetSort): (a: StacItemView, b: StacItemView) => number {\n\tswitch (sort) {\n\t\tcase 'datetime-desc':\n\t\t\treturn (a, b) => compareNullableNumber(parseTime(b.datetime), parseTime(a.datetime));\n\t\tcase 'datetime-asc':\n\t\t\treturn (a, b) => compareNullableNumber(parseTime(a.datetime), parseTime(b.datetime));\n\t\tcase 'cloud-asc':\n\t\t\treturn (a, b) => compareNullableNumber(a.cloudCover, b.cloudCover);\n\t\tcase 'cloud-desc':\n\t\t\treturn (a, b) => compareNullableNumber(b.cloudCover, a.cloudCover);\n\t\tcase 'gsd-asc':\n\t\t\treturn (a, b) => compareNullableNumber(a.gsd, b.gsd);\n\t\tcase 'gsd-desc':\n\t\t\treturn (a, b) => compareNullableNumber(b.gsd, a.gsd);\n\t\tcase 'id-asc':\n\t\t\treturn (a, b) => a.id.localeCompare(b.id);\n\t}\n}\n\nfunction parseTime(s: string | null): number | null {\n\tif (!s) return null;\n\tconst t = Date.parse(s);\n\treturn Number.isFinite(t) ? t : null;\n}\n\nfunction compareNullableNumber(a: number | null, b: number | null): number {\n\tconst aMissing = a == null || !Number.isFinite(a);\n\tconst bMissing = b == null || !Number.isFinite(b);\n\tif (aMissing && bMissing) return 0;\n\tif (aMissing) return 1;\n\tif (bMissing) return -1;\n\treturn (a as number) - (b as number);\n}\n\n// ─── State helpers ──────────────────────────────────────────────────\n\n/** True when any filter in `state` would actually narrow the input. */\nexport function hasActiveFilters(state: FacetState | null | undefined): boolean {\n\tif (!state) return false;\n\tif (state.datetime && (state.datetime.min || state.datetime.max)) return true;\n\tif (state.numeric) {\n\t\tfor (const r of Object.values(state.numeric)) {\n\t\t\tif (r && (r.min != null || r.max != null)) return true;\n\t\t}\n\t}\n\tif (state.enums) {\n\t\tfor (const a of Object.values(state.enums)) {\n\t\t\tif (Array.isArray(a) && a.length > 0) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/** Return `state` with every filter cleared. Useful for reset buttons. */\nexport function emptyFacetState(): FacetState {\n\treturn {};\n}\n","/**\n * stac-geoparquet helpers.\n *\n * Pure TypeScript, zero Svelte / DuckDB / deck.gl dependencies. Re-exported\n * through `@walkthru-earth/objex-utils` so other projects can consume the\n * detection + row-to-Item transforms without pulling the Svelte lib.\n *\n * The module is decoupled from WKB decoding: callers pass a `wkbParser`\n * callback (the objex Svelte lib threads its `parseWKB`; other consumers\n * can plug in `geoarrow-wasm`, `wkx`, or any other library).\n */\n\nimport type { StacAsset, StacItem, StacLink } from './stac.js';\n\n/** Minimal schema column shape. Works with hyparquet, DuckDB, Arrow. */\nexport interface StacGeoparquetSchemaColumn {\n\tname: string;\n\ttype?: string;\n}\n\n/** Bbox in struct shape as produced by DuckDB's `bbox struct(xmin,ymin,xmax,ymax)`. */\nexport interface StacBboxStruct {\n\txmin: number;\n\tymin: number;\n\txmax: number;\n\tymax: number;\n}\n\n/** Generic Record shape representing a single stac-geoparquet row after DuckDB decoding. */\nexport type StacGeoparquetRow = Record<string, unknown>;\n\n/**\n * Recursively convert Arrow nested cells (StructRow, ListVector, MapVector)\n * to plain JS arrays / objects so downstream `Array.isArray()` / property\n * destructuring / `Object.entries()` work the way library consumers expect.\n *\n * DuckDB-WASM bundles apache-arrow v17 and surfaces nested cells as Arrow\n * proxies even after `Row.toJSON()` (a known v17 quirk on LIST<STRUCT> and\n * nested STRUCTs). Without this conversion:\n * - `Array.isArray(properties.bands)` returns false, so `extractCogAssets`'s\n * item-level bands fallback never runs (NAIP-style 4-band catalogs collapse\n * to a single \"Band 1\" picker)\n * - destructured `{xmin, ymin, ...}` reads from a `bbox` StructRow may yield\n * undefined, so `flattenStacBbox` returns null and `buildMosaicSourceMeta`\n * drops every item (mosaic never fits to bounds)\n *\n * Plain JS values pass through unchanged.\n */\nfunction plainifyArrowValue(value: unknown): unknown {\n\tif (value === null || value === undefined) return value;\n\tconst t = typeof value;\n\tif (t === 'string' || t === 'number' || t === 'boolean' || t === 'bigint') return value;\n\tif (value instanceof Uint8Array || value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {\n\t\treturn value;\n\t}\n\tif (Array.isArray(value)) return value.map(plainifyArrowValue);\n\tconst obj = value as { toJSON?: () => unknown; toArray?: () => unknown[] };\n\tif (typeof obj.toJSON === 'function') {\n\t\treturn plainifyArrowValue(obj.toJSON());\n\t}\n\tif (typeof obj.toArray === 'function') {\n\t\treturn obj.toArray().map(plainifyArrowValue);\n\t}\n\tif (t === 'object') {\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tout[k] = plainifyArrowValue(v);\n\t\t}\n\t\treturn out;\n\t}\n\treturn value;\n}\n\nexport interface StacRowToItemOptions {\n\t/**\n\t * Decoder for the geometry column. Accepts a Uint8Array of WKB bytes and\n\t * returns a GeoJSON geometry object (or null on failure).\n\t *\n\t * Consumers in the objex Svelte lib should pass `parseWKB` from\n\t * `@walkthru-earth/objex-utils`. Other projects can use any WKB library.\n\t */\n\twkbParser?: (bytes: Uint8Array) => unknown;\n\t/**\n\t * Column name holding the WKB bytes. Defaults to `'geom_wkb'` because the\n\t * recommended SQL projection is `ST_AsWKB(geometry) AS geom_wkb`.\n\t */\n\twkbColumn?: string;\n\t/** Override the column holding the pre-decoded GeoJSON geometry, when available. */\n\tgeometryColumn?: string;\n}\n\n/** Columns every stac-geoparquet file MUST carry per the stac-geoparquet spec. */\nexport const STAC_GEOPARQUET_REQUIRED_COLUMNS = [\n\t'stac_version',\n\t'type',\n\t'geometry',\n\t'assets'\n] as const;\n\n/**\n * Detect stac-geoparquet by presence of the required STAC columns.\n *\n * Deliberately type-agnostic: some pipelines know the type (DuckDB DESCRIBE,\n * Arrow Field), others only have the name list (hyparquet schema walk). The\n * set of names is sufficient for routing.\n */\nexport function isStacGeoparquetSchema(schema: StacGeoparquetSchemaColumn[]): boolean {\n\tif (!Array.isArray(schema) || schema.length === 0) return false;\n\tconst names = new Set(schema.map((c) => c.name));\n\treturn STAC_GEOPARQUET_REQUIRED_COLUMNS.every((c) => names.has(c));\n}\n\n/**\n * Flatten a DuckDB `struct(xmin,ymin,xmax,ymax)` bbox to the `[minX, minY, maxX, maxY]`\n * array shape that STAC Items and deck.gl-geotiff MosaicLayer expect.\n *\n * Pass-through for arrays so callers that already have `[minX,minY,maxX,maxY]`\n * shape (e.g. from a Feature's `bbox` field) don't need a separate path.\n */\nexport function flattenStacBbox(\n\tbbox: StacBboxStruct | number[] | null | undefined\n): [number, number, number, number] | null {\n\tif (!bbox) return null;\n\tif (Array.isArray(bbox)) {\n\t\tif (bbox.length < 4) return null;\n\t\tconst [minX, minY, maxX, maxY] = bbox;\n\t\tif (![minX, minY, maxX, maxY].every((v) => Number.isFinite(v))) return null;\n\t\treturn [minX, minY, maxX, maxY];\n\t}\n\tif (typeof bbox === 'object') {\n\t\tconst { xmin, ymin, xmax, ymax } = bbox as StacBboxStruct;\n\t\tif (![xmin, ymin, xmax, ymax].every((v) => Number.isFinite(v))) return null;\n\t\treturn [xmin, ymin, xmax, ymax];\n\t}\n\treturn null;\n}\n\n/**\n * Resolve a possibly-relative STAC asset href against the parquet file URL.\n *\n * `./foo.tif` or `foo.tif` → absolute against `baseUrl`. Absolute URLs\n * (`http(s)://`, `s3://`, `gs://`, etc.) are returned unchanged.\n */\nexport function resolveStacAssetHref(href: string, baseUrl: string): string {\n\tif (!href) return href;\n\tif (/^[a-z][a-z0-9+\\-.]*:\\/\\//i.test(href)) return href;\n\ttry {\n\t\treturn new URL(href, baseUrl).toString();\n\t} catch {\n\t\treturn href;\n\t}\n}\n\n/**\n * Pick the \"primary\" asset from a STAC Item's `assets` map.\n *\n * Priority: caller-specified `preferredKeys` → `data` key → first asset with\n * `roles` containing `'data'` → first asset. Returns `null` if the map is\n * empty or not an object.\n */\nexport function pickStacPrimaryAsset(\n\tassets: Record<string, StacAsset> | null | undefined,\n\tpreferredKeys?: readonly string[]\n): { key: string; asset: StacAsset } | null {\n\tif (!assets || typeof assets !== 'object') return null;\n\tconst entries = Object.entries(assets).filter(\n\t\t([, a]) => a && typeof a === 'object' && typeof (a as StacAsset).href === 'string'\n\t) as [string, StacAsset][];\n\tif (entries.length === 0) return null;\n\n\tif (preferredKeys) {\n\t\tfor (const key of preferredKeys) {\n\t\t\tconst match = entries.find(([k]) => k === key);\n\t\t\tif (match) return { key: match[0], asset: match[1] };\n\t\t}\n\t}\n\tconst data = entries.find(([k]) => k === 'data');\n\tif (data) return { key: data[0], asset: data[1] };\n\n\tconst byRole = entries.find(([, a]) => Array.isArray(a.roles) && a.roles.includes('data'));\n\tif (byRole) return { key: byRole[0], asset: byRole[1] };\n\n\treturn { key: entries[0][0], asset: entries[0][1] };\n}\n\n/**\n * Normalize the `assets` value read from a stac-geoparquet row.\n *\n * DuckDB returns `assets` as a `struct` with a fixed set of named fields (one\n * per asset key present at write-time), which decodes to a plain object.\n * Some rows may have `null` asset values for keys that don't apply to them;\n * those are filtered out.\n */\nfunction normalizeAssetsField(\n\tvalue: unknown,\n\tbaseUrl: string\n): Record<string, StacAsset> | undefined {\n\tif (!value || typeof value !== 'object') return undefined;\n\tconst out: Record<string, StacAsset> = {};\n\tfor (const [key, raw] of Object.entries(value as Record<string, unknown>)) {\n\t\tif (!raw || typeof raw !== 'object') continue;\n\t\tconst asset = raw as StacAsset & Record<string, unknown>;\n\t\tif (typeof asset.href !== 'string' || !asset.href) continue;\n\t\tout[key] = {\n\t\t\t...asset,\n\t\t\thref: resolveStacAssetHref(asset.href, baseUrl)\n\t\t};\n\t}\n\treturn Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * Coerce a stac-geoparquet `datetime` cell into an ISO 8601 string.\n *\n * The stac-geoparquet spec mandates a native Parquet TIMESTAMP (microseconds,\n * UTC-adjusted) rather than a string column, so DuckDB-WASM hands these back\n * as a `BigInt` of microseconds since epoch in the common path. JS `Date` and\n * primitive `number` (ms) are also accepted for tolerance. Anything else is\n * pushed through `String()` and only kept if `Date.parse` accepts it, so\n * malformed values do not propagate as unparseable ISO strings that quietly\n * collapse the datetime facet.\n */\nfunction coerceDatetimeToIso(value: unknown): string | undefined {\n\tif (value == null) return undefined;\n\tif (value instanceof Date) {\n\t\tconst ms = value.getTime();\n\t\treturn Number.isFinite(ms) ? new Date(ms).toISOString() : undefined;\n\t}\n\tif (typeof value === 'bigint') {\n\t\t// Parquet TIMESTAMP(MICROS) → microseconds since epoch.\n\t\tconst ms = Number(value / 1000n);\n\t\treturn Number.isFinite(ms) ? new Date(ms).toISOString() : undefined;\n\t}\n\tif (typeof value === 'number' && Number.isFinite(value)) {\n\t\t// Heuristic: > 1e14 is microseconds, anything smaller is milliseconds.\n\t\tconst ms = Math.abs(value) > 1e14 ? Math.floor(value / 1000) : value;\n\t\treturn new Date(ms).toISOString();\n\t}\n\tif (typeof value === 'string') {\n\t\tconst t = Date.parse(value);\n\t\treturn Number.isFinite(t) ? new Date(t).toISOString() : undefined;\n\t}\n\treturn undefined;\n}\n\n/** Normalize the `links` field, resolving relative hrefs against `baseUrl`. */\nfunction normalizeLinksField(value: unknown, baseUrl: string): StacLink[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst links: StacLink[] = [];\n\tfor (const raw of value) {\n\t\tif (!raw || typeof raw !== 'object') continue;\n\t\tconst link = raw as StacLink;\n\t\tif (typeof link.href !== 'string' || typeof link.rel !== 'string') continue;\n\t\tlinks.push({ ...link, href: resolveStacAssetHref(link.href, baseUrl) });\n\t}\n\treturn links.length > 0 ? links : undefined;\n}\n\n/**\n * Convert one stac-geoparquet row into a standard STAC Item JSON object.\n *\n * Handles:\n * - `assets` named-struct flattening + relative href resolution\n * - `bbox` struct → `[minX, minY, maxX, maxY]` array\n * - Optional WKB geometry → GeoJSON via `opts.wkbParser`\n * - `datetime` → ISO string (passes through already-string values)\n * - Promotes `properties.*` columns (`proj:*`, `datetime`) onto `item.properties`\n */\nexport function stacRowToItem(\n\trow: StacGeoparquetRow,\n\tbaseUrl: string,\n\topts: StacRowToItemOptions = {}\n): StacItem {\n\tconst { wkbParser, wkbColumn = 'geom_wkb', geometryColumn = 'geometry' } = opts;\n\n\t// Coerce Arrow proxies (StructRow, list Vector) on the nested STAC columns\n\t// to plain JS so downstream consumers can rely on Array.isArray / destructure.\n\t// Cheap (only walks the small set of struct/list cells per row) and idempotent\n\t// for callers that already pass plain JSON rows.\n\tfor (const key of ['bbox', 'assets', 'links', 'bands', 'stac_extensions'] as const) {\n\t\tif (row[key] !== undefined && row[key] !== null) {\n\t\t\t(row as Record<string, unknown>)[key] = plainifyArrowValue(row[key]);\n\t\t}\n\t}\n\n\tlet geometry: unknown = row[geometryColumn];\n\tif (!geometry) {\n\t\tconst wkb = row[wkbColumn];\n\t\tif (wkb && wkbParser) {\n\t\t\tconst bytes = wkb instanceof Uint8Array ? wkb : toUint8Array(wkb);\n\t\t\tif (bytes) {\n\t\t\t\ttry {\n\t\t\t\t\tgeometry = wkbParser(bytes) ?? undefined;\n\t\t\t\t} catch {\n\t\t\t\t\tgeometry = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst bbox = flattenStacBbox(row.bbox as StacBboxStruct | number[] | undefined) ?? undefined;\n\tconst assets = normalizeAssetsField(row.assets, baseUrl);\n\tconst links = normalizeLinksField(row.links, baseUrl);\n\n\tconst properties: Record<string, unknown> = {};\n\t// Hoist common STAC-property columns that live at row level in stac-geoparquet.\n\tconst SCALAR_PROP_KEYS = new Set([\n\t\t'gsd',\n\t\t'platform',\n\t\t'constellation',\n\t\t'instruments',\n\t\t'mission',\n\t\t'license'\n\t]);\n\tconst TIMESTAMP_PROP_KEYS = new Set([\n\t\t'datetime',\n\t\t'start_datetime',\n\t\t'end_datetime',\n\t\t'created',\n\t\t'updated'\n\t]);\n\tfor (const [key, value] of Object.entries(row)) {\n\t\tif (value === null || value === undefined) continue;\n\t\tif (key.startsWith('proj:') || key.startsWith('raster:') || key.startsWith('eo:')) {\n\t\t\tproperties[key] = value;\n\t\t\tcontinue;\n\t\t}\n\t\tif (TIMESTAMP_PROP_KEYS.has(key)) {\n\t\t\tconst iso = coerceDatetimeToIso(value);\n\t\t\tif (iso) properties[key] = iso;\n\t\t\tcontinue;\n\t\t}\n\t\tif (SCALAR_PROP_KEYS.has(key)) {\n\t\t\tproperties[key] = value;\n\t\t\tcontinue;\n\t\t}\n\t\tif (key === 'bands') {\n\t\t\tproperties.bands = value;\n\t\t}\n\t}\n\n\tconst item: StacItem = {\n\t\ttype: 'Feature',\n\t\tstac_version: typeof row.stac_version === 'string' ? row.stac_version : '1.0.0',\n\t\tid: typeof row.id === 'string' ? row.id : String(row.id ?? ''),\n\t\tproperties\n\t};\n\tif (typeof row.collection === 'string') item.collection = row.collection;\n\tif (Array.isArray(row.stac_extensions)) {\n\t\t(item as unknown as { stac_extensions: unknown[] }).stac_extensions = row.stac_extensions;\n\t}\n\tif (bbox) item.bbox = bbox;\n\tif (geometry) item.geometry = geometry;\n\tif (assets) item.assets = assets;\n\tif (links) item.links = links;\n\n\treturn item;\n}\n\n/** Best-effort coercion of a value that may already be bytes into a Uint8Array. */\nfunction toUint8Array(value: unknown): Uint8Array | null {\n\tif (value instanceof Uint8Array) return value;\n\tif (value instanceof ArrayBuffer) return new Uint8Array(value);\n\tif (ArrayBuffer.isView(value)) {\n\t\tconst view = value as ArrayBufferView;\n\t\treturn new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n\t}\n\tif (Array.isArray(value)) return new Uint8Array(value as number[]);\n\treturn null;\n}\n","/**\n * STAC link-following hydrator. Walks `links[rel=item]` (Collection),\n * `links[rel=child]` → `links[rel=item]` (Catalog), and `links[rel=next]`\n * (paginated FeatureCollection / STAC API) into a flat list of StacItems.\n */\n\nimport type { StorageAdapter } from '../../../src/lib/storage/adapter.js';\nimport {\n\tisStacCatalog,\n\tisStacCollection,\n\tisStacFeatureCollection,\n\tisStacItem,\n\ttype StacCatalog,\n\ttype StacCollection,\n\ttype StacFeatureCollection,\n\ttype StacItem,\n\ttype StacLink,\n\ttype StacRoutableKind\n} from './stac.js';\n\nexport interface HydrateOptions {\n\tsignal: AbortSignal;\n\t/** Max parallel fetches. Default 12. */\n\tconcurrency?: number;\n\t/** Hard cap on items; catalogs larger than this are truncated. Default 2000. */\n\tlimit?: number;\n\t/** Follow `links[rel=next]` pagination in FeatureCollections. Default true. */\n\tfollowPagination?: boolean;\n\t/** Emit fetched items in batches for progressive rendering. */\n\tonBatch?: (items: StacItem[]) => void;\n\t/** Emit progress totals for UI. */\n\tonProgress?: (fetched: number, totalHinted: number | undefined) => void;\n\t/**\n\t * Map an absolute HTTPS URL to a bucket-relative key when it belongs to the\n\t * caller's connection. When provided and it returns a non-null string,\n\t * `fetchJson` routes through the storage adapter (which handles SigV4) instead\n\t * of a raw cross-origin `fetch`, so private-bucket catalogs can be walked.\n\t */\n\turlToKey?: (absoluteUrl: string) => string | null;\n\t/**\n\t * Optional native STAC API filters appended to the `rel=\"items\"` endpoint\n\t * (and applied to `links[rel=next]` pages). Lets callers narrow a\n\t * collection by spatial / temporal extent before hydration.\n\t */\n\titemsQuery?: StacItemsQuery;\n}\n\n/** Native filters supported by OGC API Features / STAC API on `/items`. */\nexport interface StacItemsQuery {\n\t/** WGS84 bbox `[west, south, east, north]`. */\n\tbbox?: [number, number, number, number];\n\t/** RFC 3339 instant or interval `start/end` (use `..` for open ends). */\n\tdatetime?: string;\n\t/** Per-page item count hint, the server may cap this. */\n\tlimit?: number;\n\t/**\n\t * CQL2-JSON filter expression (STAC API Filter extension). When set, gets\n\t * appended as `?filter=<json>&filter-lang=cql2-json` and re-stamped onto\n\t * every `rel=\"next\"` page so cursor URLs cannot strip it.\n\t */\n\tfilter?: unknown;\n}\n\nexport interface HydrateResult {\n\titems: StacItem[];\n\ttruncated: boolean;\n\trootBaseHref: string;\n}\n\nexport async function hydrateStacItems(\n\troot: StacRoutableKind,\n\tbaseHref: string,\n\tadapter: StorageAdapter,\n\topts: HydrateOptions\n): Promise<HydrateResult> {\n\tconst limit = opts.limit ?? 2000;\n\tconst concurrency = opts.concurrency ?? 12;\n\tconst followPagination = opts.followPagination ?? true;\n\tconst signal = opts.signal;\n\tconst urlToKey = opts.urlToKey;\n\n\tconst items: StacItem[] = [];\n\tlet truncated = false;\n\n\tconst emit = (batch: StacItem[]) => {\n\t\tif (batch.length === 0) return;\n\t\titems.push(...batch);\n\t\topts.onBatch?.(batch);\n\t\topts.onProgress?.(items.length, undefined);\n\t};\n\n\tif (root.kind === 'item') {\n\t\temit([absolutizeItemAssets(root.item, baseHref)]);\n\t\treturn { items, truncated: false, rootBaseHref: baseHref };\n\t}\n\n\tif (root.kind === 'item-collection') {\n\t\tawait consumeFeatureCollection(root.fc, baseHref, adapter, {\n\t\t\tsignal,\n\t\t\tconcurrency,\n\t\t\tlimit,\n\t\t\tfollowPagination,\n\t\t\turlToKey,\n\t\t\titemsQuery: opts.itemsQuery,\n\t\t\tonAccept: (batch) => emit(batch),\n\t\t\tstopCheck: () => items.length >= limit,\n\t\t\tonTruncate: () => {\n\t\t\t\ttruncated = true;\n\t\t\t}\n\t\t});\n\t\treturn { items: items.slice(0, limit), truncated, rootBaseHref: baseHref };\n\t}\n\n\tif (root.kind === 'collection' || root.kind === 'catalog') {\n\t\tconst itemLinks = collectItemLinks(root.payload, baseHref);\n\t\tconst childLinks =\n\t\t\troot.kind === 'catalog' || itemLinks.length === 0\n\t\t\t\t? collectChildLinks(root.payload, baseHref)\n\t\t\t\t: [];\n\t\t// OGC API Features convention used by STAC API endpoints (earth-search,\n\t\t// planetary-computer, pgstac, ...): a Collection advertises a single\n\t\t// `rel=\"items\"` link pointing at a paginated FeatureCollection. Static\n\t\t// \"self-contained\" catalogs use `rel=\"item\"` per item file instead, so\n\t\t// only walk the items endpoint when no static item links are present.\n\t\tconst itemsEndpoint =\n\t\t\titemLinks.length === 0 ? collectItemsEndpoint(root.payload, baseHref, opts.itemsQuery) : null;\n\n\t\tif (itemLinks.length > 0) {\n\t\t\tawait fetchItems(itemLinks, adapter, baseHref, {\n\t\t\t\tsignal,\n\t\t\t\tconcurrency,\n\t\t\t\turlToKey,\n\t\t\t\tonBatch: (batch) => emit(batch),\n\t\t\t\tstopCheck: () => items.length >= limit,\n\t\t\t\tonTruncate: () => {\n\t\t\t\t\ttruncated = true;\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (itemsEndpoint) {\n\t\t\ttry {\n\t\t\t\tconst json = await fetchJson(adapter, itemsEndpoint, baseHref, signal, urlToKey);\n\t\t\t\tif (isStacFeatureCollection(json)) {\n\t\t\t\t\tawait consumeFeatureCollection(json, itemsEndpoint, adapter, {\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\tconcurrency,\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t\tfollowPagination,\n\t\t\t\t\t\turlToKey,\n\t\t\t\t\t\titemsQuery: opts.itemsQuery,\n\t\t\t\t\t\tonAccept: (batch) => emit(batch),\n\t\t\t\t\t\tstopCheck: () => items.length >= limit,\n\t\t\t\t\t\tonTruncate: () => {\n\t\t\t\t\t\t\ttruncated = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Endpoint unreachable, fall through to childLinks below.\n\t\t\t}\n\t\t}\n\n\t\tif (!truncated && items.length < limit && childLinks.length > 0) {\n\t\t\tconst queue = [...childLinks];\n\t\t\tconst stopCheck = () => items.length >= limit || signal.aborted;\n\t\t\tconst workerCount = Math.min(concurrency, queue.length);\n\t\t\tconst workers: Promise<void>[] = [];\n\t\t\tfor (let i = 0; i < workerCount; i++) {\n\t\t\t\tworkers.push(\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\twhile (queue.length > 0) {\n\t\t\t\t\t\t\tif (stopCheck()) {\n\t\t\t\t\t\t\t\tif (items.length >= limit) truncated = true;\n\t\t\t\t\t\t\t\tqueue.length = 0;\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst childHref = queue.shift();\n\t\t\t\t\t\t\tif (!childHref) return;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst childJson = await fetchJson(adapter, childHref, baseHref, signal, urlToKey);\n\t\t\t\t\t\t\t\tif (stopCheck()) {\n\t\t\t\t\t\t\t\t\tif (items.length >= limit) truncated = true;\n\t\t\t\t\t\t\t\t\tqueue.length = 0;\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconst childKind = classifyFetchedJson(childJson);\n\t\t\t\t\t\t\t\tif (childKind.kind === 'none') continue;\n\t\t\t\t\t\t\t\tconst sub = await hydrateStacItems(childKind, childHref, adapter, {\n\t\t\t\t\t\t\t\t\t...opts,\n\t\t\t\t\t\t\t\t\tlimit: limit - items.length,\n\t\t\t\t\t\t\t\t\tonBatch: (batch) => emit(batch),\n\t\t\t\t\t\t\t\t\tonProgress: undefined\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\tif (sub.truncated) truncated = true;\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// Skip unreachable child, keep aggregating.\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})()\n\t\t\t\t);\n\t\t\t}\n\t\t\tawait Promise.all(workers);\n\t\t}\n\n\t\treturn { items: items.slice(0, limit), truncated, rootBaseHref: baseHref };\n\t}\n\n\treturn { items, truncated: false, rootBaseHref: baseHref };\n}\n\n// ─── Internals ──────────────────────────────────────────────────────\n\nfunction collectItemLinks(payload: StacCollection | StacCatalog, baseHref: string): string[] {\n\treturn (payload.links ?? [])\n\t\t.filter((l): l is StacLink => !!l && typeof l.href === 'string' && l.rel === 'item')\n\t\t.map((l) => absolutizeHref(l.href, baseHref));\n}\n\nfunction collectChildLinks(payload: StacCollection | StacCatalog, baseHref: string): string[] {\n\treturn (payload.links ?? [])\n\t\t.filter((l): l is StacLink => !!l && typeof l.href === 'string' && l.rel === 'child')\n\t\t.map((l) => absolutizeHref(l.href, baseHref));\n}\n\n/**\n * True when the payload exposes a `rel=\"items\"` link (OGC API Features /\n * STAC API convention). Lets callers switch to viewport-scoped fetching\n * instead of walking every page.\n */\nexport function hasStacItemsEndpoint(payload: StacCollection | StacCatalog): boolean {\n\treturn (payload.links ?? []).some((l) => !!l && typeof l.href === 'string' && l.rel === 'items');\n}\n\nfunction collectItemsEndpoint(\n\tpayload: StacCollection | StacCatalog,\n\tbaseHref: string,\n\tquery: StacItemsQuery | undefined\n): string | null {\n\tconst link = (payload.links ?? []).find(\n\t\t(l): l is StacLink => !!l && typeof l.href === 'string' && l.rel === 'items'\n\t);\n\tif (!link) return null;\n\treturn applyItemsQuery(absolutizeHref(link.href, baseHref), query);\n}\n\n/**\n * Stamp `bbox` / `datetime` / `limit` onto a STAC items URL. Called both for\n * the first-page endpoint and for every server-emitted `rel=next` href, since\n * some custom STAC API implementations issue cursor URLs that drop the\n * caller's filters and would otherwise return unbounded results on page 2+.\n */\nfunction applyItemsQuery(absolute: string, query: StacItemsQuery | undefined): string {\n\tif (!query) return absolute;\n\ttry {\n\t\tconst url = new URL(absolute);\n\t\tif (query.bbox && query.bbox.length === 4 && !url.searchParams.has('bbox')) {\n\t\t\turl.searchParams.set('bbox', query.bbox.join(','));\n\t\t}\n\t\tif (query.datetime && !url.searchParams.has('datetime')) {\n\t\t\turl.searchParams.set('datetime', query.datetime);\n\t\t}\n\t\tif (typeof query.limit === 'number' && query.limit > 0 && !url.searchParams.has('limit')) {\n\t\t\turl.searchParams.set('limit', String(Math.floor(query.limit)));\n\t\t}\n\t\t// CQL2-JSON filter, encoded as a query-string param per OGC API Filter.\n\t\t// Skip when the server already stamped `filter=` onto its `rel=next` URL\n\t\t// (some servers echo the original filter in cursor links, double-stamping\n\t\t// would corrupt the JSON).\n\t\tif (query.filter !== undefined && query.filter !== null && !url.searchParams.has('filter')) {\n\t\t\ttry {\n\t\t\t\turl.searchParams.set('filter', JSON.stringify(query.filter));\n\t\t\t\tif (!url.searchParams.has('filter-lang')) {\n\t\t\t\t\turl.searchParams.set('filter-lang', 'cql2-json');\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// JSON.stringify can only throw on cyclic input; fall through with\n\t\t\t\t// the URL unchanged so hydration continues without the filter.\n\t\t\t}\n\t\t}\n\t\treturn url.toString();\n\t} catch {\n\t\treturn absolute;\n\t}\n}\n\nasync function consumeFeatureCollection(\n\tfc: StacFeatureCollection,\n\tbaseHref: string,\n\tadapter: StorageAdapter,\n\tctx: {\n\t\tsignal: AbortSignal;\n\t\tconcurrency: number;\n\t\tlimit: number;\n\t\tfollowPagination: boolean;\n\t\turlToKey?: (absoluteUrl: string) => string | null;\n\t\titemsQuery?: StacItemsQuery;\n\t\tonAccept: (items: StacItem[]) => void;\n\t\tstopCheck: () => boolean;\n\t\tonTruncate: () => void;\n\t}\n): Promise<void> {\n\tconst accepted = fc.features\n\t\t.filter(isStacItem)\n\t\t.map((item) => absolutizeItemAssets(item, baseHref));\n\tctx.onAccept(accepted);\n\tif (ctx.stopCheck()) {\n\t\tctx.onTruncate();\n\t\treturn;\n\t}\n\n\tif (!ctx.followPagination) return;\n\tconst next = (fc.links ?? []).find((l) => l && l.rel === 'next' && typeof l.href === 'string');\n\tif (!next) return;\n\n\tconst nextHref = applyItemsQuery(absolutizeHref(next.href, baseHref), ctx.itemsQuery);\n\tif (ctx.signal.aborted) return;\n\ttry {\n\t\tconst json = await fetchJson(adapter, nextHref, baseHref, ctx.signal, ctx.urlToKey);\n\t\tif (!isStacFeatureCollection(json)) return;\n\t\tawait consumeFeatureCollection(json, nextHref, adapter, ctx);\n\t} catch {\n\t\t// Pagination dead-end, keep what we have.\n\t}\n}\n\nasync function fetchItems(\n\threfs: string[],\n\tadapter: StorageAdapter,\n\tbaseHref: string,\n\tctx: {\n\t\tsignal: AbortSignal;\n\t\tconcurrency: number;\n\t\turlToKey?: (absoluteUrl: string) => string | null;\n\t\tonBatch: (items: StacItem[]) => void;\n\t\tstopCheck: () => boolean;\n\t\tonTruncate: () => void;\n\t}\n): Promise<void> {\n\tconst queue = [...hrefs];\n\tconst workers: Promise<void>[] = [];\n\tconst workerCount = Math.min(ctx.concurrency, queue.length);\n\n\tfor (let i = 0; i < workerCount; i++) {\n\t\tworkers.push(\n\t\t\t(async () => {\n\t\t\t\twhile (queue.length > 0) {\n\t\t\t\t\tif (ctx.signal.aborted) return;\n\t\t\t\t\tif (ctx.stopCheck()) {\n\t\t\t\t\t\tctx.onTruncate();\n\t\t\t\t\t\tqueue.length = 0;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst href = queue.shift();\n\t\t\t\t\tif (!href) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst json = await fetchJson(adapter, href, baseHref, ctx.signal, ctx.urlToKey);\n\t\t\t\t\t\tif (isStacItem(json)) ctx.onBatch([absolutizeItemAssets(json, href)]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Skip this item, a dead link is not fatal.\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})()\n\t\t);\n\t}\n\n\tawait Promise.all(workers);\n}\n\nasync function fetchJson(\n\tadapter: StorageAdapter,\n\thref: string,\n\t_baseHref: string,\n\tsignal: AbortSignal,\n\turlToKey?: (absoluteUrl: string) => string | null\n): Promise<unknown> {\n\t// Absolute URLs that belong to the caller's own bucket route through the\n\t// adapter so SigV4 presigning applies — raw `fetch` would 403 on private\n\t// buckets. Foreign origins stay on plain `fetch`. Relative hrefs reach here\n\t// only when absolutizeHref could not resolve them against baseHref.\n\tif (/^https?:/i.test(href)) {\n\t\tconst ownKey = urlToKey ? urlToKey(href) : null;\n\t\tif (ownKey !== null) {\n\t\t\tconst buf = await adapter.read(ownKey, undefined, undefined, signal);\n\t\t\treturn JSON.parse(new TextDecoder().decode(buf));\n\t\t}\n\t\tconst res = await fetch(href, { signal });\n\t\tif (!res.ok) throw new Error(`HTTP ${res.status} for ${href}`);\n\t\treturn await res.json();\n\t}\n\tconst buf = await adapter.read(href, undefined, undefined, signal);\n\treturn JSON.parse(new TextDecoder().decode(buf));\n}\n\nfunction classifyFetchedJson(json: unknown): StacRoutableKind {\n\tif (isStacItem(json)) return { kind: 'item', item: json };\n\tif (isStacFeatureCollection(json)) return { kind: 'item-collection', fc: json };\n\tif (isStacCollection(json)) return { kind: 'collection', payload: json };\n\tif (isStacCatalog(json)) return { kind: 'catalog', payload: json };\n\treturn { kind: 'none' };\n}\n\n/**\n * Resolve a possibly-relative href against a base. STAC catalogs commonly use\n * `./child/foo.json` or `../foo.json`. `new URL(relative, base)` handles both.\n */\nexport function absolutizeHref(href: string, baseHref: string): string {\n\tif (/^https?:/i.test(href) || /^s3:/i.test(href) || /^azure:/i.test(href)) return href;\n\ttry {\n\t\treturn new URL(href, baseHref).toString();\n\t} catch {\n\t\treturn href;\n\t}\n}\n\n/**\n * Return a new StacItem with every asset href resolved against the URL the\n * item itself was fetched from. Asset hrefs in STAC Items are relative to the\n * item JSON (`./B04.tif`, `../scene/asset.tif`), so downstream consumers that\n * hand them to `GeoTIFF.fromUrl` or `fetch` need absolute URLs.\n */\nfunction absolutizeItemAssets(item: StacItem, itemHref: string): StacItem {\n\tconst assets = item.assets;\n\tif (!assets) return item;\n\tlet changed = false;\n\tconst resolved: typeof assets = {};\n\tfor (const [key, asset] of Object.entries(assets)) {\n\t\tif (asset?.href && typeof asset.href === 'string') {\n\t\t\tconst abs = absolutizeHref(asset.href, itemHref);\n\t\t\tif (abs !== asset.href) changed = true;\n\t\t\tresolved[key] = { ...asset, href: abs };\n\t\t} else {\n\t\t\tresolved[key] = asset;\n\t\t}\n\t}\n\treturn changed ? { ...item, assets: resolved } : item;\n}\n","/**\n * Translate a `FacetState` into native STAC API parameters and CQL2 filters,\n * gated by what the endpoint advertises in `conformsTo`. Pure TS, framework\n * and transport agnostic.\n *\n * The split between this module and `stac-facets.ts` is intentional. Facets\n * own discovery and client-side filtering (works for any source). This\n * module owns *server-side push-down*, which only makes sense when the\n * source is a STAC API that supports OGC API Features query params or the\n * STAC API filter extension.\n *\n * Callers that want push-down:\n * 1. Fetch the API root, read `conformsTo`.\n * 2. `caps = sniffApiCapabilities(conformsTo)` once per session.\n * 3. On each pan / filter change:\n * const native = toNativeQuery(state, caps);\n * const filter = caps.cql2 ? toCql2Filter(state, caps) : null;\n * Pass `native` to the items endpoint and apply `filter` via\n * `?filter=<json-encoded>` when present. Anything that could not be\n * pushed down stays in `state` and is filtered client-side via\n * `applyFacets`.\n */\n\nimport type { FacetState } from './stac-facets.js';\n\n// ─── Capability sniff ──────────────────────────────────────────────\n\n/**\n * Subset of STAC API capabilities relevant to filter push-down. Read once\n * per session from the API root's `conformsTo` array.\n */\nexport interface StacApiCapabilities {\n\t/** Supports `bbox=` query param (OGC API Features core). */\n\tbbox: boolean;\n\t/** Supports `datetime=` query param (OGC API Features core). */\n\tdatetime: boolean;\n\t/** Supports `collections=` filter (STAC API Item Search). */\n\tcollections: boolean;\n\t/** Supports the STAC API Filter extension via `filter=` + `filter-lang=cql2-json`. */\n\tcql2: boolean;\n\t/** Queryables endpoint advertised, lets clients sniff filterable property names. */\n\tqueryables: boolean;\n}\n\nconst CONFORMANCE_SIGNATURES: { key: keyof StacApiCapabilities; matchers: RegExp[] }[] = [\n\t{\n\t\tkey: 'bbox',\n\t\tmatchers: [/ogc-api[/-]features.*\\/conf\\/core/i, /stac-api.*\\/item-search/i]\n\t},\n\t{\n\t\tkey: 'datetime',\n\t\tmatchers: [/ogc-api[/-]features.*\\/conf\\/core/i, /stac-api.*\\/item-search/i]\n\t},\n\t{\n\t\tkey: 'collections',\n\t\tmatchers: [/stac-api.*\\/item-search/i]\n\t},\n\t{\n\t\tkey: 'cql2',\n\t\tmatchers: [/stac-api.*\\/item-search.*\\/filter/i, /ogc-api[/-]features.*\\/cql2/i, /cql2-json/i]\n\t},\n\t{\n\t\tkey: 'queryables',\n\t\tmatchers: [/stac-api.*\\/item-search.*\\/queryables/i, /ogc-api[/-]features.*\\/queryables/i]\n\t}\n];\n\n/**\n * Parse a STAC API `conformsTo` array into a capability flag set. Tolerant\n * of unknown URIs, missing entries, and casing differences. Defaults to all\n * `false` when given an empty / non-array input, so a caller that hasn't\n * fetched the root yet never accidentally pushes down something the API\n * cannot honor.\n */\nexport function sniffApiCapabilities(conformsTo: unknown): StacApiCapabilities {\n\tconst caps: StacApiCapabilities = {\n\t\tbbox: false,\n\t\tdatetime: false,\n\t\tcollections: false,\n\t\tcql2: false,\n\t\tqueryables: false\n\t};\n\tif (!Array.isArray(conformsTo)) return caps;\n\tconst normalised = conformsTo.filter((s): s is string => typeof s === 'string');\n\tfor (const sig of CONFORMANCE_SIGNATURES) {\n\t\tif (normalised.some((uri) => sig.matchers.some((re) => re.test(uri)))) {\n\t\t\tcaps[sig.key] = true;\n\t\t}\n\t}\n\treturn caps;\n}\n\n// ─── Native-query translation ──────────────────────────────────────\n\n/**\n * Generic STAC items query, compatible with both OGC API Features\n * (`/collections/{id}/items`) and STAC API Item Search (`/search`). Mirrors\n * the shape `stac-hydrate.ts::StacItemsQuery` expects, plus optional\n * `collections` and `filter` for the search endpoint.\n */\nexport interface StacNativeQuery {\n\tbbox?: [number, number, number, number];\n\tdatetime?: string;\n\tcollections?: string[];\n\tlimit?: number;\n\t/** CQL2-JSON object, encode with `JSON.stringify` when serializing. */\n\tfilter?: unknown;\n\t'filter-lang'?: 'cql2-json';\n}\n\nexport interface ToNativeQueryOptions {\n\tbbox?: [number, number, number, number];\n\tlimit?: number;\n}\n\n/**\n * Translate `state` into the subset of native query params the API supports.\n * Anything that can't be pushed down is silently dropped here, the caller is\n * expected to keep applying it client-side via `applyFacets`. This is safe\n * because client filtering is always a superset, never a contradiction.\n *\n * `bbox` / `limit` are accepted as overrides because they typically come\n * from the viewer's viewport + user setting, not from `state`.\n */\nexport function toNativeQuery(\n\tstate: FacetState | null | undefined,\n\tcaps: StacApiCapabilities,\n\topts: ToNativeQueryOptions = {}\n): StacNativeQuery {\n\tconst out: StacNativeQuery = {};\n\tif (opts.bbox && caps.bbox) out.bbox = opts.bbox;\n\tif (typeof opts.limit === 'number' && opts.limit > 0) out.limit = Math.floor(opts.limit);\n\tif (!state) return out;\n\n\tif (caps.datetime && state.datetime && (state.datetime.min || state.datetime.max)) {\n\t\tout.datetime = formatDatetimeInterval(state.datetime.min, state.datetime.max);\n\t}\n\n\tif (caps.collections && state.enums?.collection?.length) {\n\t\tout.collections = [...state.enums.collection];\n\t}\n\n\tif (caps.cql2) {\n\t\tconst filter = toCql2Filter(state, caps);\n\t\tif (filter) {\n\t\t\tout.filter = filter;\n\t\t\tout['filter-lang'] = 'cql2-json';\n\t\t}\n\t}\n\n\treturn out;\n}\n\n/**\n * RFC 3339 datetime interval string. `null/undefined` ends become `..` per\n * the STAC API spec. A bare instant is returned when both ends are equal.\n */\nfunction formatDatetimeInterval(min?: string, max?: string): string {\n\tconst lo = min ?? '..';\n\tconst hi = max ?? '..';\n\tif (lo === '..' && hi === '..') return '..';\n\tif (lo === hi) return lo;\n\treturn `${lo}/${hi}`;\n}\n\n// ─── CQL2 builder ──────────────────────────────────────────────────\n\n/**\n * CQL2-JSON expression node (very loose typing because the spec allows\n * arbitrary nesting and we only emit a small subset). Use `unknown` at the\n * boundary, cast inside this module.\n */\ntype Cql2Node = unknown;\n\n/**\n * Build a CQL2-JSON `and` expression from a `FacetState`, covering the\n * filters that aren't already handled by native params. Returns `null` when\n * nothing in `state` requires CQL2 (so the caller can omit `filter=`).\n *\n * Currently emits:\n * - eo:cloud_cover (between)\n * - gsd (between)\n * - proj:epsg (=)\n * - platform (in)\n * - constellation (in)\n * - instruments (a_overlaps)\n *\n * `collection` and `datetime` are skipped here when the corresponding native\n * cap is set, since those are cheaper to push as plain query params. They\n * fall through to CQL2 only when the API advertises CQL2 but not the\n * matching native capability (rare but legal).\n */\nexport function toCql2Filter(\n\tstate: FacetState | null | undefined,\n\tcaps: StacApiCapabilities\n): Cql2Node | null {\n\tif (!state) return null;\n\tconst clauses: Cql2Node[] = [];\n\n\tif (state.numeric) {\n\t\tconst n = state.numeric;\n\t\tpushBetween(clauses, 'eo:cloud_cover', n.cloudCover);\n\t\tpushBetween(clauses, 'gsd', n.gsd);\n\t}\n\n\tif (state.enums) {\n\t\tconst e = state.enums;\n\t\tpushIn(clauses, 'platform', e.platform);\n\t\tpushIn(clauses, 'constellation', e.constellation);\n\t\tpushOverlap(clauses, 'instruments', e.instruments);\n\t\tif (!caps.collections) pushIn(clauses, 'collection', e.collection);\n\t}\n\n\tif (!caps.datetime && state.datetime && (state.datetime.min || state.datetime.max)) {\n\t\tconst lo = state.datetime.min;\n\t\tconst hi = state.datetime.max;\n\t\tif (lo && hi) {\n\t\t\tclauses.push({\n\t\t\t\top: 't_intersects',\n\t\t\t\targs: [{ property: 'datetime' }, { interval: [lo, hi] }]\n\t\t\t});\n\t\t} else if (lo) {\n\t\t\tclauses.push({ op: '>=', args: [{ property: 'datetime' }, { timestamp: lo }] });\n\t\t} else if (hi) {\n\t\t\tclauses.push({ op: '<=', args: [{ property: 'datetime' }, { timestamp: hi }] });\n\t\t}\n\t}\n\n\tif (clauses.length === 0) return null;\n\tif (clauses.length === 1) return clauses[0];\n\treturn { op: 'and', args: clauses };\n}\n\nfunction pushBetween(\n\tout: Cql2Node[],\n\tproperty: string,\n\trange: { min?: number; max?: number } | undefined\n): void {\n\tif (!range) return;\n\tconst { min, max } = range;\n\tif (min == null && max == null) return;\n\tif (min != null && max != null) {\n\t\tout.push({ op: 'between', args: [{ property }, [min, max]] });\n\t\treturn;\n\t}\n\tif (min != null) out.push({ op: '>=', args: [{ property }, min] });\n\tif (max != null) out.push({ op: '<=', args: [{ property }, max] });\n}\n\nfunction pushIn(out: Cql2Node[], property: string, values: string[] | undefined): void {\n\tif (!values || values.length === 0) return;\n\tif (values.length === 1) {\n\t\tout.push({ op: '=', args: [{ property }, values[0]] });\n\t\treturn;\n\t}\n\tout.push({ op: 'in', args: [{ property }, values] });\n}\n\nfunction pushOverlap(out: Cql2Node[], property: string, values: string[] | undefined): void {\n\tif (!values || values.length === 0) return;\n\tout.push({ op: 'a_overlaps', args: [{ property }, values] });\n}\n\n// ─── Residue ───────────────────────────────────────────────────────\n\n/**\n * Subtract everything that was pushed down from `state`, returning the\n * remaining state that the caller still has to apply client-side. Lets the\n * UI avoid double-filtering (which would just be a no-op but wastes work).\n *\n * This is a structural diff, not a deep clone, the input is not mutated.\n */\nexport function residualState(\n\tstate: FacetState | null | undefined,\n\tcaps: StacApiCapabilities\n): FacetState {\n\tif (!state) return {};\n\tconst out: FacetState = {};\n\tif (state.datetime && !caps.datetime && !caps.cql2) out.datetime = state.datetime;\n\telse if (state.datetime && (caps.datetime || caps.cql2)) {\n\t\t// Fully pushed.\n\t}\n\tif (state.numeric) {\n\t\tconst remaining: FacetState['numeric'] = {};\n\t\tfor (const [field, range] of Object.entries(state.numeric)) {\n\t\t\tif (!range) continue;\n\t\t\tif (caps.cql2) continue; // pushed\n\t\t\tremaining[field as keyof typeof remaining] = range;\n\t\t}\n\t\tif (Object.keys(remaining).length > 0) out.numeric = remaining;\n\t}\n\tif (state.enums) {\n\t\tconst remaining: FacetState['enums'] = {};\n\t\tfor (const [field, values] of Object.entries(state.enums)) {\n\t\t\tif (!Array.isArray(values) || values.length === 0) continue;\n\t\t\tif (field === 'collection' && caps.collections) continue;\n\t\t\tif (\n\t\t\t\tcaps.cql2 &&\n\t\t\t\t(field === 'platform' || field === 'constellation' || field === 'instruments')\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tremaining[field as keyof typeof remaining] = values;\n\t\t}\n\t\tif (Object.keys(remaining).length > 0) out.enums = remaining;\n\t}\n\treturn out;\n}\n","/**\n * StacSource contract. Unified interface for the three STAC ingestion paths\n * (STAC API, stac-geoparquet, self-contained static catalog) so the viewer\n * has a single orchestration loop and the UI can branch on capability flags\n * instead of hard-coded discovery modes.\n *\n * Pure TypeScript. No Svelte / maplibre / deck.gl / DuckDB on this import\n * graph. The DuckDB-bound parquet implementation lives under `query/` so the\n * `utils/` side stays publishable via `@walkthru-earth/objex-utils` (slice 6).\n *\n * Per-batch `pushedDown` / `residual` reporting lets the caller skip\n * client-side filtering for dimensions the engine already narrowed, and lets\n * the UI render capability badges. A parquet file with a STRUCT\n * `properties` column can push `eo:cloud_cover` while a sibling file with\n * an opaque `properties` cannot, so the report is per batch, not per source.\n */\n\nimport type { StacItem } from './stac.js';\nimport type { FacetState } from './stac-facets.js';\n\n/** Which underlying engine drives this source. Used by the viewer to pick\n * atomic-swap-vs-append, by the UI to choose copy / badges, and by tests. */\nexport type StacSourceKind = 'api' | 'parquet' | 'static';\n\n/**\n * Per-source capability surface. Read by the viewer at construction (no await\n * — sources are synchronous to construct so the orchestrator can branch on\n * `kind` before any I/O) and by the filter UI to decide which controls to\n * disable / badge as \"client-side only\".\n *\n * The `pushdown` map is exhaustive: every facet field listed in\n * `FacetState` has a flag here, so adding a new facet is a compile-time\n * error in every consumer until they handle it.\n */\nexport interface StacSourceCapabilities {\n\tkind: StacSourceKind;\n\t/** Human-readable label for HUD copy. e.g. \"STAC API\", \"stac-geoparquet\". */\n\tlabel: string;\n\t/** True when count(filter, bbox) is cheap. UI surfaces \"Y of X\". */\n\tcountAvailable: boolean;\n\t/** True when query() yields multiple batches before completing. */\n\tstreaming: boolean;\n\t/**\n\t * True when the underlying source is a hive-partitioned parquet directory\n\t * (e.g. `s3://bucket/prefix/year=2023/month=01/...`). Set by the parquet\n\t * source when the factory detects a directory layout (or the SDK passes\n\t * `hivePartitioned: true`). Lets the viewer surface a HUD hint without\n\t * inspecting `kind === 'parquet'` alone, since the same `kind` covers\n\t * single-file stac-geoparquet.\n\t */\n\thivePartitioned?: boolean;\n\tpushdown: {\n\t\tbbox: boolean;\n\t\tdatetime: boolean;\n\t\tcollection: boolean;\n\t\tcloudCover: boolean;\n\t\tgsd: boolean;\n\t\tepsg: boolean;\n\t\tplatform: boolean;\n\t\tconstellation: boolean;\n\t\tinstruments: boolean;\n\t\tassetRoles: boolean;\n\t};\n}\n\n/** Per-query inputs. The signal is required, sources MUST throw\n * `DOMException(\"Aborted\", \"AbortError\")` on abort, never silently complete. */\nexport interface StacSourceRequest {\n\t/** WGS84 viewport bbox `[west, south, east, north]`. Required. Sources that\n\t * cannot push down bbox still receive it so they can stream the whole set\n\t * and rely on the caller's residual filter. */\n\tbbox: [number, number, number, number];\n\tfilter: FacetState;\n\tlimit: number;\n\t/** Per-page hint for sources that paginate. Server may ignore. */\n\tpageSize?: number;\n\tsignal: AbortSignal;\n}\n\n/** One yielded batch of items. */\nexport interface StacSourceBatch {\n\titems: StacItem[];\n\t/** Subset of filter the source / engine applied. UI reports as \"pushed\". */\n\tpushedDown: FacetState;\n\t/** Subset of filter the caller still has to apply via applyFacets(). */\n\tresidual: FacetState;\n\t/** True when no more batches will arrive for this request. The async\n\t * iterator's own end-of-iteration also signals done; this flag lets a\n\t * caller break the loop at the moment a single-yield source completes. */\n\tdone: boolean;\n\t/** Best-effort hint of total matching items, when the source knows. */\n\ttotalHinted?: number;\n}\n\nexport interface StacSource {\n\tcapabilities: StacSourceCapabilities;\n\tquery(req: StacSourceRequest): AsyncIterable<StacSourceBatch>;\n\t/** Optional cheap count(filter, bbox). Surfaced as \"Y of X\" when set. */\n\tcount?(filter: FacetState, bbox: StacSourceRequest['bbox'], signal: AbortSignal): Promise<number>;\n}\n\n/** All-false push-down flags. Helper to keep capability declarations terse. */\nexport function emptyPushdown(): StacSourceCapabilities['pushdown'] {\n\treturn {\n\t\tbbox: false,\n\t\tdatetime: false,\n\t\tcollection: false,\n\t\tcloudCover: false,\n\t\tgsd: false,\n\t\tepsg: false,\n\t\tplatform: false,\n\t\tconstellation: false,\n\t\tinstruments: false,\n\t\tassetRoles: false\n\t};\n}\n","/**\n * STAC API implementation of the StacSource contract. Wraps `hydrateStacItems`\n * link-walking with `itemsQuery: {bbox, datetime, limit, filter}` push-down and\n * yields each `onBatch` as a `StacSourceBatch`.\n *\n * Slice 2 sniffs the catalog/collection's `conformsTo` array once per source\n * instance, builds a CQL2-JSON filter (cloud cover / gsd / platform /\n * constellation / instruments / collection) via `toCql2Filter`, and reports\n * the actually-pushed subset of `FacetState` plus the residual the caller still\n * has to apply via `applyFacets`. When the sniff fails or `conformsTo` lacks\n * the Filter extension, behavior degrades gracefully to slice-1 (bbox+datetime\n * only).\n *\n * Pure TypeScript. No DuckDB / Svelte / maplibre / deck.gl import. The\n * `StorageAdapter` import is structural (an interface), and the actual\n * adapter is injected via `deps`.\n */\n\nimport type { StorageAdapter } from '../../../src/lib/storage/adapter.js';\nimport type { StacItem, StacRoutableKind } from './stac.js';\nimport type { FacetState } from './stac-facets.js';\nimport { hydrateStacItems, type StacItemsQuery } from './stac-hydrate.js';\nimport {\n\tresidualState,\n\ttype StacApiCapabilities,\n\tsniffApiCapabilities,\n\ttoCql2Filter,\n\ttoNativeQuery\n} from './stac-pushdown.js';\nimport {\n\temptyPushdown,\n\ttype StacSource,\n\ttype StacSourceBatch,\n\ttype StacSourceCapabilities,\n\ttype StacSourceRequest\n} from './stac-source.js';\n\nexport interface StacApiSourceDeps {\n\tadapter: StorageAdapter;\n\tbaseHref: string;\n\turlToKey?: (absoluteUrl: string) => string | null;\n\tconcurrency?: number;\n}\n\n/**\n * `pushedDown = full - residual`. Drops any field that survived `residualState`\n * (i.e. couldn't be pushed) and keeps everything else. `residualState` only\n * ever sets fields that already existed in `full`, so this structural diff is\n * exact — no false positives.\n */\nfunction subtractState(full: FacetState | undefined, residual: FacetState): FacetState {\n\tif (!full) return {};\n\tconst out: FacetState = {};\n\tif (full.datetime && !residual.datetime) out.datetime = full.datetime;\n\tif (full.numeric) {\n\t\tconst kept: NonNullable<FacetState['numeric']> = {};\n\t\tconst residualNumeric = residual.numeric ?? {};\n\t\tfor (const [k, v] of Object.entries(full.numeric)) {\n\t\t\tif (!v) continue;\n\t\t\tif (residualNumeric[k as keyof typeof residualNumeric]) continue;\n\t\t\tkept[k as keyof typeof kept] = v;\n\t\t}\n\t\tif (Object.keys(kept).length > 0) out.numeric = kept;\n\t}\n\tif (full.enums) {\n\t\tconst kept: NonNullable<FacetState['enums']> = {};\n\t\tconst residualEnums = residual.enums ?? {};\n\t\tfor (const [k, v] of Object.entries(full.enums)) {\n\t\t\tif (!Array.isArray(v) || v.length === 0) continue;\n\t\t\tif (Array.isArray(residualEnums[k as keyof typeof residualEnums])) continue;\n\t\t\tkept[k as keyof typeof kept] = v;\n\t\t}\n\t\tif (Object.keys(kept).length > 0) out.enums = kept;\n\t}\n\treturn out;\n}\n\n/**\n * Translate a `FacetState.datetime` into the RFC 3339 interval string the\n * STAC API spec expects. Returns `undefined` when the facet has no bounds set.\n * Bare instants (min === max) are emitted as a single RFC 3339 timestamp.\n * Open ends use `..` per the STAC API spec.\n */\nfunction datetimeFacetToRfc3339(dt: FacetState['datetime'] | undefined): string | undefined {\n\tif (!dt) return undefined;\n\tconst lo = dt.min;\n\tconst hi = dt.max;\n\tif (!lo && !hi) return undefined;\n\tif (lo && hi) return lo === hi ? lo : `${lo}/${hi}`;\n\tif (lo) return `${lo}/..`;\n\treturn `../${hi}`;\n}\n\n/**\n * Construct a STAC API source. `kind` is the classified payload from\n * `classifyStac` (Collection / Catalog with `rel=\"items\"`, or a STAC API\n * `item-collection` page). The factory checks before dispatching here, this\n * function does not re-validate.\n *\n * The advertised `capabilities.pushdown` flags reflect the *ceiling* of what a\n * STAC API can push (everything CQL2 covers). The actual push-down per request\n * depends on the `conformsTo` sniff and is reported per-batch in\n * `pushedDown` / `residual` so the caller can re-filter only what's left.\n */\nexport function createApiSource(kind: StacRoutableKind, deps: StacApiSourceDeps): StacSource {\n\tconst capabilities: StacSourceCapabilities = {\n\t\tkind: 'api',\n\t\tlabel: 'STAC API',\n\t\tcountAvailable: false,\n\t\tstreaming: true,\n\t\tpushdown: {\n\t\t\t...emptyPushdown(),\n\t\t\tbbox: true,\n\t\t\tdatetime: true,\n\t\t\tcollection: true,\n\t\t\tcloudCover: true,\n\t\t\tgsd: true,\n\t\t\tplatform: true,\n\t\t\tconstellation: true,\n\t\t\tinstruments: true\n\t\t}\n\t};\n\n\t// Lazy, cached, never-throws capability sniff. First query() awaits it; later\n\t// queries reuse the resolved promise so we never re-fetch the catalog root.\n\tlet capsPromise: Promise<StacApiCapabilities> | null = null;\n\tconst getCaps = (signal: AbortSignal): Promise<StacApiCapabilities> => {\n\t\tif (!capsPromise) {\n\t\t\tcapsPromise = sniffSourceCapabilities(kind, deps, signal).catch(() => SLICE_1_CAPS);\n\t\t}\n\t\treturn capsPromise;\n\t};\n\n\treturn {\n\t\tcapabilities,\n\t\tquery(req: StacSourceRequest): AsyncIterable<StacSourceBatch> {\n\t\t\treturn apiQueryIterable(kind, deps, req, getCaps);\n\t\t}\n\t};\n}\n\n/**\n * Slice-1 fallback capabilities: bbox + datetime only. Used when the sniff\n * fails (network error, malformed root, no `conformsTo` array) so the source\n * never throws on construction or first query.\n */\nconst SLICE_1_CAPS: StacApiCapabilities = {\n\tbbox: true,\n\tdatetime: true,\n\tcollections: false,\n\tcql2: false,\n\tqueryables: false\n};\n\n/**\n * Read `conformsTo` from the source's root. For Collection / Catalog payloads\n * we already have the parsed root in memory and check it first. STAC API roots\n * sometimes carry `conformsTo` on the parent Catalog instead of the Collection,\n * so we also fall back to fetching `baseHref` when the in-memory payload lacks\n * it. For `item-collection` (a /search page) the array is on the API root,\n * which we approximate by fetching `baseHref` directly.\n *\n * Throws on fetch failure; the caller catches and falls back to SLICE_1_CAPS.\n */\nasync function sniffSourceCapabilities(\n\tkind: StacRoutableKind,\n\tdeps: StacApiSourceDeps,\n\tsignal: AbortSignal\n): Promise<StacApiCapabilities> {\n\tconst inline = readConformsTo(kind);\n\tif (inline && inline.length > 0) return sniffApiCapabilities(inline);\n\n\t// Fall back to fetching the baseHref. Mirror hydrate.ts's adapter-vs-fetch\n\t// routing so private buckets work.\n\tconst json = await fetchRootJson(deps, signal);\n\tif (json && typeof json === 'object') {\n\t\tconst conformsTo = (json as { conformsTo?: unknown }).conformsTo;\n\t\tif (Array.isArray(conformsTo)) return sniffApiCapabilities(conformsTo);\n\t}\n\treturn SLICE_1_CAPS;\n}\n\nfunction readConformsTo(kind: StacRoutableKind): unknown[] | null {\n\tif (kind.kind === 'catalog' || kind.kind === 'collection') {\n\t\tconst ct = (kind.payload as { conformsTo?: unknown }).conformsTo;\n\t\treturn Array.isArray(ct) ? ct : null;\n\t}\n\tif (kind.kind === 'item-collection') {\n\t\tconst ct = (kind.fc as { conformsTo?: unknown }).conformsTo;\n\t\treturn Array.isArray(ct) ? ct : null;\n\t}\n\treturn null;\n}\n\nasync function fetchRootJson(deps: StacApiSourceDeps, signal: AbortSignal): Promise<unknown> {\n\tconst href = deps.baseHref;\n\tif (/^https?:/i.test(href)) {\n\t\tconst ownKey = deps.urlToKey ? deps.urlToKey(href) : null;\n\t\tif (ownKey !== null) {\n\t\t\tconst buf = await deps.adapter.read(ownKey, undefined, undefined, signal);\n\t\t\treturn JSON.parse(new TextDecoder().decode(buf));\n\t\t}\n\t\tconst res = await fetch(href, { signal });\n\t\tif (!res.ok) throw new Error(`HTTP ${res.status} for ${href}`);\n\t\treturn await res.json();\n\t}\n\tconst buf = await deps.adapter.read(href, undefined, undefined, signal);\n\treturn JSON.parse(new TextDecoder().decode(buf));\n}\n\n/**\n * Bridge `hydrateStacItems`' callback-based onBatch into an async iterable.\n * A simple promise-based queue: each onBatch resolves a pending `next()`\n * (or pushes onto a buffer when no consumer is waiting); completion / abort\n * resolve the iterator.\n */\nasync function* apiQueryIterable(\n\tkind: StacRoutableKind,\n\tdeps: StacApiSourceDeps,\n\treq: StacSourceRequest,\n\tgetCaps: (signal: AbortSignal) => Promise<StacApiCapabilities>\n): AsyncIterable<StacSourceBatch> {\n\tif (req.signal.aborted) throw new DOMException('Aborted', 'AbortError');\n\n\tconst caps = await getCaps(req.signal);\n\tif (req.signal.aborted) throw new DOMException('Aborted', 'AbortError');\n\n\t// Translate FacetState into the native query the API actually supports.\n\t// `toNativeQuery` handles bbox/datetime/collections + CQL2 filter together.\n\tconst native = toNativeQuery(req.filter, caps, {\n\t\tbbox: req.bbox,\n\t\tlimit: req.pageSize ?? req.limit\n\t});\n\n\t// Map the native query onto `StacItemsQuery`, which is what `hydrateStacItems`\n\t// re-stamps on every `rel=\"next\"` URL. `collections` cannot be passed here\n\t// because hydrate walks `/items` (per-collection); the residual state will\n\t// re-apply it client-side when the engine could not narrow.\n\tconst datetime = native.datetime ?? datetimeFacetToRfc3339(req.filter.datetime);\n\tconst itemsQuery: StacItemsQuery = {\n\t\tbbox: native.bbox ?? req.bbox,\n\t\tdatetime,\n\t\tlimit: native.limit ?? req.pageSize ?? req.limit,\n\t\tfilter: native.filter\n\t};\n\n\t// Compute the actually-pushed FacetState by inverting `residualState`. The\n\t// caller applies only the residual via `applyFacets`, avoiding double work.\n\tconst residual = residualState(req.filter, caps);\n\tconst pushedDown = subtractState(req.filter, residual);\n\n\t// When the API doesn't support CQL2 but state needs it, the filter is empty\n\t// and the residual covers it. When CQL2 is on but the builder produced null\n\t// (no fields requiring CQL2), itemsQuery.filter stays undefined and we don't\n\t// emit `?filter=`. `toCql2Filter` is reachable here only via toNativeQuery\n\t// for clarity; the explicit call lets us short-circuit the URL stamping.\n\tif (!caps.cql2) {\n\t\t// Nothing extra; native already has no filter. Keep itemsQuery clean.\n\t\titemsQuery.filter = undefined;\n\t} else if (itemsQuery.filter === undefined) {\n\t\tconst cql = toCql2Filter(req.filter, caps);\n\t\tif (cql) itemsQuery.filter = cql;\n\t}\n\n\ttype QueueState =\n\t\t| { kind: 'value'; batch: StacItem[] }\n\t\t| { kind: 'done' }\n\t\t| { kind: 'error'; error: unknown };\n\n\tconst buffer: QueueState[] = [];\n\tlet pendingResolve: ((s: QueueState) => void) | null = null;\n\n\tconst push = (s: QueueState) => {\n\t\tif (pendingResolve) {\n\t\t\tconst r = pendingResolve;\n\t\t\tpendingResolve = null;\n\t\t\tr(s);\n\t\t} else {\n\t\t\tbuffer.push(s);\n\t\t}\n\t};\n\n\tconst next = (): Promise<QueueState> => {\n\t\tif (buffer.length > 0) return Promise.resolve(buffer.shift()!);\n\t\treturn new Promise((resolve) => {\n\t\t\tpendingResolve = resolve;\n\t\t});\n\t};\n\n\tconst onAbort = () => push({ kind: 'error', error: new DOMException('Aborted', 'AbortError') });\n\treq.signal.addEventListener('abort', onAbort, { once: true });\n\n\t// Run hydration in the background; it pushes onto the queue. Errors and\n\t// completion both push terminal states so the consumer loop ends cleanly.\n\tvoid (async () => {\n\t\ttry {\n\t\t\tawait hydrateStacItems(kind, deps.baseHref, deps.adapter, {\n\t\t\t\tsignal: req.signal,\n\t\t\t\tconcurrency: deps.concurrency ?? 12,\n\t\t\t\tlimit: req.limit,\n\t\t\t\turlToKey: deps.urlToKey,\n\t\t\t\titemsQuery,\n\t\t\t\tonBatch: (batch) => {\n\t\t\t\t\tif (batch.length > 0) push({ kind: 'value', batch });\n\t\t\t\t}\n\t\t\t});\n\t\t\tpush({ kind: 'done' });\n\t\t} catch (err) {\n\t\t\tpush({ kind: 'error', error: err });\n\t\t}\n\t})();\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst state = await next();\n\t\t\tif (state.kind === 'value') {\n\t\t\t\tyield {\n\t\t\t\t\titems: state.batch,\n\t\t\t\t\tpushedDown,\n\t\t\t\t\tresidual,\n\t\t\t\t\tdone: false\n\t\t\t\t};\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (state.kind === 'done') {\n\t\t\t\tyield {\n\t\t\t\t\titems: [],\n\t\t\t\t\tpushedDown,\n\t\t\t\t\tresidual,\n\t\t\t\t\tdone: true\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow state.error;\n\t\t}\n\t} finally {\n\t\treq.signal.removeEventListener('abort', onAbort);\n\t}\n}\n","/**\n * Self-contained static catalog implementation of the StacSource contract.\n * Wraps `hydrateStacItems` link-walking with no `itemsQuery`, so the entire\n * advertised tree is fetched and the caller filters client-side.\n *\n * Slice 1 reports zero push-down. Slice 4 adds extent-pruning (skip child\n * links whose `extent.spatial` / `extent.temporal` does not intersect the\n * request bbox / datetime), which lifts `bbox` and `datetime` to true.\n *\n * Pure TypeScript. No DuckDB / Svelte / maplibre / deck.gl import.\n */\n\nimport type { StorageAdapter } from '../../../src/lib/storage/adapter.js';\nimport type { StacItem, StacRoutableKind } from './stac.js';\nimport type { FacetState } from './stac-facets.js';\nimport { hydrateStacItems } from './stac-hydrate.js';\nimport {\n\temptyPushdown,\n\ttype StacSource,\n\ttype StacSourceBatch,\n\ttype StacSourceCapabilities,\n\ttype StacSourceRequest\n} from './stac-source.js';\n\nexport interface StacStaticSourceDeps {\n\tadapter: StorageAdapter;\n\tbaseHref: string;\n\turlToKey?: (absoluteUrl: string) => string | null;\n\tconcurrency?: number;\n}\n\nexport function createStaticSource(kind: StacRoutableKind, deps: StacStaticSourceDeps): StacSource {\n\tconst capabilities: StacSourceCapabilities = {\n\t\tkind: 'static',\n\t\tlabel: 'Static catalog',\n\t\tcountAvailable: false,\n\t\tstreaming: true,\n\t\tpushdown: { ...emptyPushdown() }\n\t};\n\n\treturn {\n\t\tcapabilities,\n\t\tquery(req: StacSourceRequest): AsyncIterable<StacSourceBatch> {\n\t\t\treturn staticQueryIterable(kind, deps, req);\n\t\t}\n\t};\n}\n\nasync function* staticQueryIterable(\n\tkind: StacRoutableKind,\n\tdeps: StacStaticSourceDeps,\n\treq: StacSourceRequest\n): AsyncIterable<StacSourceBatch> {\n\tif (req.signal.aborted) throw new DOMException('Aborted', 'AbortError');\n\n\t// Slice 1: nothing pushed, everything residual. Slice 4 widens this.\n\tconst pushedDown: FacetState = {};\n\tconst residual: FacetState = req.filter;\n\n\ttype QueueState =\n\t\t| { kind: 'value'; batch: StacItem[] }\n\t\t| { kind: 'done' }\n\t\t| { kind: 'error'; error: unknown };\n\n\tconst buffer: QueueState[] = [];\n\tlet pendingResolve: ((s: QueueState) => void) | null = null;\n\n\tconst push = (s: QueueState) => {\n\t\tif (pendingResolve) {\n\t\t\tconst r = pendingResolve;\n\t\t\tpendingResolve = null;\n\t\t\tr(s);\n\t\t} else {\n\t\t\tbuffer.push(s);\n\t\t}\n\t};\n\n\tconst next = (): Promise<QueueState> => {\n\t\tif (buffer.length > 0) return Promise.resolve(buffer.shift()!);\n\t\treturn new Promise((resolve) => {\n\t\t\tpendingResolve = resolve;\n\t\t});\n\t};\n\n\tconst onAbort = () => push({ kind: 'error', error: new DOMException('Aborted', 'AbortError') });\n\treq.signal.addEventListener('abort', onAbort, { once: true });\n\n\tvoid (async () => {\n\t\ttry {\n\t\t\tawait hydrateStacItems(kind, deps.baseHref, deps.adapter, {\n\t\t\t\tsignal: req.signal,\n\t\t\t\tconcurrency: deps.concurrency ?? 12,\n\t\t\t\tlimit: req.limit,\n\t\t\t\turlToKey: deps.urlToKey,\n\t\t\t\tonBatch: (batch) => {\n\t\t\t\t\tif (batch.length > 0) push({ kind: 'value', batch });\n\t\t\t\t}\n\t\t\t});\n\t\t\tpush({ kind: 'done' });\n\t\t} catch (err) {\n\t\t\tpush({ kind: 'error', error: err });\n\t\t}\n\t})();\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst state = await next();\n\t\t\tif (state.kind === 'value') {\n\t\t\t\tyield {\n\t\t\t\t\titems: state.batch,\n\t\t\t\t\tpushedDown,\n\t\t\t\t\tresidual,\n\t\t\t\t\tdone: false\n\t\t\t\t};\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (state.kind === 'done') {\n\t\t\t\tyield { items: [], pushedDown, residual, done: true };\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow state.error;\n\t\t}\n\t} finally {\n\t\treq.signal.removeEventListener('abort', onAbort);\n\t}\n}\n","/**\n * Open-time storage probe. Issues a single ranged GET against a presigned\n * asset URL to surface auth, CORS, and bucket-misconfiguration errors at\n * viewer load time, before any tile read kicks off.\n *\n * Inspired by lazycogs `_smoketest_store` (developmentseed/lazycogs). The\n * Python library calls `store.head()` on a representative asset during\n * `open()` so credential or region misconfiguration fails in <1s instead of\n * mid-mosaic when the first COG range fetch errors out.\n *\n * We use ranged GET instead of HEAD because:\n * - Many private buckets allow GET but block HEAD via CORS.\n * - Range `bytes=0-0` is one byte, cheaper than a full body fetch.\n * - Successful 206 / 200 confirms BOTH auth and CORS headers are correct,\n * which a HEAD response sometimes lies about under bucket policies that\n * return mismatched `Access-Control-Expose-Headers`.\n *\n * Pure TS, no Svelte / framework deps. Safe to publish via objex-utils.\n */\n\nexport type SmokeTestResult = { ok: true } | { ok: false; status: number | null; reason: string };\n\n/**\n * Probe a presigned URL with a one-byte Range GET. Resolves to `{ ok: true }`\n * on 200 / 206, otherwise returns a structured failure with the HTTP status\n * (or null when the request never reached a server, e.g. CORS preflight\n * failure or DNS error). AbortError is re-thrown so callers can distinguish\n * intentional cancellation from real failures.\n */\nexport async function smokeTestHref(href: string, signal?: AbortSignal): Promise<SmokeTestResult> {\n\tlet response: Response;\n\ttry {\n\t\tresponse = await fetch(href, {\n\t\t\tmethod: 'GET',\n\t\t\theaders: { Range: 'bytes=0-0' },\n\t\t\tsignal,\n\t\t\tredirect: 'follow'\n\t\t});\n\t} catch (err) {\n\t\tif (err instanceof DOMException && err.name === 'AbortError') throw err;\n\t\tconst reason = err instanceof Error ? err.message : String(err);\n\t\treturn { ok: false, status: null, reason };\n\t}\n\tif (response.ok || response.status === 206) {\n\t\tawait response.body?.cancel().catch(() => {});\n\t\treturn { ok: true };\n\t}\n\tconst reason = `${response.status} ${response.statusText || ''}`.trim();\n\treturn { ok: false, status: response.status, reason };\n}\n","/**\n * Lightweight WKB (Well-Known Binary) parser for extracting coordinates.\n * Supports Point, LineString, Polygon, and Multi* variants.\n * Handles standard WKB, ISO WKB (with Z/M), and EWKB (PostGIS SRID).\n */\n\nexport type GeoType =\n\t| 'Point'\n\t| 'LineString'\n\t| 'Polygon'\n\t| 'MultiPoint'\n\t| 'MultiLineString'\n\t| 'MultiPolygon'\n\t| 'Unknown';\n\nexport interface ParsedGeometry {\n\ttype: GeoType;\n\tcoordinates: number[] | number[][] | number[][][] | number[][][][];\n}\n\n// WKB type codes\nconst WKB_POINT = 1;\nconst WKB_LINESTRING = 2;\nconst WKB_POLYGON = 3;\nconst WKB_MULTIPOINT = 4;\nconst WKB_MULTILINESTRING = 5;\nconst WKB_MULTIPOLYGON = 6;\n\n// EWKB flags\nconst EWKB_Z_FLAG = 0x80000000;\nconst EWKB_M_FLAG = 0x40000000;\nconst EWKB_SRID_FLAG = 0x20000000;\n\n/**\n * Normalize binary data from various formats to Uint8Array.\n * Handles Uint8Array, ArrayBuffer, number arrays, hex strings,\n * and DuckDB toJSON() blob objects ({0: byte, 1: byte, ...}).\n */\nexport function toBinary(value: unknown): Uint8Array | null {\n\tif (value === null || value === undefined) return null;\n\tif (value instanceof Uint8Array) return value;\n\tif (value instanceof ArrayBuffer) return new Uint8Array(value);\n\tif (Array.isArray(value) && value.length > 0 && typeof value[0] === 'number') {\n\t\treturn new Uint8Array(value);\n\t}\n\tif (typeof value === 'string' && /^[0-9a-fA-F]+$/.test(value) && value.length % 2 === 0) {\n\t\tconst bytes = new Uint8Array(value.length / 2);\n\t\tfor (let i = 0; i < value.length; i += 2) {\n\t\t\tbytes[i / 2] = parseInt(value.substring(i, i + 2), 16);\n\t\t}\n\t\treturn bytes;\n\t}\n\t// DuckDB toJSON() serializes BLOB/GEOMETRY as {\"0\": byte, \"1\": byte, ...}\n\tif (typeof value === 'object' && !Array.isArray(value)) {\n\t\tconst obj = value as Record<string, number>;\n\t\tconst keys = Object.keys(obj);\n\t\tif (keys.length > 4 && typeof obj['0'] === 'number') {\n\t\t\tconst arr = new Uint8Array(keys.length);\n\t\t\tfor (let i = 0; i < keys.length; i++) arr[i] = obj[i];\n\t\t\treturn arr;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Parse a WKB binary blob into coordinates and geometry type.\n */\nexport function parseWKB(data: Uint8Array): ParsedGeometry | null {\n\tif (data.length < 5) return null;\n\ttry {\n\t\treturn readGeometry(new DataView(data.buffer, data.byteOffset, data.byteLength), 0).geometry;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readGeometry(\n\tview: DataView,\n\toffset: number\n): { geometry: ParsedGeometry; offset: number } {\n\tconst le = view.getUint8(offset) === 1;\n\toffset += 1;\n\n\tlet typeInt = view.getUint32(offset, le);\n\toffset += 4;\n\n\t// Detect coordinate dimensions from EWKB flags or ISO type ranges\n\tconst hasZ =\n\t\t(typeInt & EWKB_Z_FLAG) !== 0 ||\n\t\t(typeInt % 10000 >= 1000 && typeInt % 10000 < 2000) ||\n\t\t(typeInt % 10000 >= 3000 && typeInt % 10000 < 4000);\n\tconst hasM =\n\t\t(typeInt & EWKB_M_FLAG) !== 0 ||\n\t\t(typeInt % 10000 >= 2000 && typeInt % 10000 < 3000) ||\n\t\t(typeInt % 10000 >= 3000 && typeInt % 10000 < 4000);\n\n\t// Skip SRID if present (EWKB)\n\tif (typeInt & EWKB_SRID_FLAG) offset += 4;\n\n\t// Strip all flags to get base geometry type\n\ttypeInt = (typeInt & 0x0000ffff) % 1000;\n\n\tconst extraDims = (hasZ ? 1 : 0) + (hasM ? 1 : 0);\n\tconst rd = (o: number) => view.getFloat64(o, le);\n\tconst ru = (o: number) => view.getUint32(o, le);\n\n\tfunction readPoint(off: number): { coords: number[]; offset: number } {\n\t\tconst x = rd(off);\n\t\tconst y = rd(off + 8);\n\t\treturn { coords: [x, y], offset: off + 16 + extraDims * 8 };\n\t}\n\n\tfunction readLineString(off: number): { coords: number[][]; offset: number } {\n\t\tconst n = ru(off);\n\t\toff += 4;\n\t\tconst coords: number[][] = [];\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst pt = readPoint(off);\n\t\t\tcoords.push(pt.coords);\n\t\t\toff = pt.offset;\n\t\t}\n\t\treturn { coords, offset: off };\n\t}\n\n\tfunction readPolygon(off: number): { coords: number[][][]; offset: number } {\n\t\tconst n = ru(off);\n\t\toff += 4;\n\t\tconst coords: number[][][] = [];\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst ring = readLineString(off);\n\t\t\tcoords.push(ring.coords);\n\t\t\toff = ring.offset;\n\t\t}\n\t\treturn { coords, offset: off };\n\t}\n\n\tswitch (typeInt) {\n\t\tcase WKB_POINT: {\n\t\t\tconst pt = readPoint(offset);\n\t\t\treturn { geometry: { type: 'Point', coordinates: pt.coords }, offset: pt.offset };\n\t\t}\n\t\tcase WKB_LINESTRING: {\n\t\t\tconst ls = readLineString(offset);\n\t\t\treturn { geometry: { type: 'LineString', coordinates: ls.coords }, offset: ls.offset };\n\t\t}\n\t\tcase WKB_POLYGON: {\n\t\t\tconst pg = readPolygon(offset);\n\t\t\treturn { geometry: { type: 'Polygon', coordinates: pg.coords }, offset: pg.offset };\n\t\t}\n\t\tcase WKB_MULTIPOINT: {\n\t\t\tconst n = ru(offset);\n\t\t\toffset += 4;\n\t\t\tconst coords: number[][] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst r = readGeometry(view, offset);\n\t\t\t\tcoords.push(r.geometry.coordinates as number[]);\n\t\t\t\toffset = r.offset;\n\t\t\t}\n\t\t\treturn { geometry: { type: 'MultiPoint', coordinates: coords }, offset };\n\t\t}\n\t\tcase WKB_MULTILINESTRING: {\n\t\t\tconst n = ru(offset);\n\t\t\toffset += 4;\n\t\t\tconst coords: number[][][] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst r = readGeometry(view, offset);\n\t\t\t\tcoords.push(r.geometry.coordinates as number[][]);\n\t\t\t\toffset = r.offset;\n\t\t\t}\n\t\t\treturn { geometry: { type: 'MultiLineString', coordinates: coords }, offset };\n\t\t}\n\t\tcase WKB_MULTIPOLYGON: {\n\t\t\tconst n = ru(offset);\n\t\t\toffset += 4;\n\t\t\tconst coords: number[][][][] = [];\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tconst r = readGeometry(view, offset);\n\t\t\t\tcoords.push(r.geometry.coordinates as number[][][]);\n\t\t\t\toffset = r.offset;\n\t\t\t}\n\t\t\treturn { geometry: { type: 'MultiPolygon', coordinates: coords }, offset };\n\t\t}\n\t\tdefault:\n\t\t\treturn { geometry: { type: 'Unknown', coordinates: [] }, offset };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Geometry column detection\n// ---------------------------------------------------------------------------\n\n/** Exact well-known geometry column names (lowercase for comparison). */\nconst GEO_NAMES = [\n\t'geometry',\n\t'geom',\n\t'wkb_geometry',\n\t'the_geom',\n\t'shape',\n\t'geo',\n\t'wkt_geometry',\n\t'the_geog',\n\t'geog',\n\t'way',\n\t'ora_geometry'\n];\n\n/** Type keywords that indicate a geometry column. */\nconst GEO_TYPE_KEYWORDS = [\n\t'geometry',\n\t'geography',\n\t'wkb',\n\t'point',\n\t'linestring',\n\t'polygon',\n\t'multipoint',\n\t'multilinestring',\n\t'multipolygon',\n\t'geometrycollection',\n\t'sdo_geometry'\n];\n\n/**\n * Tokens in column names that hint at geometry content. Matched against\n * snake_case / kebab-case / camelCase tokens only — never as loose substrings\n * (e.g. `_geographic_` must not match `geo` via the `_geo` substring, because\n * count columns like `n_geographic_entities` are INT, not geometry).\n */\nconst GEO_NAME_HINTS = ['geom', 'geometry', 'wkb', 'wkt', 'shape', 'spatial', 'geo'];\n\n/** Split a column name into lowercase tokens for hint matching. */\nfunction tokenizeColumnName(name: string): string[] {\n\treturn name\n\t\t.replace(/([a-z])([A-Z])/g, '$1_$2')\n\t\t.replace(/([a-z])([0-9])/g, '$1_$2')\n\t\t.toLowerCase()\n\t\t.split(/[^a-z0-9]+/)\n\t\t.filter(Boolean);\n}\n\n/** Valid GeoJSON geometry type names. */\nconst GEOJSON_TYPES = [\n\t'Point',\n\t'LineString',\n\t'Polygon',\n\t'MultiPoint',\n\t'MultiLineString',\n\t'MultiPolygon'\n];\n\n/** Check if a value is a GeoJSON geometry object ({type, coordinates}). */\nfunction isGeoJSONGeometry(value: unknown): value is { type: GeoType; coordinates: unknown } {\n\tif (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n\tconst obj = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof obj.type === 'string' && GEOJSON_TYPES.includes(obj.type) && obj.coordinates != null\n\t);\n}\n\n/**\n * Find the geometry column name from a schema.\n *\n * Detection priority:\n * 1. Column type contains a geometry keyword (GEOMETRY, POINT, WKB, etc.)\n * 2. Exact well-known column name with BLOB/BINARY type\n * 3. Exact well-known column name regardless of type\n * 4. Column name contains a geo-related substring with BLOB/BINARY type\n * 5. Column name contains a geo-related substring regardless of type\n */\nexport function findGeoColumn(schema: { name: string; type: string }[]): string | null {\n\t// Priority 1: column type contains a geometry keyword\n\t// Skip STRUCT/MAP/LIST types — their field names can false-positive\n\t// (e.g. STRUCT(... Geometry VARCHAR ...) matches 'geometry')\n\tfor (const f of schema) {\n\t\tconst t = f.type.toLowerCase();\n\t\tif (t.startsWith('struct') || t.startsWith('map') || t.startsWith('list')) continue;\n\t\tif (GEO_TYPE_KEYWORDS.some((kw) => t.includes(kw))) return f.name;\n\t}\n\n\t// Priority 2: exact well-known name with binary type\n\tfor (const f of schema) {\n\t\tconst n = f.name.toLowerCase();\n\t\tconst t = f.type.toLowerCase();\n\t\tconst isBinary = t.includes('blob') || t.includes('binary') || t.includes('bytea');\n\t\tif (GEO_NAMES.includes(n) && isBinary) return f.name;\n\t}\n\n\t// Priority 3: exact well-known name, any type\n\tfor (const f of schema) {\n\t\tif (GEO_NAMES.includes(f.name.toLowerCase())) return f.name;\n\t}\n\n\t// Priority 4: name token matches geo hint with binary type\n\tfor (const f of schema) {\n\t\tconst tokens = tokenizeColumnName(f.name);\n\t\tconst t = f.type.toLowerCase();\n\t\tconst isBinary = t.includes('blob') || t.includes('binary') || t.includes('bytea');\n\t\tif (isBinary && tokens.some((tok) => GEO_NAME_HINTS.includes(tok))) return f.name;\n\t}\n\n\t// Priority 5: name token matches geo hint, any type\n\tfor (const f of schema) {\n\t\tconst tokens = tokenizeColumnName(f.name);\n\t\tif (tokens.some((tok) => GEO_NAME_HINTS.includes(tok))) return f.name;\n\t}\n\n\treturn null;\n}\n\n/**\n * Check if a value looks like valid WKB by inspecting its first bytes.\n * WKB starts with a byte-order marker (0x00 big-endian, 0x01 little-endian)\n * followed by a uint32 geometry type code.\n */\nfunction looksLikeWKB(value: unknown): boolean {\n\tconst bytes = toBinary(value);\n\tif (!bytes || bytes.length < 5) return false;\n\n\tconst bom = bytes[0];\n\tif (bom !== 0x00 && bom !== 0x01) return false;\n\n\tconst le = bom === 0x01;\n\tconst view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n\tlet typeInt = view.getUint32(1, le);\n\n\t// Strip EWKB flags\n\ttypeInt = (typeInt & 0x0000ffff) % 1000;\n\n\t// Valid base geometry types are 1–7\n\treturn typeInt >= 1 && typeInt <= 7;\n}\n\n/**\n * Fallback: probe actual row data to find a column containing WKB geometry.\n * Use this when schema-only detection via `findGeoColumn()` returns null.\n * Samples the first row and checks each BLOB/binary column for WKB magic bytes.\n */\nexport function findGeoColumnFromRows(\n\trows: Record<string, unknown>[],\n\tschema: { name: string; type: string }[]\n): string | null {\n\tif (rows.length === 0) return null;\n\n\tconst sample = rows[0];\n\n\t// First pass: check binary-typed columns\n\tfor (const f of schema) {\n\t\tconst t = f.type.toLowerCase();\n\t\tconst isBinary = t.includes('blob') || t.includes('binary') || t.includes('bytea');\n\t\tif (isBinary && looksLikeWKB(sample[f.name])) return f.name;\n\t}\n\n\t// Second pass: check any column that holds binary-like data or WKT strings\n\tfor (const [key, value] of Object.entries(sample)) {\n\t\tif (value instanceof Uint8Array || value instanceof ArrayBuffer) {\n\t\t\tif (looksLikeWKB(value)) return key;\n\t\t}\n\t\tif (typeof value === 'string') {\n\t\t\t// Hex-encoded WKB\n\t\t\tif (/^[0-9a-fA-F]+$/.test(value) && value.length >= 10 && looksLikeWKB(value)) {\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\t// WKT string (from DuckDB spatial GEOMETRY type)\n\t\t\tif (isWKT(value)) return key;\n\t\t}\n\t\t// GeoJSON geometry object (from DuckDB read_json_auto struct serialization)\n\t\tif (isGeoJSONGeometry(value)) return key;\n\t\t// GeoJSON JSON string (from DuckDB to_json()::VARCHAR)\n\t\tif (typeof value === 'string' && value.startsWith('{')) {\n\t\t\ttry {\n\t\t\t\tif (isGeoJSONGeometry(JSON.parse(value))) return key;\n\t\t\t} catch {\n\t\t\t\t// not JSON\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// WKT detection (used by findGeoColumnFromRows for column sniffing)\n// ---------------------------------------------------------------------------\n\nconst WKT_TYPES = [\n\t'POINT',\n\t'LINESTRING',\n\t'POLYGON',\n\t'MULTIPOINT',\n\t'MULTILINESTRING',\n\t'MULTIPOLYGON'\n];\n\n/** Check if a string looks like WKT. */\nfunction isWKT(value: unknown): value is string {\n\tif (typeof value !== 'string') return false;\n\tconst s = value.trimStart().toUpperCase();\n\treturn WKT_TYPES.some((t) => s.startsWith(t) || s.startsWith(`MULTI${t}`));\n}\n"]}