@pythia-software/query-table-react 0.5.0 → 0.6.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useComputedColumns.ts","../src/formulaWorker.ts","../src/useQueryTable.ts","../src/useAggregations.ts","../src/useSelection.ts","../src/useSelect.ts","../src/useColumnDrag.ts","../src/useSavedQueries.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n applyQuery,\n compileFormula,\n computedFieldName,\n groupPreview,\n isComputedField,\n memoryComputedColumnStore,\n readFieldValue,\n toServerQuery,\n validateComputedColumn,\n isSelectable,\n type ColumnPreview,\n type ComputedColumn,\n type ComputedColumnDraft,\n type ComputedColumnStore,\n type FieldDef,\n type FieldSchema,\n type FormulaPlan,\n type FormulaResult,\n type FormulaValue,\n type QueryState,\n type Transport,\n} from \"@pythia-software/query-table-core\";\nimport {\n evaluateFormulaRows,\n type FormulaWorkerFactory,\n} from \"./formulaWorker\";\n\nexport interface ComputedColumnsApi<Row> {\n definitions: ComputedColumn[];\n catalogue: FieldDef<Row>[];\n loading: boolean;\n error: string | null;\n reload: () => Promise<void>;\n save: (\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ) => Promise<ComputedColumn>;\n compile: (source: string, editingId?: string) => FormulaPlan;\n /** Sample the first N matching rows in current sort order, independent of table paging. */\n preview: (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs?: boolean,\n ) => Promise<ColumnPreview>;\n}\ninterface Options<Row> {\n schema: FieldSchema<Row>;\n query: QueryState;\n rows: Row[];\n store?: ComputedColumnStore;\n transport?: Transport<Row>;\n clientRows?: Row[];\n workerFactory?: FormulaWorkerFactory;\n}\nexport function useComputedColumns<Row>(options: Options<Row>): {\n api: ComputedColumnsApi<Row>;\n displaySchema: FieldSchema<Row>;\n} {\n const { schema, query, rows, transport, clientRows, workerFactory } = options;\n const store = useMemo(\n () => options.store ?? memoryComputedColumnStore(),\n [options.store],\n );\n const [catalogue, setCatalogue] = useState<{\n dataset: string;\n store: ComputedColumnStore;\n items: ComputedColumn[];\n } | null>(null);\n const definitions = useMemo(\n () =>\n catalogue?.dataset === schema.name && catalogue.store === store\n ? catalogue.items\n : [],\n [catalogue, schema.name, store],\n );\n const [loading, setLoading] = useState(false),\n [error, setError] = useState<string | null>(null);\n const catalogueRequest = useRef<AbortController | null>(null);\n const reload = useCallback(async () => {\n catalogueRequest.current?.abort();\n const ac = new AbortController();\n catalogueRequest.current = ac;\n setLoading(true);\n setError(null);\n try {\n const items = await store.list(schema.name, ac.signal);\n if (ac.signal.aborted) return;\n const valid = items\n .map(validateComputedColumn)\n .sort((a, b) => a.id.localeCompare(b.id));\n if (new Set(valid.map((c) => c.id)).size !== valid.length)\n throw new Error(\"Duplicate computed column IDs.\");\n setCatalogue((previous) =>\n previous?.dataset === schema.name &&\n previous.store === store &&\n JSON.stringify(previous.items) === JSON.stringify(valid)\n ? previous\n : { dataset: schema.name, store, items: valid },\n );\n } catch (e) {\n if (!ac.signal.aborted)\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!ac.signal.aborted) setLoading(false);\n }\n }, [store, schema.name]);\n useEffect(() => {\n void reload();\n return () => catalogueRequest.current?.abort();\n }, [reload]);\n useEffect(\n () =>\n store.subscribe?.(schema.name, () => {\n void reload();\n }),\n [store, schema.name, reload],\n );\n useEffect(() => {\n const focus = () => {\n void reload();\n };\n window.addEventListener(\"focus\", focus);\n return () => window.removeEventListener(\"focus\", focus);\n }, [reload]);\n const inputFields = useMemo(\n () =>\n schema.fields\n .filter(isSelectable)\n .filter(\n (f) =>\n f.source.kind === \"backend\" ||\n (f.source.accessor && f.source.dependencies),\n ),\n [schema],\n );\n const compile = useCallback(\n (source: string, editingId?: string): FormulaPlan => {\n const stack = new Set<string>(editingId ? [editingId] : []);\n let expanded = 0;\n const resolve = (name: string): FormulaPlan | undefined => {\n if (!isComputedField(name)) return undefined;\n const id = name.slice(\"@computed/\".length),\n def = definitions.find((d) => d.id === id);\n if (!def) throw new Error(`Computed column unavailable: ${id}`);\n if (stack.has(id))\n throw new Error(`Circular computed-column reference: ${def.label}`);\n if (stack.size >= 20 || ++expanded > 100)\n throw new Error(\"Computed dependency graph is too large.\");\n stack.add(id);\n try {\n return compileFormula(def.expression.source, inputFields, resolve);\n } finally {\n stack.delete(id);\n }\n };\n return compileFormula(source, inputFields, resolve);\n },\n [inputFields, definitions],\n );\n const plans = useMemo(\n () =>\n new Map<string, { plan?: FormulaPlan; error?: string }>(\n definitions.map((def) => {\n try {\n return [\n def.id,\n { plan: compile(def.expression.source, def.id) },\n ] as const;\n } catch (e) {\n return [\n def.id,\n { error: e instanceof Error ? e.message : String(e) },\n ] as const;\n }\n }),\n ),\n [definitions, compile],\n );\n const backendDependencies = useCallback(\n (plan: FormulaPlan) =>\n [\n ...new Set(\n plan.dependencies.flatMap((name) => {\n const f = inputFields.find((f) => f.name === name);\n return f?.source.kind === \"backend\"\n ? [name]\n : (f?.source.dependencies ?? []);\n }),\n ),\n ]\n .filter((name) =>\n schema.fields.some(\n (f) => f.name === name && f.source.kind === \"backend\",\n ),\n )\n .sort(),\n [schema, inputFields],\n );\n const inputsFor = useCallback(\n (plan: FormulaPlan, batch: Row[]) => {\n let size = 0;\n return batch.map((row) => {\n const values: Record<string, FormulaValue> = Object.create(null);\n for (const name of plan.dependencies) {\n const field = inputFields.find((f) => f.name === name)!;\n const raw = readFieldValue(field, row);\n values[name] =\n raw instanceof Date ? raw.toISOString() : (raw as FormulaValue);\n }\n size += JSON.stringify(values).length;\n if (size > 16000000)\n throw new Error(\n \"Input sample exceeds 16 MB. Reduce the rows to process.\",\n );\n return values;\n });\n },\n [inputFields],\n );\n const activeSelect = query.select.length\n ? query.select\n : (schema.defaultSelect ?? []);\n const activeIds = activeSelect\n .filter((c) => isComputedField(c.field))\n .map((c) => c.field.slice(\"@computed/\".length))\n .sort()\n .join(\",\");\n const [evaluated, setEvaluated] = useState<{\n rows: Row[];\n plans: typeof plans;\n values: Map<string, FormulaResult[]>;\n } | null>(null);\n useEffect(() => {\n const ac = new AbortController();\n const values = new Map<string, FormulaResult[]>();\n void (async () => {\n for (const id of activeIds.split(\",\").filter(Boolean)) {\n const entry = plans.get(id);\n if (!entry?.plan) continue;\n try {\n values.set(\n id,\n await evaluateFormulaRows(\n entry.plan.ast,\n inputsFor(entry.plan, rows),\n ac.signal,\n workerFactory,\n ),\n );\n } catch (e) {\n if (ac.signal.aborted) return;\n values.set(\n id,\n rows.map(() => ({\n value: null,\n error: e instanceof Error ? e.message : String(e),\n })),\n );\n }\n }\n if (!ac.signal.aborted) setEvaluated({ rows, plans, values });\n })();\n return () => ac.abort();\n }, [activeIds, rows, plans, inputsFor, workerFactory]);\n const displaySchema = useMemo<FieldSchema<Row>>(() => {\n const indices = new Map(rows.map((row, i) => [row, i]));\n const fields: FieldDef<Row>[] = definitions.map((def) => {\n const entry = plans.get(def.id);\n return {\n name: computedFieldName(def.id),\n label: def.label,\n type:\n entry?.plan?.type === \"null\" ? \"text\" : (entry?.plan?.type ?? \"text\"),\n group: \"Computed columns\",\n source: {\n kind: \"derived\",\n computedId: def.id,\n dependencies: entry?.plan ? backendDependencies(entry.plan) : [],\n accessor: (row: Row) => {\n if (entry?.error) return { computedError: entry.error };\n const result =\n evaluated?.rows === rows && evaluated.plans === plans\n ? evaluated.values.get(def.id)?.[indices.get(row) ?? -1]\n : undefined;\n return result?.error\n ? { computedError: result.error }\n : result\n ? result.value\n : { computedError: \"Calculating…\" };\n },\n },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n };\n });\n for (const col of activeSelect)\n if (\n isComputedField(col.field) &&\n !fields.some((f) => f.name === col.field)\n )\n fields.push({\n name: col.field,\n label: col.field.slice(10),\n type: \"text\",\n source: {\n kind: \"derived\",\n computedId: col.field.slice(10),\n accessor: () => ({\n computedError: loading\n ? \"Loading definition…\"\n : \"Definition unavailable. Reload the catalogue or contact its owner.\",\n }),\n },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n });\n return { ...schema, fields: [...schema.fields, ...fields] };\n }, [\n schema,\n definitions,\n plans,\n backendDependencies,\n evaluated,\n rows,\n query.select,\n schema.defaultSelect,\n loading,\n ]);\n const save = useCallback(\n async (column: ComputedColumnDraft, expectedRevision: string | null) => {\n compile(column.expression.source, column.id);\n const saved = validateComputedColumn(\n await store.save(schema.name, column, expectedRevision),\n );\n setCatalogue((prev) => ({\n dataset: schema.name,\n store,\n items: [\n ...(prev?.dataset === schema.name && prev.store === store\n ? prev.items.filter((d) => d.id !== saved.id)\n : []),\n saved,\n ],\n }));\n return saved;\n },\n [compile, store, schema.name],\n );\n const preview = useCallback(\n async (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs = true,\n ): Promise<ColumnPreview> => {\n if (!Number.isInteger(count) || count < 1 || count > 10000)\n throw new Error(\"Choose between 1 and 10,000 rows.\");\n const plan = compile(source, editingId);\n let batch: Row[] = [],\n total = 0;\n if (transport) {\n const request = toServerQuery(\n {\n ...query,\n select: [\n ...new Set([schema.idField, ...backendDependencies(plan)]),\n ].map((field) => ({ field })),\n limit: Math.min(count, 500),\n offset: 0,\n },\n schema,\n );\n while (batch.length < count) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const res = await transport.fetchRows(\n {\n ...request,\n offset: batch.length,\n limit: Math.min(500, count - batch.length),\n },\n signal,\n );\n total = res.total;\n batch.push(...res.rows.slice(0, count - batch.length));\n if (!res.rows.length || batch.length >= total) break;\n }\n } else {\n const result = applyQuery(\n clientRows ?? [],\n { ...query, limit: count, offset: 0 },\n schema,\n );\n batch = result.rows;\n total = result.total;\n }\n const inputs = inputsFor(plan, batch),\n results = await evaluateFormulaRows(\n plan.ast,\n inputs,\n signal,\n workerFactory,\n );\n return groupPreview(\n includeInputs ? plan.dependencies : [],\n inputs,\n results,\n total,\n );\n },\n [\n compile,\n transport,\n query,\n schema,\n backendDependencies,\n clientRows,\n inputsFor,\n workerFactory,\n ],\n );\n return {\n displaySchema,\n api: {\n definitions,\n catalogue: displaySchema.fields,\n loading,\n error,\n reload,\n save,\n compile,\n preview,\n },\n };\n}\n","import {\n formulaRuntime,\n type FormulaNode,\n type FormulaResult,\n type FormulaValue,\n} from \"@pythia-software/query-table-core\";\n\nexport type FormulaWorkerFactory = () => Worker;\n/** Host applications with a restrictive CSP can supply their own worker factory. */\nexport const createFormulaWorker: FormulaWorkerFactory = () => {\n const code = `const evaluate = ${formulaRuntime.toString()}; self.onmessage = e => { const { ast, inputs } = e.data; self.postMessage(inputs.map(row => evaluate(ast, row))); };`;\n const url = URL.createObjectURL(\n new Blob([code], { type: \"text/javascript\" }),\n );\n try {\n return new Worker(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n};\nexport function evaluateFormulaRows(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>[],\n signal?: AbortSignal,\n factory: FormulaWorkerFactory = createFormulaWorker,\n): Promise<FormulaResult[]> {\n if (signal?.aborted)\n return Promise.reject(new DOMException(\"Aborted\", \"AbortError\"));\n if (!inputs.length) return Promise.resolve([]);\n return new Promise((resolve, reject) => {\n let worker: Worker;\n try {\n worker = factory();\n } catch (e) {\n reject(\n new Error(\n `Formula worker unavailable: ${e instanceof Error ? e.message : String(e)}`,\n ),\n );\n return;\n }\n let timer: ReturnType<typeof setTimeout>;\n const started = Date.now();\n let offset = 0;\n const results: FormulaResult[] = [];\n const cleanup = () => {\n clearTimeout(timer);\n worker.terminate();\n signal?.removeEventListener(\"abort\", abort);\n };\n const abort = () => {\n cleanup();\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n const send = () => {\n if (Date.now() - started > 30000) {\n cleanup();\n reject(\n new Error(\n \"Formula exceeded the 30-second processing budget. Reduce the row count or simplify the formula.\",\n ),\n );\n return;\n }\n timer = setTimeout(() => {\n cleanup();\n reject(\n new Error(\n \"Formula timed out. Check the regex or reduce the row count.\",\n ),\n );\n }, 2000);\n try {\n worker.postMessage({ ast, inputs: inputs.slice(offset, offset + 200) });\n } catch (e) {\n cleanup();\n reject(e);\n }\n };\n signal?.addEventListener(\"abort\", abort, { once: true });\n worker.onerror = () => {\n cleanup();\n reject(new Error(\"Formula worker failed.\"));\n };\n worker.onmessage = (event: MessageEvent<FormulaResult[]>) => {\n clearTimeout(timer);\n results.push(...event.data);\n offset += event.data.length;\n if (offset >= inputs.length) {\n cleanup();\n resolve(results);\n } else send();\n };\n send();\n });\n}\n","// useQueryTable — the one hook that owns everything.\n//\n// The headless brain of the table: it holds the QueryState, keeps it in sync\n// with the URL (`?q=`) and the StorageAdapter, orchestrates fetches through the\n// Transport (debounced + abortable), and exposes intent-level mutators so a UI\n// never hand-edits QueryState. @pythia-software/query-table-ui is a thin layer over this; you\n// can also build an entirely custom table on it.\n\nimport { useComputedColumns, type ComputedColumnsApi } from \"./useComputedColumns\";\nimport type { FormulaWorkerFactory } from \"./formulaWorker\";\nimport type { ComputedColumnStore } from \"@pythia-software/query-table-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n EMPTY_QUERY,\n applyQuery,\n decodeQuery,\n encodeQuery,\n memoryStorageAdapter,\n normalizeQueryState,\n readFieldValue,\n selectedFields,\n toServerQuery,\n queriesEqual,\n isOrGroup,\n predicatesOf,\n negateClause,\n opsForField,\n} from \"@pythia-software/query-table-core\";\n\nconst AUTOCOMPLETE_LIMIT = 50;\nconst MAX_AUTO_REFRESH_POLLS = 1000;\nimport type {\n QueryState,\n WhereClause,\n WhereTerm,\n OrderByClause,\n AggOp,\n AggregationClause,\n AggregationResult,\n RowId,\n FieldDef,\n FieldSchema,\n Transport,\n StorageAdapter,\n DistinctValuesResult,\n FieldStats,\n} from \"@pythia-software/query-table-core\";\nimport { useAggregations } from \"./useAggregations\";\nimport { useSelection, type SelectionApi } from \"./useSelection\";\nimport { useSelect, type SelectApi } from \"./useSelect\";\nimport { useColumnDrag, type ColumnDragApi } from \"./useColumnDrag\";\nimport { useSavedQueries, type SavedQueriesApi } from \"./useSavedQueries\";\n\nexport interface UseQueryTableOptions<Row> {\n /** Normalize external aliases without storing presentation in query state. Must be pure and not throw. */\n canonicalizeQuery?: (query: QueryState) => QueryState;\n /** Reject an entire query before rows or metrics execute. Errors retain editable query state. */\n validateQuery?: (query: QueryState) => void;\n\n schema: FieldSchema<Row>;\n /** Data access. Omit for a purely client-side table driven by `clientRows`. */\n transport?: Transport<Row>;\n /** All rows, for client-side mode (applyQuery runs locally over these). */\n clientRows?: Row[];\n /** Saved/last-query persistence. Defaults to a non-durable in-memory adapter.\n * Pass localStorageAdapter() explicitly only when filter values are safe to\n * retain as cleartext JSON on the device. */\n storage?: StorageAdapter;\n /** Shared reusable definitions, independent of saved-query storage. */\n computedColumnStore?: ComputedColumnStore;\n /** Override the worker factory when CSP disallows blob workers. */\n formulaWorkerFactory?: FormulaWorkerFactory;\n /** Seed query, normalized and resource-bounded before use. When omitted the\n * hook resolves: opted-in URL → storage.loadLast → schema defaults. */\n initialQuery?: QueryState;\n /** Mirror QueryState to `?q=` via history.replaceState. Default false because\n * base64url is encoding, not encryption: filters will appear in browser\n * history, referrers, logs, analytics, and screenshots when enabled. */\n syncUrl?: boolean;\n /** Debounce (ms) between a query change and the fetch it triggers. Default 200. */\n debounceMs?: number;\n /** Injected clock for deterministic saved-query timestamps. Default Date.now. */\n now?: () => number;\n /** Side-effect to run on every refresh — both manual `api.refresh()` and each\n * auto-refresh tick. Fires *in addition to* the internal `setNonce` re-query,\n * so manual and auto stay identical. Use it in client mode (no transport) to\n * bridge a UI refresh to your own server fetch without monkey-patching the\n * returned `api`. Always read through a ref, so supplying it never tears down\n * and recreates the auto-refresh interval. */\n onRefresh?: () => void;\n}\n\nexport interface AutoRefreshConfig {\n frequencyMs: number;\n turnOffAfterMs: number;\n}\n\nexport interface AutoRefreshStatus extends AutoRefreshConfig {\n startedAt: number;\n stopsAt: number;\n pollCount: number;\n}\n\nexport interface AutoRefreshApi {\n status: AutoRefreshStatus | null;\n start: (config: AutoRefreshConfig) => void;\n stop: () => void;\n}\n\n/** A patch for one metric. `field`/`label` accept an explicit `undefined` to\n * CLEAR them (e.g. switching to an op whose measure no longer applies); an\n * absent key leaves the existing value untouched. */\nexport interface AggregationPatch {\n op?: AggOp;\n field?: string | undefined;\n groupBy?: string[];\n label?: string | undefined;\n}\n\nexport interface AggregationsApi {\n /** The metric specs currently in the query. */\n clauses: AggregationClause[];\n /** Server (or client-mirror) results, one entry per clause; null when none. */\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n /** Append a metric. Defaults to \"count all rows\"; pass a partial to override.\n * Returns the generated id. */\n add: (partial?: Partial<Omit<AggregationClause, \"id\">>) => string;\n /** Patch a metric by id. */\n update: (id: string, patch: AggregationPatch) => void;\n /** Reorder: move the metric `id` to `toIndex` (an index in the list with the\n * metric removed, so a drag preview's slot maps straight to the result). */\n move: (id: string, toIndex: number) => void;\n /** Remove a metric by id. */\n remove: (id: string) => void;\n /** Remove all metrics. */\n clear: () => void;\n}\n\nexport interface QueryTableApi<Row> {\n // state\n query: QueryState;\n /** Schema defaults used for reset controls. */\n defaults: QueryState;\n setQuery: (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n /** Can move back to a previously applied local query state. */\n canUndo: boolean;\n /** Can move forward to a previously undone local query state. */\n canRedo: boolean;\n /** Move backward through local, unsaved query history. */\n undo: () => void;\n /** Move forward through local, unsaved query history. */\n redo: () => void;\n\n // data\n rows: Row[];\n total: number | null;\n loading: boolean;\n error: Error | null;\n refresh: () => void;\n autoRefresh: AutoRefreshApi;\n refreshRow: (id: RowId) => Promise<void>;\n\n // aggregation metrics (the dashboard panel above the table)\n aggregations: AggregationsApi;\n\n // filters — WHERE is CNF: `query.where` is an array of terms (a literal or an\n // OR group), ANDed together. The top-level intents address a whole term by\n // index; the predicate-level intents address one literal within a term.\n /** Append a predicate as its own AND term. */\n addFilter: (clause: WhereClause) => void;\n /** Replace the whole term at `index` with a single predicate. */\n updateFilter: (index: number, clause: WhereClause) => void;\n /** Remove the whole term at `index`. */\n removeFilter: (index: number) => void;\n clearFilters: () => void;\n /** Replace one predicate inside a term (predIndex 0 for a literal term). */\n updatePredicate: (termIndex: number, predIndex: number, clause: WhereClause) => void;\n /** Remove one predicate; a group of one flattens to a literal, an emptied term drops. */\n removePredicate: (termIndex: number, predIndex: number) => void;\n /** Logically invert one predicate (flips the op, else toggles its NOT flag). */\n negatePredicate: (termIndex: number, predIndex: number) => void;\n /** Move the term at `fromIndex` to `toIndex` (an index in the list with the\n * dragged term removed, so a drag preview's slot maps straight to the result). */\n reorderFilters: (fromIndex: number, toIndex: number) => void;\n /** OR-merge the term at `sourceIndex` into the term at `targetIndex`: the\n * target becomes (or stays) an OR group holding both terms' predicates, and\n * the source term is removed. This is the drag-onto-another-filter gesture. */\n mergeFilters: (sourceIndex: number, targetIndex: number) => void;\n /** Reset the complete query state back to schema defaults. */\n resetAll: () => void;\n /** Keystroke-driven filter-value autocomplete (Transport.fetchDistinctValues). */\n filterValues: (field: string, search: string) => Promise<DistinctValuesResult>;\n /** Dataset-wide field statistics for catalogue and picker affordances. */\n fieldStats: (\n fields: string[],\n signal?: AbortSignal,\n ) => Promise<Record<string, FieldStats>>;\n\n // sorting (multi-sort): click header sets/cycles primary; shift-click appends.\n toggleSort: (field: string, additive?: boolean) => void;\n setSort: (orderBy: OrderByClause[]) => void;\n\n // select + pagination + selection + saved\n select: SelectApi<Row>;\n computed: ComputedColumnsApi<Row>;\n setLimit: (limit: number) => void;\n setOffset: (offset: number) => void;\n nextPage: () => void;\n prevPage: () => void;\n selection: SelectionApi;\n saved: SavedQueriesApi;\n /** Shared, transient column-reorder drag state (table headers + select chips). */\n columnDrag: ColumnDragApi;\n\n // resolved view\n visibleFields: FieldDef<Row>[];\n rowId: (row: Row) => RowId | null;\n}\n\nfunction defaultsFor<Row>(schema: FieldSchema<Row>): QueryState {\n return normalizeQueryState({\n select: schema.defaultSelect ?? [],\n where: [],\n orderBy: schema.defaultSort ?? [],\n limit: schema.defaultLimit ?? EMPTY_QUERY.limit,\n offset: 0,\n });\n}\n\nfunction cloneWhereTerm(term: WhereTerm): WhereTerm {\n const copy = isOrGroup(term) ? { ...term, any: term.any.map((c) => ({ ...c })) } : { ...term };\n if (term.setFilter) copy.setFilter = { ...term.setFilter, values: [...term.setFilter.values] };\n return copy;\n}\n\nfunction cloneQueryState(q: QueryState): QueryState {\n const clone: QueryState = {\n select: q.select.map((column) => ({ ...column })),\n where: q.where.map(cloneWhereTerm),\n orderBy: q.orderBy.map((term) => (term.extract ? { ...term, extract: { ...term.extract } } : { ...term })),\n limit: q.limit,\n offset: q.offset,\n };\n if (q.aggregations) clone.aggregations = q.aggregations.map((a) => ({ ...a, groupBy: [...a.groupBy] }));\n return clone;\n}\n\n/** Apply a patch to a metric, building a fresh clause so optional `field`/`label`\n * can be dropped (passing them as `undefined` clears; omitting the key keeps the\n * current value) without ever materializing an `undefined`-valued property. */\nfunction mergeAggregation(a: AggregationClause, patch: AggregationPatch): AggregationClause {\n const next: AggregationClause = {\n id: a.id,\n op: patch.op ?? a.op,\n groupBy: patch.groupBy ?? a.groupBy,\n };\n const field = \"field\" in patch ? patch.field : a.field;\n if (field) next.field = field;\n const label = \"label\" in patch ? patch.label : a.label;\n if (label) next.label = label;\n return next;\n}\n\nfunction isNullLike(value: unknown): boolean {\n return value == null || (Array.isArray(value) && value.length === 0);\n}\n\nfunction asDistinctValue(value: unknown): string | null {\n if (isNullLike(value)) return null;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return null;\n}\n\nfunction fieldHasNullInRows<Row>(field: FieldDef<Row>, rows: Row[]): boolean {\n for (const row of rows) {\n if (isNullLike(readFieldValue(field, row))) return true;\n }\n return false;\n}\n\nfunction distinctValuesFromRows<Row>(field: FieldDef<Row>, rows: Row[], search: string): { values: string[]; hasMore: boolean } {\n const target = search.trim().toLowerCase();\n const values: string[] = [];\n const seen = new Set<string>();\n let hasMore = false;\n\n for (const row of rows) {\n const raw = asDistinctValue(readFieldValue(field, row));\n if (raw == null || seen.has(raw)) continue;\n if (target && !raw.toLowerCase().includes(target)) continue;\n\n if (values.length < AUTOCOMPLETE_LIMIT) {\n seen.add(raw);\n values.push(raw);\n continue;\n }\n\n hasMore = true;\n break;\n }\n\n return { values: values.sort((a, b) => a.localeCompare(b)), hasMore };\n}\n\nfunction resolveInitial<Row>(opts: UseQueryTableOptions<Row>): { q: QueryState; fromUrl: boolean } {\n const defaults = defaultsFor(opts.schema);\n if (opts.initialQuery) return { q: normalizeQueryState(opts.initialQuery, defaults), fromUrl: false };\n if (opts.syncUrl === true && typeof window !== \"undefined\") {\n const token = new URLSearchParams(window.location.search).get(\"q\");\n if (token) return { q: normalizeQueryState(decodeQuery(token), defaults), fromUrl: true };\n }\n return { q: defaults, fromUrl: false };\n}\n\nexport function useQueryTable<Row>(opts: UseQueryTableOptions<Row>): QueryTableApi<Row> {\n const { schema, transport, clientRows, initialQuery, syncUrl = false, debounceMs = 200 } = opts;\n const storage = useMemo(() => opts.storage ?? memoryStorageAdapter(), [opts.storage]);\n const now = opts.now ?? Date.now;\n const nowRef = useRef(now);\n const onRefreshRef = useRef(opts.onRefresh);\n const defaults = useMemo(() => defaultsFor(schema), [schema]);\n const byName = useMemo(() => new Map(schema.fields.map((f) => [f.name, f])), [schema]);\n\n const initRef = useRef(resolveInitial(opts));\n const aggIdRef = useRef(0);\n const [storedQuery, setQueryState] = useState<QueryState>(initRef.current.q);\n const query = useMemo(() => opts.canonicalizeQuery?.(storedQuery) ?? storedQuery, [storedQuery, opts.canonicalizeQuery]);\n const undoStack = useRef<QueryState[]>([cloneQueryState(initRef.current.q)]);\n const redoStack = useRef<QueryState[]>([]);\n const [rows, setRows] = useState<Row[]>([]);\n const [total, setTotal] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [nonce, setNonce] = useState(0);\n const [autoRefreshStatus, setAutoRefreshStatus] = useState<AutoRefreshStatus | null>(null);\n\n useEffect(() => {\n nowRef.current = now;\n }, [now]);\n\n useEffect(() => {\n onRefreshRef.current = opts.onRefresh;\n }, [opts.onRefresh]);\n\n const setQuery = useCallback<QueryTableApi<Row>[\"setQuery\"]>((next) => {\n setQueryState((prev) => {\n const candidate = typeof next === \"function\" ? (next as (p: QueryState) => QueryState)(prev) : next;\n const nextQuery = normalizeQueryState(candidate, defaults);\n if (queriesEqual(prev, nextQuery)) return prev;\n undoStack.current.push(cloneQueryState(prev));\n redoStack.current = [];\n return cloneQueryState(nextQuery);\n });\n }, [defaults]);\n\n // Restore the default saved query (preferred) or last query on mount when\n // nothing explicit seeded the view.\n useEffect(() => {\n if (initRef.current.fromUrl || initialQuery) return;\n let cancelled = false;\n void (async () => {\n const defaultSaved = await storage.loadDefaultSaved?.(schema.name);\n const restored = defaultSaved?.query ?? (await storage.loadLast(schema.name));\n if (!cancelled && restored) {\n const normalized = normalizeQueryState(restored, defaults);\n undoStack.current = [cloneQueryState(normalized)];\n redoStack.current = [];\n setQueryState(normalized);\n }\n })();\n return () => {\n cancelled = true;\n };\n // mount-only\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const { api: computed, displaySchema } = useComputedColumns({\n schema, query, rows,\n ...(opts.computedColumnStore ? {store:opts.computedColumnStore} : {}),\n ...(opts.formulaWorkerFactory ? {workerFactory:opts.formulaWorkerFactory} : {}),\n ...(transport ? {transport} : {}), ...(clientRows ? {clientRows} : {}),\n });\n\n // Fetch (debounced + abortable). Transport mode, or client-side applyQuery.\n const queryKey = useMemo(() => encodeQuery(query), [query]);\n const serverRowQuery = useMemo(() => toServerQuery(query, displaySchema), [queryKey, displaySchema]);\n // Keep presentation-only query changes out of the expensive row pipeline.\n // Widths do not leave the client at all, and SELECT does not affect client-side\n // filtering/sorting/paging. The full queryKey still drives URL + persistence.\n const rowQueryKey = useMemo(\n () => transport\n ? `server:${JSON.stringify(serverRowQuery)}`\n : `client:${JSON.stringify([query.where, query.orderBy, query.limit, query.offset])}`,\n [transport, serverRowQuery, query.where, query.orderBy, query.limit, query.offset],\n );\n useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n const run = async () => {\n setLoading(true);\n setError(null);\n try {\n opts.validateQuery?.(query);\n if (transport) {\n const res = await transport.fetchRows(serverRowQuery, ac.signal);\n if (!cancelled) {\n setRows(res.rows);\n setTotal(res.total);\n }\n } else {\n const res = applyQuery(clientRows ?? [], query, schema);\n if (!cancelled) {\n setRows(res.rows);\n setTotal(res.total);\n }\n }\n } catch (e) {\n if (!cancelled && !ac.signal.aborted) { setError(e as Error); setRows([]); setTotal(null); }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n const t = setTimeout(run, debounceMs);\n return () => {\n cancelled = true;\n clearTimeout(t);\n ac.abort();\n };\n // rowQueryKey captures only row-affecting query state; clientRows/nonce\n // force refetch. Presentation changes still sync/persist via queryKey below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rowQueryKey, transport, clientRows, schema, debounceMs, nonce, opts.validateQuery]);\n\n // URL sync.\n useEffect(() => {\n if (!syncUrl || typeof window === \"undefined\") return;\n const url = new URL(window.location.href);\n const token = encodeQuery(query);\n if (token) url.searchParams.set(\"q\", token);\n else url.searchParams.delete(\"q\");\n window.history.replaceState(null, \"\", url.toString());\n }, [queryKey, syncUrl, query]);\n\n // Persist last query (debounced).\n useEffect(() => {\n const t = setTimeout(() => void storage.saveLast(schema.name, query), 400);\n return () => clearTimeout(t);\n }, [queryKey, storage, schema.name, query]);\n\n // Resolved id accessor.\n const idField = useMemo(() => schema.fields.find((f) => f.name === schema.idField), [schema]);\n const rowId = useCallback(\n (row: Row): RowId | null => (idField ? (readFieldValue(idField, row) as RowId | null) : null),\n [idField],\n );\n\n // Sub-APIs.\n const displayedIds = useMemo(() => rows.map(rowId).filter((id): id is RowId => id != null), [rows, rowId]);\n const selection = useSelection(displayedIds);\n const select = useSelect(query, setQuery, displaySchema);\n const columnDrag = useColumnDrag();\n const saved = useSavedQueries(\n schema.name,\n query,\n (q) => setQuery(q),\n storage,\n now,\n );\n const aggState = useAggregations(query, schema, transport, clientRows, debounceMs, nonce, opts.validateQuery);\n\n const canUndo = undoStack.current.length > 0;\n const canRedo = redoStack.current.length > 0;\n\n const undo = useCallback(() => {\n setQueryState((prev) => {\n const previous = undoStack.current.pop();\n if (!previous) return prev;\n redoStack.current.push(cloneQueryState(prev));\n return cloneQueryState(previous);\n });\n }, []);\n\n const redo = useCallback(() => {\n setQueryState((prev) => {\n const next = redoStack.current.pop();\n if (!next) return prev;\n undoStack.current.push(cloneQueryState(prev));\n return cloneQueryState(next);\n });\n }, []);\n\n // ---- intent helpers (keep offset/url/storage coherent) ----\n const patch = useCallback((p: Partial<QueryState>) => setQuery((prev) => ({ ...prev, ...p })), [setQuery]);\n\n const addFilter = useCallback((clause: WhereClause) => setQuery((q) => ({ ...q, offset: 0, where: [...q.where, clause] })), [setQuery]);\n const updateFilter = useCallback(\n (index: number, clause: WhereClause) =>\n setQuery((q) => ({ ...q, offset: 0, where: q.where.map((t, i) => (i === index ? clause : t)) })),\n [setQuery],\n );\n const removeFilter = useCallback(\n (index: number) => setQuery((q) => ({ ...q, offset: 0, where: q.where.filter((_, i) => i !== index) })),\n [setQuery],\n );\n const clearFilters = useCallback(() => setQuery((q) => ({ ...q, offset: 0, where: [] })), [setQuery]);\n\n const updatePredicate = useCallback<QueryTableApi<Row>[\"updatePredicate\"]>(\n (termIndex, predIndex, clause) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term)) return { any: term.any.map((c, j) => (j === predIndex ? clause : c)) };\n return clause;\n }),\n })),\n [setQuery],\n );\n const removePredicate = useCallback<QueryTableApi<Row>[\"removePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => {\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i !== termIndex) {\n where.push(term);\n return;\n }\n if (isOrGroup(term)) {\n const members = term.any.filter((_, j) => j !== predIndex);\n if (members.length === 1) where.push(members[0]!);\n else if (members.length > 1) where.push({ any: members });\n return; // 0 members → drop the term\n }\n // literal term → removing its predicate drops the whole term\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const negateOne = useCallback(\n (clause: WhereClause): WhereClause => {\n const field = byName.get(clause.field);\n return negateClause(clause, field ? opsForField(field) : undefined);\n },\n [byName],\n );\n const negatePredicate = useCallback<QueryTableApi<Row>[\"negatePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term)) return { any: term.any.map((c, j) => (j === predIndex ? negateOne(c) : c)) };\n return negateOne(term);\n }),\n })),\n [setQuery, negateOne],\n );\n const reorderFilters = useCallback<QueryTableApi<Row>[\"reorderFilters\"]>(\n (fromIndex, toIndex) =>\n setQuery((q) => {\n if (fromIndex < 0 || fromIndex >= q.where.length) return q;\n const where = [...q.where];\n const [moved] = where.splice(fromIndex, 1);\n where.splice(Math.max(0, Math.min(toIndex, where.length)), 0, moved!);\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const mergeFilters = useCallback<QueryTableApi<Row>[\"mergeFilters\"]>(\n (sourceIndex, targetIndex) =>\n setQuery((q) => {\n if (sourceIndex === targetIndex) return q;\n const source = q.where[sourceIndex];\n const target = q.where[targetIndex];\n if (!source || !target) return q;\n const merged: WhereTerm = { any: [...predicatesOf(target), ...predicatesOf(source)] };\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i === sourceIndex) return; // remove the dragged term\n where.push(i === targetIndex ? merged : term);\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const resetAll = useCallback(() => setQuery(() => cloneQueryState(defaults)), [setQuery, defaults]);\n\n // ---- aggregation metric mutators (don't touch paging — scope is the whole set) ----\n const addAggregation = useCallback<AggregationsApi[\"add\"]>(\n (partial) => {\n const id = `a${nowRef.current()}-${aggIdRef.current++}`;\n const clause: AggregationClause = { id, op: \"count\", groupBy: [], ...partial };\n setQuery((q) => ({ ...q, aggregations: [...(q.aggregations ?? []), clause] }));\n return id;\n },\n [setQuery],\n );\n const updateAggregation = useCallback<AggregationsApi[\"update\"]>(\n (id, patch) =>\n setQuery((q) => ({\n ...q,\n aggregations: (q.aggregations ?? []).map((a) => (a.id === id ? mergeAggregation(a, patch) : a)),\n })),\n [setQuery],\n );\n const moveAggregation = useCallback<AggregationsApi[\"move\"]>(\n (id, toIndex) =>\n setQuery((q) => {\n const current = q.aggregations ?? [];\n const from = current.findIndex((a) => a.id === id);\n if (from === -1) return q;\n const next = [...current];\n const [item] = next.splice(from, 1);\n next.splice(Math.max(0, Math.min(toIndex, next.length)), 0, item!);\n return { ...q, aggregations: next };\n }),\n [setQuery],\n );\n const removeAggregation = useCallback<AggregationsApi[\"remove\"]>(\n (id) => setQuery((q) => ({ ...q, aggregations: (q.aggregations ?? []).filter((a) => a.id !== id) })),\n [setQuery],\n );\n const clearAggregations = useCallback<AggregationsApi[\"clear\"]>(\n () => setQuery((q) => ({ ...q, aggregations: [] })),\n [setQuery],\n );\n\n const setSort = useCallback((orderBy: OrderByClause[]) => setQuery((q) => ({ ...q, offset: 0, orderBy })), [setQuery]);\n const toggleSort = useCallback(\n (field: string, additive = false) =>\n setQuery((q) => ({ ...q, offset: 0, orderBy: nextOrderBy(q.orderBy, field, additive) })),\n [setQuery],\n );\n\n const setLimit = useCallback((limit: number) => patch({ limit, offset: 0 }), [patch]);\n const setOffset = useCallback((offset: number) => patch({ offset }), [patch]);\n const nextPage = useCallback(() => setQuery((q) => ({ ...q, offset: q.offset + q.limit })), [setQuery]);\n const prevPage = useCallback(() => setQuery((q) => ({ ...q, offset: Math.max(0, q.offset - q.limit) })), [setQuery]);\n\n const filterValues = useCallback(\n async (field: string, search: string): Promise<DistinctValuesResult> => {\n if (!transport?.fetchDistinctValues) {\n const f = byName.get(field);\n if (!f || !clientRows) return { values: [], hasMore: false };\n\n const fieldHasNull = fieldHasNullInRows(f, clientRows);\n const matches = distinctValuesFromRows(f, clientRows, search);\n\n return {\n values: matches.values,\n hasMore: matches.hasMore,\n hasNull: fieldHasNull,\n };\n }\n return transport.fetchDistinctValues({ field, search });\n },\n [transport, byName, clientRows],\n );\n\n const fieldStats = useCallback<QueryTableApi<Row>[\"fieldStats\"]>(\n async (fields, signal) => {\n const requested = [...new Set(fields)];\n if (transport?.fetchFieldStats) {\n const backendFields = requested.filter(\n (name) => byName.get(name)?.source.kind === \"backend\",\n );\n return backendFields.length\n ? transport.fetchFieldStats(backendFields, signal)\n : {};\n }\n if (!clientRows) return {};\n\n const result: Record<string, FieldStats> = {};\n for (const name of requested) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const field = byName.get(name);\n if (!field) continue;\n const distinct = new Set<string>();\n for (const row of clientRows) {\n const value = readFieldValue(field, row);\n if (value !== null) distinct.add(JSON.stringify(value));\n }\n result[name] = { distinct: distinct.size };\n }\n return result;\n },\n [transport, byName, clientRows],\n );\n\n // Single refresh seam: re-runs the internal query (setNonce) and fires the\n // consumer's onRefresh, if any. Both the manual `api.refresh()` and every\n // auto-refresh tick go through here, so they stay observably identical. Read\n // onRefresh through a ref to keep this callback (and the interval that depends\n // on it) stable across renders.\n const refresh = useCallback(() => {\n setNonce((n) => n + 1);\n onRefreshRef.current?.();\n }, []);\n const stopAutoRefresh = useCallback(() => setAutoRefreshStatus(null), []);\n const startAutoRefresh = useCallback(\n ({ frequencyMs, turnOffAfterMs }: AutoRefreshConfig) => {\n const pollCount = frequencyMs > 0 && turnOffAfterMs > 0 ? Math.floor(turnOffAfterMs / frequencyMs) : 0;\n if (pollCount < 1 || pollCount > MAX_AUTO_REFRESH_POLLS) {\n throw new Error(\"Auto-refresh must schedule between 1 and 1000 polls.\");\n }\n\n const startedAt = nowRef.current();\n refresh();\n setAutoRefreshStatus({\n frequencyMs,\n turnOffAfterMs,\n startedAt,\n stopsAt: startedAt + turnOffAfterMs,\n pollCount: 1,\n });\n },\n [refresh],\n );\n\n const autoRefreshFrequencyMs = autoRefreshStatus?.frequencyMs ?? null;\n const autoRefreshStopsAt = autoRefreshStatus?.stopsAt ?? null;\n\n useEffect(() => {\n if (autoRefreshFrequencyMs == null || autoRefreshStopsAt == null) return;\n\n const tick = () => {\n if (nowRef.current() >= autoRefreshStopsAt) {\n setAutoRefreshStatus((current) => (current?.stopsAt === autoRefreshStopsAt ? null : current));\n return;\n }\n\n refresh();\n setAutoRefreshStatus((current) => {\n if (!current) return current;\n if (current.stopsAt !== autoRefreshStopsAt) return current;\n return { ...current, pollCount: current.pollCount + 1 };\n });\n };\n\n const interval = setInterval(tick, autoRefreshFrequencyMs);\n const timeout = setTimeout(\n () => setAutoRefreshStatus((current) => (current?.stopsAt === autoRefreshStopsAt ? null : current)),\n Math.max(0, autoRefreshStopsAt - nowRef.current()),\n );\n\n return () => {\n clearInterval(interval);\n clearTimeout(timeout);\n };\n }, [autoRefreshFrequencyMs, autoRefreshStopsAt, refresh]);\n\n const autoRefresh = useMemo<AutoRefreshApi>(\n () => ({\n status: autoRefreshStatus,\n start: startAutoRefresh,\n stop: stopAutoRefresh,\n }),\n [autoRefreshStatus, startAutoRefresh, stopAutoRefresh],\n );\n\n const refreshRow = useCallback(\n async (id: RowId) => {\n if (!transport?.fetchRow) return;\n const updated = await transport.fetchRow(id);\n setRows((prev) => prev.map((r) => (rowId(r) === id ? updated ?? r : r)));\n },\n [transport, rowId],\n );\n\n const visibleFields = useMemo(() => selectedFields(displaySchema, query), [displaySchema, query]);\n\n const aggregations = useMemo<AggregationsApi>(\n () => ({\n clauses: query.aggregations ?? [],\n results: aggState.results,\n loading: aggState.loading,\n error: aggState.error,\n add: addAggregation,\n update: updateAggregation,\n move: moveAggregation,\n remove: removeAggregation,\n clear: clearAggregations,\n }),\n [\n query.aggregations,\n aggState.results,\n aggState.loading,\n aggState.error,\n addAggregation,\n updateAggregation,\n moveAggregation,\n removeAggregation,\n clearAggregations,\n ],\n );\n\n return {\n query,\n defaults,\n setQuery,\n rows,\n total,\n loading,\n error,\n canUndo,\n canRedo,\n undo,\n redo,\n refresh,\n autoRefresh,\n refreshRow,\n aggregations,\n addFilter,\n updateFilter,\n removeFilter,\n clearFilters,\n updatePredicate,\n removePredicate,\n negatePredicate,\n reorderFilters,\n mergeFilters,\n resetAll,\n filterValues,\n fieldStats,\n toggleSort,\n setSort,\n select,\n computed,\n setLimit,\n setOffset,\n nextPage,\n prevPage,\n selection,\n saved,\n columnDrag,\n visibleFields,\n rowId,\n };\n}\n\n/** Multi-sort header click logic.\n * - plain click on the sole sorted column → flip its direction\n * - plain click on another column → make it the only sort (desc)\n * - shift-click a new column → append it (desc) as a secondary term\n * - shift-click an existing term → cycle desc → asc → remove */\nfunction nextOrderBy(existing: OrderByClause[], field: string, additive: boolean): OrderByClause[] {\n const i = existing.findIndex((s) => s.field === field);\n if (!additive) {\n if (i === 0 && existing.length === 1) {\n const flipped: \"asc\" | \"desc\" = existing[0]!.dir === \"desc\" ? \"asc\" : \"desc\";\n return [{ ...existing[0]!, dir: flipped }];\n }\n return [{ field, dir: \"desc\" }];\n }\n if (i === -1) return [...existing, { field, dir: \"desc\" }];\n const cur = existing[i]!;\n if (cur.dir === \"desc\") {\n const next = [...existing];\n next[i] = { ...cur, dir: \"asc\" };\n return next;\n }\n return existing.filter((_, k) => k !== i); // asc → remove\n}\n","// useAggregations — the metric panel's data side.\n//\n// Runs the optional GROUP BY queries that back the metrics shown above the table.\n// Kept separate from the rows fetch so the panel loads/refreshes independently:\n// metrics depend ONLY on the WHERE filter + the aggregation specs (scope is the\n// whole filtered set — never the page window), so paging or re-sorting the table\n// does not re-issue them. Debounced + abortable, mirroring the rows fetch.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { applyAggregations, toAggregationQuery } from \"@pythia-software/query-table-core\";\nimport type { AggregationResult, FieldSchema, QueryState, Transport } from \"@pythia-software/query-table-core\";\n\nexport interface AggregationsApiState {\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n}\n\nconst EMPTY_RESULT: AggregationResult = { metrics: [] };\n\nexport function useAggregations<Row>(\n query: QueryState,\n schema: FieldSchema<Row>,\n transport: Transport<Row> | undefined,\n clientRows: Row[] | undefined,\n debounceMs: number,\n nonce: number,\n validateQuery?: (query: QueryState) => void,\n): AggregationsApiState {\n const [results, setResults] = useState<AggregationResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Metrics depend only on WHERE + the agg specs. Keying on just those avoids\n // refetching when the user pages or re-sorts the table.\n const key = useMemo(\n () => JSON.stringify({ where: query.where, aggregations: query.aggregations ?? [] }),\n [query.where, query.aggregations],\n );\n const hasAggregations = (query.aggregations?.length ?? 0) > 0;\n\n useEffect(() => {\n if (!hasAggregations) {\n setResults(null);\n setError(null);\n setLoading(false);\n return;\n }\n\n const ac = new AbortController();\n let cancelled = false;\n const run = async () => {\n setLoading(true);\n setError(null);\n try {\n validateQuery?.(query);\n let res: AggregationResult;\n if (transport?.fetchAggregations) {\n res = await transport.fetchAggregations(toAggregationQuery(query, schema), ac.signal);\n } else if (clientRows) {\n res = applyAggregations(clientRows, query, schema);\n } else {\n res = EMPTY_RESULT;\n }\n if (!cancelled) setResults(res);\n } catch (e) {\n if (!cancelled && !ac.signal.aborted) { setError(e as Error); setResults(null); }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n const t = setTimeout(run, debounceMs);\n return () => {\n cancelled = true;\n clearTimeout(t);\n ac.abort();\n };\n // `key` captures the relevant query subset; clientRows/nonce force a refetch.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key, hasAggregations, transport, clientRows, schema, debounceMs, nonce, validateQuery]);\n\n return { results, loading, error };\n}\n","// useSelection — row selection for paged and re-sortable datasets.\n//\n// - Shift-click range select, anchored by ROW ID (not index) so a\n// range survives re-sort / re-filter / paging. Index anchors break the moment\n// the data reorders; id anchors don't.\n// - Indeterminate header checkbox + select-all-on-page.\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { RowId } from \"@pythia-software/query-table-core\";\n\nexport interface SelectionApi {\n selected: Set<RowId>;\n isSelected: (id: RowId) => boolean;\n /** Toggle one row. With `shiftKey`, extend from the last-toggled anchor to `id`\n * across the *currently displayed* order (falls back to a plain toggle if the\n * anchor row is no longer present). */\n toggle: (id: RowId, shiftKey?: boolean) => void;\n /** Select / clear every row currently on the page. */\n setPage: (ids: RowId[], selected: boolean) => void;\n /** Atomically replace the complete selection with arbitrary stable row ids. */\n replace: (ids: Iterable<RowId>) => void;\n /** Atomically retain only selected ids that are also present in `ids`. */\n retain: (ids: Iterable<RowId>) => void;\n /** Header checkbox tri-state for the current page. */\n pageState: (pageIds: RowId[]) => \"none\" | \"some\" | \"all\";\n clear: () => void;\n count: number;\n}\n\n/** `displayedIds` is the page's id list in display order; the hook uses it to\n * resolve shift-ranges and header tri-state against what the user sees. */\nexport function useSelection(displayedIds: RowId[]): SelectionApi {\n const [selected, setSelected] = useState<Set<RowId>>(() => new Set());\n const anchor = useRef<RowId | null>(null);\n\n const toggle = useCallback(\n (id: RowId, shiftKey = false) => {\n setSelected((prev) => {\n const next = new Set(prev);\n const a = anchor.current;\n if (shiftKey && a != null) {\n const i = displayedIds.indexOf(a);\n const j = displayedIds.indexOf(id);\n if (i !== -1 && j !== -1) {\n const [lo, hi] = i <= j ? [i, j] : [j, i];\n const span = displayedIds.slice(lo, hi + 1);\n const allChecked = span.every((rowId) => prev.has(rowId));\n for (const rowId of span) {\n if (allChecked) next.delete(rowId);\n else next.add(rowId);\n }\n anchor.current = id;\n return next;\n }\n }\n if (next.has(id)) next.delete(id);\n else next.add(id);\n anchor.current = id;\n return next;\n });\n },\n [displayedIds],\n );\n\n const setPage = useCallback((ids: RowId[], select: boolean) => {\n setSelected((prev) => {\n const next = new Set(prev);\n for (const id of ids) {\n if (select) next.add(id);\n else next.delete(id);\n }\n return next;\n });\n }, []);\n\n const replace = useCallback((ids: Iterable<RowId>) => {\n const next = new Set(ids);\n anchor.current = null;\n setSelected(next);\n }, []);\n\n const retain = useCallback((ids: Iterable<RowId>) => {\n const allowed = new Set(ids);\n anchor.current = null;\n setSelected((prev) => {\n const next = new Set<RowId>();\n for (const id of prev) if (allowed.has(id)) next.add(id);\n return next;\n });\n }, []);\n\n const pageState = useCallback(\n (pageIds: RowId[]): \"none\" | \"some\" | \"all\" => {\n if (pageIds.length === 0) return \"none\";\n let n = 0;\n for (const id of pageIds) if (selected.has(id)) n++;\n return n === 0 ? \"none\" : n === pageIds.length ? \"all\" : \"some\";\n },\n [selected],\n );\n\n const clear = useCallback(() => {\n anchor.current = null;\n setSelected(new Set());\n }, []);\n\n return useMemo<SelectionApi>(\n () => ({\n selected,\n isSelected: (id) => selected.has(id),\n toggle,\n setPage,\n replace,\n retain,\n pageState,\n clear,\n count: selected.size,\n }),\n [selected, toggle, setPage, replace, retain, pageState, clear],\n );\n}\n","// useSelect — the SELECT list: visible columns, their order, and their widths,\n// all persisted INTO the query (decision #5, so one URL renders identically\n// anywhere). This API mutates QueryState.select; it holds no state of its own.\n// Width changes should be debounced by the caller before they hit the query to\n// avoid flooding history during a drag (useQueryTable does this).\n\nimport { useCallback, useMemo } from \"react\";\nimport type { QueryState, SelectColumn, FieldDef, FieldSchema } from \"@pythia-software/query-table-core\";\nimport { selectedFields } from \"@pythia-software/query-table-core\";\n\nexport interface SelectApi<Row> {\n /** Ordered visible columns (resolved: schema defaults when query.select is empty). */\n visible: SelectColumn[];\n /** The corresponding FieldDefs, same order. */\n fields: FieldDef<Row>[];\n /** Selectable fields not currently shown (for the \"add column\" picker). */\n hidden: FieldDef<Row>[];\n\n show: (field: string) => void;\n hide: (field: string) => void;\n /** Reorder via drag-drop: move `field` to `toIndex` in the visible order. */\n move: (field: string, toIndex: number) => void;\n /** Set a column's pixel width. */\n setWidth: (field: string, width: number) => void;\n /** Reset to the schema's default columns (clears query.select). */\n reset: () => void;\n}\n\ntype SetQuery = (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n\nexport function useSelect<Row>(query: QueryState, setQuery: SetQuery, schema: FieldSchema<Row>): SelectApi<Row> {\n const fields = useMemo(() => selectedFields(schema, query), [schema, query]);\n\n // The materialized SelectColumn[] (resolve defaults so the UI always has a\n // concrete, reorderable list even before the user customizes it).\n const visible = useMemo<SelectColumn[]>(() => fields.map((f) => columnFor(query.select, f.name)), [fields, query.select]);\n\n const hidden = useMemo<FieldDef<Row>[]>(() => {\n const shown = new Set(fields.map((f) => f.name));\n return schema.fields.filter((f) => !shown.has(f.name) && (f.select?.enabled ?? true));\n }, [schema, fields]);\n\n const writeSelect = useCallback(\n (mutate: (cols: SelectColumn[]) => SelectColumn[]) => {\n setQuery((prev) => {\n // Materialize current (resolved) columns the first time we diverge from defaults.\n const current = prev.select.length ? prev.select : visible;\n return { ...prev, select: mutate([...current]) };\n });\n },\n [setQuery, visible],\n );\n\n const show = useCallback((field: string) => writeSelect((c) => (c.some((x) => x.field === field) ? c : [...c, { field }])), [writeSelect]);\n const hide = useCallback((field: string) => writeSelect((c) => c.filter((x) => x.field !== field)), [writeSelect]);\n const move = useCallback(\n (field: string, toIndex: number) =>\n writeSelect((c) => {\n const from = c.findIndex((x) => x.field === field);\n if (from === -1) return c;\n const [item] = c.splice(from, 1);\n c.splice(Math.max(0, Math.min(toIndex, c.length)), 0, item!);\n return c;\n }),\n [writeSelect],\n );\n const setWidth = useCallback(\n (field: string, width: number) =>\n writeSelect((c) => c.map((x) => (x.field === field ? { ...x, width: Math.round(width) } : x))),\n [writeSelect],\n );\n const reset = useCallback(() => setQuery((prev) => ({ ...prev, select: [] })), [setQuery]);\n\n return { visible, fields, hidden, show, hide, move, setWidth, reset };\n}\n\nfunction columnFor(select: SelectColumn[], name: string): SelectColumn {\n const found = select.find((c) => c.field === name);\n return found ?? { field: name };\n}\n","// useColumnDrag — transient, SHARED state for a column-reorder drag. One instance\n// is owned by useQueryTable and read by BOTH the table headers and the\n// QueryBuilder select chips, so a drag started in either surface live-previews\n// (and dims) the same column in the other. It holds no query state; the reorder\n// is committed to QueryState.select by whichever surface handles the drop.\n\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface ColumnDragApi {\n /** Field name currently being dragged, or null when idle. */\n source: string | null;\n /** Insertion index within the order with `source` removed (0..n; n = append). */\n overIndex: number | null;\n /** True while a column drag is in progress. */\n active: boolean;\n /** Begin dragging `field`, initially previewed at `index` (its own slot). */\n start: (field: string, index: number) => void;\n /** Update the previewed insertion index (no-op if unchanged). */\n over: (index: number) => void;\n /** End the drag (on drop or cancel). */\n end: () => void;\n /** The live order to render while dragging: `source` moved to `overIndex`.\n * Returns `order` unchanged when idle, or when `source` isn't in `order`. */\n preview: (order: string[]) => string[];\n}\n\ninterface DragState {\n source: string;\n overIndex: number;\n}\n\nexport function useColumnDrag(): ColumnDragApi {\n const [state, setState] = useState<DragState | null>(null);\n\n const start = useCallback((field: string, index: number) => setState({ source: field, overIndex: index }), []);\n const over = useCallback(\n (index: number) =>\n // Keep the SAME object reference when unchanged so React can bail out of the\n // re-render — onDragOver fires continuously while the cursor moves.\n setState((s) => (s && s.overIndex !== index ? { source: s.source, overIndex: index } : s)),\n [],\n );\n const end = useCallback(() => setState(null), []);\n\n const preview = useCallback(\n (order: string[]): string[] => {\n if (!state) return order;\n const without = order.filter((n) => n !== state.source);\n if (without.length === order.length) return order; // source not part of this list\n const at = Math.max(0, Math.min(state.overIndex, without.length));\n return [...without.slice(0, at), state.source, ...without.slice(at)];\n },\n [state],\n );\n\n return useMemo(\n () => ({\n source: state?.source ?? null,\n overIndex: state?.overIndex ?? null,\n active: state != null,\n start,\n over,\n end,\n preview,\n }),\n [state, start, over, end, preview],\n );\n}\n","// useSavedQueries — named query snapshots over a StorageAdapter.\n//\n// \"Last query\" auto-restore and named saves both flow through the injected\n// StorageAdapter (in-memory by default, explicitly durable when the caller\n// provides one). Loading a saved query pushes its QueryState into the controller.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { QueryState, SavedQuery, StorageAdapter } from \"@pythia-software/query-table-core\";\n\nexport interface SavedQueriesApi {\n items: SavedQuery[];\n loading: boolean;\n /** Saved query id used as the default view when no query is specified. */\n defaultId: string | null;\n /** Persist the current query under a name. Rejects on duplicate names. */\n save: (name: string) => Promise<SavedQuery>;\n /** Load a saved query into the live controller. */\n load: (id: string) => void;\n /** Mark a saved query as the default view. No-op when storage lacks support. */\n setDefault: (id: string) => Promise<void>;\n /** Clear the saved-query default view. */\n clearDefault: () => Promise<void>;\n remove: (id: string) => Promise<void>;\n}\n\nexport function useSavedQueries(\n key: string,\n currentQuery: QueryState,\n applyQueryState: (q: QueryState) => void,\n storage: StorageAdapter,\n /** Injected clock so saves are deterministic/testable. */\n now: () => number,\n): SavedQueriesApi {\n const [items, setItems] = useState<SavedQuery[]>([]);\n const [defaultId, setDefaultId] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const [savedItems, defaultSaved] = await Promise.all([\n storage.listSaved(key),\n storage.loadDefaultSaved?.(key) ?? Promise.resolve(null),\n ]);\n setItems(savedItems);\n setDefaultId(defaultSaved?.id ?? null);\n } finally {\n setLoading(false);\n }\n }, [storage, key]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const save = useCallback(\n async (name: string) => {\n const saved = await storage.saveNamed(key, name, currentQuery, now());\n await refresh();\n return saved;\n },\n [storage, key, currentQuery, now, refresh],\n );\n\n const load = useCallback(\n (id: string) => {\n const found = items.find((q) => q.id === id);\n if (found) applyQueryState(found.query);\n },\n [items, applyQueryState],\n );\n\n const setDefault = useCallback(\n async (id: string) => {\n await storage.setDefaultSaved?.(key, id);\n await refresh();\n },\n [storage, key, refresh],\n );\n\n const clearDefault = useCallback(async () => {\n await storage.setDefaultSaved?.(key, null);\n await refresh();\n }, [storage, key, refresh]);\n\n const remove = useCallback(\n async (id: string) => {\n if (id === defaultId) await storage.setDefaultSaved?.(key, null);\n await storage.deleteSaved(key, id);\n await refresh();\n },\n [storage, key, defaultId, refresh],\n );\n\n return { items, loading, defaultId, save, load, setDefault, clearDefault, remove };\n}\n"],"mappings":";AAAA,SAAS,aAAa,WAAW,SAAS,QAAQ,gBAAgB;AAClE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAYK;;;ACvBP;AAAA,EACE;AAAA,OAIK;AAIA,IAAM,sBAA4C,MAAM;AAC7D,QAAM,OAAO,oBAAoB,eAAe,SAAS,CAAC;AAC1D,QAAM,MAAM,IAAI;AAAA,IACd,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAAA,EAC9C;AACA,MAAI;AACF,WAAO,IAAI,OAAO,GAAG;AAAA,EACvB,UAAE;AACA,QAAI,gBAAgB,GAAG;AAAA,EACzB;AACF;AACO,SAAS,oBACd,KACA,QACA,QACA,UAAgC,qBACN;AAC1B,MAAI,QAAQ;AACV,WAAO,QAAQ,OAAO,IAAI,aAAa,WAAW,YAAY,CAAC;AACjE,MAAI,CAAC,OAAO,OAAQ,QAAO,QAAQ,QAAQ,CAAC,CAAC;AAC7C,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI;AACJ,QAAI;AACF,eAAS,QAAQ;AAAA,IACnB,SAAS,GAAG;AACV;AAAA,QACE,IAAI;AAAA,UACF,+BAA+B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,QAC3E;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI;AACJ,UAAM,UAAU,KAAK,IAAI;AACzB,QAAI,SAAS;AACb,UAAM,UAA2B,CAAC;AAClC,UAAM,UAAU,MAAM;AACpB,mBAAa,KAAK;AAClB,aAAO,UAAU;AACjB,cAAQ,oBAAoB,SAAS,KAAK;AAAA,IAC5C;AACA,UAAM,QAAQ,MAAM;AAClB,cAAQ;AACR,aAAO,IAAI,aAAa,WAAW,YAAY,CAAC;AAAA,IAClD;AACA,UAAM,OAAO,MAAM;AACjB,UAAI,KAAK,IAAI,IAAI,UAAU,KAAO;AAChC,gBAAQ;AACR;AAAA,UACE,IAAI;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA;AAAA,MACF;AACA,cAAQ,WAAW,MAAM;AACvB,gBAAQ;AACR;AAAA,UACE,IAAI;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,GAAG,GAAI;AACP,UAAI;AACF,eAAO,YAAY,EAAE,KAAK,QAAQ,OAAO,MAAM,QAAQ,SAAS,GAAG,EAAE,CAAC;AAAA,MACxE,SAAS,GAAG;AACV,gBAAQ;AACR,eAAO,CAAC;AAAA,MACV;AAAA,IACF;AACA,YAAQ,iBAAiB,SAAS,OAAO,EAAE,MAAM,KAAK,CAAC;AACvD,WAAO,UAAU,MAAM;AACrB,cAAQ;AACR,aAAO,IAAI,MAAM,wBAAwB,CAAC;AAAA,IAC5C;AACA,WAAO,YAAY,CAAC,UAAyC;AAC3D,mBAAa,KAAK;AAClB,cAAQ,KAAK,GAAG,MAAM,IAAI;AAC1B,gBAAU,MAAM,KAAK;AACrB,UAAI,UAAU,OAAO,QAAQ;AAC3B,gBAAQ;AACR,gBAAQ,OAAO;AAAA,MACjB,MAAO,MAAK;AAAA,IACd;AACA,SAAK;AAAA,EACP,CAAC;AACH;;;ADrCO,SAAS,mBAAwB,SAGtC;AACA,QAAM,EAAE,QAAQ,OAAO,MAAM,WAAW,YAAY,cAAc,IAAI;AACtE,QAAM,QAAQ;AAAA,IACZ,MAAM,QAAQ,SAAS,0BAA0B;AAAA,IACjD,CAAC,QAAQ,KAAK;AAAA,EAChB;AACA,QAAM,CAAC,WAAW,YAAY,IAAI,SAIxB,IAAI;AACd,QAAM,cAAc;AAAA,IAClB,MACE,WAAW,YAAY,OAAO,QAAQ,UAAU,UAAU,QACtD,UAAU,QACV,CAAC;AAAA,IACP,CAAC,WAAW,OAAO,MAAM,KAAK;AAAA,EAChC;AACA,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK,GAC1C,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAClD,QAAM,mBAAmB,OAA+B,IAAI;AAC5D,QAAM,SAAS,YAAY,YAAY;AACrC,qBAAiB,SAAS,MAAM;AAChC,UAAM,KAAK,IAAI,gBAAgB;AAC/B,qBAAiB,UAAU;AAC3B,eAAW,IAAI;AACf,aAAS,IAAI;AACb,QAAI;AACF,YAAM,QAAQ,MAAM,MAAM,KAAK,OAAO,MAAM,GAAG,MAAM;AACrD,UAAI,GAAG,OAAO,QAAS;AACvB,YAAM,QAAQ,MACX,IAAI,sBAAsB,EAC1B,KAAK,CAAC,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AAC1C,UAAI,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,SAAS,MAAM;AACjD,cAAM,IAAI,MAAM,gCAAgC;AAClD;AAAA,QAAa,CAAC,aACZ,UAAU,YAAY,OAAO,QAC7B,SAAS,UAAU,SACnB,KAAK,UAAU,SAAS,KAAK,MAAM,KAAK,UAAU,KAAK,IACnD,WACA,EAAE,SAAS,OAAO,MAAM,OAAO,OAAO,MAAM;AAAA,MAClD;AAAA,IACF,SAAS,GAAG;AACV,UAAI,CAAC,GAAG,OAAO;AACb,iBAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IACvD,UAAE;AACA,UAAI,CAAC,GAAG,OAAO,QAAS,YAAW,KAAK;AAAA,IAC1C;AAAA,EACF,GAAG,CAAC,OAAO,OAAO,IAAI,CAAC;AACvB,YAAU,MAAM;AACd,SAAK,OAAO;AACZ,WAAO,MAAM,iBAAiB,SAAS,MAAM;AAAA,EAC/C,GAAG,CAAC,MAAM,CAAC;AACX;AAAA,IACE,MACE,MAAM,YAAY,OAAO,MAAM,MAAM;AACnC,WAAK,OAAO;AAAA,IACd,CAAC;AAAA,IACH,CAAC,OAAO,OAAO,MAAM,MAAM;AAAA,EAC7B;AACA,YAAU,MAAM;AACd,UAAM,QAAQ,MAAM;AAClB,WAAK,OAAO;AAAA,IACd;AACA,WAAO,iBAAiB,SAAS,KAAK;AACtC,WAAO,MAAM,OAAO,oBAAoB,SAAS,KAAK;AAAA,EACxD,GAAG,CAAC,MAAM,CAAC;AACX,QAAM,cAAc;AAAA,IAClB,MACE,OAAO,OACJ,OAAO,YAAY,EACnB;AAAA,MACC,CAAC,MACC,EAAE,OAAO,SAAS,aACjB,EAAE,OAAO,YAAY,EAAE,OAAO;AAAA,IACnC;AAAA,IACJ,CAAC,MAAM;AAAA,EACT;AACA,QAAM,UAAU;AAAA,IACd,CAAC,QAAgB,cAAoC;AACnD,YAAM,QAAQ,IAAI,IAAY,YAAY,CAAC,SAAS,IAAI,CAAC,CAAC;AAC1D,UAAI,WAAW;AACf,YAAM,UAAU,CAAC,SAA0C;AACzD,YAAI,CAAC,gBAAgB,IAAI,EAAG,QAAO;AACnC,cAAM,KAAK,KAAK,MAAM,aAAa,MAAM,GACvC,MAAM,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC3C,YAAI,CAAC,IAAK,OAAM,IAAI,MAAM,gCAAgC,EAAE,EAAE;AAC9D,YAAI,MAAM,IAAI,EAAE;AACd,gBAAM,IAAI,MAAM,uCAAuC,IAAI,KAAK,EAAE;AACpE,YAAI,MAAM,QAAQ,MAAM,EAAE,WAAW;AACnC,gBAAM,IAAI,MAAM,yCAAyC;AAC3D,cAAM,IAAI,EAAE;AACZ,YAAI;AACF,iBAAO,eAAe,IAAI,WAAW,QAAQ,aAAa,OAAO;AAAA,QACnE,UAAE;AACA,gBAAM,OAAO,EAAE;AAAA,QACjB;AAAA,MACF;AACA,aAAO,eAAe,QAAQ,aAAa,OAAO;AAAA,IACpD;AAAA,IACA,CAAC,aAAa,WAAW;AAAA,EAC3B;AACA,QAAM,QAAQ;AAAA,IACZ,MACE,IAAI;AAAA,MACF,YAAY,IAAI,CAAC,QAAQ;AACvB,YAAI;AACF,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,EAAE,MAAM,QAAQ,IAAI,WAAW,QAAQ,IAAI,EAAE,EAAE;AAAA,UACjD;AAAA,QACF,SAAS,GAAG;AACV,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,EAAE,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAE;AAAA,UACtD;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACF,CAAC,aAAa,OAAO;AAAA,EACvB;AACA,QAAM,sBAAsB;AAAA,IAC1B,CAAC,SACC;AAAA,MACE,GAAG,IAAI;AAAA,QACL,KAAK,aAAa,QAAQ,CAAC,SAAS;AAClC,gBAAM,IAAI,YAAY,KAAK,CAACA,OAAMA,GAAE,SAAS,IAAI;AACjD,iBAAO,GAAG,OAAO,SAAS,YACtB,CAAC,IAAI,IACJ,GAAG,OAAO,gBAAgB,CAAC;AAAA,QAClC,CAAC;AAAA,MACH;AAAA,IACF,EACG;AAAA,MAAO,CAAC,SACP,OAAO,OAAO;AAAA,QACZ,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,OAAO,SAAS;AAAA,MAC9C;AAAA,IACF,EACC,KAAK;AAAA,IACV,CAAC,QAAQ,WAAW;AAAA,EACtB;AACA,QAAM,YAAY;AAAA,IAChB,CAAC,MAAmB,UAAiB;AACnC,UAAI,OAAO;AACX,aAAO,MAAM,IAAI,CAAC,QAAQ;AACxB,cAAM,SAAuC,uBAAO,OAAO,IAAI;AAC/D,mBAAW,QAAQ,KAAK,cAAc;AACpC,gBAAM,QAAQ,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACrD,gBAAM,MAAM,eAAe,OAAO,GAAG;AACrC,iBAAO,IAAI,IACT,eAAe,OAAO,IAAI,YAAY,IAAK;AAAA,QAC/C;AACA,gBAAQ,KAAK,UAAU,MAAM,EAAE;AAC/B,YAAI,OAAO;AACT,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AACF,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AACA,QAAM,eAAe,MAAM,OAAO,SAC9B,MAAM,SACL,OAAO,iBAAiB,CAAC;AAC9B,QAAM,YAAY,aACf,OAAO,CAAC,MAAM,gBAAgB,EAAE,KAAK,CAAC,EACtC,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,aAAa,MAAM,CAAC,EAC7C,KAAK,EACL,KAAK,GAAG;AACX,QAAM,CAAC,WAAW,YAAY,IAAI,SAIxB,IAAI;AACd,YAAU,MAAM;AACd,UAAM,KAAK,IAAI,gBAAgB;AAC/B,UAAM,SAAS,oBAAI,IAA6B;AAChD,UAAM,YAAY;AAChB,iBAAW,MAAM,UAAU,MAAM,GAAG,EAAE,OAAO,OAAO,GAAG;AACrD,cAAM,QAAQ,MAAM,IAAI,EAAE;AAC1B,YAAI,CAAC,OAAO,KAAM;AAClB,YAAI;AACF,iBAAO;AAAA,YACL;AAAA,YACA,MAAM;AAAA,cACJ,MAAM,KAAK;AAAA,cACX,UAAU,MAAM,MAAM,IAAI;AAAA,cAC1B,GAAG;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,GAAG;AACV,cAAI,GAAG,OAAO,QAAS;AACvB,iBAAO;AAAA,YACL;AAAA,YACA,KAAK,IAAI,OAAO;AAAA,cACd,OAAO;AAAA,cACP,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,YAClD,EAAE;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA,UAAI,CAAC,GAAG,OAAO,QAAS,cAAa,EAAE,MAAM,OAAO,OAAO,CAAC;AAAA,IAC9D,GAAG;AACH,WAAO,MAAM,GAAG,MAAM;AAAA,EACxB,GAAG,CAAC,WAAW,MAAM,OAAO,WAAW,aAAa,CAAC;AACrD,QAAM,gBAAgB,QAA0B,MAAM;AACpD,UAAM,UAAU,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACtD,UAAM,SAA0B,YAAY,IAAI,CAAC,QAAQ;AACvD,YAAM,QAAQ,MAAM,IAAI,IAAI,EAAE;AAC9B,aAAO;AAAA,QACL,MAAM,kBAAkB,IAAI,EAAE;AAAA,QAC9B,OAAO,IAAI;AAAA,QACX,MACE,OAAO,MAAM,SAAS,SAAS,SAAU,OAAO,MAAM,QAAQ;AAAA,QAChE,OAAO;AAAA,QACP,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,YAAY,IAAI;AAAA,UAChB,cAAc,OAAO,OAAO,oBAAoB,MAAM,IAAI,IAAI,CAAC;AAAA,UAC/D,UAAU,CAAC,QAAa;AACtB,gBAAI,OAAO,MAAO,QAAO,EAAE,eAAe,MAAM,MAAM;AACtD,kBAAM,SACJ,WAAW,SAAS,QAAQ,UAAU,UAAU,QAC5C,UAAU,OAAO,IAAI,IAAI,EAAE,IAAI,QAAQ,IAAI,GAAG,KAAK,EAAE,IACrD;AACN,mBAAO,QAAQ,QACX,EAAE,eAAe,OAAO,MAAM,IAC9B,SACE,OAAO,QACP,EAAE,eAAe,oBAAe;AAAA,UACxC;AAAA,QACF;AAAA,QACA,QAAQ,EAAE,SAAS,MAAM;AAAA,QACzB,MAAM,EAAE,SAAS,MAAM;AAAA,QACvB,WAAW,EAAE,SAAS,OAAO,WAAW,MAAM;AAAA,MAChD;AAAA,IACF,CAAC;AACD,eAAW,OAAO;AAChB,UACE,gBAAgB,IAAI,KAAK,KACzB,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK;AAExC,eAAO,KAAK;AAAA,UACV,MAAM,IAAI;AAAA,UACV,OAAO,IAAI,MAAM,MAAM,EAAE;AAAA,UACzB,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,YAAY,IAAI,MAAM,MAAM,EAAE;AAAA,YAC9B,UAAU,OAAO;AAAA,cACf,eAAe,UACX,6BACA;AAAA,YACN;AAAA,UACF;AAAA,UACA,QAAQ,EAAE,SAAS,MAAM;AAAA,UACzB,MAAM,EAAE,SAAS,MAAM;AAAA,UACvB,WAAW,EAAE,SAAS,OAAO,WAAW,MAAM;AAAA,QAChD,CAAC;AACL,WAAO,EAAE,GAAG,QAAQ,QAAQ,CAAC,GAAG,OAAO,QAAQ,GAAG,MAAM,EAAE;AAAA,EAC5D,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,OAAO;AAAA,IACP;AAAA,EACF,CAAC;AACD,QAAM,OAAO;AAAA,IACX,OAAO,QAA6B,qBAAoC;AACtE,cAAQ,OAAO,WAAW,QAAQ,OAAO,EAAE;AAC3C,YAAM,QAAQ;AAAA,QACZ,MAAM,MAAM,KAAK,OAAO,MAAM,QAAQ,gBAAgB;AAAA,MACxD;AACA,mBAAa,CAAC,UAAU;AAAA,QACtB,SAAS,OAAO;AAAA,QAChB;AAAA,QACA,OAAO;AAAA,UACL,GAAI,MAAM,YAAY,OAAO,QAAQ,KAAK,UAAU,QAChD,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,IAC1C,CAAC;AAAA,UACL;AAAA,QACF;AAAA,MACF,EAAE;AACF,aAAO;AAAA,IACT;AAAA,IACA,CAAC,SAAS,OAAO,OAAO,IAAI;AAAA,EAC9B;AACA,QAAM,UAAU;AAAA,IACd,OACE,QACA,OACA,QACA,WACA,gBAAgB,SACW;AAC3B,UAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ;AACnD,cAAM,IAAI,MAAM,mCAAmC;AACrD,YAAM,OAAO,QAAQ,QAAQ,SAAS;AACtC,UAAI,QAAe,CAAC,GAClB,QAAQ;AACV,UAAI,WAAW;AACb,cAAM,UAAU;AAAA,UACd;AAAA,YACE,GAAG;AAAA,YACH,QAAQ;AAAA,cACN,GAAG,oBAAI,IAAI,CAAC,OAAO,SAAS,GAAG,oBAAoB,IAAI,CAAC,CAAC;AAAA,YAC3D,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAAA,YAC5B,OAAO,KAAK,IAAI,OAAO,GAAG;AAAA,YAC1B,QAAQ;AAAA,UACV;AAAA,UACA;AAAA,QACF;AACA,eAAO,MAAM,SAAS,OAAO;AAC3B,cAAI,QAAQ,QAAS,OAAM,IAAI,aAAa,WAAW,YAAY;AACnE,gBAAM,MAAM,MAAM,UAAU;AAAA,YAC1B;AAAA,cACE,GAAG;AAAA,cACH,QAAQ,MAAM;AAAA,cACd,OAAO,KAAK,IAAI,KAAK,QAAQ,MAAM,MAAM;AAAA,YAC3C;AAAA,YACA;AAAA,UACF;AACA,kBAAQ,IAAI;AACZ,gBAAM,KAAK,GAAG,IAAI,KAAK,MAAM,GAAG,QAAQ,MAAM,MAAM,CAAC;AACrD,cAAI,CAAC,IAAI,KAAK,UAAU,MAAM,UAAU,MAAO;AAAA,QACjD;AAAA,MACF,OAAO;AACL,cAAM,SAAS;AAAA,UACb,cAAc,CAAC;AAAA,UACf,EAAE,GAAG,OAAO,OAAO,OAAO,QAAQ,EAAE;AAAA,UACpC;AAAA,QACF;AACA,gBAAQ,OAAO;AACf,gBAAQ,OAAO;AAAA,MACjB;AACA,YAAM,SAAS,UAAU,MAAM,KAAK,GAClC,UAAU,MAAM;AAAA,QACd,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACF,aAAO;AAAA,QACL,gBAAgB,KAAK,eAAe,CAAC;AAAA,QACrC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,KAAK;AAAA,MACH;AAAA,MACA,WAAW,cAAc;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AE7aA,SAAS,eAAAC,cAAa,aAAAC,YAAW,WAAAC,UAAS,UAAAC,SAAQ,YAAAC,iBAAgB;AAClE;AAAA,EACE;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACnBP,SAAS,aAAAC,YAAW,WAAAC,UAAS,YAAAC,iBAAgB;AAC7C,SAAS,mBAAmB,0BAA0B;AAStD,IAAM,eAAkC,EAAE,SAAS,CAAC,EAAE;AAE/C,SAAS,gBACd,OACA,QACA,WACA,YACA,YACA,OACA,eACsB;AACtB,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAmC,IAAI;AACrE,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAuB,IAAI;AAIrD,QAAM,MAAMD;AAAA,IACV,MAAM,KAAK,UAAU,EAAE,OAAO,MAAM,OAAO,cAAc,MAAM,gBAAgB,CAAC,EAAE,CAAC;AAAA,IACnF,CAAC,MAAM,OAAO,MAAM,YAAY;AAAA,EAClC;AACA,QAAM,mBAAmB,MAAM,cAAc,UAAU,KAAK;AAE5D,EAAAD,WAAU,MAAM;AACd,QAAI,CAAC,iBAAiB;AACpB,iBAAW,IAAI;AACf,eAAS,IAAI;AACb,iBAAW,KAAK;AAChB;AAAA,IACF;AAEA,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,YAAY;AAChB,UAAM,MAAM,YAAY;AACtB,iBAAW,IAAI;AACf,eAAS,IAAI;AACb,UAAI;AACF,wBAAgB,KAAK;AACrB,YAAI;AACJ,YAAI,WAAW,mBAAmB;AAChC,gBAAM,MAAM,UAAU,kBAAkB,mBAAmB,OAAO,MAAM,GAAG,GAAG,MAAM;AAAA,QACtF,WAAW,YAAY;AACrB,gBAAM,kBAAkB,YAAY,OAAO,MAAM;AAAA,QACnD,OAAO;AACL,gBAAM;AAAA,QACR;AACA,YAAI,CAAC,UAAW,YAAW,GAAG;AAAA,MAChC,SAAS,GAAG;AACV,YAAI,CAAC,aAAa,CAAC,GAAG,OAAO,SAAS;AAAE,mBAAS,CAAU;AAAG,qBAAW,IAAI;AAAA,QAAG;AAAA,MAClF,UAAE;AACA,YAAI,CAAC,UAAW,YAAW,KAAK;AAAA,MAClC;AAAA,IACF;AACA,UAAM,IAAI,WAAW,KAAK,UAAU;AACpC,WAAO,MAAM;AACX,kBAAY;AACZ,mBAAa,CAAC;AACd,SAAG,MAAM;AAAA,IACX;AAAA,EAGF,GAAG,CAAC,KAAK,iBAAiB,WAAW,YAAY,QAAQ,YAAY,OAAO,aAAa,CAAC;AAE1F,SAAO,EAAE,SAAS,SAAS,MAAM;AACnC;;;AC3EA,SAAS,eAAAG,cAAa,WAAAC,UAAS,UAAAC,SAAQ,YAAAC,iBAAgB;AAwBhD,SAAS,aAAa,cAAqC;AAChE,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAqB,MAAM,oBAAI,IAAI,CAAC;AACpE,QAAM,SAASD,QAAqB,IAAI;AAExC,QAAM,SAASF;AAAA,IACb,CAAC,IAAW,WAAW,UAAU;AAC/B,kBAAY,CAAC,SAAS;AACpB,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,cAAM,IAAI,OAAO;AACjB,YAAI,YAAY,KAAK,MAAM;AACzB,gBAAM,IAAI,aAAa,QAAQ,CAAC;AAChC,gBAAM,IAAI,aAAa,QAAQ,EAAE;AACjC,cAAI,MAAM,MAAM,MAAM,IAAI;AACxB,kBAAM,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AACxC,kBAAM,OAAO,aAAa,MAAM,IAAI,KAAK,CAAC;AAC1C,kBAAM,aAAa,KAAK,MAAM,CAAC,UAAU,KAAK,IAAI,KAAK,CAAC;AACxD,uBAAW,SAAS,MAAM;AACxB,kBAAI,WAAY,MAAK,OAAO,KAAK;AAAA,kBAC5B,MAAK,IAAI,KAAK;AAAA,YACrB;AACA,mBAAO,UAAU;AACjB,mBAAO;AAAA,UACT;AAAA,QACF;AACA,YAAI,KAAK,IAAI,EAAE,EAAG,MAAK,OAAO,EAAE;AAAA,YAC3B,MAAK,IAAI,EAAE;AAChB,eAAO,UAAU;AACjB,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,QAAM,UAAUA,aAAY,CAAC,KAAc,WAAoB;AAC7D,gBAAY,CAAC,SAAS;AACpB,YAAM,OAAO,IAAI,IAAI,IAAI;AACzB,iBAAW,MAAM,KAAK;AACpB,YAAI,OAAQ,MAAK,IAAI,EAAE;AAAA,YAClB,MAAK,OAAO,EAAE;AAAA,MACrB;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,UAAUA,aAAY,CAAC,QAAyB;AACpD,UAAM,OAAO,IAAI,IAAI,GAAG;AACxB,WAAO,UAAU;AACjB,gBAAY,IAAI;AAAA,EAClB,GAAG,CAAC,CAAC;AAEL,QAAM,SAASA,aAAY,CAAC,QAAyB;AACnD,UAAM,UAAU,IAAI,IAAI,GAAG;AAC3B,WAAO,UAAU;AACjB,gBAAY,CAAC,SAAS;AACpB,YAAM,OAAO,oBAAI,IAAW;AAC5B,iBAAW,MAAM,KAAM,KAAI,QAAQ,IAAI,EAAE,EAAG,MAAK,IAAI,EAAE;AACvD,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,YAAYA;AAAA,IAChB,CAAC,YAA8C;AAC7C,UAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,UAAI,IAAI;AACR,iBAAW,MAAM,QAAS,KAAI,SAAS,IAAI,EAAE,EAAG;AAChD,aAAO,MAAM,IAAI,SAAS,MAAM,QAAQ,SAAS,QAAQ;AAAA,IAC3D;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,QAAM,QAAQA,aAAY,MAAM;AAC9B,WAAO,UAAU;AACjB,gBAAY,oBAAI,IAAI,CAAC;AAAA,EACvB,GAAG,CAAC,CAAC;AAEL,SAAOC;AAAA,IACL,OAAO;AAAA,MACL;AAAA,MACA,YAAY,CAAC,OAAO,SAAS,IAAI,EAAE;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,SAAS;AAAA,IAClB;AAAA,IACA,CAAC,UAAU,QAAQ,SAAS,SAAS,QAAQ,WAAW,KAAK;AAAA,EAC/D;AACF;;;AClHA,SAAS,eAAAG,cAAa,WAAAC,gBAAe;AAErC,SAAS,sBAAsB;AAsBxB,SAAS,UAAe,OAAmB,UAAoB,QAA0C;AAC9G,QAAM,SAASA,SAAQ,MAAM,eAAe,QAAQ,KAAK,GAAG,CAAC,QAAQ,KAAK,CAAC;AAI3E,QAAM,UAAUA,SAAwB,MAAM,OAAO,IAAI,CAAC,MAAM,UAAU,MAAM,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,MAAM,MAAM,CAAC;AAExH,QAAM,SAASA,SAAyB,MAAM;AAC5C,UAAM,QAAQ,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAC/C,WAAO,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,IAAI,MAAM,EAAE,QAAQ,WAAW,KAAK;AAAA,EACtF,GAAG,CAAC,QAAQ,MAAM,CAAC;AAEnB,QAAM,cAAcD;AAAA,IAClB,CAAC,WAAqD;AACpD,eAAS,CAAC,SAAS;AAEjB,cAAM,UAAU,KAAK,OAAO,SAAS,KAAK,SAAS;AACnD,eAAO,EAAE,GAAG,MAAM,QAAQ,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,MACjD,CAAC;AAAA,IACH;AAAA,IACA,CAAC,UAAU,OAAO;AAAA,EACpB;AAEA,QAAM,OAAOA,aAAY,CAAC,UAAkB,YAAY,CAAC,MAAO,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,MAAM,CAAC,CAAE,GAAG,CAAC,WAAW,CAAC;AACzI,QAAM,OAAOA,aAAY,CAAC,UAAkB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;AACjH,QAAM,OAAOA;AAAA,IACX,CAAC,OAAe,YACd,YAAY,CAAC,MAAM;AACjB,YAAM,OAAO,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,KAAK;AACjD,UAAI,SAAS,GAAI,QAAO;AACxB,YAAM,CAAC,IAAI,IAAI,EAAE,OAAO,MAAM,CAAC;AAC/B,QAAE,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,EAAE,MAAM,CAAC,GAAG,GAAG,IAAK;AAC3D,aAAO;AAAA,IACT,CAAC;AAAA,IACH,CAAC,WAAW;AAAA,EACd;AACA,QAAM,WAAWA;AAAA,IACf,CAAC,OAAe,UACd,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,MAAO,EAAE,UAAU,QAAQ,EAAE,GAAG,GAAG,OAAO,KAAK,MAAM,KAAK,EAAE,IAAI,CAAE,CAAC;AAAA,IAC/F,CAAC,WAAW;AAAA,EACd;AACA,QAAM,QAAQA,aAAY,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC;AAEzF,SAAO,EAAE,SAAS,QAAQ,QAAQ,MAAM,MAAM,MAAM,UAAU,MAAM;AACtE;AAEA,SAAS,UAAU,QAAwB,MAA4B;AACrE,QAAM,QAAQ,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,IAAI;AACjD,SAAO,SAAS,EAAE,OAAO,KAAK;AAChC;;;ACzEA,SAAS,eAAAE,cAAa,WAAAC,UAAS,YAAAC,iBAAgB;AAyBxC,SAAS,gBAA+B;AAC7C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAA2B,IAAI;AAEzD,QAAM,QAAQF,aAAY,CAAC,OAAe,UAAkB,SAAS,EAAE,QAAQ,OAAO,WAAW,MAAM,CAAC,GAAG,CAAC,CAAC;AAC7G,QAAM,OAAOA;AAAA,IACX,CAAC;AAAA;AAAA;AAAA,MAGC,SAAS,CAAC,MAAO,KAAK,EAAE,cAAc,QAAQ,EAAE,QAAQ,EAAE,QAAQ,WAAW,MAAM,IAAI,CAAE;AAAA;AAAA,IAC3F,CAAC;AAAA,EACH;AACA,QAAM,MAAMA,aAAY,MAAM,SAAS,IAAI,GAAG,CAAC,CAAC;AAEhD,QAAM,UAAUA;AAAA,IACd,CAAC,UAA8B;AAC7B,UAAI,CAAC,MAAO,QAAO;AACnB,YAAM,UAAU,MAAM,OAAO,CAAC,MAAM,MAAM,MAAM,MAAM;AACtD,UAAI,QAAQ,WAAW,MAAM,OAAQ,QAAO;AAC5C,YAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,WAAW,QAAQ,MAAM,CAAC;AAChE,aAAO,CAAC,GAAG,QAAQ,MAAM,GAAG,EAAE,GAAG,MAAM,QAAQ,GAAG,QAAQ,MAAM,EAAE,CAAC;AAAA,IACrE;AAAA,IACA,CAAC,KAAK;AAAA,EACR;AAEA,SAAOC;AAAA,IACL,OAAO;AAAA,MACL,QAAQ,OAAO,UAAU;AAAA,MACzB,WAAW,OAAO,aAAa;AAAA,MAC/B,QAAQ,SAAS;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,OAAO,OAAO,MAAM,KAAK,OAAO;AAAA,EACnC;AACF;;;AC7DA,SAAS,eAAAE,cAAa,aAAAC,YAAW,YAAAC,iBAAgB;AAmB1C,SAAS,gBACd,KACA,cACA,iBACA,SAEA,KACiB;AACjB,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAuB,CAAC,CAAC;AACnD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAwB,IAAI;AAC9D,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,IAAI;AAE3C,QAAM,UAAUF,aAAY,YAAY;AACtC,eAAW,IAAI;AACf,QAAI;AACF,YAAM,CAAC,YAAY,YAAY,IAAI,MAAM,QAAQ,IAAI;AAAA,QACnD,QAAQ,UAAU,GAAG;AAAA,QACrB,QAAQ,mBAAmB,GAAG,KAAK,QAAQ,QAAQ,IAAI;AAAA,MACzD,CAAC;AACD,eAAS,UAAU;AACnB,mBAAa,cAAc,MAAM,IAAI;AAAA,IACvC,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,SAAS,GAAG,CAAC;AAEjB,EAAAC,WAAU,MAAM;AACd,SAAK,QAAQ;AAAA,EACf,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,OAAOD;AAAA,IACX,OAAO,SAAiB;AACtB,YAAM,QAAQ,MAAM,QAAQ,UAAU,KAAK,MAAM,cAAc,IAAI,CAAC;AACpE,YAAM,QAAQ;AACd,aAAO;AAAA,IACT;AAAA,IACA,CAAC,SAAS,KAAK,cAAc,KAAK,OAAO;AAAA,EAC3C;AAEA,QAAM,OAAOA;AAAA,IACX,CAAC,OAAe;AACd,YAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC3C,UAAI,MAAO,iBAAgB,MAAM,KAAK;AAAA,IACxC;AAAA,IACA,CAAC,OAAO,eAAe;AAAA,EACzB;AAEA,QAAM,aAAaA;AAAA,IACjB,OAAO,OAAe;AACpB,YAAM,QAAQ,kBAAkB,KAAK,EAAE;AACvC,YAAM,QAAQ;AAAA,IAChB;AAAA,IACA,CAAC,SAAS,KAAK,OAAO;AAAA,EACxB;AAEA,QAAM,eAAeA,aAAY,YAAY;AAC3C,UAAM,QAAQ,kBAAkB,KAAK,IAAI;AACzC,UAAM,QAAQ;AAAA,EAChB,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC;AAE1B,QAAM,SAASA;AAAA,IACb,OAAO,OAAe;AACpB,UAAI,OAAO,UAAW,OAAM,QAAQ,kBAAkB,KAAK,IAAI;AAC/D,YAAM,QAAQ,YAAY,KAAK,EAAE;AACjC,YAAM,QAAQ;AAAA,IAChB;AAAA,IACA,CAAC,SAAS,KAAK,WAAW,OAAO;AAAA,EACnC;AAEA,SAAO,EAAE,OAAO,SAAS,WAAW,MAAM,MAAM,YAAY,cAAc,OAAO;AACnF;;;ALlEA,IAAM,qBAAqB;AAC3B,IAAM,yBAAyB;AA+L/B,SAAS,YAAiB,QAAsC;AAC9D,SAAO,oBAAoB;AAAA,IACzB,QAAQ,OAAO,iBAAiB,CAAC;AAAA,IACjC,OAAO,CAAC;AAAA,IACR,SAAS,OAAO,eAAe,CAAC;AAAA,IAChC,OAAO,OAAO,gBAAgB,YAAY;AAAA,IAC1C,QAAQ;AAAA,EACV,CAAC;AACH;AAEA,SAAS,eAAe,MAA4B;AAClD,QAAM,OAAO,UAAU,IAAI,IAAI,EAAE,GAAG,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,KAAK;AAC7F,MAAI,KAAK,UAAW,MAAK,YAAY,EAAE,GAAG,KAAK,WAAW,QAAQ,CAAC,GAAG,KAAK,UAAU,MAAM,EAAE;AAC7F,SAAO;AACT;AAEA,SAAS,gBAAgB,GAA2B;AAClD,QAAM,QAAoB;AAAA,IACxB,QAAQ,EAAE,OAAO,IAAI,CAAC,YAAY,EAAE,GAAG,OAAO,EAAE;AAAA,IAChD,OAAO,EAAE,MAAM,IAAI,cAAc;AAAA,IACjC,SAAS,EAAE,QAAQ,IAAI,CAAC,SAAU,KAAK,UAAU,EAAE,GAAG,MAAM,SAAS,EAAE,GAAG,KAAK,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAE;AAAA,IACzG,OAAO,EAAE;AAAA,IACT,QAAQ,EAAE;AAAA,EACZ;AACA,MAAI,EAAE,aAAc,OAAM,eAAe,EAAE,aAAa,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE;AACtG,SAAO;AACT;AAKA,SAAS,iBAAiB,GAAsB,OAA4C;AAC1F,QAAM,OAA0B;AAAA,IAC9B,IAAI,EAAE;AAAA,IACN,IAAI,MAAM,MAAM,EAAE;AAAA,IAClB,SAAS,MAAM,WAAW,EAAE;AAAA,EAC9B;AACA,QAAM,QAAQ,WAAW,QAAQ,MAAM,QAAQ,EAAE;AACjD,MAAI,MAAO,MAAK,QAAQ;AACxB,QAAM,QAAQ,WAAW,QAAQ,MAAM,QAAQ,EAAE;AACjD,MAAI,MAAO,MAAK,QAAQ;AACxB,SAAO;AACT;AAEA,SAAS,WAAW,OAAyB;AAC3C,SAAO,SAAS,QAAS,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;AACpE;AAEA,SAAS,gBAAgB,OAA+B;AACtD,MAAI,WAAW,KAAK,EAAG,QAAO;AAC9B,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,WAAW;AACxF,WAAO,OAAO,KAAK;AAAA,EACrB;AACA,SAAO;AACT;AAEA,SAAS,mBAAwB,OAAsB,MAAsB;AAC3E,aAAW,OAAO,MAAM;AACtB,QAAI,WAAWG,gBAAe,OAAO,GAAG,CAAC,EAAG,QAAO;AAAA,EACrD;AACA,SAAO;AACT;AAEA,SAAS,uBAA4B,OAAsB,MAAa,QAAwD;AAC9H,QAAM,SAAS,OAAO,KAAK,EAAE,YAAY;AACzC,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAO,oBAAI,IAAY;AAC7B,MAAI,UAAU;AAEd,aAAW,OAAO,MAAM;AACtB,UAAM,MAAM,gBAAgBA,gBAAe,OAAO,GAAG,CAAC;AACtD,QAAI,OAAO,QAAQ,KAAK,IAAI,GAAG,EAAG;AAClC,QAAI,UAAU,CAAC,IAAI,YAAY,EAAE,SAAS,MAAM,EAAG;AAEnD,QAAI,OAAO,SAAS,oBAAoB;AACtC,WAAK,IAAI,GAAG;AACZ,aAAO,KAAK,GAAG;AACf;AAAA,IACF;AAEA,cAAU;AACV;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,OAAO,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC,GAAG,QAAQ;AACtE;AAEA,SAAS,eAAoB,MAAsE;AACjG,QAAM,WAAW,YAAY,KAAK,MAAM;AACxC,MAAI,KAAK,aAAc,QAAO,EAAE,GAAG,oBAAoB,KAAK,cAAc,QAAQ,GAAG,SAAS,MAAM;AACpG,MAAI,KAAK,YAAY,QAAQ,OAAO,WAAW,aAAa;AAC1D,UAAM,QAAQ,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI,GAAG;AACjE,QAAI,MAAO,QAAO,EAAE,GAAG,oBAAoB,YAAY,KAAK,GAAG,QAAQ,GAAG,SAAS,KAAK;AAAA,EAC1F;AACA,SAAO,EAAE,GAAG,UAAU,SAAS,MAAM;AACvC;AAEO,SAAS,cAAmB,MAAqD;AACtF,QAAM,EAAE,QAAQ,WAAW,YAAY,cAAc,UAAU,OAAO,aAAa,IAAI,IAAI;AAC3F,QAAM,UAAUC,SAAQ,MAAM,KAAK,WAAW,qBAAqB,GAAG,CAAC,KAAK,OAAO,CAAC;AACpF,QAAM,MAAM,KAAK,OAAO,KAAK;AAC7B,QAAM,SAASC,QAAO,GAAG;AACzB,QAAM,eAAeA,QAAO,KAAK,SAAS;AAC1C,QAAM,WAAWD,SAAQ,MAAM,YAAY,MAAM,GAAG,CAAC,MAAM,CAAC;AAC5D,QAAM,SAASA,SAAQ,MAAM,IAAI,IAAI,OAAO,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;AAErF,QAAM,UAAUC,QAAO,eAAe,IAAI,CAAC;AAC3C,QAAM,WAAWA,QAAO,CAAC;AACzB,QAAM,CAAC,aAAa,aAAa,IAAIC,UAAqB,QAAQ,QAAQ,CAAC;AAC3E,QAAM,QAAQF,SAAQ,MAAM,KAAK,oBAAoB,WAAW,KAAK,aAAa,CAAC,aAAa,KAAK,iBAAiB,CAAC;AACvH,QAAM,YAAYC,QAAqB,CAAC,gBAAgB,QAAQ,QAAQ,CAAC,CAAC,CAAC;AAC3E,QAAM,YAAYA,QAAqB,CAAC,CAAC;AACzC,QAAM,CAAC,MAAM,OAAO,IAAIC,UAAgB,CAAC,CAAC;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAuB,IAAI;AACrD,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAS,CAAC;AACpC,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAAmC,IAAI;AAEzF,EAAAC,WAAU,MAAM;AACd,WAAO,UAAU;AAAA,EACnB,GAAG,CAAC,GAAG,CAAC;AAER,EAAAA,WAAU,MAAM;AACd,iBAAa,UAAU,KAAK;AAAA,EAC9B,GAAG,CAAC,KAAK,SAAS,CAAC;AAEnB,QAAM,WAAWC,aAA4C,CAAC,SAAS;AACrE,kBAAc,CAAC,SAAS;AACtB,YAAM,YAAY,OAAO,SAAS,aAAc,KAAuC,IAAI,IAAI;AAC/F,YAAM,YAAY,oBAAoB,WAAW,QAAQ;AACzD,UAAI,aAAa,MAAM,SAAS,EAAG,QAAO;AAC1C,gBAAU,QAAQ,KAAK,gBAAgB,IAAI,CAAC;AAC5C,gBAAU,UAAU,CAAC;AACrB,aAAO,gBAAgB,SAAS;AAAA,IAClC,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,CAAC;AAIb,EAAAD,WAAU,MAAM;AACd,QAAI,QAAQ,QAAQ,WAAW,aAAc;AAC7C,QAAI,YAAY;AAChB,UAAM,YAAY;AAChB,YAAM,eAAe,MAAM,QAAQ,mBAAmB,OAAO,IAAI;AACjE,YAAM,WAAW,cAAc,SAAU,MAAM,QAAQ,SAAS,OAAO,IAAI;AAC3E,UAAI,CAAC,aAAa,UAAU;AAC1B,cAAM,aAAa,oBAAoB,UAAU,QAAQ;AACzD,kBAAU,UAAU,CAAC,gBAAgB,UAAU,CAAC;AAChD,kBAAU,UAAU,CAAC;AACrB,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF,GAAG;AACH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EAGF,GAAG,CAAC,CAAC;AAEL,QAAM,EAAE,KAAK,UAAU,cAAc,IAAI,mBAAmB;AAAA,IAC1D;AAAA,IAAQ;AAAA,IAAO;AAAA,IACf,GAAI,KAAK,sBAAsB,EAAC,OAAM,KAAK,oBAAmB,IAAI,CAAC;AAAA,IACnE,GAAI,KAAK,uBAAuB,EAAC,eAAc,KAAK,qBAAoB,IAAI,CAAC;AAAA,IAC7E,GAAI,YAAY,EAAC,UAAS,IAAI,CAAC;AAAA,IAAI,GAAI,aAAa,EAAC,WAAU,IAAI,CAAC;AAAA,EACtE,CAAC;AAGD,QAAM,WAAWH,SAAQ,MAAM,YAAY,KAAK,GAAG,CAAC,KAAK,CAAC;AAC1D,QAAM,iBAAiBA,SAAQ,MAAMK,eAAc,OAAO,aAAa,GAAG,CAAC,UAAU,aAAa,CAAC;AAInG,QAAM,cAAcL;AAAA,IAClB,MAAM,YACF,UAAU,KAAK,UAAU,cAAc,CAAC,KACxC,UAAU,KAAK,UAAU,CAAC,MAAM,OAAO,MAAM,SAAS,MAAM,OAAO,MAAM,MAAM,CAAC,CAAC;AAAA,IACrF,CAAC,WAAW,gBAAgB,MAAM,OAAO,MAAM,SAAS,MAAM,OAAO,MAAM,MAAM;AAAA,EACnF;AACA,EAAAG,WAAU,MAAM;AACd,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,YAAY;AAChB,UAAM,MAAM,YAAY;AACtB,iBAAW,IAAI;AACf,eAAS,IAAI;AACb,UAAI;AACF,aAAK,gBAAgB,KAAK;AAC1B,YAAI,WAAW;AACb,gBAAM,MAAM,MAAM,UAAU,UAAU,gBAAgB,GAAG,MAAM;AAC/D,cAAI,CAAC,WAAW;AACd,oBAAQ,IAAI,IAAI;AAChB,qBAAS,IAAI,KAAK;AAAA,UACpB;AAAA,QACF,OAAO;AACL,gBAAM,MAAMG,YAAW,cAAc,CAAC,GAAG,OAAO,MAAM;AACtD,cAAI,CAAC,WAAW;AACd,oBAAQ,IAAI,IAAI;AAChB,qBAAS,IAAI,KAAK;AAAA,UACpB;AAAA,QACF;AAAA,MACF,SAAS,GAAG;AACV,YAAI,CAAC,aAAa,CAAC,GAAG,OAAO,SAAS;AAAE,mBAAS,CAAU;AAAG,kBAAQ,CAAC,CAAC;AAAG,mBAAS,IAAI;AAAA,QAAG;AAAA,MAC7F,UAAE;AACA,YAAI,CAAC,UAAW,YAAW,KAAK;AAAA,MAClC;AAAA,IACF;AACA,UAAM,IAAI,WAAW,KAAK,UAAU;AACpC,WAAO,MAAM;AACX,kBAAY;AACZ,mBAAa,CAAC;AACd,SAAG,MAAM;AAAA,IACX;AAAA,EAIF,GAAG,CAAC,aAAa,WAAW,YAAY,QAAQ,YAAY,OAAO,KAAK,aAAa,CAAC;AAGtF,EAAAH,WAAU,MAAM;AACd,QAAI,CAAC,WAAW,OAAO,WAAW,YAAa;AAC/C,UAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,UAAM,QAAQ,YAAY,KAAK;AAC/B,QAAI,MAAO,KAAI,aAAa,IAAI,KAAK,KAAK;AAAA,QACrC,KAAI,aAAa,OAAO,GAAG;AAChC,WAAO,QAAQ,aAAa,MAAM,IAAI,IAAI,SAAS,CAAC;AAAA,EACtD,GAAG,CAAC,UAAU,SAAS,KAAK,CAAC;AAG7B,EAAAA,WAAU,MAAM;AACd,UAAM,IAAI,WAAW,MAAM,KAAK,QAAQ,SAAS,OAAO,MAAM,KAAK,GAAG,GAAG;AACzE,WAAO,MAAM,aAAa,CAAC;AAAA,EAC7B,GAAG,CAAC,UAAU,SAAS,OAAO,MAAM,KAAK,CAAC;AAG1C,QAAM,UAAUH,SAAQ,MAAM,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO,OAAO,GAAG,CAAC,MAAM,CAAC;AAC5F,QAAM,QAAQI;AAAA,IACZ,CAAC,QAA4B,UAAWL,gBAAe,SAAS,GAAG,IAAqB;AAAA,IACxF,CAAC,OAAO;AAAA,EACV;AAGA,QAAM,eAAeC,SAAQ,MAAM,KAAK,IAAI,KAAK,EAAE,OAAO,CAAC,OAAoB,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;AACzG,QAAM,YAAY,aAAa,YAAY;AAC3C,QAAM,SAAS,UAAU,OAAO,UAAU,aAAa;AACvD,QAAM,aAAa,cAAc;AACjC,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,IACP;AAAA,IACA,CAAC,MAAM,SAAS,CAAC;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACA,QAAM,WAAW,gBAAgB,OAAO,QAAQ,WAAW,YAAY,YAAY,OAAO,KAAK,aAAa;AAE5G,QAAM,UAAU,UAAU,QAAQ,SAAS;AAC3C,QAAM,UAAU,UAAU,QAAQ,SAAS;AAE3C,QAAM,OAAOI,aAAY,MAAM;AAC7B,kBAAc,CAAC,SAAS;AACtB,YAAM,WAAW,UAAU,QAAQ,IAAI;AACvC,UAAI,CAAC,SAAU,QAAO;AACtB,gBAAU,QAAQ,KAAK,gBAAgB,IAAI,CAAC;AAC5C,aAAO,gBAAgB,QAAQ;AAAA,IACjC,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,OAAOA,aAAY,MAAM;AAC7B,kBAAc,CAAC,SAAS;AACtB,YAAM,OAAO,UAAU,QAAQ,IAAI;AACnC,UAAI,CAAC,KAAM,QAAO;AAClB,gBAAU,QAAQ,KAAK,gBAAgB,IAAI,CAAC;AAC5C,aAAO,gBAAgB,IAAI;AAAA,IAC7B,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAGL,QAAM,QAAQA,aAAY,CAAC,MAA2B,SAAS,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC;AAEzG,QAAM,YAAYA,aAAY,CAAC,WAAwB,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,MAAM,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC;AACtI,QAAM,eAAeA;AAAA,IACnB,CAAC,OAAe,WACd,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,OAAO,EAAE,MAAM,IAAI,CAAC,GAAG,MAAO,MAAM,QAAQ,SAAS,CAAE,EAAE,EAAE;AAAA,IACjG,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,eAAeA;AAAA,IACnB,CAAC,UAAkB,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,OAAO,EAAE,MAAM,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,EAAE,EAAE;AAAA,IACtG,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,eAAeA,aAAY,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC;AAEpG,QAAM,kBAAkBA;AAAA,IACtB,CAAC,WAAW,WAAW,WACrB,SAAS,CAAC,OAAO;AAAA,MACf,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,OAAO,EAAE,MAAM,IAAI,CAAC,MAAM,MAAM;AAC9B,YAAI,MAAM,UAAW,QAAO;AAC5B,YAAI,UAAU,IAAI,EAAG,QAAO,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC,GAAG,MAAO,MAAM,YAAY,SAAS,CAAE,EAAE;AAC1F,eAAO;AAAA,MACT,CAAC;AAAA,IACH,EAAE;AAAA,IACJ,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,kBAAkBA;AAAA,IACtB,CAAC,WAAW,cACV,SAAS,CAAC,MAAM;AACd,YAAM,QAAqB,CAAC;AAC5B,QAAE,MAAM,QAAQ,CAAC,MAAM,MAAM;AAC3B,YAAI,MAAM,WAAW;AACnB,gBAAM,KAAK,IAAI;AACf;AAAA,QACF;AACA,YAAI,UAAU,IAAI,GAAG;AACnB,gBAAM,UAAU,KAAK,IAAI,OAAO,CAAC,GAAG,MAAM,MAAM,SAAS;AACzD,cAAI,QAAQ,WAAW,EAAG,OAAM,KAAK,QAAQ,CAAC,CAAE;AAAA,mBACvC,QAAQ,SAAS,EAAG,OAAM,KAAK,EAAE,KAAK,QAAQ,CAAC;AACxD;AAAA,QACF;AAAA,MAEF,CAAC;AACD,aAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,MAAM;AAAA,IAClC,CAAC;AAAA,IACH,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,YAAYA;AAAA,IAChB,CAAC,WAAqC;AACpC,YAAM,QAAQ,OAAO,IAAI,OAAO,KAAK;AACrC,aAAO,aAAa,QAAQ,QAAQ,YAAY,KAAK,IAAI,MAAS;AAAA,IACpE;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AACA,QAAM,kBAAkBA;AAAA,IACtB,CAAC,WAAW,cACV,SAAS,CAAC,OAAO;AAAA,MACf,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,OAAO,EAAE,MAAM,IAAI,CAAC,MAAM,MAAM;AAC9B,YAAI,MAAM,UAAW,QAAO;AAC5B,YAAI,UAAU,IAAI,EAAG,QAAO,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC,GAAG,MAAO,MAAM,YAAY,UAAU,CAAC,IAAI,CAAE,EAAE;AAChG,eAAO,UAAU,IAAI;AAAA,MACvB,CAAC;AAAA,IACH,EAAE;AAAA,IACJ,CAAC,UAAU,SAAS;AAAA,EACtB;AACA,QAAM,iBAAiBA;AAAA,IACrB,CAAC,WAAW,YACV,SAAS,CAAC,MAAM;AACd,UAAI,YAAY,KAAK,aAAa,EAAE,MAAM,OAAQ,QAAO;AACzD,YAAM,QAAQ,CAAC,GAAG,EAAE,KAAK;AACzB,YAAM,CAAC,KAAK,IAAI,MAAM,OAAO,WAAW,CAAC;AACzC,YAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,MAAM,MAAM,CAAC,GAAG,GAAG,KAAM;AACpE,aAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,MAAM;AAAA,IAClC,CAAC;AAAA,IACH,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,eAAeA;AAAA,IACnB,CAAC,aAAa,gBACZ,SAAS,CAAC,MAAM;AACd,UAAI,gBAAgB,YAAa,QAAO;AACxC,YAAM,SAAS,EAAE,MAAM,WAAW;AAClC,YAAM,SAAS,EAAE,MAAM,WAAW;AAClC,UAAI,CAAC,UAAU,CAAC,OAAQ,QAAO;AAC/B,YAAM,SAAoB,EAAE,KAAK,CAAC,GAAG,aAAa,MAAM,GAAG,GAAG,aAAa,MAAM,CAAC,EAAE;AACpF,YAAM,QAAqB,CAAC;AAC5B,QAAE,MAAM,QAAQ,CAAC,MAAM,MAAM;AAC3B,YAAI,MAAM,YAAa;AACvB,cAAM,KAAK,MAAM,cAAc,SAAS,IAAI;AAAA,MAC9C,CAAC;AACD,aAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,MAAM;AAAA,IAClC,CAAC;AAAA,IACH,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,WAAWA,aAAY,MAAM,SAAS,MAAM,gBAAgB,QAAQ,CAAC,GAAG,CAAC,UAAU,QAAQ,CAAC;AAGlG,QAAM,iBAAiBA;AAAA,IACrB,CAAC,YAAY;AACX,YAAM,KAAK,IAAI,OAAO,QAAQ,CAAC,IAAI,SAAS,SAAS;AACrD,YAAM,SAA4B,EAAE,IAAI,IAAI,SAAS,SAAS,CAAC,GAAG,GAAG,QAAQ;AAC7E,eAAS,CAAC,OAAO,EAAE,GAAG,GAAG,cAAc,CAAC,GAAI,EAAE,gBAAgB,CAAC,GAAI,MAAM,EAAE,EAAE;AAC7E,aAAO;AAAA,IACT;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,oBAAoBA;AAAA,IACxB,CAAC,IAAIG,WACH,SAAS,CAAC,OAAO;AAAA,MACf,GAAG;AAAA,MACH,eAAe,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAAC,MAAO,EAAE,OAAO,KAAK,iBAAiB,GAAGA,MAAK,IAAI,CAAE;AAAA,IAChG,EAAE;AAAA,IACJ,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,kBAAkBH;AAAA,IACtB,CAAC,IAAI,YACH,SAAS,CAAC,MAAM;AACd,YAAM,UAAU,EAAE,gBAAgB,CAAC;AACnC,YAAM,OAAO,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AACjD,UAAI,SAAS,GAAI,QAAO;AACxB,YAAM,OAAO,CAAC,GAAG,OAAO;AACxB,YAAM,CAAC,IAAI,IAAI,KAAK,OAAO,MAAM,CAAC;AAClC,WAAK,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,KAAK,MAAM,CAAC,GAAG,GAAG,IAAK;AACjE,aAAO,EAAE,GAAG,GAAG,cAAc,KAAK;AAAA,IACpC,CAAC;AAAA,IACH,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,oBAAoBA;AAAA,IACxB,CAAC,OAAO,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,eAAe,EAAE,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;AAAA,IACnG,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,oBAAoBA;AAAA,IACxB,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,cAAc,CAAC,EAAE,EAAE;AAAA,IAClD,CAAC,QAAQ;AAAA,EACX;AAEA,QAAM,UAAUA,aAAY,CAAC,YAA6B,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC;AACrH,QAAM,aAAaA;AAAA,IACjB,CAAC,OAAe,WAAW,UACzB,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,GAAG,SAAS,YAAY,EAAE,SAAS,OAAO,QAAQ,EAAE,EAAE;AAAA,IACzF,CAAC,QAAQ;AAAA,EACX;AAEA,QAAM,WAAWA,aAAY,CAAC,UAAkB,MAAM,EAAE,OAAO,QAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC;AACpF,QAAM,YAAYA,aAAY,CAAC,WAAmB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AAC5E,QAAM,WAAWA,aAAY,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;AACtG,QAAM,WAAWA,aAAY,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC;AAEnH,QAAM,eAAeA;AAAA,IACnB,OAAO,OAAe,WAAkD;AACtE,UAAI,CAAC,WAAW,qBAAqB;AACnC,cAAM,IAAI,OAAO,IAAI,KAAK;AAC1B,YAAI,CAAC,KAAK,CAAC,WAAY,QAAO,EAAE,QAAQ,CAAC,GAAG,SAAS,MAAM;AAE3D,cAAM,eAAe,mBAAmB,GAAG,UAAU;AACrD,cAAM,UAAU,uBAAuB,GAAG,YAAY,MAAM;AAE5D,eAAO;AAAA,UACL,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ;AAAA,UACjB,SAAS;AAAA,QACX;AAAA,MACF;AACA,aAAO,UAAU,oBAAoB,EAAE,OAAO,OAAO,CAAC;AAAA,IACxD;AAAA,IACA,CAAC,WAAW,QAAQ,UAAU;AAAA,EAChC;AAEA,QAAM,aAAaA;AAAA,IACjB,OAAO,QAAQ,WAAW;AACxB,YAAM,YAAY,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AACrC,UAAI,WAAW,iBAAiB;AAC9B,cAAM,gBAAgB,UAAU;AAAA,UAC9B,CAAC,SAAS,OAAO,IAAI,IAAI,GAAG,OAAO,SAAS;AAAA,QAC9C;AACA,eAAO,cAAc,SACjB,UAAU,gBAAgB,eAAe,MAAM,IAC/C,CAAC;AAAA,MACP;AACA,UAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,YAAM,SAAqC,CAAC;AAC5C,iBAAW,QAAQ,WAAW;AAC5B,YAAI,QAAQ,QAAS,OAAM,IAAI,aAAa,WAAW,YAAY;AACnE,cAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,YAAI,CAAC,MAAO;AACZ,cAAM,WAAW,oBAAI,IAAY;AACjC,mBAAW,OAAO,YAAY;AAC5B,gBAAM,QAAQL,gBAAe,OAAO,GAAG;AACvC,cAAI,UAAU,KAAM,UAAS,IAAI,KAAK,UAAU,KAAK,CAAC;AAAA,QACxD;AACA,eAAO,IAAI,IAAI,EAAE,UAAU,SAAS,KAAK;AAAA,MAC3C;AACA,aAAO;AAAA,IACT;AAAA,IACA,CAAC,WAAW,QAAQ,UAAU;AAAA,EAChC;AAOA,QAAM,UAAUK,aAAY,MAAM;AAChC,aAAS,CAAC,MAAM,IAAI,CAAC;AACrB,iBAAa,UAAU;AAAA,EACzB,GAAG,CAAC,CAAC;AACL,QAAM,kBAAkBA,aAAY,MAAM,qBAAqB,IAAI,GAAG,CAAC,CAAC;AACxE,QAAM,mBAAmBA;AAAA,IACvB,CAAC,EAAE,aAAa,eAAe,MAAyB;AACtD,YAAM,YAAY,cAAc,KAAK,iBAAiB,IAAI,KAAK,MAAM,iBAAiB,WAAW,IAAI;AACrG,UAAI,YAAY,KAAK,YAAY,wBAAwB;AACvD,cAAM,IAAI,MAAM,sDAAsD;AAAA,MACxE;AAEA,YAAM,YAAY,OAAO,QAAQ;AACjC,cAAQ;AACR,2BAAqB;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,YAAY;AAAA,QACrB,WAAW;AAAA,MACb,CAAC;AAAA,IACH;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,QAAM,yBAAyB,mBAAmB,eAAe;AACjE,QAAM,qBAAqB,mBAAmB,WAAW;AAEzD,EAAAD,WAAU,MAAM;AACd,QAAI,0BAA0B,QAAQ,sBAAsB,KAAM;AAElE,UAAM,OAAO,MAAM;AACjB,UAAI,OAAO,QAAQ,KAAK,oBAAoB;AAC1C,6BAAqB,CAAC,YAAa,SAAS,YAAY,qBAAqB,OAAO,OAAQ;AAC5F;AAAA,MACF;AAEA,cAAQ;AACR,2BAAqB,CAAC,YAAY;AAChC,YAAI,CAAC,QAAS,QAAO;AACrB,YAAI,QAAQ,YAAY,mBAAoB,QAAO;AACnD,eAAO,EAAE,GAAG,SAAS,WAAW,QAAQ,YAAY,EAAE;AAAA,MACxD,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,YAAY,MAAM,sBAAsB;AACzD,UAAM,UAAU;AAAA,MACd,MAAM,qBAAqB,CAAC,YAAa,SAAS,YAAY,qBAAqB,OAAO,OAAQ;AAAA,MAClG,KAAK,IAAI,GAAG,qBAAqB,OAAO,QAAQ,CAAC;AAAA,IACnD;AAEA,WAAO,MAAM;AACX,oBAAc,QAAQ;AACtB,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,wBAAwB,oBAAoB,OAAO,CAAC;AAExD,QAAM,cAAcH;AAAA,IAClB,OAAO;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAAA,IACA,CAAC,mBAAmB,kBAAkB,eAAe;AAAA,EACvD;AAEA,QAAM,aAAaI;AAAA,IACjB,OAAO,OAAc;AACnB,UAAI,CAAC,WAAW,SAAU;AAC1B,YAAM,UAAU,MAAM,UAAU,SAAS,EAAE;AAC3C,cAAQ,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,CAAE,CAAC;AAAA,IACzE;AAAA,IACA,CAAC,WAAW,KAAK;AAAA,EACnB;AAEA,QAAM,gBAAgBJ,SAAQ,MAAMQ,gBAAe,eAAe,KAAK,GAAG,CAAC,eAAe,KAAK,CAAC;AAEhG,QAAM,eAAeR;AAAA,IACnB,OAAO;AAAA,MACL,SAAS,MAAM,gBAAgB,CAAC;AAAA,MAChC,SAAS,SAAS;AAAA,MAClB,SAAS,SAAS;AAAA,MAClB,OAAO,SAAS;AAAA,MAChB,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOA,SAAS,YAAY,UAA2B,OAAe,UAAoC;AACjG,QAAM,IAAI,SAAS,UAAU,CAAC,MAAM,EAAE,UAAU,KAAK;AACrD,MAAI,CAAC,UAAU;AACb,QAAI,MAAM,KAAK,SAAS,WAAW,GAAG;AACpC,YAAM,UAA0B,SAAS,CAAC,EAAG,QAAQ,SAAS,QAAQ;AACtE,aAAO,CAAC,EAAE,GAAG,SAAS,CAAC,GAAI,KAAK,QAAQ,CAAC;AAAA,IAC3C;AACA,WAAO,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;AAAA,EAChC;AACA,MAAI,MAAM,GAAI,QAAO,CAAC,GAAG,UAAU,EAAE,OAAO,KAAK,OAAO,CAAC;AACzD,QAAM,MAAM,SAAS,CAAC;AACtB,MAAI,IAAI,QAAQ,QAAQ;AACtB,UAAM,OAAO,CAAC,GAAG,QAAQ;AACzB,SAAK,CAAC,IAAI,EAAE,GAAG,KAAK,KAAK,MAAM;AAC/B,WAAO;AAAA,EACT;AACA,SAAO,SAAS,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC;AAC1C;","names":["f","useCallback","useEffect","useMemo","useRef","useState","applyQuery","readFieldValue","selectedFields","toServerQuery","useEffect","useMemo","useState","useCallback","useMemo","useRef","useState","useCallback","useMemo","useCallback","useMemo","useState","useCallback","useEffect","useState","readFieldValue","useMemo","useRef","useState","useEffect","useCallback","toServerQuery","applyQuery","patch","selectedFields"]}
1
+ {"version":3,"sources":["../src/computedExecution.ts","../src/useComputedColumns.ts","../src/formulaWorker.ts","../src/useQueryTable.ts","../src/useRequestActivity.ts","../src/useAggregations.ts","../src/metricExecution.ts","../src/useSelection.ts","../src/useSelect.ts","../src/useColumnDrag.ts","../src/useSavedQueries.ts"],"sourcesContent":["import {\n isComputedField,\n readFieldValue,\n type ComputedExecution,\n type FetchRowsResultV2,\n type FieldSchema,\n type ServerQueryV2,\n} from \"@pythia-software/query-table-core\";\nexport function executionRevision(\n execution: ComputedExecution | undefined,\n id: string,\n): string | undefined {\n return (\n execution?.resolvedRevisions[id] ??\n execution?.resolvedRevisions[`@computed/${id}`]\n );\n}\n/** Reject mismatched sidecars before they can be attached to committed row identities. */\nexport function validateComputedResponse<Row>(\n request: ServerQueryV2,\n result: FetchRowsResultV2<Row>,\n schema: FieldSchema<Row>,\n): void {\n const execution = result.execution;\n if (\n result.version !== 2 ||\n !execution ||\n execution.profile !== request.profile ||\n (request.planToken && execution.planToken !== request.planToken) ||\n (request.snapshot !== undefined && execution.snapshot !== request.snapshot)\n )\n throw Error(\n \"Server computed execution identity changed. Refresh the handshake.\",\n );\n for (const [name, revision] of Object.entries(request.expectedRevisions)) {\n const id = name.replace(/^@computed\\//, \"\");\n if (executionRevision(execution, id) !== revision)\n throw Error(\n \"Server computed definition revision changed. Refresh the handshake.\",\n );\n }\n const idField = schema.fields.find((f) => f.name === schema.idField);\n if (!idField)\n throw Error(\"Stable row identity is required for computed values.\");\n const ids = new Set(result.rows.map((row) => readFieldValue(idField, row)));\n if (ids.has(null) || ids.has(undefined) || ids.size !== result.rows.length)\n throw Error(\n \"Computed response contains missing or duplicate row identities.\",\n );\n const sidecars = new Map(\n result.computed.map((item) => [item.id, item.values]),\n );\n if (\n sidecars.size !== result.computed.length ||\n [...sidecars.keys()].some((id) => !ids.has(id))\n )\n throw Error(\"Computed sidecars do not match returned row identities.\");\n for (const field of request.select.filter(isComputedField)) {\n const id = field.slice(\"@computed/\".length);\n for (const rowId of ids) {\n const value = sidecars.get(rowId as string | number)?.[id];\n if (\n !value ||\n (value.value !== null &&\n ![\"string\", \"number\", \"boolean\"].includes(typeof value.value)) ||\n (typeof value.value === \"number\" && !Number.isFinite(value.value))\n )\n throw Error(`Missing or invalid server computed result: ${field}.`);\n }\n }\n}\n","import { executionRevision } from \"./computedExecution\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n applyQuery,\n compileFormula,\n computedFieldName,\n groupPreview,\n isComputedField,\n memoryComputedColumnStore,\n readFieldValue,\n toServerQuery,\n validateComputedColumn,\n isSelectable,\n hasRegex,\n type ColumnPreview,\n type ComputedColumn,\n type ComputedExecution,\n type RowComputedValues,\n type RowId,\n type ComputedColumnDraft,\n type ComputedColumnStore,\n type FieldDef,\n type FieldSchema,\n type FormulaPlan,\n type FormulaResult,\n type FormulaValue,\n type QueryState,\n type Transport,\n} from \"@pythia-software/query-table-core\";\nimport {\n evaluateFormulaRows,\n type FormulaWorkerFactory,\n} from \"./formulaWorker\";\n\nexport interface ComputedColumnsApi<Row> {\n definitions: ComputedColumn[];\n catalogue: FieldDef<Row>[];\n loading: boolean;\n error: string | null;\n reload: () => Promise<void>;\n save: (\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ) => Promise<ComputedColumn>;\n compile: (source: string, editingId?: string) => FormulaPlan;\n /** Sample the first N matching rows in current sort order, independent of table paging. */\n preview: (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs?: boolean,\n ) => Promise<ColumnPreview>;\n}\ninterface Options<Row> {\n schema: FieldSchema<Row>;\n query: QueryState;\n rows: Row[];\n store?: ComputedColumnStore;\n transport?: Transport<Row>;\n clientRows?: Row[];\n workerFactory?: FormulaWorkerFactory;\n execution?: ComputedExecution;\n serverComputed?: Map<RowId, RowComputedValues>;\n serverExecution?: ComputedExecution;\n}\nexport function useComputedColumns<Row>(options: Options<Row>): {\n api: ComputedColumnsApi<Row>;\n displaySchema: FieldSchema<Row>;\n} {\n const { schema, query, rows, transport, clientRows, workerFactory } = options;\n const store = useMemo(\n () => options.store ?? memoryComputedColumnStore(),\n [options.store],\n );\n const [catalogue, setCatalogue] = useState<{\n dataset: string;\n store: ComputedColumnStore;\n items: ComputedColumn[];\n } | null>(null);\n const definitions = useMemo(\n () =>\n catalogue?.dataset === schema.name && catalogue.store === store\n ? catalogue.items\n : [],\n [catalogue, schema.name, store],\n );\n const [loading, setLoading] = useState(false),\n [error, setError] = useState<string | null>(null);\n const catalogueRequest = useRef<AbortController | null>(null);\n const reload = useCallback(async () => {\n catalogueRequest.current?.abort();\n const ac = new AbortController();\n catalogueRequest.current = ac;\n setLoading(true);\n setError(null);\n try {\n const items = await store.list(schema.name, ac.signal);\n if (ac.signal.aborted) return;\n const valid = items\n .map(validateComputedColumn)\n .sort((a, b) => a.id.localeCompare(b.id));\n if (new Set(valid.map((c) => c.id)).size !== valid.length)\n throw new Error(\"Duplicate computed column IDs.\");\n setCatalogue((previous) =>\n previous?.dataset === schema.name &&\n previous.store === store &&\n JSON.stringify(previous.items) === JSON.stringify(valid)\n ? previous\n : { dataset: schema.name, store, items: valid },\n );\n } catch (e) {\n if (!ac.signal.aborted)\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!ac.signal.aborted) setLoading(false);\n }\n }, [store, schema.name]);\n useEffect(() => {\n void reload();\n return () => catalogueRequest.current?.abort();\n }, [reload]);\n useEffect(\n () =>\n store.subscribe?.(schema.name, () => {\n void reload();\n }),\n [store, schema.name, reload],\n );\n useEffect(() => {\n const focus = () => {\n void reload();\n };\n window.addEventListener(\"focus\", focus);\n return () => window.removeEventListener(\"focus\", focus);\n }, [reload]);\n const inputFields = useMemo(\n () =>\n schema.fields\n .filter(isSelectable)\n .filter(\n (f) =>\n f.source.kind === \"backend\" ||\n (f.source.accessor && f.source.dependencies),\n ),\n [schema],\n );\n const compile = useCallback(\n (source: string, editingId?: string): FormulaPlan => {\n const stack = new Set<string>(editingId ? [editingId] : []);\n let expanded = 0;\n const resolve = (name: string): FormulaPlan | undefined => {\n if (!isComputedField(name)) return undefined;\n const id = name.slice(\"@computed/\".length),\n def = definitions.find((d) => d.id === id);\n if (!def) throw new Error(`Computed column unavailable: ${id}`);\n if (stack.has(id))\n throw new Error(`Circular computed-column reference: ${def.label}`);\n if (stack.size >= 20 || ++expanded > 100)\n throw new Error(\"Computed dependency graph is too large.\");\n stack.add(id);\n try {\n return compileFormula(def.expression.source, inputFields, resolve);\n } finally {\n stack.delete(id);\n }\n };\n return compileFormula(source, inputFields, resolve);\n },\n [inputFields, definitions],\n );\n const plans = useMemo(\n () =>\n new Map<string, { plan?: FormulaPlan; error?: string }>(\n definitions.map((def) => {\n try {\n return [\n def.id,\n { plan: compile(def.expression.source, def.id) },\n ] as const;\n } catch (e) {\n return [\n def.id,\n { error: e instanceof Error ? e.message : String(e) },\n ] as const;\n }\n }),\n ),\n [definitions, compile],\n );\n const backendDependencies = useCallback(\n (plan: FormulaPlan) =>\n [\n ...new Set(\n plan.dependencies.flatMap((name) => {\n const f = inputFields.find((f) => f.name === name);\n return f?.source.kind === \"backend\"\n ? [name]\n : (f?.source.dependencies ?? []);\n }),\n ),\n ]\n .filter((name) =>\n schema.fields.some(\n (f) => f.name === name && f.source.kind === \"backend\",\n ),\n )\n .sort(),\n [schema, inputFields],\n );\n const inputsFor = useCallback(\n (plan: FormulaPlan, batch: Row[]) => {\n let size = 0;\n return batch.map((row) => {\n const values: Record<string, FormulaValue> = Object.create(null);\n for (const name of plan.dependencies) {\n const field = inputFields.find((f) => f.name === name)!;\n const raw = readFieldValue(field, row);\n values[name] =\n raw instanceof Date ? raw.toISOString() : (raw as FormulaValue);\n }\n size += JSON.stringify(values).length;\n if (size > 16000000)\n throw new Error(\n \"Input sample exceeds 16 MB. Reduce the rows to process.\",\n );\n return values;\n });\n },\n [inputFields],\n );\n const activeSelect = query.select.length\n ? query.select\n : (schema.defaultSelect ?? []);\n const activeIds = activeSelect\n .filter((c) => isComputedField(c.field))\n .map((c) => c.field.slice(\"@computed/\".length))\n .sort()\n .join(\",\");\n const [evaluated, setEvaluated] = useState<{\n rows: Row[];\n plans: typeof plans;\n values: Map<string, FormulaResult[]>;\n } | null>(null);\n useEffect(() => {\n const ac = new AbortController();\n const values = new Map<string, FormulaResult[]>();\n void (async () => {\n if (options.execution && transport?.fetchRowsV2) return;\n for (const id of activeIds.split(\",\").filter(Boolean)) {\n const entry = plans.get(id);\n if (!entry?.plan) continue;\n try {\n values.set(\n id,\n await evaluateFormulaRows(\n entry.plan.ast,\n inputsFor(entry.plan, rows),\n ac.signal,\n workerFactory,\n ),\n );\n } catch (e) {\n if (ac.signal.aborted) return;\n values.set(\n id,\n rows.map(() => ({\n value: null,\n error: e instanceof Error ? e.message : String(e),\n })),\n );\n }\n }\n if (!ac.signal.aborted) setEvaluated({ rows, plans, values });\n })();\n return () => ac.abort();\n }, [\n activeIds,\n rows,\n plans,\n inputsFor,\n workerFactory,\n options.execution,\n transport,\n ]);\n const displaySchema = useMemo<FieldSchema<Row>>(() => {\n const indices = new Map(rows.map((row, i) => [row, i]));\n const fields: FieldDef<Row>[] = definitions.map((def) => {\n const entry = plans.get(def.id);\n return {\n name: computedFieldName(def.id),\n label: def.label,\n type:\n entry?.plan?.type === \"null\" ? \"text\" : (entry?.plan?.type ?? \"text\"),\n group: \"Computed columns\",\n source: {\n kind: \"derived\",\n computedId: def.id,\n dependencies: entry?.plan ? backendDependencies(entry.plan) : [],\n accessor: (row: Row) => {\n if (entry?.error) return { computedError: entry.error };\n if (options.execution && transport?.fetchRowsV2) {\n if (\n options.serverExecution?.profile !==\n options.execution.profile ||\n options.serverExecution?.planToken !==\n options.execution.planToken ||\n options.serverExecution?.snapshot !==\n options.execution.snapshot ||\n executionRevision(options.execution, def.id) !== def.revision ||\n executionRevision(options.serverExecution, def.id) !==\n def.revision\n )\n return {\n computedError:\n \"Definition changed or values are pending. Refresh the server handshake.\",\n };\n const idField = schema.fields.find(\n (f) => f.name === schema.idField,\n );\n const id = idField\n ? (readFieldValue(idField, row) as RowId)\n : null;\n const server =\n id === null\n ? undefined\n : options.serverComputed?.get(id)?.[def.id];\n return server\n ? server.error\n ? { computedError: server.error.code }\n : server.value\n : { computedError: \"Server computed result unavailable.\" };\n }\n const result =\n evaluated?.rows === rows && evaluated.plans === plans\n ? evaluated.values.get(def.id)?.[indices.get(row) ?? -1]\n : undefined;\n return result?.error\n ? { computedError: result.error }\n : result\n ? result.value\n : { computedError: \"Calculating…\" };\n },\n },\n filter: { enabled: false },\n sort: {\n enabled:\n !!transport?.fetchRowsV2 &&\n !!options.execution?.fields[computedFieldName(def.id)]?.sort &&\n executionRevision(options.execution, def.id) === def.revision &&\n !!entry?.plan &&\n !hasRegex(entry.plan),\n },\n aggregate: {\n measure: !!entry?.plan,\n groupable:\n !!transport?.fetchMetrics &&\n transport.metricCapabilities?.version === 2 &&\n !!options.execution?.fields[computedFieldName(def.id)]?.group &&\n executionRevision(options.execution, def.id) === def.revision &&\n !!entry?.plan &&\n !hasRegex(entry.plan),\n },\n };\n });\n for (const col of activeSelect)\n if (\n isComputedField(col.field) &&\n !fields.some((f) => f.name === col.field)\n )\n fields.push({\n name: col.field,\n label: col.field.slice(10),\n type: \"text\",\n source: {\n kind: \"derived\",\n computedId: col.field.slice(10),\n accessor: () => ({\n computedError: loading\n ? \"Loading definition…\"\n : \"Definition unavailable. Reload the catalogue or contact its owner.\",\n }),\n },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n });\n return { ...schema, fields: [...schema.fields, ...fields] };\n }, [\n schema,\n definitions,\n plans,\n backendDependencies,\n evaluated,\n rows,\n query.select,\n schema.defaultSelect,\n loading,\n transport,\n options.execution,\n options.serverComputed,\n options.serverExecution,\n ]);\n const save = useCallback(\n async (column: ComputedColumnDraft, expectedRevision: string | null) => {\n compile(column.expression.source, column.id);\n const saved = validateComputedColumn(\n await store.save(schema.name, column, expectedRevision),\n );\n setCatalogue((prev) => ({\n dataset: schema.name,\n store,\n items: [\n ...(prev?.dataset === schema.name && prev.store === store\n ? prev.items.filter((d) => d.id !== saved.id)\n : []),\n saved,\n ],\n }));\n return saved;\n },\n [compile, store, schema.name],\n );\n const preview = useCallback(\n async (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs = true,\n ): Promise<ColumnPreview> => {\n if (!Number.isInteger(count) || count < 1 || count > 10000)\n throw new Error(\"Choose between 1 and 10,000 rows.\");\n const plan = compile(source, editingId);\n let batch: Row[] = [],\n total = 0;\n if (transport) {\n const request = toServerQuery(\n {\n ...query,\n select: [\n ...new Set([schema.idField, ...backendDependencies(plan)]),\n ].map((field) => ({ field })),\n limit: Math.min(count, 500),\n offset: 0,\n },\n schema,\n );\n while (batch.length < count) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const res = await transport.fetchRows(\n {\n ...request,\n offset: batch.length,\n limit: Math.min(500, count - batch.length),\n },\n signal,\n );\n total = res.total;\n batch.push(...res.rows.slice(0, count - batch.length));\n if (!res.rows.length || batch.length >= total) break;\n }\n } else {\n const result = applyQuery(\n clientRows ?? [],\n { ...query, limit: count, offset: 0 },\n schema,\n );\n batch = result.rows;\n total = result.total;\n }\n const inputs = inputsFor(plan, batch),\n results = await evaluateFormulaRows(\n plan.ast,\n inputs,\n signal,\n workerFactory,\n );\n return groupPreview(\n includeInputs ? plan.dependencies : [],\n inputs,\n results,\n total,\n );\n },\n [\n compile,\n transport,\n query,\n schema,\n backendDependencies,\n clientRows,\n inputsFor,\n workerFactory,\n ],\n );\n return {\n displaySchema,\n api: {\n definitions,\n catalogue: displaySchema.fields,\n loading,\n error,\n reload,\n save,\n compile,\n preview,\n },\n };\n}\n","import {\n formulaRuntime,\n type FormulaNode,\n type FormulaResult,\n type FormulaValue,\n} from \"@pythia-software/query-table-core\";\n\nexport type FormulaWorkerFactory = () => Worker;\n/** Host applications with a restrictive CSP can supply their own worker factory. */\nexport const createFormulaWorker: FormulaWorkerFactory = () => {\n const code = `const evaluate = ${formulaRuntime.toString()}; self.onmessage = e => { const { ast, inputs } = e.data; self.postMessage(inputs.map(row => evaluate(ast, row))); };`;\n const url = URL.createObjectURL(\n new Blob([code], { type: \"text/javascript\" }),\n );\n try {\n return new Worker(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n};\nexport function evaluateFormulaRows(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>[],\n signal?: AbortSignal,\n factory: FormulaWorkerFactory = createFormulaWorker,\n): Promise<FormulaResult[]> {\n if (signal?.aborted)\n return Promise.reject(new DOMException(\"Aborted\", \"AbortError\"));\n if (!inputs.length) return Promise.resolve([]);\n return new Promise((resolve, reject) => {\n let worker: Worker;\n try {\n worker = factory();\n } catch (e) {\n reject(\n new Error(\n `Formula worker unavailable: ${e instanceof Error ? e.message : String(e)}`,\n ),\n );\n return;\n }\n let timer: ReturnType<typeof setTimeout>;\n const started = Date.now();\n let offset = 0;\n const results: FormulaResult[] = [];\n const cleanup = () => {\n clearTimeout(timer);\n worker.terminate();\n signal?.removeEventListener(\"abort\", abort);\n };\n const abort = () => {\n cleanup();\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n const send = () => {\n if (Date.now() - started > 30000) {\n cleanup();\n reject(\n new Error(\n \"Formula exceeded the 30-second processing budget. Reduce the row count or simplify the formula.\",\n ),\n );\n return;\n }\n timer = setTimeout(() => {\n cleanup();\n reject(\n new Error(\n \"Formula timed out. Check the regex or reduce the row count.\",\n ),\n );\n }, 2000);\n try {\n worker.postMessage({ ast, inputs: inputs.slice(offset, offset + 200) });\n } catch (e) {\n cleanup();\n reject(e);\n }\n };\n signal?.addEventListener(\"abort\", abort, { once: true });\n worker.onerror = () => {\n cleanup();\n reject(new Error(\"Formula worker failed.\"));\n };\n worker.onmessage = (event: MessageEvent<FormulaResult[]>) => {\n clearTimeout(timer);\n results.push(...event.data);\n offset += event.data.length;\n if (offset >= inputs.length) {\n cleanup();\n resolve(results);\n } else send();\n };\n send();\n });\n}\n","// useQueryTable — the one hook that owns everything.\n//\n// The headless brain of the table: it holds the QueryState, keeps it in sync\n// with the URL (`?q=`) and the StorageAdapter, orchestrates fetches through the\n// Transport (debounced + abortable), and exposes intent-level mutators so a UI\n// never hand-edits QueryState. @pythia-software/query-table-ui is a thin layer over this; you\n// can also build an entirely custom table on it.\n\nimport {\n executionRevision,\n validateComputedResponse,\n} from \"./computedExecution\";\nimport {\n useComputedColumns,\n type ComputedColumnsApi,\n} from \"./useComputedColumns\";\nimport type { FormulaWorkerFactory } from \"./formulaWorker\";\nimport type {\n ComputedColumnStore,\n ComputedExecution,\n RowComputedValues,\n} from \"@pythia-software/query-table-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n EMPTY_QUERY,\n applyQuery,\n decodeQuery,\n encodeQuery,\n memoryStorageAdapter,\n normalizeQueryState,\n readFieldValue,\n selectedFields,\n toServerQuery,\n queriesEqual,\n isOrGroup,\n predicatesOf,\n negateClause,\n opsForField,\n metricPlans,\n validateMetric,\n metricDependencies,\n isComputedField,\n toServerQueryV2,\n} from \"@pythia-software/query-table-core\";\n\nconst AUTOCOMPLETE_LIMIT = 50;\nconst MAX_AUTO_REFRESH_POLLS = 1000;\nimport type {\n QueryState,\n WhereClause,\n WhereTerm,\n OrderByClause,\n AggOp,\n AggregationClause,\n AggregationResult,\n RowId,\n FieldDef,\n FieldSchema,\n Transport,\n StorageAdapter,\n DistinctValuesResult,\n FieldStats,\n} from \"@pythia-software/query-table-core\";\nimport {\n useRequestActivity,\n type RequestActivityApi,\n} from \"./useRequestActivity\";\nimport { useAggregations } from \"./useAggregations\";\nimport { useSelection, type SelectionApi } from \"./useSelection\";\nimport { useSelect, type SelectApi } from \"./useSelect\";\nimport { useColumnDrag, type ColumnDragApi } from \"./useColumnDrag\";\nimport { useSavedQueries, type SavedQueriesApi } from \"./useSavedQueries\";\n\nexport interface UseQueryTableOptions<Row> {\n /** Normalize external aliases without storing presentation in query state. Must be pure and not throw. */\n canonicalizeQuery?: (query: QueryState) => QueryState;\n /** Reject an entire query before rows or metrics execute. Errors retain editable query state. */\n validateQuery?: (query: QueryState) => void;\n\n schema: FieldSchema<Row>;\n /** Data access. Omit for a purely client-side table driven by `clientRows`. */\n transport?: Transport<Row>;\n /** All rows, for client-side mode (applyQuery runs locally over these). */\n clientRows?: Row[];\n /** Saved/last-query persistence. Defaults to a non-durable in-memory adapter.\n * Pass localStorageAdapter() explicitly only when filter values are safe to\n * retain as cleartext JSON on the device. */\n storage?: StorageAdapter;\n /** Shared reusable definitions, independent of saved-query storage. */\n computedColumnStore?: ComputedColumnStore;\n /** Authoritative host handshake for versioned server SELECT, sorts, and metrics. */\n computedExecution?: ComputedExecution;\n /** Override the worker factory when CSP disallows blob workers. */\n formulaWorkerFactory?: FormulaWorkerFactory;\n /** Seed query, normalized and resource-bounded before use. When omitted the\n * hook resolves: opted-in URL → storage.loadLast → schema defaults. */\n initialQuery?: QueryState;\n /** Mirror QueryState to `?q=` via history.replaceState. Default false because\n * base64url is encoding, not encryption: filters will appear in browser\n * history, referrers, logs, analytics, and screenshots when enabled. */\n syncUrl?: boolean;\n /** Debounce (ms) between a query change and the fetch it triggers. Default 200. */\n debounceMs?: number;\n /** Injected clock for deterministic saved-query timestamps. Default Date.now. */\n now?: () => number;\n /** Side-effect to run on every refresh — both manual `api.refresh()` and each\n * auto-refresh tick. Fires *in addition to* the internal `setNonce` re-query,\n * so manual and auto stay identical. Use it in client mode (no transport) to\n * bridge a UI refresh to your own server fetch without monkey-patching the\n * returned `api`. Always read through a ref, so supplying it never tears down\n * and recreates the auto-refresh interval. */\n onRefresh?: () => void;\n}\n\nexport interface AutoRefreshConfig {\n frequencyMs: number;\n turnOffAfterMs: number;\n}\n\nexport interface AutoRefreshStatus extends AutoRefreshConfig {\n startedAt: number;\n stopsAt: number;\n pollCount: number;\n}\n\nexport interface AutoRefreshApi {\n status: AutoRefreshStatus | null;\n start: (config: AutoRefreshConfig) => void;\n stop: () => void;\n}\n\n/** A patch for one metric. `field`/`label` accept an explicit `undefined` to\n * CLEAR them (e.g. switching to an op whose measure no longer applies); an\n * absent key leaves the existing value untouched. */\nexport type AggregationPatch = { op?: AggOp; groupBy?: string[] } & {\n [K in keyof Omit<AggregationClause, \"id\" | \"op\" | \"groupBy\">]?:\n AggregationClause[K] | undefined;\n};\n\nexport interface AggregationsApi {\n /** The metric specs currently in the query. */\n clauses: AggregationClause[];\n /** Server (or client-mirror) results, one entry per clause; null when none. */\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n /** Append a metric. Defaults to \"count all rows\"; pass a partial to override.\n * Returns the generated id. */\n add: (partial?: Partial<Omit<AggregationClause, \"id\">>) => string;\n /** Patch a metric by id. */\n update: (id: string, patch: AggregationPatch) => void;\n /** Reorder: move the metric `id` to `toIndex` (an index in the list with the\n * metric removed, so a drag preview's slot maps straight to the result). */\n move: (id: string, toIndex: number) => void;\n /** Remove a metric by id. */\n remove: (id: string) => void;\n /** Remove all metrics. */\n clear: () => void;\n /** Evaluate a draft without modifying the query. */\n preview?: (\n clauses: AggregationClause[],\n signal?: AbortSignal,\n ) => Promise<AggregationResult>;\n /** Commit the complete draft as one undoable change. */\n replace?: (\n clauses: AggregationClause[],\n expected?: AggregationClause[],\n ) => void;\n /** Validate a clause, including reusable computed dependencies. */\n compile?: (clause: AggregationClause) => unknown;\n /** Invalidation token for page, refresh, schema, and definition changes. */\n contextKey?: string;\n}\n\nexport interface QueryTableApi<Row> {\n // state\n query: QueryState;\n /** Schema defaults used for reset controls. */\n defaults: QueryState;\n setQuery: (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n /** Can move back to a previously applied local query state. */\n canUndo: boolean;\n /** Can move forward to a previously undone local query state. */\n canRedo: boolean;\n /** Move backward through local, unsaved query history. */\n undo: () => void;\n /** Move forward through local, unsaved query history. */\n redo: () => void;\n\n requestActivity: RequestActivityApi;\n\n // data\n rows: Row[];\n total: number | null;\n loading: boolean;\n error: Error | null;\n refresh: () => void;\n autoRefresh: AutoRefreshApi;\n /** Refresh one legacy row, or schedule a full V2 page refresh so computed\n * values and page membership remain coherent. Track V2 completion via loading/error. */\n refreshRow: (id: RowId) => Promise<void>;\n\n // aggregation metrics (the dashboard panel above the table)\n aggregations: AggregationsApi;\n\n // filters — WHERE is CNF: `query.where` is an array of terms (a literal or an\n // OR group), ANDed together. The top-level intents address a whole term by\n // index; the predicate-level intents address one literal within a term.\n /** Append a predicate as its own AND term. */\n addFilter: (clause: WhereClause) => void;\n /** Replace the whole term at `index` with a single predicate. */\n updateFilter: (index: number, clause: WhereClause) => void;\n /** Remove the whole term at `index`. */\n removeFilter: (index: number) => void;\n clearFilters: () => void;\n /** Replace one predicate inside a term (predIndex 0 for a literal term). */\n updatePredicate: (\n termIndex: number,\n predIndex: number,\n clause: WhereClause,\n ) => void;\n /** Remove one predicate; a group of one flattens to a literal, an emptied term drops. */\n removePredicate: (termIndex: number, predIndex: number) => void;\n /** Logically invert one predicate (flips the op, else toggles its NOT flag). */\n negatePredicate: (termIndex: number, predIndex: number) => void;\n /** Move the term at `fromIndex` to `toIndex` (an index in the list with the\n * dragged term removed, so a drag preview's slot maps straight to the result). */\n reorderFilters: (fromIndex: number, toIndex: number) => void;\n /** OR-merge the term at `sourceIndex` into the term at `targetIndex`: the\n * target becomes (or stays) an OR group holding both terms' predicates, and\n * the source term is removed. This is the drag-onto-another-filter gesture. */\n mergeFilters: (sourceIndex: number, targetIndex: number) => void;\n /** Reset the complete query state back to schema defaults. */\n resetAll: () => void;\n /** Keystroke-driven filter-value autocomplete (Transport.fetchDistinctValues). */\n filterValues: (\n field: string,\n search: string,\n ) => Promise<DistinctValuesResult>;\n /** Dataset-wide field statistics for catalogue and picker affordances. */\n fieldStats: (\n fields: string[],\n signal?: AbortSignal,\n ) => Promise<Record<string, FieldStats>>;\n\n // sorting (multi-sort): click header sets/cycles primary; shift-click appends.\n toggleSort: (field: string, additive?: boolean) => void;\n setSort: (orderBy: OrderByClause[]) => void;\n\n // select + pagination + selection + saved\n select: SelectApi<Row>;\n computed: ComputedColumnsApi<Row>;\n setLimit: (limit: number) => void;\n setOffset: (offset: number) => void;\n nextPage: () => void;\n prevPage: () => void;\n selection: SelectionApi;\n saved: SavedQueriesApi;\n /** Shared, transient column-reorder drag state (table headers + select chips). */\n columnDrag: ColumnDragApi;\n\n // resolved view\n visibleFields: FieldDef<Row>[];\n rowId: (row: Row) => RowId | null;\n}\n\nfunction defaultsFor<Row>(schema: FieldSchema<Row>): QueryState {\n return normalizeQueryState({\n select: schema.defaultSelect ?? [],\n where: [],\n orderBy: schema.defaultSort ?? [],\n limit: schema.defaultLimit ?? EMPTY_QUERY.limit,\n offset: 0,\n });\n}\n\nfunction cloneWhereTerm(term: WhereTerm): WhereTerm {\n const copy = isOrGroup(term)\n ? { ...term, any: term.any.map((c) => ({ ...c })) }\n : { ...term };\n if (term.setFilter)\n copy.setFilter = { ...term.setFilter, values: [...term.setFilter.values] };\n return copy;\n}\n\nfunction cloneQueryState(q: QueryState): QueryState {\n const clone: QueryState = {\n select: q.select.map((column) => ({ ...column })),\n where: q.where.map(cloneWhereTerm),\n orderBy: q.orderBy.map((term) =>\n term.extract ? { ...term, extract: { ...term.extract } } : { ...term },\n ),\n limit: q.limit,\n offset: q.offset,\n };\n if (q.aggregations)\n clone.aggregations = JSON.parse(\n JSON.stringify(q.aggregations),\n ) as AggregationClause[];\n return clone;\n}\n\n/** Apply a patch to a metric, building a fresh clause so optional `field`/`label`\n * can be dropped (passing them as `undefined` clears; omitting the key keeps the\n * current value) without ever materializing an `undefined`-valued property. */\nfunction mergeAggregation(\n a: AggregationClause,\n patch: AggregationPatch,\n): AggregationClause {\n const next = { ...a, ...patch } as AggregationClause;\n for (const key of Object.keys(next) as Array<keyof AggregationClause>) {\n if (next[key] === undefined) delete next[key];\n }\n return next;\n}\n\nfunction isNullLike(value: unknown): boolean {\n return value == null || (Array.isArray(value) && value.length === 0);\n}\n\nfunction asDistinctValue(value: unknown): string | null {\n if (isNullLike(value)) return null;\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return String(value);\n }\n return null;\n}\n\nfunction fieldHasNullInRows<Row>(field: FieldDef<Row>, rows: Row[]): boolean {\n for (const row of rows) {\n if (isNullLike(readFieldValue(field, row))) return true;\n }\n return false;\n}\n\nfunction distinctValuesFromRows<Row>(\n field: FieldDef<Row>,\n rows: Row[],\n search: string,\n): { values: string[]; hasMore: boolean } {\n const target = search.trim().toLowerCase();\n const values: string[] = [];\n const seen = new Set<string>();\n let hasMore = false;\n\n rowsLoop: for (const row of rows) {\n const value = readFieldValue(field, row);\n const candidates =\n field.type === \"textarray\" && Array.isArray(value) ? value : [value];\n for (const candidate of candidates) {\n const raw = asDistinctValue(candidate);\n if (raw == null || seen.has(raw)) continue;\n if (target && !raw.toLowerCase().includes(target)) continue;\n\n if (values.length < AUTOCOMPLETE_LIMIT) {\n seen.add(raw);\n values.push(raw);\n continue;\n }\n\n hasMore = true;\n break rowsLoop;\n }\n }\n\n return { values: values.sort((a, b) => a.localeCompare(b)), hasMore };\n}\n\nfunction resolveInitial<Row>(opts: UseQueryTableOptions<Row>): {\n q: QueryState;\n fromUrl: boolean;\n} {\n const defaults = defaultsFor(opts.schema);\n if (opts.initialQuery)\n return {\n q: normalizeQueryState(opts.initialQuery, defaults),\n fromUrl: false,\n };\n if (opts.syncUrl === true && typeof window !== \"undefined\") {\n const token = new URLSearchParams(window.location.search).get(\"q\");\n if (token)\n return {\n q: normalizeQueryState(decodeQuery(token), defaults),\n fromUrl: true,\n };\n }\n return { q: defaults, fromUrl: false };\n}\n\nexport function useQueryTable<Row>(\n opts: UseQueryTableOptions<Row>,\n): QueryTableApi<Row> {\n const {\n schema,\n transport: sourceTransport,\n clientRows,\n initialQuery,\n syncUrl = false,\n debounceMs = 200,\n } = opts;\n const { transport, activity: requestActivity } =\n useRequestActivity(sourceTransport);\n const storage = useMemo(\n () => opts.storage ?? memoryStorageAdapter(),\n [opts.storage],\n );\n const now = opts.now ?? Date.now;\n const nowRef = useRef(now);\n const onRefreshRef = useRef(opts.onRefresh);\n const defaults = useMemo(() => defaultsFor(schema), [schema]);\n const byName = useMemo(\n () => new Map(schema.fields.map((f) => [f.name, f])),\n [schema],\n );\n\n const initRef = useRef(resolveInitial(opts));\n const aggIdRef = useRef(0);\n const [storedQuery, setQueryState] = useState<QueryState>(initRef.current.q);\n const query = useMemo(\n () => opts.canonicalizeQuery?.(storedQuery) ?? storedQuery,\n [storedQuery, opts.canonicalizeQuery],\n );\n const undoStack = useRef<QueryState[]>([cloneQueryState(initRef.current.q)]);\n const redoStack = useRef<QueryState[]>([]);\n const [rows, setRows] = useState<Row[]>([]);\n const [serverComputed, setServerComputed] = useState<\n Map<RowId, RowComputedValues>\n >(new Map());\n const [committedFields, setCommittedFields] = useState<string[]>([]);\n const [serverExecution, setServerExecution] = useState<\n ComputedExecution | undefined\n >();\n const [total, setTotal] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [nonce, setNonce] = useState(0);\n const [committedPage, setCommittedPage] = useState<string | null>(null);\n const [committedSource, setCommittedSource] = useState<{\n schema: FieldSchema<Row>;\n transport: Transport<Row> | undefined;\n clientRows: Row[] | undefined;\n } | null>(null);\n const [autoRefreshStatus, setAutoRefreshStatus] =\n useState<AutoRefreshStatus | null>(null);\n\n useEffect(() => {\n nowRef.current = now;\n }, [now]);\n\n useEffect(() => {\n onRefreshRef.current = opts.onRefresh;\n }, [opts.onRefresh]);\n\n const setQuery = useCallback<QueryTableApi<Row>[\"setQuery\"]>(\n (next) => {\n setQueryState((prev) => {\n const candidate =\n typeof next === \"function\"\n ? (next as (p: QueryState) => QueryState)(prev)\n : next;\n const nextQuery = normalizeQueryState(candidate, defaults);\n if (queriesEqual(prev, nextQuery)) return prev;\n undoStack.current.push(cloneQueryState(prev));\n redoStack.current = [];\n return cloneQueryState(nextQuery);\n });\n },\n [defaults],\n );\n\n // Restore the default saved query (preferred) or last query on mount when\n // nothing explicit seeded the view.\n useEffect(() => {\n if (initRef.current.fromUrl || initialQuery) return;\n let cancelled = false;\n void (async () => {\n const defaultSaved = await storage.loadDefaultSaved?.(schema.name);\n const restored =\n defaultSaved?.query ?? (await storage.loadLast(schema.name));\n if (!cancelled && restored) {\n const normalized = normalizeQueryState(restored, defaults);\n undoStack.current = [cloneQueryState(normalized)];\n redoStack.current = [];\n setQueryState(normalized);\n }\n })();\n return () => {\n cancelled = true;\n };\n // mount-only\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const { api: computed, displaySchema } = useComputedColumns({\n schema,\n query,\n rows,\n serverComputed,\n ...(serverExecution ? { serverExecution } : {}),\n ...(opts.computedExecution ? { execution: opts.computedExecution } : {}),\n ...(opts.computedColumnStore ? { store: opts.computedColumnStore } : {}),\n ...(opts.formulaWorkerFactory\n ? { workerFactory: opts.formulaWorkerFactory }\n : {}),\n ...(transport ? { transport } : {}),\n ...(clientRows ? { clientRows } : {}),\n });\n\n const resolveComputed = useCallback(\n (name: string) =>\n isComputedField(name)\n ? computed.compile(`[${name.replace(/]/g, \"]] \".trim())}]`)\n : undefined,\n [computed.compile],\n );\n const metricCompile = useCallback(\n (clause: AggregationClause) => {\n const diagnostics = validateMetric(\n clause,\n displaySchema,\n resolveComputed,\n );\n if (diagnostics.length)\n throw new Error(diagnostics.map((d) => d.message).join(\" \"));\n return metricPlans(clause, displaySchema, resolveComputed);\n },\n [displaySchema, resolveComputed],\n );\n const computedRevisions = useMemo(\n () =>\n Object.fromEntries(computed.definitions.map((d) => [d.id, d.revision])),\n [computed.definitions],\n );\n const definitionKey = JSON.stringify(computedRevisions);\n\n // Fetch (debounced + abortable). Transport mode, or client-side applyQuery.\n const queryKey = useMemo(() => encodeQuery(query), [query]);\n const serverRowQuery = useMemo(() => {\n const execution = opts.computedExecution;\n const v2Request =\n execution && transport?.fetchRowsV2\n ? toServerQueryV2(query, displaySchema, execution)\n : undefined;\n const request = v2Request ?? toServerQuery(query, displaySchema);\n if (v2Request)\n for (const definition of computed.definitions) {\n if (\n executionRevision(execution, definition.id) !== undefined &&\n executionRevision(execution, definition.id) !== definition.revision\n )\n v2Request.diagnostics.push({\n from: 0,\n to: 1,\n code: \"definition_changed\",\n message:\n \"Computed definitions changed. Refresh the server execution handshake.\",\n });\n }\n // A shown-row metric may refer to columns outside the visible projection.\n for (const clause of query.aggregations ?? [])\n if (clause.scope === \"shownRows\") {\n try {\n for (const name of metricDependencies(\n clause,\n schema,\n resolveComputed,\n )) {\n const field = schema.fields.find((f) => f.name === name);\n if (field?.source.kind === \"backend\") request.select.push(name);\n else\n for (const dep of field?.source.kind === \"derived\"\n ? (field.source.dependencies ?? [])\n : [])\n request.select.push(dep);\n }\n } catch {\n /* Invalid metric stays editable and fails metric validation. */\n }\n }\n request.select = [...new Set(request.select)].sort();\n return request;\n }, [\n queryKey,\n displaySchema,\n transport,\n computedRevisions,\n schema,\n resolveComputed,\n opts.computedExecution,\n ]);\n // Keep presentation-only query changes out of the expensive row pipeline.\n // Widths do not leave the client at all, and SELECT does not affect client-side\n // filtering/sorting/paging. The full queryKey still drives URL + persistence.\n const rowQueryKey = useMemo(\n () =>\n transport\n ? `server:${JSON.stringify(serverRowQuery)}`\n : `client:${JSON.stringify([query.where, query.orderBy, query.limit, query.offset])}`,\n [\n transport,\n serverRowQuery,\n query.where,\n query.orderBy,\n query.limit,\n query.offset,\n ],\n );\n const executionKey = JSON.stringify(opts.computedExecution ?? null);\n const pageContext = `${schema.name}:${rowQueryKey}:${nonce}:${executionKey}`;\n useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n const run = async () => {\n setLoading(true);\n setError(null);\n try {\n opts.validateQuery?.(query);\n if (transport) {\n const useV2 = \"version\" in serverRowQuery && transport.fetchRowsV2;\n if (\n \"diagnostics\" in serverRowQuery &&\n Array.isArray(serverRowQuery.diagnostics) &&\n serverRowQuery.diagnostics.length\n )\n throw Error(\n serverRowQuery.diagnostics.map((d) => d.message).join(\" \"),\n );\n if (!useV2 && query.orderBy.some((s) => isComputedField(s.field)))\n throw Error(\n \"Global computed sorting requires a server execution handshake and fetchRowsV2.\",\n );\n const res = useV2\n ? await transport.fetchRowsV2!(\n serverRowQuery as ReturnType<typeof toServerQueryV2<Row>>,\n ac.signal,\n )\n : await transport.fetchRows(serverRowQuery, ac.signal);\n if (useV2)\n validateComputedResponse(\n serverRowQuery as ReturnType<typeof toServerQueryV2<Row>>,\n res as import(\"@pythia-software/query-table-core\").FetchRowsResultV2<Row>,\n schema,\n );\n if (!cancelled) {\n setCommittedFields(serverRowQuery.select);\n setServerExecution(\n useV2\n ? (\n res as import(\"@pythia-software/query-table-core\").FetchRowsResultV2<Row>\n ).execution\n : undefined,\n );\n if (\"computed\" in res && Array.isArray(res.computed))\n setServerComputed(\n new Map(res.computed.map((c) => [c.id, c.values])),\n );\n else setServerComputed(new Map());\n setRows(res.rows);\n setTotal(res.total);\n setCommittedPage(pageContext);\n setCommittedSource({ schema, transport, clientRows });\n }\n } else {\n const res = applyQuery(clientRows ?? [], query, schema);\n if (!cancelled) {\n setRows(res.rows);\n setTotal(res.total);\n setCommittedPage(pageContext);\n setCommittedSource({ schema, transport, clientRows });\n }\n }\n } catch (e) {\n if (!cancelled && !ac.signal.aborted) {\n setError(e as Error);\n setRows([]);\n setTotal(null);\n setCommittedPage(null);\n }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n const t = setTimeout(run, debounceMs);\n return () => {\n cancelled = true;\n clearTimeout(t);\n ac.abort();\n };\n // rowQueryKey captures only row-affecting query state; clientRows/nonce\n // force refetch. Presentation changes still sync/persist via queryKey below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n rowQueryKey,\n transport,\n clientRows,\n schema,\n debounceMs,\n nonce,\n opts.validateQuery,\n executionKey,\n ]);\n\n // URL sync.\n useEffect(() => {\n if (!syncUrl || typeof window === \"undefined\") return;\n const url = new URL(window.location.href);\n const token = encodeQuery(query);\n if (token) url.searchParams.set(\"q\", token);\n else url.searchParams.delete(\"q\");\n window.history.replaceState(null, \"\", url.toString());\n }, [queryKey, syncUrl, query]);\n\n // Persist last query (debounced).\n useEffect(() => {\n const t = setTimeout(() => void storage.saveLast(schema.name, query), 400);\n return () => clearTimeout(t);\n }, [queryKey, storage, schema.name, query]);\n\n // Resolved id accessor.\n const idField = useMemo(\n () => schema.fields.find((f) => f.name === schema.idField),\n [schema],\n );\n const rowId = useCallback(\n (row: Row): RowId | null =>\n idField ? (readFieldValue(idField, row) as RowId | null) : null,\n [idField],\n );\n\n // Sub-APIs.\n const displayedIds = useMemo(\n () => rows.map(rowId).filter((id): id is RowId => id != null),\n [rows, rowId],\n );\n const selection = useSelection(displayedIds);\n const select = useSelect(query, setQuery, displaySchema);\n const columnDrag = useColumnDrag();\n const saved = useSavedQueries(\n schema.name,\n query,\n (q) => setQuery(q),\n storage,\n now,\n );\n const pageReady =\n committedPage === pageContext &&\n committedSource?.schema === schema &&\n committedSource?.transport === transport &&\n committedSource?.clientRows === clientRows &&\n !error;\n const dataToken = useRef(0);\n const dataVersion = useMemo(\n () => ++dataToken.current,\n [schema, transport, clientRows, nonce, definitionKey, executionKey],\n );\n const aggState = useAggregations(\n query,\n schema,\n transport,\n clientRows,\n debounceMs,\n nonce,\n opts.validateQuery,\n {\n shownRows: rows,\n rowsReady: pageReady,\n rowsError: error,\n ...(transport ? { shownFields: committedFields } : {}),\n resolveComputed,\n revisions: computedRevisions,\n ...(opts.computedExecution\n ? {\n execution:\n pageReady && serverExecution\n ? serverExecution\n : opts.computedExecution,\n }\n : {}),\n ...(opts.formulaWorkerFactory\n ? { workerFactory: opts.formulaWorkerFactory }\n : {}),\n },\n );\n const queryRef = useRef(query);\n queryRef.current = query;\n const replaceAggregations = useCallback(\n (clauses: AggregationClause[], expected?: AggregationClause[]) => {\n if (\n expected &&\n JSON.stringify(queryRef.current.aggregations ?? []) !==\n JSON.stringify(expected)\n )\n throw new Error(\n \"Metrics changed while editing. Reopen the editor to use the latest configuration.\",\n );\n for (const clause of clauses) metricCompile(clause);\n setQuery((q) => ({\n ...q,\n aggregations: JSON.parse(\n JSON.stringify(clauses),\n ) as AggregationClause[],\n }));\n },\n [setQuery, metricCompile],\n );\n\n const canUndo = undoStack.current.length > 0;\n const canRedo = redoStack.current.length > 0;\n\n const undo = useCallback(() => {\n setQueryState((prev) => {\n const previous = undoStack.current.pop();\n if (!previous) return prev;\n redoStack.current.push(cloneQueryState(prev));\n return cloneQueryState(previous);\n });\n }, []);\n\n const redo = useCallback(() => {\n setQueryState((prev) => {\n const next = redoStack.current.pop();\n if (!next) return prev;\n undoStack.current.push(cloneQueryState(prev));\n return cloneQueryState(next);\n });\n }, []);\n\n // ---- intent helpers (keep offset/url/storage coherent) ----\n const patch = useCallback(\n (p: Partial<QueryState>) => setQuery((prev) => ({ ...prev, ...p })),\n [setQuery],\n );\n\n const addFilter = useCallback(\n (clause: WhereClause) =>\n setQuery((q) => ({ ...q, offset: 0, where: [...q.where, clause] })),\n [setQuery],\n );\n const updateFilter = useCallback(\n (index: number, clause: WhereClause) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((t, i) => (i === index ? clause : t)),\n })),\n [setQuery],\n );\n const removeFilter = useCallback(\n (index: number) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.filter((_, i) => i !== index),\n })),\n [setQuery],\n );\n const clearFilters = useCallback(\n () => setQuery((q) => ({ ...q, offset: 0, where: [] })),\n [setQuery],\n );\n\n const updatePredicate = useCallback<QueryTableApi<Row>[\"updatePredicate\"]>(\n (termIndex, predIndex, clause) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term))\n return {\n any: term.any.map((c, j) => (j === predIndex ? clause : c)),\n };\n return clause;\n }),\n })),\n [setQuery],\n );\n const removePredicate = useCallback<QueryTableApi<Row>[\"removePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => {\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i !== termIndex) {\n where.push(term);\n return;\n }\n if (isOrGroup(term)) {\n const members = term.any.filter((_, j) => j !== predIndex);\n if (members.length === 1) where.push(members[0]!);\n else if (members.length > 1) where.push({ any: members });\n return; // 0 members → drop the term\n }\n // literal term → removing its predicate drops the whole term\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const negateOne = useCallback(\n (clause: WhereClause): WhereClause => {\n const field = byName.get(clause.field);\n return negateClause(clause, field ? opsForField(field) : undefined);\n },\n [byName],\n );\n const negatePredicate = useCallback<QueryTableApi<Row>[\"negatePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term))\n return {\n any: term.any.map((c, j) => (j === predIndex ? negateOne(c) : c)),\n };\n return negateOne(term);\n }),\n })),\n [setQuery, negateOne],\n );\n const reorderFilters = useCallback<QueryTableApi<Row>[\"reorderFilters\"]>(\n (fromIndex, toIndex) =>\n setQuery((q) => {\n if (fromIndex < 0 || fromIndex >= q.where.length) return q;\n const where = [...q.where];\n const [moved] = where.splice(fromIndex, 1);\n where.splice(Math.max(0, Math.min(toIndex, where.length)), 0, moved!);\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const mergeFilters = useCallback<QueryTableApi<Row>[\"mergeFilters\"]>(\n (sourceIndex, targetIndex) =>\n setQuery((q) => {\n if (sourceIndex === targetIndex) return q;\n const source = q.where[sourceIndex];\n const target = q.where[targetIndex];\n if (!source || !target) return q;\n const merged: WhereTerm = {\n any: [...predicatesOf(target), ...predicatesOf(source)],\n };\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i === sourceIndex) return; // remove the dragged term\n where.push(i === targetIndex ? merged : term);\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const resetAll = useCallback(\n () => setQuery(() => cloneQueryState(defaults)),\n [setQuery, defaults],\n );\n\n // ---- aggregation metric mutators (don't touch paging — scope is the whole set) ----\n const addAggregation = useCallback<AggregationsApi[\"add\"]>(\n (partial) => {\n const id = `a${nowRef.current()}-${aggIdRef.current++}`;\n const clause: AggregationClause = {\n id,\n op: \"count\",\n groupBy: [],\n ...partial,\n };\n setQuery((q) => ({\n ...q,\n aggregations: [...(q.aggregations ?? []), clause],\n }));\n return id;\n },\n [setQuery],\n );\n const updateAggregation = useCallback<AggregationsApi[\"update\"]>(\n (id, patch) =>\n setQuery((q) => ({\n ...q,\n aggregations: (q.aggregations ?? []).map((a) =>\n a.id === id ? mergeAggregation(a, patch) : a,\n ),\n })),\n [setQuery],\n );\n const moveAggregation = useCallback<AggregationsApi[\"move\"]>(\n (id, toIndex) =>\n setQuery((q) => {\n const current = q.aggregations ?? [];\n const from = current.findIndex((a) => a.id === id);\n if (from === -1) return q;\n const next = [...current];\n const [item] = next.splice(from, 1);\n next.splice(Math.max(0, Math.min(toIndex, next.length)), 0, item!);\n return { ...q, aggregations: next };\n }),\n [setQuery],\n );\n const removeAggregation = useCallback<AggregationsApi[\"remove\"]>(\n (id) =>\n setQuery((q) => ({\n ...q,\n aggregations: (q.aggregations ?? []).filter((a) => a.id !== id),\n })),\n [setQuery],\n );\n const clearAggregations = useCallback<AggregationsApi[\"clear\"]>(\n () => setQuery((q) => ({ ...q, aggregations: [] })),\n [setQuery],\n );\n\n const setSort = useCallback(\n (orderBy: OrderByClause[]) =>\n setQuery((q) => ({ ...q, offset: 0, orderBy })),\n [setQuery],\n );\n const toggleSort = useCallback(\n (field: string, additive = false) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n orderBy: nextOrderBy(q.orderBy, field, additive),\n })),\n [setQuery],\n );\n\n const setLimit = useCallback(\n (limit: number) => patch({ limit, offset: 0 }),\n [patch],\n );\n const setOffset = useCallback((offset: number) => patch({ offset }), [patch]);\n const nextPage = useCallback(\n () => setQuery((q) => ({ ...q, offset: q.offset + q.limit })),\n [setQuery],\n );\n const prevPage = useCallback(\n () => setQuery((q) => ({ ...q, offset: Math.max(0, q.offset - q.limit) })),\n [setQuery],\n );\n\n const filterValues = useCallback(\n async (field: string, search: string): Promise<DistinctValuesResult> => {\n if (!transport?.fetchDistinctValues) {\n const f = byName.get(field);\n if (!f || !clientRows) return { values: [], hasMore: false };\n\n const fieldHasNull = fieldHasNullInRows(f, clientRows);\n const matches = distinctValuesFromRows(f, clientRows, search);\n\n return {\n values: matches.values,\n hasMore: matches.hasMore,\n hasNull: fieldHasNull,\n };\n }\n return transport.fetchDistinctValues({ field, search });\n },\n [transport, byName, clientRows],\n );\n\n const fieldStats = useCallback<QueryTableApi<Row>[\"fieldStats\"]>(\n async (fields, signal) => {\n const requested = [...new Set(fields)];\n if (transport?.fetchFieldStats) {\n const backendFields = requested.filter(\n (name) => byName.get(name)?.source.kind === \"backend\",\n );\n return backendFields.length\n ? transport.fetchFieldStats(backendFields, signal)\n : {};\n }\n if (!clientRows) return {};\n\n const result: Record<string, FieldStats> = {};\n for (const name of requested) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const field = byName.get(name);\n if (!field) continue;\n const distinct = new Set<string>();\n for (const row of clientRows) {\n const value = readFieldValue(field, row);\n if (value !== null) distinct.add(JSON.stringify(value));\n }\n result[name] = { distinct: distinct.size };\n }\n return result;\n },\n [transport, byName, clientRows],\n );\n\n // Single refresh seam: re-runs the internal query (setNonce) and fires the\n // consumer's onRefresh, if any. Both the manual `api.refresh()` and every\n // auto-refresh tick go through here, so they stay observably identical. Read\n // onRefresh through a ref to keep this callback (and the interval that depends\n // on it) stable across renders.\n const refresh = useCallback(() => {\n setNonce((n) => n + 1);\n onRefreshRef.current?.();\n }, []);\n const stopAutoRefresh = useCallback(() => setAutoRefreshStatus(null), []);\n const startAutoRefresh = useCallback(\n ({ frequencyMs, turnOffAfterMs }: AutoRefreshConfig) => {\n const pollCount =\n frequencyMs > 0 && turnOffAfterMs > 0\n ? Math.floor(turnOffAfterMs / frequencyMs)\n : 0;\n if (pollCount < 1 || pollCount > MAX_AUTO_REFRESH_POLLS) {\n throw new Error(\"Auto-refresh must schedule between 1 and 1000 polls.\");\n }\n\n const startedAt = nowRef.current();\n refresh();\n setAutoRefreshStatus({\n frequencyMs,\n turnOffAfterMs,\n startedAt,\n stopsAt: startedAt + turnOffAfterMs,\n pollCount: 1,\n });\n },\n [refresh],\n );\n\n const autoRefreshFrequencyMs = autoRefreshStatus?.frequencyMs ?? null;\n const autoRefreshStopsAt = autoRefreshStatus?.stopsAt ?? null;\n\n useEffect(() => {\n if (autoRefreshFrequencyMs == null || autoRefreshStopsAt == null) return;\n\n const tick = () => {\n if (nowRef.current() >= autoRefreshStopsAt) {\n setAutoRefreshStatus((current) =>\n current?.stopsAt === autoRefreshStopsAt ? null : current,\n );\n return;\n }\n\n refresh();\n setAutoRefreshStatus((current) => {\n if (!current) return current;\n if (current.stopsAt !== autoRefreshStopsAt) return current;\n return { ...current, pollCount: current.pollCount + 1 };\n });\n };\n\n const interval = setInterval(tick, autoRefreshFrequencyMs);\n const timeout = setTimeout(\n () =>\n setAutoRefreshStatus((current) =>\n current?.stopsAt === autoRefreshStopsAt ? null : current,\n ),\n Math.max(0, autoRefreshStopsAt - nowRef.current()),\n );\n\n return () => {\n clearInterval(interval);\n clearTimeout(timeout);\n };\n }, [autoRefreshFrequencyMs, autoRefreshStopsAt, refresh]);\n\n const autoRefresh = useMemo<AutoRefreshApi>(\n () => ({\n status: autoRefreshStatus,\n start: startAutoRefresh,\n stop: stopAutoRefresh,\n }),\n [autoRefreshStatus, startAutoRefresh, stopAutoRefresh],\n );\n\n const refreshRow = useCallback(\n async (id: RowId) => {\n if (opts.computedExecution && transport?.fetchRowsV2) {\n // Base rows and computed sidecars belong to one committed page. A\n // single-row fetch cannot replace either independently, and changes\n // to a computed sort may also change page membership.\n refresh();\n return;\n }\n if (!transport?.fetchRow) return;\n const updated = await transport.fetchRow(id);\n setRows((prev) =>\n prev.map((r) => (rowId(r) === id ? (updated ?? r) : r)),\n );\n },\n [transport, rowId, opts.computedExecution, refresh],\n );\n\n const visibleFields = useMemo(\n () => selectedFields(displaySchema, query),\n [displaySchema, query],\n );\n\n const aggregations = useMemo<AggregationsApi>(\n () => ({\n clauses: query.aggregations ?? [],\n results: aggState.results,\n loading: aggState.loading,\n error: aggState.error,\n add: addAggregation,\n update: updateAggregation,\n move: moveAggregation,\n remove: removeAggregation,\n clear: clearAggregations,\n preview: aggState.preview,\n replace: replaceAggregations,\n compile: metricCompile,\n contextKey: `${dataVersion}:${pageContext}:${pageReady}:${JSON.stringify(query.where)}`,\n }),\n [\n query.aggregations,\n aggState.results,\n aggState.loading,\n aggState.error,\n addAggregation,\n updateAggregation,\n moveAggregation,\n removeAggregation,\n clearAggregations,\n aggState.preview,\n replaceAggregations,\n metricCompile,\n pageContext,\n pageReady,\n dataVersion,\n query.where,\n ],\n );\n\n return {\n query,\n defaults,\n setQuery,\n rows,\n total,\n loading,\n error,\n requestActivity,\n canUndo,\n canRedo,\n undo,\n redo,\n refresh,\n autoRefresh,\n refreshRow,\n aggregations,\n addFilter,\n updateFilter,\n removeFilter,\n clearFilters,\n updatePredicate,\n removePredicate,\n negatePredicate,\n reorderFilters,\n mergeFilters,\n resetAll,\n filterValues,\n fieldStats,\n toggleSort,\n setSort,\n select,\n computed,\n setLimit,\n setOffset,\n nextPage,\n prevPage,\n selection,\n saved,\n columnDrag,\n visibleFields,\n rowId,\n };\n}\n\n/** Multi-sort header click logic.\n * - plain click on the sole sorted column → flip its direction\n * - plain click on another column → make it the only sort (desc)\n * - shift-click a new column → append it (desc) as a secondary term\n * - shift-click an existing term → cycle desc → asc → remove */\nfunction nextOrderBy(\n existing: OrderByClause[],\n field: string,\n additive: boolean,\n): OrderByClause[] {\n const i = existing.findIndex((s) => s.field === field);\n if (!additive) {\n if (i === 0 && existing.length === 1) {\n const flipped: \"asc\" | \"desc\" =\n existing[0]!.dir === \"desc\" ? \"asc\" : \"desc\";\n return [{ ...existing[0]!, dir: flipped }];\n }\n return [{ field, dir: \"desc\" }];\n }\n if (i === -1) return [...existing, { field, dir: \"desc\" }];\n const cur = existing[i]!;\n if (cur.dir === \"desc\") {\n const next = [...existing];\n next[i] = { ...cur, dir: \"asc\" };\n return next;\n }\n return existing.filter((_, k) => k !== i); // asc → remove\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { Transport } from \"@pythia-software/query-table-core\";\n\nexport interface RequestActivityEntry {\n id: number;\n kind: string;\n startedAt: number;\n status: \"pending\" | \"success\" | \"error\" | \"aborted\";\n durationMs?: number;\n error?: string;\n}\nexport interface RequestActivityApi {\n /** Newest first; bounded to the latest 100 calls. Query values and results are never retained. */\n entries: readonly RequestActivityEntry[];\n clear: () => void;\n}\nconst methods = new Set([\n \"fetchRows\",\n \"fetchRowsV2\",\n \"fetchMetrics\",\n \"fetchAggregations\",\n \"fetchRow\",\n \"fetchDistinctValues\",\n \"fetchFieldStats\",\n]);\n\n/** Observe the transport boundary without changing receiver, arguments or errors. */\nexport function observeTransport<Row>(\n transport: Transport<Row>,\n publish: (entry: RequestActivityEntry) => void,\n nextId: () => number,\n): Transport<Row> {\n const wrappers = new Map<PropertyKey, unknown>();\n return new Proxy(Object.create(transport) as Transport<Row>, {\n get(_target, key) {\n const method = Reflect.get(transport, key, transport);\n if (!methods.has(String(key)) || typeof method !== \"function\")\n return method;\n if (!wrappers.has(key))\n wrappers.set(key, async (...args: unknown[]) => {\n const signal = args[1] as AbortSignal | undefined;\n const start = performance.now();\n const entry: RequestActivityEntry = {\n id: nextId(),\n kind: String(key).replace(/^fetch/, \"\"),\n startedAt: Date.now(),\n status: \"pending\",\n };\n publish(entry);\n let done = false;\n const finish = (\n status: RequestActivityEntry[\"status\"],\n error?: unknown,\n ) => {\n if (done) return;\n done = true;\n publish({\n ...entry,\n status,\n durationMs: Math.max(0, performance.now() - start),\n ...(error !== undefined\n ? {\n error:\n error instanceof Error ? error.message : String(error),\n }\n : {}),\n });\n };\n const abort = () => finish(\"aborted\");\n signal?.addEventListener(\"abort\", abort, { once: true });\n if (signal?.aborted) abort();\n try {\n const result = await method.apply(transport, args);\n finish(signal?.aborted ? \"aborted\" : \"success\");\n return result;\n } catch (error) {\n finish(\n signal?.aborted ||\n (error instanceof Error && error.name === \"AbortError\")\n ? \"aborted\"\n : \"error\",\n error,\n );\n throw error;\n } finally {\n signal?.removeEventListener(\"abort\", abort);\n }\n });\n return wrappers.get(key);\n },\n });\n}\n\nexport function useRequestActivity<Row>(source: Transport<Row> | undefined) {\n const [entries, setEntries] = useState<RequestActivityEntry[]>([]);\n const sequence = useRef(0),\n mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const publish = useCallback((entry: RequestActivityEntry) => {\n if (mounted.current)\n setEntries((previous) =>\n [entry, ...previous.filter((e) => e.id !== entry.id)]\n .sort((a, b) => b.id - a.id)\n .slice(0, 100),\n );\n }, []);\n const transport = useMemo(\n () =>\n source\n ? observeTransport(source, publish, () => ++sequence.current)\n : undefined,\n [source, publish],\n );\n const clear = useCallback(\n () =>\n setEntries((previous) => previous.filter((e) => e.status === \"pending\")),\n [],\n );\n const activity: RequestActivityApi = useMemo(\n () => ({ entries, clear }),\n [entries, clear],\n );\n return { transport, activity };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n metricComputationKey,\n metricPlans,\n hasRegex,\n type AggregationClause,\n type AggregationResult,\n type FieldSchema,\n type QueryState,\n type Transport,\n} from \"@pythia-software/query-table-core\";\nimport { executeMetrics, type MetricExecutionContext } from \"./metricExecution\";\n\nexport interface AggregationsApiState {\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n preview: (\n clauses: AggregationClause[],\n signal?: AbortSignal,\n ) => Promise<AggregationResult>;\n}\n/** Fetch state is keyed by computation and scope, never card presentation. */\nexport function useAggregations<Row>(\n query: QueryState,\n schema: FieldSchema<Row>,\n transport: Transport<Row> | undefined,\n clientRows: Row[] | undefined,\n debounceMs: number,\n nonce: number,\n validateQuery?: (q: QueryState) => void,\n options: Omit<\n MetricExecutionContext<Row>,\n \"schema\" | \"transport\" | \"clientRows\"\n > = {},\n): AggregationsApiState {\n const [results, setResults] = useState<AggregationResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const latest = useRef({\n query,\n schema,\n transport,\n clientRows,\n options,\n validateQuery,\n });\n latest.current = {\n query,\n schema,\n transport,\n clientRows,\n options,\n validateQuery,\n };\n const preview = useCallback(\n async (clauses: AggregationClause[], signal?: AbortSignal) => {\n const current = latest.current;\n const draft = { ...current.query, aggregations: clauses };\n current.validateQuery?.(draft);\n return executeMetrics(\n draft,\n {\n schema: current.schema,\n transport: current.transport,\n clientRows: current.clientRows,\n ...current.options,\n },\n signal,\n );\n },\n [],\n );\n const shown = (query.aggregations ?? []).some((c) => c.scope === \"shownRows\");\n // A v2 server scopes shownRows from the query window and snapshot itself.\n // Only client/legacy/regex evaluation depends on the downloaded row page.\n const localPage =\n shown &&\n (!transport?.fetchMetrics ||\n transport.metricCapabilities?.version !== 2 ||\n (query.aggregations ?? []).some((clause) => {\n if (clause.scope !== \"shownRows\") return false;\n try {\n return metricPlans(clause, schema, options.resolveComputed).some(\n hasRegex,\n );\n } catch {\n return true;\n } // Validation reports invalid inputs through fetch state.\n }));\n const key = useMemo(\n () =>\n JSON.stringify([\n query.where,\n metricComputationKey(query.aggregations ?? []),\n shown ? [query.orderBy, query.limit, query.offset] : null,\n ]),\n [\n query.where,\n query.aggregations,\n query.orderBy,\n query.limit,\n query.offset,\n shown,\n ],\n );\n const dependencyKey = JSON.stringify([\n options.revisions ?? {},\n options.execution ?? null,\n ]);\n useEffect(() => {\n if (!latest.current.query.aggregations?.length) {\n setResults(null);\n setLoading(false);\n setError(null);\n return;\n }\n const ac = new AbortController();\n setLoading(true);\n setResults(null);\n // Automatic shown-page evaluation waits for the committed page. Explicit\n // previews still report missing inputs rather than using stale rows.\n if (localPage && transport && !options.rowsReady) {\n try {\n latest.current.validateQuery?.(latest.current.query);\n setError(options.rowsError ?? null);\n if (options.rowsError) setLoading(false);\n } catch (e) {\n setError(e instanceof Error ? e : Error(String(e)));\n setLoading(false);\n }\n return;\n }\n const timer = setTimeout(() => {\n setError(null);\n try {\n latest.current.validateQuery?.(latest.current.query);\n } catch (e) {\n setError(e instanceof Error ? e : Error(String(e)));\n setLoading(false);\n return;\n }\n void preview(latest.current.query.aggregations ?? [], ac.signal)\n .then((result) => {\n if (!ac.signal.aborted) setResults(result);\n })\n .catch((e) => {\n if (!ac.signal.aborted)\n setError(e instanceof Error ? e : Error(String(e)));\n })\n .finally(() => {\n if (!ac.signal.aborted) setLoading(false);\n });\n }, debounceMs);\n return () => {\n ac.abort();\n clearTimeout(timer);\n };\n }, [\n key,\n schema,\n transport,\n clientRows,\n debounceMs,\n nonce,\n validateQuery,\n dependencyKey,\n localPage,\n localPage ? options.shownRows : undefined,\n localPage ? options.rowsReady : undefined,\n localPage ? options.rowsError : undefined,\n preview,\n ]);\n return { results, loading, error, preview };\n}\n","import {\n applyAggregations,\n normalizeQueryState,\n evaluateMetrics,\n metricPlans,\n hasRegex,\n toAggregationQuery,\n toMetricQuery,\n validateMetric,\n selectMetricShownRows,\n readFieldValue,\n resolveFieldName,\n isComputedField,\n type AggregationClause,\n type AggregationResult,\n type FieldSchema,\n type FormulaNode,\n type FormulaPlan,\n type FormulaResult,\n type FormulaValue,\n type QueryState,\n type Transport,\n type ComputedExecution,\n} from \"@pythia-software/query-table-core\";\nimport {\n evaluateFormulaRows,\n type FormulaWorkerFactory,\n} from \"./formulaWorker\";\n\nexport interface MetricExecutionContext<Row> {\n schema: FieldSchema<Row>;\n transport?: Transport<Row> | undefined;\n clientRows?: Row[] | undefined;\n shownRows?: Row[] | undefined;\n rowsReady?: boolean | undefined;\n rowsError?: Error | null | undefined;\n shownFields?: readonly string[] | undefined;\n resolveComputed?: ((name: string) => FormulaPlan | undefined) | undefined;\n workerFactory?: FormulaWorkerFactory | undefined;\n revisions?: Record<string, string> | undefined;\n execution?: ComputedExecution;\n}\nconst abort = (signal?: AbortSignal) => {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n};\n\n/** Local regex inputs run in terminable workers; reduction uses only cached values. */\nasync function localMetrics<Row>(\n rows: Row[],\n query: QueryState,\n context: MetricExecutionContext<Row>,\n signal?: AbortSignal,\n): Promise<AggregationResult> {\n // Keep legacy aggregates on their permissive compatibility path. Advanced\n // metrics still use the typed formula engine and isolated regex workers.\n const originalClauses = query.aggregations ?? [];\n const advanced = (query.aggregations ?? []).filter(\n (c) =>\n isComputedField(c.field ?? \"\") ||\n c.groupBy.some(isComputedField) ||\n c.diagnostics?.length ||\n c.expression !== undefined ||\n c.expressionY !== undefined ||\n c.scope !== undefined ||\n c.distribution ||\n c.sort ||\n c.groupLimit !== undefined,\n );\n if (\n advanced.length &&\n (originalClauses.length > 20 ||\n normalizeQueryState(query).aggregations?.length !==\n originalClauses.length)\n )\n return evaluateMetrics(rows, query, context.schema, {\n ...(signal ? { signal } : {}),\n ...(context.resolveComputed\n ? { resolveComputed: context.resolveComputed }\n : {}),\n });\n const legacy = (query.aggregations ?? []).filter(\n (c) => !advanced.includes(c),\n );\n const compatible = applyAggregations(\n rows,\n { ...query, aggregations: legacy },\n context.schema,\n {\n ...(signal ? { signal } : {}),\n },\n );\n if (!advanced.length) return compatible;\n query = { ...query, aggregations: advanced };\n const options = {\n ...(context.resolveComputed\n ? { resolveComputed: context.resolveComputed }\n : {}),\n ...(signal ? { signal } : {}),\n };\n for (const clause of query.aggregations ?? []) {\n const diagnostics = validateMetric(\n clause,\n context.schema,\n context.resolveComputed,\n );\n if (diagnostics.length)\n throw Error(diagnostics.map((d) => d.message).join(\" \"));\n }\n const requiresPage = (query.aggregations ?? []).some(\n (clause) => clause.scope === \"shownRows\",\n );\n const page = requiresPage\n ? selectMetricShownRows(rows, query, context.schema, {\n ...options,\n ...(context.rowsReady && context.shownRows\n ? { shownRows: context.shownRows }\n : {}),\n })\n : [];\n const caches = new Map<string, Map<Row, FormulaResult>>();\n for (const clause of query.aggregations ?? []) {\n for (const plan of metricPlans(\n clause,\n context.schema,\n context.resolveComputed,\n )) {\n if (!hasRegex(plan)) continue;\n const nodes =\n \"aggregates\" in plan\n ? (\n plan as FormulaPlan & {\n aggregates: Array<{ args: FormulaNode[] }>;\n }\n ).aggregates.flatMap((a) => a.args)\n : [plan.ast];\n for (const node of nodes) {\n if (!hasRegex({ ...plan, ast: node })) continue;\n const key = JSON.stringify(node);\n if (caches.has(key)) continue;\n let bytes = 0;\n const inputs = page.map((row) => {\n const values: Record<string, FormulaValue> = Object.create(null);\n for (const name of plan.dependencies) {\n const field = context.schema.fields.find((f) => f.name === name);\n if (!field) throw Error(`Unavailable metric input: ${name}`);\n const raw = readFieldValue(field, row);\n values[name] =\n raw instanceof Date\n ? raw.toISOString()\n : ((raw ?? null) as FormulaValue);\n }\n bytes += JSON.stringify(values).length;\n if (bytes > 16000000)\n throw Error(\n \"Metric worker input exceeds 16 MB. Reduce the shown rows.\",\n );\n return values;\n });\n const values = await evaluateFormulaRows(\n node,\n inputs,\n signal,\n context.workerFactory,\n );\n caches.set(\n key,\n new Map(page.map((row, i) => [row, values[i]!] as const)),\n );\n }\n }\n }\n abort(signal);\n const typed = evaluateMetrics(rows, query, context.schema, {\n ...options,\n shownRows: page,\n ...(caches.size\n ? {\n evaluateInput: (node: FormulaNode, row: Row, plan: FormulaPlan) => {\n const cached = caches.get(JSON.stringify(node));\n if (cached)\n return (\n cached.get(row) ?? {\n value: null,\n error: \"Metric worker result missing.\",\n }\n );\n // Core calls the override only for regex inputs.\n throw Error(\"Metric regex input was not evaluated in a worker.\");\n },\n }\n : {}),\n });\n const byId = new Map(\n [...compatible.metrics, ...typed.metrics].map((m) => [m.id, m]),\n );\n return { metrics: originalClauses.flatMap((c) => byId.get(c.id) ?? []) };\n}\n\nexport async function executeMetrics<Row>(\n query: QueryState,\n context: MetricExecutionContext<Row>,\n signal?: AbortSignal,\n): Promise<AggregationResult> {\n abort(signal);\n const clauses = query.aggregations ?? [];\n if (!clauses.length) return { metrics: [] };\n const supportsV2 =\n !!context.transport?.fetchMetrics &&\n context.transport.metricCapabilities?.version === 2;\n if (\n context.clientRows &&\n !supportsV2 &&\n !context.transport?.fetchAggregations\n )\n return localMetrics(context.clientRows, query, context, signal);\n const needsWorker = (c: AggregationClause) =>\n metricPlans(c, context.schema, context.resolveComputed).some(hasRegex);\n const shown = clauses.filter(\n (c) => c.scope === \"shownRows\" && (!supportsV2 || needsWorker(c)),\n );\n const matching = clauses.filter(\n (c) => c.scope !== \"shownRows\" || (supportsV2 && !needsWorker(c)),\n );\n const results: AggregationResult[\"metrics\"] = [];\n if (shown.length) {\n if (!context.rowsReady || !context.shownRows)\n throw Error(\n \"Wait for the current table page before previewing shown-row metrics.\",\n );\n // Only committed inputs can claim \"shown rows\". Never hydrate them from a\n // newer response with the same IDs; that would mix data snapshots.\n const names = new Set(\n shown.flatMap((clause) => [\n ...clause.groupBy,\n ...metricPlans(clause, context.schema, context.resolveComputed).flatMap(\n (p) => p.dependencies,\n ),\n ]),\n );\n for (const name of names) {\n const canonical = resolveFieldName(context.schema, name) ?? name;\n const field = context.schema.fields.find((f) => f.name === canonical);\n const dependencies =\n field?.source.kind === \"derived\"\n ? (field.source.dependencies ?? [])\n : [canonical];\n const loaded = context.shownFields\n ? dependencies.every((dep) => context.shownFields!.includes(dep))\n : field &&\n context.shownRows.every(\n (row) =>\n field.source.kind === \"derived\" ||\n loadedPath(\n row,\n field.source.kind === \"backend\"\n ? (field.source.path ?? field.name)\n : field.name,\n ),\n );\n if (!field || !loaded)\n throw Error(\n `Shown-page input ${name} is not loaded. Add it to the selected columns and refresh, or use a snapshot-capable metric transport.`,\n );\n }\n const pageQuery = {\n ...query,\n where: [],\n orderBy: [],\n limit: Math.max(1, context.shownRows.length),\n offset: 0,\n aggregations: shown,\n };\n results.push(\n ...(await localMetrics(context.shownRows, pageQuery, context, signal))\n .metrics,\n );\n }\n if (matching.length) {\n const transport = context.transport;\n const scoped = { ...query, aggregations: matching };\n if (\n transport?.fetchMetrics &&\n transport.metricCapabilities?.version === 2\n ) {\n const request = toMetricQuery(scoped, context.schema, context.execution);\n if (request.diagnostics.length)\n throw Error(request.diagnostics.map((d) => d.message).join(\" \"));\n if (\n matching.some((c) => c.scope === \"shownRows\") &&\n !transport.metricCapabilities.shownRows\n )\n throw Error(\"This server does not support shown-row metrics.\");\n if (\n request.profile &&\n transport.metricCapabilities.profile &&\n request.profile !== transport.metricCapabilities.profile\n )\n throw Error(\n \"Metric transport and computed execution profiles do not match. Refresh the handshake.\",\n );\n const remoteFields = new Map(\n context.schema.fields.map((field) => [field.name, field]),\n );\n for (const [name, capability] of Object.entries(\n context.execution?.fields ?? {},\n ))\n if (isComputedField(name))\n remoteFields.set(name, {\n name,\n label: name,\n type: capability.type,\n source: { kind: \"backend\" },\n });\n const remoteSchema = {\n ...context.schema,\n fields: [...remoteFields.values()],\n };\n if (\n matching.some((clause) =>\n [\n ...clause.groupBy,\n ...metricPlans(clause, remoteSchema).flatMap(\n (plan) => plan.dependencies,\n ),\n ].some(isComputedField),\n ) &&\n !transport.metricCapabilities.computedFields\n )\n throw Error(\"This metric server does not support computed fields.\");\n if (\n request.metrics.some(\n (c) =>\n !c.distribution &&\n (c.expression !== undefined || c.expressionY !== undefined),\n ) &&\n !transport.metricCapabilities.expressions\n )\n throw Error(\n \"This server does not support composed metric expressions.\",\n );\n if (\n matching.some(\n (c) =>\n c.distribution &&\n (!c.display || [\"box\", \"histogram\"].includes(c.display.kind)),\n ) &&\n !transport.metricCapabilities.distributions\n )\n throw Error(\"This server does not support distributions.\");\n results.push(...(await transport.fetchMetrics(request, signal)).metrics);\n } else if (transport?.fetchAggregations) {\n const request = toAggregationQuery(scoped, context.schema);\n if (request.diagnostics?.length)\n throw Error(request.diagnostics.map((d) => d.message).join(\" \"));\n results.push(\n ...(await transport.fetchAggregations(request, signal)).metrics,\n );\n } else\n throw Error(\n \"All-matching metrics require a complete client dataset or a metric-capable server transport.\",\n );\n }\n abort(signal);\n const byId = new Map(results.map((r) => [r.id, r]));\n return {\n metrics: clauses.map(\n (c) =>\n byId.get(c.id) ?? {\n id: c.id,\n buckets: [],\n error: \"Server omitted this metric.\",\n },\n ),\n };\n}\n\nfunction loadedPath(row: unknown, path: string): boolean {\n if (!row || typeof row !== \"object\") return false;\n if (path in row) return true;\n let value: unknown = row;\n for (const part of path.split(\".\")) {\n if (value === null) return true;\n if (!value || typeof value !== \"object\" || !(part in value)) return false;\n value = (value as Record<string, unknown>)[part];\n }\n return true;\n}\n","// useSelection — row selection for paged and re-sortable datasets.\n//\n// - Shift-click range select, anchored by ROW ID (not index) so a\n// range survives re-sort / re-filter / paging. Index anchors break the moment\n// the data reorders; id anchors don't.\n// - Indeterminate header checkbox + select-all-on-page.\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { RowId } from \"@pythia-software/query-table-core\";\n\nexport interface SelectionApi {\n selected: Set<RowId>;\n isSelected: (id: RowId) => boolean;\n /** Toggle one row. With `shiftKey`, extend from the last-toggled anchor to `id`\n * across the *currently displayed* order (falls back to a plain toggle if the\n * anchor row is no longer present). */\n toggle: (id: RowId, shiftKey?: boolean) => void;\n /** Select / clear every row currently on the page. */\n setPage: (ids: RowId[], selected: boolean) => void;\n /** Atomically replace the complete selection with arbitrary stable row ids. */\n replace: (ids: Iterable<RowId>) => void;\n /** Atomically retain only selected ids that are also present in `ids`. */\n retain: (ids: Iterable<RowId>) => void;\n /** Header checkbox tri-state for the current page. */\n pageState: (pageIds: RowId[]) => \"none\" | \"some\" | \"all\";\n clear: () => void;\n count: number;\n}\n\n/** `displayedIds` is the page's id list in display order; the hook uses it to\n * resolve shift-ranges and header tri-state against what the user sees. */\nexport function useSelection(displayedIds: RowId[]): SelectionApi {\n const [selected, setSelected] = useState<Set<RowId>>(() => new Set());\n const anchor = useRef<RowId | null>(null);\n\n const toggle = useCallback(\n (id: RowId, shiftKey = false) => {\n setSelected((prev) => {\n const next = new Set(prev);\n const a = anchor.current;\n if (shiftKey && a != null) {\n const i = displayedIds.indexOf(a);\n const j = displayedIds.indexOf(id);\n if (i !== -1 && j !== -1) {\n const [lo, hi] = i <= j ? [i, j] : [j, i];\n const span = displayedIds.slice(lo, hi + 1);\n const allChecked = span.every((rowId) => prev.has(rowId));\n for (const rowId of span) {\n if (allChecked) next.delete(rowId);\n else next.add(rowId);\n }\n anchor.current = id;\n return next;\n }\n }\n if (next.has(id)) next.delete(id);\n else next.add(id);\n anchor.current = id;\n return next;\n });\n },\n [displayedIds],\n );\n\n const setPage = useCallback((ids: RowId[], select: boolean) => {\n setSelected((prev) => {\n const next = new Set(prev);\n for (const id of ids) {\n if (select) next.add(id);\n else next.delete(id);\n }\n return next;\n });\n }, []);\n\n const replace = useCallback((ids: Iterable<RowId>) => {\n const next = new Set(ids);\n anchor.current = null;\n setSelected(next);\n }, []);\n\n const retain = useCallback((ids: Iterable<RowId>) => {\n const allowed = new Set(ids);\n anchor.current = null;\n setSelected((prev) => {\n const next = new Set<RowId>();\n for (const id of prev) if (allowed.has(id)) next.add(id);\n return next;\n });\n }, []);\n\n const pageState = useCallback(\n (pageIds: RowId[]): \"none\" | \"some\" | \"all\" => {\n if (pageIds.length === 0) return \"none\";\n let n = 0;\n for (const id of pageIds) if (selected.has(id)) n++;\n return n === 0 ? \"none\" : n === pageIds.length ? \"all\" : \"some\";\n },\n [selected],\n );\n\n const clear = useCallback(() => {\n anchor.current = null;\n setSelected(new Set());\n }, []);\n\n return useMemo<SelectionApi>(\n () => ({\n selected,\n isSelected: (id) => selected.has(id),\n toggle,\n setPage,\n replace,\n retain,\n pageState,\n clear,\n count: selected.size,\n }),\n [selected, toggle, setPage, replace, retain, pageState, clear],\n );\n}\n","// useSelect — the SELECT list: visible columns, their order, and their widths,\n// all persisted INTO the query (decision #5, so one URL renders identically\n// anywhere). This API mutates QueryState.select; it holds no state of its own.\n// Width changes should be debounced by the caller before they hit the query to\n// avoid flooding history during a drag (useQueryTable does this).\n\nimport { useCallback, useMemo } from \"react\";\nimport type { QueryState, SelectColumn, FieldDef, FieldSchema } from \"@pythia-software/query-table-core\";\nimport { selectedFields } from \"@pythia-software/query-table-core\";\n\nexport interface SelectApi<Row> {\n /** Ordered visible columns (resolved: schema defaults when query.select is empty). */\n visible: SelectColumn[];\n /** The corresponding FieldDefs, same order. */\n fields: FieldDef<Row>[];\n /** Selectable fields not currently shown (for the \"add column\" picker). */\n hidden: FieldDef<Row>[];\n\n show: (field: string) => void;\n hide: (field: string) => void;\n /** Reorder via drag-drop: move `field` to `toIndex` in the visible order. */\n move: (field: string, toIndex: number) => void;\n /** Set a column's pixel width. */\n setWidth: (field: string, width: number) => void;\n /** Reset to the schema's default columns (clears query.select). */\n reset: () => void;\n}\n\ntype SetQuery = (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n\nexport function useSelect<Row>(query: QueryState, setQuery: SetQuery, schema: FieldSchema<Row>): SelectApi<Row> {\n const fields = useMemo(() => selectedFields(schema, query), [schema, query]);\n\n // The materialized SelectColumn[] (resolve defaults so the UI always has a\n // concrete, reorderable list even before the user customizes it).\n const visible = useMemo<SelectColumn[]>(() => fields.map((f) => columnFor(query.select, f.name)), [fields, query.select]);\n\n const hidden = useMemo<FieldDef<Row>[]>(() => {\n const shown = new Set(fields.map((f) => f.name));\n return schema.fields.filter((f) => !shown.has(f.name) && (f.select?.enabled ?? true));\n }, [schema, fields]);\n\n const writeSelect = useCallback(\n (mutate: (cols: SelectColumn[]) => SelectColumn[]) => {\n setQuery((prev) => {\n // Materialize current (resolved) columns the first time we diverge from defaults.\n const current = prev.select.length ? prev.select : visible;\n return { ...prev, select: mutate([...current]) };\n });\n },\n [setQuery, visible],\n );\n\n const show = useCallback((field: string) => writeSelect((c) => (c.some((x) => x.field === field) ? c : [...c, { field }])), [writeSelect]);\n const hide = useCallback((field: string) => writeSelect((c) => c.filter((x) => x.field !== field)), [writeSelect]);\n const move = useCallback(\n (field: string, toIndex: number) =>\n writeSelect((c) => {\n const from = c.findIndex((x) => x.field === field);\n if (from === -1) return c;\n const [item] = c.splice(from, 1);\n c.splice(Math.max(0, Math.min(toIndex, c.length)), 0, item!);\n return c;\n }),\n [writeSelect],\n );\n const setWidth = useCallback(\n (field: string, width: number) =>\n writeSelect((c) => c.map((x) => (x.field === field ? { ...x, width: Math.round(width) } : x))),\n [writeSelect],\n );\n const reset = useCallback(() => setQuery((prev) => ({ ...prev, select: [] })), [setQuery]);\n\n return { visible, fields, hidden, show, hide, move, setWidth, reset };\n}\n\nfunction columnFor(select: SelectColumn[], name: string): SelectColumn {\n const found = select.find((c) => c.field === name);\n return found ?? { field: name };\n}\n","// useColumnDrag — transient, SHARED state for a column-reorder drag. One instance\n// is owned by useQueryTable and read by BOTH the table headers and the\n// QueryBuilder select chips, so a drag started in either surface live-previews\n// (and dims) the same column in the other. It holds no query state; the reorder\n// is committed to QueryState.select by whichever surface handles the drop.\n\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface ColumnDragApi {\n /** Field name currently being dragged, or null when idle. */\n source: string | null;\n /** Insertion index within the order with `source` removed (0..n; n = append). */\n overIndex: number | null;\n /** True while a column drag is in progress. */\n active: boolean;\n /** Changes only for confirmed drops, so surfaces can persist auxiliary positions. */\n dropRevision?: number;\n /** Begin dragging `field` at `index`. Supply the surface order for cross-surface mapping. */\n start: (field: string, index: number, order?: string[]) => void;\n /** Update the insertion slot and optional surface order (no-op if unchanged). */\n over: (index: number, order?: string[]) => void;\n /** End the drag (on drop or cancel). */\n end: (committed?: boolean) => void;\n /** The live order to render while dragging: `source` moved to `overIndex`.\n * Returns `order` unchanged when idle, or when `source` isn't in `order`. */\n preview: (order: string[]) => string[];\n}\n\ninterface DragState {\n source: string;\n overIndex: number;\n order: string[] | undefined;\n moved: boolean;\n}\n\nexport function useColumnDrag(): ColumnDragApi {\n const [state, setState] = useState<DragState | null>(null);\n const [dropRevision, setDropRevision] = useState(0);\n\n const start = useCallback(\n (field: string, index: number, order?: string[]) =>\n setState({\n source: field,\n overIndex: index,\n order: order?.slice(),\n moved: false,\n }),\n [],\n );\n const over = useCallback(\n (index: number, order?: string[]) =>\n // Keep the SAME object reference when unchanged so React can bail out of the\n // re-render — onDragOver fires continuously while the cursor moves.\n setState((s) => {\n if (!s) return s;\n if (\n s.moved &&\n s.overIndex === index &&\n ((!order && !s.order) ||\n (order &&\n s.order &&\n order.length === s.order.length &&\n order.every((name, i) => name === s.order![i])))\n )\n return s;\n return {\n source: s.source,\n overIndex: index,\n order: order?.slice(),\n moved: true,\n };\n }),\n [],\n );\n const end = useCallback((committed = false) => {\n if (committed) setDropRevision((revision) => revision + 1);\n setState(null);\n }, []);\n\n const preview = useCallback(\n (order: string[]): string[] => {\n if (!state || (state.order && !state.moved)) return order;\n const without = order.filter((n) => n !== state.source);\n if (without.length === order.length) return order; // source not part of this list\n let at = Math.max(0, Math.min(state.overIndex, without.length));\n if (state.order) {\n // Surfaces can contain different auxiliary columns (e.g. selection).\n // Resolve the slot against shared neighboring fields, not raw indices.\n const reference = state.order.filter((name) => name !== state.source);\n const slot = Math.max(0, Math.min(state.overIndex, reference.length));\n const following = reference\n .slice(slot)\n .find((name) => without.includes(name));\n const preceding = reference\n .slice(0, slot)\n .reverse()\n .find((name) => without.includes(name));\n if (following != null) at = without.indexOf(following);\n else if (preceding != null) at = without.indexOf(preceding) + 1;\n }\n return [...without.slice(0, at), state.source, ...without.slice(at)];\n },\n [state],\n );\n\n return useMemo(\n () => ({\n source: state?.source ?? null,\n overIndex: state?.overIndex ?? null,\n active: state != null,\n dropRevision,\n start,\n over,\n end,\n preview,\n }),\n [state, dropRevision, start, over, end, preview],\n );\n}\n","// useSavedQueries — named query snapshots over a StorageAdapter.\n//\n// \"Last query\" auto-restore and named saves both flow through the injected\n// StorageAdapter (in-memory by default, explicitly durable when the caller\n// provides one). Loading a saved query pushes its QueryState into the controller.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { QueryState, SavedQuery, StorageAdapter } from \"@pythia-software/query-table-core\";\n\nexport interface SavedQueriesApi {\n items: SavedQuery[];\n loading: boolean;\n /** Saved query id used as the default view when no query is specified. */\n defaultId: string | null;\n /** Persist the current query under a name. Rejects on duplicate names. */\n save: (name: string) => Promise<SavedQuery>;\n /** Load a saved query into the live controller. */\n load: (id: string) => void;\n /** Mark a saved query as the default view. No-op when storage lacks support. */\n setDefault: (id: string) => Promise<void>;\n /** Clear the saved-query default view. */\n clearDefault: () => Promise<void>;\n remove: (id: string) => Promise<void>;\n}\n\nexport function useSavedQueries(\n key: string,\n currentQuery: QueryState,\n applyQueryState: (q: QueryState) => void,\n storage: StorageAdapter,\n /** Injected clock so saves are deterministic/testable. */\n now: () => number,\n): SavedQueriesApi {\n const [items, setItems] = useState<SavedQuery[]>([]);\n const [defaultId, setDefaultId] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const [savedItems, defaultSaved] = await Promise.all([\n storage.listSaved(key),\n storage.loadDefaultSaved?.(key) ?? Promise.resolve(null),\n ]);\n setItems(savedItems);\n setDefaultId(defaultSaved?.id ?? null);\n } finally {\n setLoading(false);\n }\n }, [storage, key]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const save = useCallback(\n async (name: string) => {\n const saved = await storage.saveNamed(key, name, currentQuery, now());\n await refresh();\n return saved;\n },\n [storage, key, currentQuery, now, refresh],\n );\n\n const load = useCallback(\n (id: string) => {\n const found = items.find((q) => q.id === id);\n if (found) applyQueryState(found.query);\n },\n [items, applyQueryState],\n );\n\n const setDefault = useCallback(\n async (id: string) => {\n await storage.setDefaultSaved?.(key, id);\n await refresh();\n },\n [storage, key, refresh],\n );\n\n const clearDefault = useCallback(async () => {\n await storage.setDefaultSaved?.(key, null);\n await refresh();\n }, [storage, key, refresh]);\n\n const remove = useCallback(\n async (id: string) => {\n if (id === defaultId) await storage.setDefaultSaved?.(key, null);\n await storage.deleteSaved(key, id);\n await refresh();\n },\n [storage, key, defaultId, refresh],\n );\n\n return { items, loading, defaultId, save, load, setDefault, clearDefault, remove };\n}\n"],"mappings":"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","names":["isComputedField","readFieldValue","abort","isComputedField","f","readFieldValue","useCallback","useEffect","useMemo","useRef","useState","applyQuery","normalizeQueryState","readFieldValue","selectedFields","toServerQuery","metricPlans","validateMetric","isComputedField","useCallback","useEffect","useMemo","useRef","useState","abort","useCallback","useEffect","useMemo","useRef","useState","metricPlans","hasRegex","hasRegex","readFieldValue","isComputedField","isComputedField","hasRegex","values","readFieldValue","useState","useRef","useCallback","metricPlans","hasRegex","useMemo","useEffect","useCallback","useMemo","useRef","useState","useCallback","useMemo","useCallback","useMemo","useState","useCallback","useEffect","useState","normalizeQueryState","readFieldValue","useMemo","useRef","useState","useEffect","useCallback","isComputedField","validateMetric","metricPlans","toServerQuery","applyQuery","patch","selectedFields"]}