@deepagents/text2sql 6.1.2 → 7.0.1
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/README.md +16 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/lib/adapters/bigquery/index.js +87 -7
- package/dist/lib/adapters/bigquery/index.js.map +3 -3
- package/dist/lib/adapters/clickhouse/index.js +1 -1
- package/dist/lib/adapters/clickhouse/index.js.map +2 -2
- package/dist/lib/adapters/duckdb/duckdb-identifiers.d.ts +8 -0
- package/dist/lib/adapters/duckdb/duckdb-identifiers.d.ts.map +1 -0
- package/dist/lib/adapters/duckdb/duckdb.d.ts +40 -0
- package/dist/lib/adapters/duckdb/duckdb.d.ts.map +1 -0
- package/dist/lib/adapters/duckdb/duckdb.groundings.d.ts +58 -0
- package/dist/lib/adapters/duckdb/duckdb.groundings.d.ts.map +1 -0
- package/dist/lib/adapters/duckdb/duckdb.sql-policy.d.ts +8 -0
- package/dist/lib/adapters/duckdb/duckdb.sql-policy.d.ts.map +1 -0
- package/dist/lib/adapters/duckdb/index.d.ts +34 -0
- package/dist/lib/adapters/duckdb/index.d.ts.map +1 -0
- package/dist/lib/adapters/duckdb/index.js +1933 -0
- package/dist/lib/adapters/duckdb/index.js.map +7 -0
- package/dist/lib/adapters/mysql/index.js +87 -7
- package/dist/lib/adapters/mysql/index.js.map +3 -3
- package/dist/lib/adapters/parser-sql-policy.d.ts.map +1 -1
- package/dist/lib/adapters/postgres/index.js +87 -7
- package/dist/lib/adapters/postgres/index.js.map +3 -3
- package/dist/lib/adapters/postgres/postgres-parser-workaround.d.ts +8 -0
- package/dist/lib/adapters/postgres/postgres-parser-workaround.d.ts.map +1 -0
- package/dist/lib/adapters/posthog/index.js +1 -1
- package/dist/lib/adapters/posthog/index.js.map +2 -2
- package/dist/lib/adapters/spreadsheet/index.js +87 -7
- package/dist/lib/adapters/spreadsheet/index.js.map +3 -3
- package/dist/lib/adapters/sqlite/index.js +87 -7
- package/dist/lib/adapters/sqlite/index.js.map +3 -3
- package/dist/lib/adapters/sqlserver/index.js +87 -7
- package/dist/lib/adapters/sqlserver/index.js.map +3 -3
- package/dist/lib/agents/question.agent.d.ts.map +1 -1
- package/dist/lib/synthesis/extractors/base-contextual-extractor.d.ts.map +1 -1
- package/dist/lib/synthesis/index.js.map +2 -2
- package/package.json +18 -19
|
@@ -398,7 +398,7 @@ var Adapter = class {
|
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
400
|
#decodeShellEscapes(sql) {
|
|
401
|
-
return sql.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\([()
|
|
401
|
+
return sql.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\([().*$])/g, "$1").replace(/\\(?=$)/gm, "");
|
|
402
402
|
}
|
|
403
403
|
#cachedAllowedEntities = null;
|
|
404
404
|
async #resolveScope() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/adapters/adapter.ts", "../../../../src/lib/agents/exceptions.ts", "../../../../src/lib/fragments/schema.ts", "../../../../src/lib/adapters/groundings/context.ts", "../../../../src/lib/sql-scope-error.ts", "../../../../src/lib/adapters/clickhouse/clickhouse.sql-policy.ts", "../../../../src/lib/adapters/clickhouse/clickhouse.ts", "../../../../src/lib/adapters/groundings/abstract.grounding.ts", "../../../../src/lib/adapters/groundings/constraint.grounding.ts", "../../../../src/lib/adapters/clickhouse/constraint.clickhouse.grounding.ts", "../../../../src/lib/adapters/groundings/indexes.grounding.ts", "../../../../src/lib/adapters/clickhouse/indexes.clickhouse.grounding.ts", "../../../../src/lib/adapters/groundings/info.grounding.ts", "../../../../src/lib/adapters/clickhouse/info.clickhouse.grounding.ts", "../../../../src/lib/adapters/groundings/row-count.grounding.ts", "../../../../src/lib/adapters/clickhouse/row-count.clickhouse.grounding.ts", "../../../../src/lib/adapters/groundings/table.grounding.ts", "../../../../src/lib/adapters/clickhouse/table.clickhouse.grounding.ts", "../../../../src/lib/adapters/groundings/view.grounding.ts", "../../../../src/lib/adapters/clickhouse/view.clickhouse.grounding.ts", "../../../../src/lib/adapters/clickhouse/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { type SqlLanguage, format as formatSql } from 'sql-formatter';\n\nimport type { ContextFragment, FragmentObject } from '@deepagents/context';\n\nimport { SQLReadOnlyError, SQLScopeError } from '../agents/exceptions.ts';\nimport {\n column,\n constraint,\n dialectInfo,\n index,\n relationship,\n table,\n view,\n} from '../fragments/schema.ts';\nimport type { AbstractGrounding } from './groundings/abstract.grounding.ts';\nimport {\n type GroundingContext,\n createGroundingContext,\n} from './groundings/context.ts';\nimport type { View } from './groundings/view.grounding.ts';\nimport {\n type SqlPolicyAnalyzer,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport {\n type SqlPolicyAnalyzer,\n type SqlPolicyContext,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\n/**\n * Filter type for view/table names.\n * - string[]: explicit list of view names\n * - RegExp: pattern to match view names\n * - function: predicate to filter view names\n */\nexport type Filter = string[] | RegExp | ((viewName: string) => boolean);\n\nexport interface Table {\n name: string;\n schema?: string;\n rawName?: string;\n columns: {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n isIndexed?: boolean;\n stats?: ColumnStats;\n }[];\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n indexes?: TableIndex[];\n constraints?: TableConstraint[];\n}\n\nexport interface TableIndex {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}\n\nexport interface TableConstraint {\n name: string;\n type:\n 'CHECK' | 'UNIQUE' | 'NOT_NULL' | 'DEFAULT' | 'PRIMARY_KEY' | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}\n\nexport interface ColumnStats {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n}\n\nexport type Relationship = {\n table: string;\n from: string[];\n referenced_table: string;\n to: string[];\n};\n\nexport type TablesFilter = string[] | RegExp;\n\nexport interface Introspection {\n tables: Table[];\n relationships: Relationship[];\n}\n\nexport interface AdapterInfo {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}\n\nexport type AdapterInfoProvider =\n AdapterInfo | (() => Promise<AdapterInfo> | AdapterInfo);\n\nexport type IntrospectionPhase =\n | 'info'\n | 'tables'\n | 'views'\n | 'row_counts'\n | 'constraints'\n | 'indexes'\n | 'column_stats'\n | 'column_values'\n | 'low_cardinality'\n | 'relationships'\n | 'definitions';\n\nexport type IntrospectionProgressType =\n 'phase:start' | 'phase:progress' | 'phase:end';\n\nexport interface IntrospectionProgress {\n type: IntrospectionProgressType;\n phase: IntrospectionPhase;\n message: string;\n table?: string;\n current?: number;\n total?: number;\n timestampMs?: number;\n}\n\nexport type OnProgress = (progress: IntrospectionProgress) => void;\n\nexport type GroundingFn = (adapter: Adapter) => AbstractGrounding;\n\nexport type ExecuteFunction = (sql: string) => Promise<any> | any;\nexport type ValidateFunction = (\n sql: string,\n) => Promise<string | void> | string | void;\n\nexport abstract class Adapter {\n readonly #policyAnalyzer: SqlPolicyAnalyzer;\n\n /**\n * Injects the strategy that guards validate() and execute().\n */\n protected constructor(policyAnalyzer: SqlPolicyAnalyzer) {\n this.#policyAnalyzer = policyAnalyzer;\n }\n\n abstract grounding: GroundingFn[];\n\n abstract readonly formatterLanguage: SqlLanguage;\n\n /**\n * Default schema name for this database.\n * PostgreSQL: 'public', SQL Server: 'dbo', SQLite: undefined\n */\n abstract readonly defaultSchema: string | undefined;\n\n /**\n * System schemas to exclude from introspection by default.\n */\n abstract readonly systemSchemas: string[];\n\n /**\n * Introspect the database schema and return context fragments.\n *\n * Executes all configured groundings to populate the context, then\n * generates fragments from the complete context data.\n *\n * @param ctx - Optional grounding context for sharing state between groundings\n * @returns Array of context fragments representing the database schema\n */\n async introspect(ctx = createGroundingContext()): Promise<ContextFragment[]> {\n // Phase 1: All groundings populate ctx\n for (const fn of this.grounding) {\n const grounding = fn(this);\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:start',\n phase: grounding.phase,\n message: `Starting ${grounding.name} introspection...`,\n });\n }\n try {\n await grounding.execute(ctx);\n } finally {\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:end',\n phase: grounding.phase,\n message: `Finished ${grounding.name} introspection.`,\n });\n }\n }\n }\n\n // Phase 2: Generate fragments from complete ctx\n return this.#toSchemaFragments(ctx);\n }\n\n /**\n * Resolve the allowed entity names (tables + views) from grounding config.\n * Asks each grounding to contribute its entities; annotators contribute\n * nothing, so their metadata scans are skipped.\n * Results are NOT cached \u2014 call once and store the result.\n */\n async resolveAllowedEntities(): Promise<string[]> {\n const ctx = createGroundingContext();\n for (const fn of this.grounding) {\n await fn(this).contributeEntities(ctx);\n }\n return [...ctx.tables.map((t) => t.name), ...ctx.views.map((v) => v.name)];\n }\n\n /**\n * Convert complete grounding context to schema fragments.\n * Called after all groundings have populated ctx with data.\n */\n #toSchemaFragments(ctx: GroundingContext): ContextFragment[] {\n const fragments: ContextFragment[] = [];\n\n // Dialect info\n if (ctx.info) {\n fragments.push(\n dialectInfo({\n dialect: ctx.info.dialect,\n version: ctx.info.version,\n database: ctx.info.database,\n details: ctx.info.details,\n }),\n );\n }\n\n // Tables (with all annotations now included)\n for (const t of ctx.tables) {\n fragments.push(this.#tableToFragment(t));\n }\n\n // Views\n for (const v of ctx.views) {\n fragments.push(this.#viewToFragment(v));\n }\n\n // Relationships \u2014 filter out FK columns that were removed by column restriction\n const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));\n const tableColumnSets = new Map(\n ctx.tables.map((t) => [t.name, new Set(t.columns.map((c) => c.name))]),\n );\n for (const rel of ctx.relationships) {\n const sourceColumns = tableColumnSets.get(rel.table);\n const targetColumns = tableColumnSets.get(rel.referenced_table);\n if (\n sourceColumns &&\n rel.from.some((column) => !sourceColumns.has(column))\n ) {\n continue;\n }\n if (\n targetColumns &&\n rel.to.some((column) => !targetColumns.has(column))\n ) {\n continue;\n }\n\n const sourceTable = tableMap.get(rel.table);\n const targetTable = tableMap.get(rel.referenced_table);\n fragments.push(\n this.#relationshipToFragment(rel, sourceTable, targetTable),\n );\n }\n\n fragments.push(...(ctx.fragments ?? []));\n\n return fragments;\n }\n\n /**\n * Convert a Table to a table fragment with nested column, index, and constraint fragments.\n */\n #tableToFragment(t: Table): ContextFragment {\n // Build constraint lookup maps for column-level annotations\n const pkConstraint = t.constraints?.find((c) => c.type === 'PRIMARY_KEY');\n const pkColumns = new Set(pkConstraint?.columns ?? []);\n\n const notNullColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'NOT_NULL')\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n const defaultByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'DEFAULT') ?? []) {\n for (const col of c.columns ?? []) {\n if (c.defaultValue != null) {\n defaultByColumn.set(col, c.defaultValue);\n }\n }\n }\n\n // Single-column UNIQUE constraints\n const uniqueColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'UNIQUE' && c.columns?.length === 1)\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n // Foreign key lookup: column -> referenced table.column\n const fkByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'FOREIGN_KEY') ??\n []) {\n const cols = c.columns ?? [];\n const refCols = c.referencedColumns ?? [];\n for (let i = 0; i < cols.length; i++) {\n const refCol = refCols[i] ?? refCols[0] ?? cols[i];\n fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);\n }\n }\n\n // Build column fragments\n const columnFragments = t.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n pk: pkColumns.has(col.name) || undefined,\n fk: fkByColumn.get(col.name),\n unique: uniqueColumns.has(col.name) || undefined,\n notNull: notNullColumns.has(col.name) || undefined,\n default: defaultByColumn.get(col.name),\n indexed: col.isIndexed || undefined,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n // Set of present column names for cascade-cleaning indexes/constraints\n const presentColumns = new Set(t.columns.map((c) => c.name));\n\n // Build index fragments\n const indexFragments = (t.indexes ?? [])\n .filter((idx) =>\n idx.columns.every((column) => presentColumns.has(column)),\n )\n .map((idx) =>\n index({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n type: idx.type,\n }),\n );\n\n // Build constraint fragments for multi-column UNIQUE and CHECK constraints\n const constraintFragments = (t.constraints ?? [])\n .filter(\n (c) =>\n c.type === 'CHECK' ||\n (c.type === 'UNIQUE' && (c.columns?.length ?? 0) > 1),\n )\n .filter(\n (c) =>\n !c.columns?.length ||\n c.columns.every((column) => presentColumns.has(column)),\n )\n .map((c) =>\n constraint({\n name: c.name,\n type: c.type,\n columns: c.columns,\n definition: c.definition,\n }),\n );\n\n return table({\n name: t.name,\n schema: t.schema,\n rowCount: t.rowCount,\n sizeHint: t.sizeHint,\n columns: columnFragments,\n indexes: indexFragments.length > 0 ? indexFragments : undefined,\n constraints:\n constraintFragments.length > 0 ? constraintFragments : undefined,\n });\n }\n\n /**\n * Convert a View to a view fragment with nested column fragments.\n */\n #viewToFragment(v: View): ContextFragment {\n const columnFragments = v.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n return view({\n name: v.name,\n schema: v.schema,\n columns: columnFragments,\n definition: v.definition,\n });\n }\n\n /**\n * Convert a Relationship to a relationship fragment.\n * Infers cardinality from row counts if available.\n */\n #relationshipToFragment(\n rel: Relationship,\n sourceTable?: Table,\n targetTable?: Table,\n ): ContextFragment {\n const sourceCount = sourceTable?.rowCount;\n const targetCount = targetTable?.rowCount;\n\n let cardinality:\n 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many' | undefined;\n\n if (sourceCount != null && targetCount != null && targetCount > 0) {\n const ratio = sourceCount / targetCount;\n if (ratio > 5) {\n cardinality = 'many-to-one';\n } else if (ratio < 1.2 && ratio > 0.8) {\n cardinality = 'one-to-one';\n } else if (ratio < 0.2) {\n cardinality = 'one-to-many';\n }\n }\n\n return relationship({\n from: { table: rel.table, columns: rel.from },\n to: { table: rel.referenced_table, columns: rel.to },\n cardinality,\n });\n }\n format(sql: string): string {\n const decoded = this.#decodeShellEscapes(sql);\n try {\n return formatSql(decoded, { language: this.formatterLanguage });\n } catch {\n return decoded;\n }\n }\n\n #decodeShellEscapes(sql: string): string {\n return sql\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([().*])/g, '$1')\n .replace(/\\\\(?=$)/gm, '');\n }\n\n #cachedAllowedEntities: string[] | null = null;\n\n async #resolveScope(): Promise<string[]> {\n if (this.#cachedAllowedEntities) return this.#cachedAllowedEntities;\n this.#cachedAllowedEntities = await this.resolveAllowedEntities();\n return this.#cachedAllowedEntities;\n }\n\n async #analyzePolicy(sql: string): Promise<SqlPolicyViolation | null> {\n return this.#policyAnalyzer.analyze(sql, {\n resolveAllowedEntities: () => this.#resolveScope(),\n });\n }\n\n async validate(sql: string): Promise<string | void> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') return violation.message;\n if (violation?.kind === 'scope') return JSON.stringify(violation.payload);\n return this.validateImpl(decoded);\n }\n\n async execute(sql: string): Promise<any[]> {\n return this.executeImpl(await this.enforceExecutionPolicy(sql));\n }\n\n protected async enforceExecutionPolicy(sql: string): Promise<string> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') {\n throw new SQLReadOnlyError(violation.message);\n }\n if (violation?.kind === 'scope') {\n throw new SQLScopeError(violation.payload);\n }\n return decoded;\n }\n\n abstract executeImpl(sql: string): Promise<any[]> | any[];\n abstract validateImpl(sql: string): Promise<string | void> | string | void;\n abstract runQuery<Row>(sql: string): Promise<Row[]> | Row[];\n\n /**\n * Quote an identifier (table/column name) for safe use in SQL.\n * Each database uses different quoting styles.\n */\n abstract quoteIdentifier(name: string): string;\n\n /**\n * Escape a string value for safe use in SQL.\n * Each database escapes different characters.\n */\n abstract escape(value: string): string;\n\n /**\n * Build a SELECT query to sample rows from a table.\n * Each database uses different syntax for limiting rows (LIMIT vs TOP).\n */\n abstract buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string;\n\n /**\n * Convert unknown database value to number.\n * Handles number, bigint, and string types.\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'bigint') {\n return Number(value);\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n }\n\n /**\n * Parse a potentially qualified table name into schema and table parts.\n */\n parseTableName(name: string): { schema: string; table: string } {\n if (name.includes('.')) {\n const [schema, ...rest] = name.split('.');\n return { schema, table: rest.join('.') };\n }\n return { schema: this.defaultSchema ?? '', table: name };\n }\n\n /**\n * Escape a string value for use in SQL string literals (single quotes).\n * Used in WHERE clauses like: WHERE name = '${escapeString(value)}'\n */\n escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n /**\n * Build a SQL filter clause to include/exclude schemas.\n * @param columnName - The schema column name (e.g., 'TABLE_SCHEMA')\n * @param allowedSchemas - If provided, filter to these schemas only\n */\n buildSchemaFilter(columnName: string, allowedSchemas?: string[]): string {\n if (allowedSchemas && allowedSchemas.length > 0) {\n const values = allowedSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} IN (${values})`;\n }\n if (this.systemSchemas.length > 0) {\n const values = this.systemSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} NOT IN (${values})`;\n }\n return '';\n }\n}\n\nexport function filterTablesByName<T extends { name: string }>(\n tables: T[],\n filter: TablesFilter | undefined,\n): T[] {\n if (!filter) return tables;\n return tables.filter((table) => matchesFilter(table.name, filter));\n}\n\nexport function filterRelationshipsByTables(\n relationships: Relationship[],\n tableNames: Set<string> | undefined,\n): Relationship[] {\n if (tableNames === undefined) {\n return relationships;\n }\n if (tableNames.size === 0) {\n return [];\n }\n return relationships.filter(\n (it) => tableNames.has(it.table) || tableNames.has(it.referenced_table),\n );\n}\n\nexport function applyTablesFilter(\n tables: Table[],\n relationships: Relationship[],\n filter: TablesFilter | undefined,\n): { tables: Table[]; relationships: Relationship[] } {\n if (!filter) {\n return { tables, relationships };\n }\n\n const allowedNames = new Set(\n getTablesWithRelated(tables, relationships, filter),\n );\n\n return {\n tables: tables.filter((table) => allowedNames.has(table.name)),\n relationships: filterRelationshipsByTables(relationships, allowedNames),\n };\n}\n\nexport function matchesFilter(\n tableName: string,\n filter: TablesFilter,\n): boolean {\n if (Array.isArray(filter)) {\n return filter.includes(tableName);\n }\n return filter.test(tableName);\n}\n\nexport function getTablesWithRelated(\n allTables: Table[],\n relationships: Relationship[],\n filter: TablesFilter,\n): string[] {\n const matchedTables = filterTablesByName(allTables, filter).map(\n (it) => it.name,\n );\n\n if (matchedTables.length === 0) {\n return [];\n }\n\n const adjacency = new Map<string, Set<string>>();\n\n for (const rel of relationships) {\n if (!adjacency.has(rel.table)) {\n adjacency.set(rel.table, new Set());\n }\n if (!adjacency.has(rel.referenced_table)) {\n adjacency.set(rel.referenced_table, new Set());\n }\n adjacency.get(rel.table)!.add(rel.referenced_table);\n adjacency.get(rel.referenced_table)!.add(rel.table);\n }\n\n const result = new Set<string>(matchedTables);\n const queue = [...matchedTables];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const neighbors = adjacency.get(current);\n\n if (!neighbors) {\n continue;\n }\n\n for (const neighbor of neighbors) {\n if (!result.has(neighbor)) {\n result.add(neighbor);\n queue.push(neighbor);\n }\n }\n }\n\n return Array.from(result);\n}\n", "const sqlValidationMarker = Symbol('SQLValidationError');\nconst unanswerableSqlMarker = Symbol('UnanswerableSQLError');\nconst sqlScopeMarker = Symbol('SQLScopeError');\nconst sqlReadOnlyMarker = Symbol('SQLReadOnlyError');\n\nexport type SQLScopeErrorType = 'OUT_OF_SCOPE' | 'SQL_SCOPE_PARSE_ERROR';\n\nexport interface SQLScopeErrorPayload {\n error: string;\n error_type: SQLScopeErrorType;\n suggestion: string;\n sql_attempted: string;\n referenced_entities?: string[];\n allowed_entities?: string[];\n parser_dialect?: string;\n parser_error?: string;\n}\n\n/**\n * Error thrown when SQL validation fails.\n */\nexport class SQLValidationError extends Error {\n [sqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLValidationError';\n this[sqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLValidationError {\n return (\n error instanceof SQLValidationError && error[sqlValidationMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when the question cannot be answered with the given schema.\n */\nexport class UnanswerableSQLError extends Error {\n [unanswerableSqlMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'UnanswerableSQLError';\n this[unanswerableSqlMarker] = true;\n }\n\n static isInstance(error: unknown): error is UnanswerableSQLError {\n return (\n error instanceof UnanswerableSQLError &&\n error[unanswerableSqlMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when a query falls outside the grounded SQL scope.\n */\nexport class SQLScopeError extends Error {\n [sqlScopeMarker]: true;\n readonly payload: SQLScopeErrorPayload;\n readonly errorType: SQLScopeErrorType;\n\n constructor(payload: SQLScopeErrorPayload) {\n super(JSON.stringify(payload));\n this.name = 'SQLScopeError';\n this.payload = payload;\n this.errorType = payload.error_type;\n this[sqlScopeMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLScopeError {\n return error instanceof SQLScopeError && error[sqlScopeMarker] === true;\n }\n}\n\n/**\n * Error thrown when a query is not read-only (does not start with SELECT or WITH).\n */\nexport class SQLReadOnlyError extends Error {\n [sqlReadOnlyMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLReadOnlyError';\n this[sqlReadOnlyMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLReadOnlyError {\n return (\n error instanceof SQLReadOnlyError && error[sqlReadOnlyMarker] === true\n );\n }\n}\n", "import type { ContextFragment, FragmentObject } from '@deepagents/context';\n\n/**\n * Schema fragment builders.\n *\n * These fragments represent database schema metadata that can be injected\n * into AI prompts. Use with renderers (XML, Markdown, TOML, TOON) to format.\n *\n * @example\n * ```ts\n * import { dialectInfo, table, column, relationship } from '@deepagents/text2sql';\n *\n * const schemaFragments = [\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5' }),\n * table({\n * name: 'users',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true }),\n * ],\n * }),\n * ];\n * ```\n */\n\n/**\n * Database dialect and version information.\n *\n * @param input.dialect - Database type (PostgreSQL, SQLite, SQL Server, etc.)\n * @param input.version - Database version string\n * @param input.database - Database name\n *\n * @example\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5', database: 'myapp' })\n */\nexport function dialectInfo(input: {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}): ContextFragment {\n return {\n name: 'dialectInfo',\n data: {\n dialect: input.dialect,\n ...(input.version && { version: input.version }),\n ...(input.database && { database: input.database }),\n ...(input.details && { details: input.details }),\n },\n };\n}\n\n/**\n * Database table with columns and optional metadata.\n *\n * @param input.name - Table name\n * @param input.schema - Schema name (e.g., 'public' for PostgreSQL)\n * @param input.rowCount - Approximate row count\n * @param input.sizeHint - Size category for query optimization hints\n * @param input.columns - Array of column() fragments\n * @param input.indexes - Array of index() fragments\n * @param input.constraints - Array of constraint() fragments\n *\n * @example\n * table({\n * name: 'users',\n * rowCount: 1500,\n * sizeHint: 'medium',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true, indexed: true }),\n * ],\n * indexes: [\n * index({ name: 'idx_email', columns: ['email'], unique: true }),\n * ],\n * })\n */\nexport function table(input: {\n name: string;\n schema?: string;\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n columns: ContextFragment[];\n indexes?: ContextFragment[];\n constraints?: ContextFragment[];\n}): ContextFragment {\n return {\n name: 'table',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n ...(input.rowCount != null && { rowCount: input.rowCount }),\n ...(input.sizeHint && { sizeHint: input.sizeHint }),\n columns: input.columns,\n ...(input.indexes?.length && { indexes: input.indexes }),\n ...(input.constraints?.length && { constraints: input.constraints }),\n },\n };\n}\n\n/**\n * Table column with type and annotations.\n *\n * @param input.name - Column name\n * @param input.type - Column data type (e.g., 'integer', 'varchar(255)')\n * @param input.pk - Is primary key\n * @param input.fk - Foreign key reference in \"table.column\" format\n * @param input.unique - Has unique constraint\n * @param input.notNull - Has NOT NULL constraint\n * @param input.default - Default value expression\n * @param input.indexed - Has index on this column\n * @param input.values - Enum or low cardinality values\n * @param input.stats - Column statistics (min, max, null fraction)\n *\n * @example\n * column({\n * name: 'status',\n * type: 'varchar',\n * notNull: true,\n * indexed: true,\n * values: ['active', 'inactive', 'suspended'],\n * })\n */\nexport function column(input: {\n name: string;\n type: string;\n pk?: boolean;\n fk?: string;\n unique?: boolean;\n notNull?: boolean;\n default?: string;\n indexed?: boolean;\n values?: string[];\n stats?: {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n };\n}): ContextFragment {\n return {\n name: 'column',\n data: {\n name: input.name,\n type: input.type,\n ...(input.pk && { pk: true }),\n ...(input.fk && { fk: input.fk }),\n ...(input.unique && { unique: true }),\n ...(input.notNull && { notNull: true }),\n ...(input.default && { default: input.default }),\n ...(input.indexed && { indexed: true }),\n ...(input.values?.length && { values: input.values }),\n ...(input.stats && { stats: input.stats }),\n },\n };\n}\n\n/**\n * Table index.\n *\n * @param input.name - Index name\n * @param input.columns - Columns included in the index\n * @param input.unique - Is unique index\n * @param input.type - Index type (BTREE, HASH, GIN, etc.)\n *\n * @example\n * index({ name: 'idx_user_email', columns: ['email'], unique: true, type: 'BTREE' })\n */\nexport function index(input: {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}): ContextFragment {\n return {\n name: 'index',\n data: {\n name: input.name,\n columns: input.columns,\n ...(input.unique && { unique: true }),\n ...(input.type && { type: input.type }),\n },\n };\n}\n\n/**\n * Table constraint (CHECK, UNIQUE, PRIMARY_KEY, FOREIGN_KEY, etc).\n *\n * @param input.name - Constraint name\n * @param input.type - Constraint type\n * @param input.columns - Columns involved in the constraint\n * @param input.definition - CHECK constraint SQL definition\n * @param input.defaultValue - DEFAULT constraint value\n * @param input.referencedTable - For FK: referenced table name\n * @param input.referencedColumns - For FK: referenced column names\n *\n * @example\n * constraint({\n * name: 'chk_amount_positive',\n * type: 'CHECK',\n * definition: 'amount > 0',\n * })\n *\n * @example\n * constraint({\n * name: 'fk_order_user',\n * type: 'FOREIGN_KEY',\n * columns: ['user_id'],\n * referencedTable: 'users',\n * referencedColumns: ['id'],\n * })\n */\nexport function constraint(input: {\n name: string;\n type:\n | 'CHECK'\n | 'UNIQUE'\n | 'NOT_NULL'\n | 'DEFAULT'\n | 'PRIMARY_KEY'\n | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}): ContextFragment {\n return {\n name: 'constraint',\n data: {\n name: input.name,\n type: input.type,\n ...(input.columns?.length && { columns: input.columns }),\n ...(input.definition && { definition: input.definition }),\n ...(input.defaultValue && { defaultValue: input.defaultValue }),\n ...(input.referencedTable && { referencedTable: input.referencedTable }),\n ...(input.referencedColumns?.length && {\n referencedColumns: input.referencedColumns,\n }),\n },\n };\n}\n\n/**\n * Database view.\n *\n * @param input.name - View name\n * @param input.schema - Schema name\n * @param input.columns - Array of column() fragments\n * @param input.definition - View SQL definition\n *\n * @example\n * view({\n * name: 'active_users',\n * columns: [\n * column({ name: 'id', type: 'integer' }),\n * column({ name: 'email', type: 'varchar' }),\n * ],\n * definition: \"SELECT id, email FROM users WHERE status = 'active'\",\n * })\n */\nexport function view(input: {\n name: string;\n schema?: string;\n columns: ContextFragment[];\n definition?: string;\n}): ContextFragment {\n return {\n name: 'view',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n columns: input.columns,\n ...(input.definition && { definition: input.definition }),\n },\n };\n}\n\n/**\n * Relationship between tables (foreign key connection).\n *\n * @param input.from - Source table and columns\n * @param input.to - Referenced table and columns\n * @param input.cardinality - Relationship cardinality\n *\n * @example\n * relationship({\n * from: { table: 'orders', columns: ['user_id'] },\n * to: { table: 'users', columns: ['id'] },\n * cardinality: 'many-to-one',\n * })\n */\nexport function relationship(input: {\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n cardinality?: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';\n}): ContextFragment {\n return {\n name: 'relationship',\n data: {\n from: input.from,\n to: input.to,\n ...(input.cardinality && { cardinality: input.cardinality }),\n },\n };\n}\n", "import type { ContextFragment } from '@deepagents/context';\n\nimport type {\n AdapterInfo,\n ColumnStats,\n OnProgress,\n Relationship,\n Table,\n} from '../adapter.ts';\nimport type { View } from './view.grounding.ts';\n\n/**\n * Column type for grounding operations.\n * Common interface between Table.columns and View.columns.\n */\nexport interface Column {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n stats?: ColumnStats;\n}\n\n/**\n * Entity with columns (Table or View).\n */\nexport interface ColumnContainer {\n name: string;\n columns: Column[];\n}\n\n/**\n * Shared context object passed to all groundings.\n * Groundings read from and write to this context.\n */\nexport interface GroundingContext {\n /** Tables discovered by TableGrounding */\n tables: Table[];\n\n /** Views discovered by ViewGrounding */\n views: View[];\n\n /** Relationships discovered by TableGrounding */\n relationships: Relationship[];\n\n /** Database info collected by InfoGrounding */\n info?: AdapterInfo;\n\n /** Adapter-specific fragments contributed during grounding. */\n fragments?: ContextFragment[];\n\n /** Shared cache for cross-grounding deduplication. Keyed by `type:key`. */\n cache: Map<string, unknown>;\n\n /** Progress sink for long-running introspection work. */\n onProgress: OnProgress;\n}\n\nconst noopProgress: OnProgress = () => {};\n\nfunction timestampProgress(onProgress?: OnProgress): OnProgress {\n if (!onProgress) return noopProgress;\n return (progress) => {\n onProgress({\n ...progress,\n timestampMs: progress.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Create a new empty grounding context.\n */\nexport function createGroundingContext(\n options: { onProgress?: OnProgress } = {},\n): GroundingContext {\n return {\n tables: [],\n views: [],\n relationships: [],\n info: undefined,\n fragments: [],\n cache: new Map(),\n onProgress: timestampProgress(options.onProgress),\n };\n}\n", "import type { SQLScopeErrorPayload } from './agents/exceptions.ts';\n\nexport function buildScopeParseErrorPayload(\n sql: string,\n parserDialect: string,\n error: unknown,\n): SQLScopeErrorPayload {\n const parserError =\n error instanceof Error ? error.message : String(error ?? 'Unknown error');\n\n return {\n error: `SQL scope analysis failed before validation/execution: ${parserError}`,\n error_type: 'SQL_SCOPE_PARSE_ERROR',\n suggestion:\n 'Rewrite the query into simpler SQL that can be analyzed safely, or extend parser coverage for this dialect feature.',\n sql_attempted: sql,\n parser_dialect: parserDialect,\n parser_error: parserError,\n };\n}\n", "import type { SQLScopeErrorPayload } from '../../agents/exceptions.ts';\nimport { buildScopeParseErrorPayload } from '../../sql-scope-error.ts';\nimport type { ExecuteFunction } from '../adapter.ts';\nimport type {\n SqlPolicyAnalyzer,\n SqlPolicyContext,\n SqlPolicyViolation,\n} from '../sql-policy.ts';\n\nconst READ_ONLY_MESSAGE = 'only SELECT queries allowed';\n\ntype ExplainNode = {\n text: string;\n children: ExplainNode[];\n};\n\nexport class ClickHouseSqlPolicyAnalyzer implements SqlPolicyAnalyzer {\n readonly #query: ExecuteFunction;\n #readonlyCheck?: Promise<void>;\n #currentDatabase?: string;\n\n constructor(query: ExecuteFunction) {\n this.#query = query;\n }\n\n async analyze(\n sql: string,\n context: SqlPolicyContext,\n ): Promise<SqlPolicyViolation | null> {\n try {\n await (this.#readonlyCheck ??= this.#verifyReadonly());\n\n const ast = await this.#explain(`EXPLAIN AST ${sql}`);\n const astAnalysis = analyzeAst(ast);\n if (!astAnalysis.isSelect) {\n return { kind: 'read-only', message: READ_ONLY_MESSAGE };\n }\n if (await this.#hasUnsafeFunction(astAnalysis.functions)) {\n return { kind: 'read-only', message: READ_ONLY_MESSAGE };\n }\n\n const syntacticTree = await this.#explain(\n `EXPLAIN QUERY TREE run_passes = 0 ${sql}`,\n );\n const analyzedTree = await this.#explain(`EXPLAIN QUERY TREE ${sql}`);\n const syntacticRelations = readQueryTreeRelations(\n syntacticTree,\n 'syntactic',\n );\n const analyzedRelations = readQueryTreeRelations(\n analyzedTree,\n 'analyzed',\n );\n if (!this.#currentDatabase) {\n throw new Error('ClickHouse current database was not established.');\n }\n const relations = [\n ...new Set(\n [...syntacticRelations, ...analyzedRelations].map((relation) =>\n qualifyRelation(relation, this.#currentDatabase!),\n ),\n ),\n ];\n const allowed = await context.resolveAllowedEntities();\n const rejected = relations.filter(\n (relation) => !isAllowedRelation(relation, allowed),\n );\n\n return rejected.length\n ? {\n kind: 'scope',\n payload: buildOutOfScopePayload(sql, rejected, [...allowed]),\n }\n : null;\n } catch (error) {\n return {\n kind: 'scope',\n payload: buildScopeParseErrorPayload(sql, 'clickhouse', error),\n };\n }\n }\n\n async #verifyReadonly(): Promise<void> {\n const rows = readRows(\n await this.#query(\n \"SELECT getSetting('readonly') AS readonly, currentDatabase() AS database\",\n ),\n );\n const row = rows[0];\n if (\n rows.length !== 1 ||\n !row ||\n Object.keys(row).length !== 2 ||\n typeof row.database !== 'string' ||\n row.database.length === 0\n ) {\n throw new Error(\n 'ClickHouse readonly probe returned an unknown row shape.',\n );\n }\n const value = row.readonly;\n if (value !== 1 && value !== '1') {\n throw new Error(\n `ClickHouse connection must have effective readonly = 1; received ${String(value)}.`,\n );\n }\n this.#currentDatabase = row.database;\n }\n\n async #explain(sql: string): Promise<string[]> {\n const rows = readRows(await this.#query(sql));\n if (rows.length === 0) {\n throw new Error('ClickHouse EXPLAIN returned no rows.');\n }\n return rows.map((row) => {\n if (Object.keys(row).length !== 1 || typeof row.explain !== 'string') {\n throw new Error(\n 'ClickHouse EXPLAIN must return rows with exactly one string `explain` column.',\n );\n }\n return row.explain;\n });\n }\n\n async #hasUnsafeFunction(functions: readonly string[]): Promise<boolean> {\n if (functions.some(isScopeBypassingFunction)) return true;\n if (functions.length === 0) return false;\n const names = [...new Set(functions)]\n .map((name) => `'${name.replaceAll(\"'\", \"''\")}'`)\n .join(', ');\n const rows = readRows(\n await this.#query(`\n SELECT name, toString(origin) AS origin\n FROM system.functions\n WHERE name IN (${names})\n AND origin != 'System'\n `),\n );\n for (const row of rows) {\n if (typeof row.name !== 'string' || typeof row.origin !== 'string') {\n throw new Error(\n 'ClickHouse system.functions returned an unknown row shape.',\n );\n }\n if (\n row.origin !== 'SQLUserDefined' &&\n row.origin !== 'ExecutableUserDefined' &&\n row.origin !== 'WasmUserDefined'\n ) {\n throw new Error(`Unknown ClickHouse function origin: ${row.origin}`);\n }\n }\n return rows.length > 0;\n }\n}\n\nfunction isScopeBypassingFunction(name: string): boolean {\n const normalized = name.toLocaleLowerCase('en-US');\n return normalized.startsWith('dict') || normalized.startsWith('joinget');\n}\n\nfunction readRows(result: unknown): Record<string, unknown>[] {\n const rows = Array.isArray(result)\n ? result\n : result && typeof result === 'object' && 'data' in result\n ? (result as { data: unknown }).data\n : result && typeof result === 'object' && 'rows' in result\n ? (result as { rows: unknown }).rows\n : undefined;\n if (!Array.isArray(rows) || rows.some((row) => !isRecord(row))) {\n throw new Error(\n 'ClickHouse query callback must return row objects as an array, { data }, or { rows }.',\n );\n }\n return rows;\n}\n\nfunction analyzeAst(lines: string[]): {\n isSelect: boolean;\n functions: string[];\n} {\n const rootLines = lines.filter(\n (line) => line.length - line.trimStart().length === 0,\n );\n if (\n rootLines.length !== 1 ||\n !rootLines[0]?.startsWith('SelectWithUnionQuery')\n ) {\n return { isSelect: false, functions: [] };\n }\n const roots = parseIndentedTree(lines, validateAstLine);\n const root = roots[0];\n const isSelect =\n roots.length === 1 &&\n !!root &&\n !root.children.some((child) => child.text.startsWith('Literal ')) &&\n !containsTableFunction(root);\n return {\n isSelect,\n functions: isSelect && root ? collectAstFunctions(root) : [],\n };\n}\n\nfunction validateAstLine(text: string): void {\n const type = /^([A-Za-z][A-Za-z0-9]*)/.exec(text)?.[1];\n const allowed = new Set([\n 'ArrayJoin',\n 'Asterisk',\n 'ExpressionList',\n 'Function',\n 'Identifier',\n 'Literal',\n 'OrderByElement',\n 'SelectQuery',\n 'SelectWithUnionQuery',\n 'Subquery',\n 'TableExpression',\n 'TableIdentifier',\n 'TableJoin',\n 'TablesInSelectQuery',\n 'TablesInSelectQueryElement',\n 'WithElement',\n 'WindowDefinition',\n ]);\n if (!type || !allowed.has(type)) {\n throw new Error(`Unknown ClickHouse AST node: ${text}`);\n }\n}\n\nfunction containsTableFunction(node: ExplainNode): boolean {\n if (\n node.text.startsWith('TableExpression') &&\n node.children.some((child) => child.text.startsWith('Function '))\n ) {\n return true;\n }\n return node.children.some(containsTableFunction);\n}\n\nfunction collectAstFunctions(node: ExplainNode): string[] {\n const functions: string[] = [];\n if (node.text.startsWith('Function ')) {\n const name = /^Function (\\S+)/.exec(node.text)?.[1];\n if (!name) throw new Error(`Unknown ClickHouse AST function: ${node.text}`);\n functions.push(name);\n }\n for (const child of node.children)\n functions.push(...collectAstFunctions(child));\n return functions;\n}\n\nfunction readQueryTreeRelations(\n lines: string[],\n phase: 'syntactic' | 'analyzed',\n): string[] {\n const roots = parseIndentedTree(lines, (text, parent) =>\n validateQueryTreeLine(text, parent),\n );\n if (\n roots.length !== 1 ||\n (!roots[0]?.text.startsWith('QUERY ') &&\n !roots[0]?.text.startsWith('UNION '))\n ) {\n throw new Error(`Unknown ClickHouse ${phase} query-tree root.`);\n }\n\n const relations: string[] = [];\n const cteNames = new Set<string>();\n collectCteNames(roots[0], cteNames);\n visitQueryTree(roots[0], false, phase, cteNames, relations);\n return relations;\n}\n\nfunction validateQueryTreeLine(text: string, parent?: ExplainNode): void {\n const nodePatterns = [\n /^QUERY id:/,\n /^UNION id:/,\n /^QUERIES$/,\n /^PROJECTION(?: COLUMNS)?$/,\n /^WITH$/,\n /^LIST id:/,\n /^MATCHER id:/,\n /^COLUMN id:/,\n /^JOIN TREE$/,\n /^ARRAY_JOIN id:/,\n /^IDENTIFIER id:/,\n /^TABLE id:/,\n /^JOIN id:/,\n /^(?:(?:LEFT|RIGHT) )?TABLE EXPRESSION$/,\n /^JOIN EXPRESSIONS?$/,\n /^FUNCTION id:/,\n /^ARGUMENTS$/,\n /^CONSTANT id:/,\n /^PREWHERE$/,\n /^WHERE$/,\n /^WINDOW$/,\n /^WINDOW id:/,\n /^PARTITION BY$/,\n /^QUALIFY$/,\n /^GROUP BY$/,\n /^HAVING$/,\n /^ORDER BY$/,\n /^SORT id:/,\n /^EXPRESSION(?: .*)?$/,\n /^LIMIT BY LIMIT$/,\n /^LIMIT BY$/,\n /^LIMIT$/,\n /^OFFSET$/,\n ];\n if (nodePatterns.some((pattern) => pattern.test(text))) return;\n if (parent?.text === 'PROJECTION COLUMNS' && /^\\S+\\s+\\S+/.test(text)) {\n return;\n }\n throw new Error(`Unknown ClickHouse query-tree node: ${text}`);\n}\n\nfunction visitQueryTree(\n node: ExplainNode,\n relationPosition: boolean,\n phase: 'syntactic' | 'analyzed',\n cteNames: ReadonlySet<string>,\n relations: string[],\n): void {\n if (relationPosition && node.text.startsWith('IDENTIFIER ')) {\n const identifier = /(?:^|, )identifier: (.+)$/.exec(node.text)?.[1];\n if (!identifier) {\n throw new Error(`Unknown ClickHouse ${phase} relation: ${node.text}`);\n }\n if (!cteNames.has(identifier)) {\n relations.push(identifier);\n }\n } else if (relationPosition && node.text.startsWith('TABLE ')) {\n const table = /(?:^|, )table_name: ([^,]+)(?:,|$)/.exec(node.text)?.[1];\n if (!table) {\n throw new Error(`Unknown ClickHouse ${phase} relation: ${node.text}`);\n }\n relations.push(table);\n }\n\n for (const child of node.children) {\n const childrenAreRelations =\n node.text === 'JOIN TREE' ||\n node.text === 'LEFT TABLE EXPRESSION' ||\n node.text === 'RIGHT TABLE EXPRESSION' ||\n node.text === 'TABLE EXPRESSION';\n visitQueryTree(child, childrenAreRelations, phase, cteNames, relations);\n }\n}\n\nfunction collectCteNames(node: ExplainNode, cteNames: Set<string>): void {\n const name = /(?:^|, )cte_name: ([^,]+)(?:,|$)/.exec(node.text)?.[1];\n if (name) cteNames.add(name);\n for (const child of node.children) collectCteNames(child, cteNames);\n}\n\nfunction parseIndentedTree(\n lines: string[],\n validate: (text: string, parent?: ExplainNode) => void,\n): ExplainNode[] {\n const roots: ExplainNode[] = [];\n const stack: Array<{ indent: number; node: ExplainNode }> = [];\n\n for (const line of lines) {\n if (!line.trim())\n throw new Error('ClickHouse EXPLAIN returned an empty line.');\n const indent = line.length - line.trimStart().length;\n const text = line.trimStart();\n while (stack.length && stack.at(-1)!.indent >= indent) stack.pop();\n const parent = stack.at(-1)?.node;\n validate(text, parent);\n const node = { text, children: [] };\n if (parent) parent.children.push(node);\n else roots.push(node);\n stack.push({ indent, node });\n }\n\n return roots;\n}\n\nfunction isAllowedRelation(\n relation: string,\n allowedEntities: readonly string[],\n): boolean {\n return allowedEntities.includes(relation);\n}\n\nfunction qualifyRelation(relation: string, database: string): string {\n return relation.includes('.') ? relation : `${database}.${relation}`;\n}\n\nfunction buildOutOfScopePayload(\n sql: string,\n referencedEntities: string[],\n allowedEntities: string[],\n): SQLScopeErrorPayload {\n return {\n error: `Query references entities outside grounded scope: ${referencedEntities.join(', ')}`,\n error_type: 'OUT_OF_SCOPE',\n suggestion:\n 'Restrict the query to grounded tables/views or expand grounding to include the referenced entities.',\n sql_attempted: sql,\n referenced_entities: referencedEntities,\n allowed_entities: allowedEntities,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n", "import {\n Adapter,\n type ExecuteFunction,\n type GroundingFn,\n type ValidateFunction,\n} from '../adapter.ts';\nimport { ClickHouseSqlPolicyAnalyzer } from './clickhouse.sql-policy.ts';\n\nexport interface ClickHouseAdapterOptions {\n execute: ExecuteFunction;\n validate: ValidateFunction;\n grounding?: GroundingFn[];\n defaultDatabase?: string;\n}\n\ntype RowResult<Row> = Row[] | { data: Row[] } | { rows: Row[] };\n\nexport class ClickHouse extends Adapter {\n readonly #options: ClickHouseAdapterOptions;\n\n override readonly grounding: GroundingFn[];\n override readonly defaultSchema: string | undefined;\n override readonly systemSchemas = [\n 'system',\n 'information_schema',\n 'INFORMATION_SCHEMA',\n ];\n override readonly formatterLanguage = 'clickhouse';\n\n constructor(options: ClickHouseAdapterOptions) {\n if (!options || typeof options.execute !== 'function') {\n throw new Error('ClickHouse adapter requires an execute(sql) function.');\n }\n if (typeof options.validate !== 'function') {\n throw new Error('ClickHouse adapter requires a validate(sql) function.');\n }\n\n super(new ClickHouseSqlPolicyAnalyzer(options.execute));\n this.#options = options;\n this.grounding = options.grounding ?? [];\n this.defaultSchema = options.defaultDatabase;\n }\n\n override async executeImpl(sql: string): Promise<unknown[]> {\n return rowsFromResult(await this.#options.execute(sql));\n }\n\n override async validateImpl(sql: string): Promise<string | void> {\n try {\n return await this.#options.validate(sql);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return JSON.stringify({\n error: message,\n error_type: 'CLICKHOUSE_ERROR',\n suggestion:\n 'Review the ClickHouse syntax and verify referenced databases, tables, columns, and functions.',\n sql_attempted: sql,\n });\n }\n }\n\n override async runQuery<Row>(sql: string): Promise<Row[]> {\n return rowsFromResult<Row>(await this.#options.execute(sql));\n }\n\n override quoteIdentifier(name: string): string {\n return `\\`${name.replace(/`/g, '``')}\\``;\n }\n\n override escape(value: string): string {\n return value.replace(/`/g, '``');\n }\n\n override buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string {\n const { schema, table } = this.parseTableName(tableName);\n const relation = schema\n ? `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table)}`\n : this.quoteIdentifier(table);\n const projection = columns?.length\n ? columns.map((column) => this.quoteIdentifier(column)).join(', ')\n : '*';\n return `SELECT ${projection} FROM ${relation} LIMIT ${limit}`;\n }\n}\n\nfunction rowsFromResult<Row>(result: unknown): Row[] {\n if (Array.isArray(result)) return result as Row[];\n if (result && typeof result === 'object') {\n const candidate = result as Partial<RowResult<Row>> & {\n data?: unknown;\n rows?: unknown;\n };\n if (Array.isArray(candidate.data)) return candidate.data as Row[];\n if (Array.isArray(candidate.rows)) return candidate.rows as Row[];\n }\n throw new Error(\n 'ClickHouse execute() must return an array of rows, { data: rows }, or { rows }.',\n );\n}\n", "import type { Filter, IntrospectionPhase } from '../adapter.ts';\nimport type { GroundingContext } from './context.ts';\n\nexport type { AdapterInfo, AdapterInfoProvider, Filter } from '../adapter.ts';\n\n/**\n * Per-entity column filter.\n * Maps entity name (table or view) to a Filter that selects which columns to keep.\n * Entities not listed in the record keep all their columns.\n */\nexport type ColumnsFilter = Record<string, Filter>;\n\n/**\n * Filter a columns array using a Filter.\n * Keeps columns whose name matches the filter.\n */\nexport function filterColumns<T extends { name: string }>(\n columns: T[],\n filter: Filter,\n): T[] {\n if (Array.isArray(filter)) {\n return columns.filter((col) => filter.includes(col.name));\n }\n if (filter instanceof RegExp) {\n return columns.filter((col) => filter.test(col.name));\n }\n return columns.filter((col) => filter(col.name));\n}\n\n/**\n * Apply per-entity column filtering.\n * Returns the entity unchanged if no filter matches its name.\n */\nexport function applyColumnFilter<\n T extends { name: string; columns: { name: string }[] },\n>(entity: T, columnsConfig?: ColumnsFilter): T {\n if (!columnsConfig) return entity;\n const filter = columnsConfig[entity.name];\n if (!filter) return entity;\n return { ...entity, columns: filterColumns(entity.columns, filter) } as T;\n}\n\n/**\n * Abstract base class for database schema groundings.\n *\n * Groundings collect schema metadata into the shared GroundingContext.\n * Fragment generation is centralized in Adapter.introspect().\n */\nexport abstract class AbstractGrounding {\n /**\n * Grounding identifier for debugging/logging.\n */\n name: string;\n phase?: IntrospectionPhase;\n\n constructor(name: string, phase?: IntrospectionPhase) {\n this.name = name;\n this.phase = phase;\n }\n\n /**\n * Execute grounding to populate the shared context.\n * Groundings mutate ctx to add their collected data (tables, views, indexes, etc).\n * Fragment generation happens centrally in Adapter after all groundings complete.\n *\n * @param ctx - Shared context for accumulating schema data\n */\n abstract execute(ctx: GroundingContext): Promise<void>;\n\n /**\n * Populate ctx with the tables/views this grounding makes available for scope\n * resolution. Annotators decorate entities other groundings produced and add\n * no membership, so the default is a no-op; entity-producing groundings\n * override it. This lets scope resolution skip the annotators' metadata scans.\n *\n * @param _ctx - Shared context for accumulating entity membership\n */\n async contributeEntities(_ctx: GroundingContext): Promise<void> {}\n}\n", "import type { TableConstraint } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for ConstraintGrounding.\n */\nexport interface ConstraintGroundingConfig {\n // Future: filter which tables/constraint types to collect\n}\n\n/**\n * Abstract base class for constraint grounding.\n *\n * Reads tables from the context and annotates them with constraints\n * (CHECK, UNIQUE, NOT_NULL, DEFAULT).\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getConstraints()` - fetch constraints for a table\n */\nexport abstract class ConstraintGrounding extends AbstractGrounding {\n constructor(config: ConstraintGroundingConfig = {}) {\n super('constraint', 'constraints');\n }\n\n /**\n * Fetch constraints for a specific table.\n */\n protected abstract getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their constraints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'constraints',\n table: table.name,\n message: `Loading constraints for ${table.name}...`,\n current: i + 1,\n total,\n });\n try {\n table.constraints = await this.getConstraints(table.name);\n } catch (error) {\n // Skip on error - table might not exist or be inaccessible\n console.warn('Error collecting constraints for', table.name, error);\n }\n }\n }\n}\n", "import type { Adapter, TableConstraint } from '../adapter.ts';\nimport {\n ConstraintGrounding,\n type ConstraintGroundingConfig,\n} from '../groundings/constraint.grounding.ts';\n\ntype ColumnMetadataRow = {\n name: string;\n type: string;\n default_kind: string;\n default_expression: string;\n is_in_primary_key: number | string;\n};\n\nexport class ClickHouseConstraintGrounding extends ConstraintGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: ConstraintGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n if (!schema) return [];\n\n const rows = await this.#adapter.runQuery<ColumnMetadataRow>(`\n SELECT name, type, default_kind, default_expression, is_in_primary_key\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY position\n `);\n const constraints: TableConstraint[] = [];\n const primaryKey = rows\n .filter((row) => Number(row.is_in_primary_key) === 1)\n .map((row) => row.name);\n\n if (primaryKey.length > 0) {\n constraints.push({\n name: 'PRIMARY_KEY',\n type: 'PRIMARY_KEY',\n columns: primaryKey,\n });\n }\n\n for (const row of rows) {\n if (!hasNullableType(row.type)) {\n constraints.push({\n name: `${row.name}_not_null`,\n type: 'NOT_NULL',\n columns: [row.name],\n });\n }\n if (row.default_kind === 'DEFAULT' && row.default_expression) {\n constraints.push({\n name: `${row.name}_default`,\n type: 'DEFAULT',\n columns: [row.name],\n defaultValue: row.default_expression,\n });\n }\n }\n\n return constraints;\n }\n}\n\nfunction hasNullableType(type: string): boolean {\n return /(?:^|\\()Nullable\\(/.test(type);\n}\n", "import type { TableIndex } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for IndexesGrounding.\n */\nexport interface IndexesGroundingConfig {\n // Future: filter which tables to collect indexes for\n}\n\n/**\n * Abstract base class for indexes grounding.\n *\n * Reads tables from the context and annotates them with index metadata.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getIndexes()` - fetch indexes for a table\n */\nexport abstract class IndexesGrounding extends AbstractGrounding {\n constructor(config: IndexesGroundingConfig = {}) {\n super('index', 'indexes');\n }\n\n /**\n * Fetch indexes for a specific table.\n */\n protected abstract getIndexes(tableName: string): Promise<TableIndex[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their indexes and marks indexed columns.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'indexes',\n table: table.name,\n message: `Loading indexes for ${table.name}...`,\n current: i + 1,\n total,\n });\n table.indexes = await this.getIndexes(table.name);\n // Mark columns that are part of indexes\n for (const index of table.indexes ?? []) {\n for (const colName of index.columns) {\n const column = table.columns.find((c) => c.name === colName);\n if (column) {\n column.isIndexed = true;\n }\n }\n }\n }\n }\n}\n", "import type { Adapter, TableIndex } from '../adapter.ts';\nimport {\n IndexesGrounding,\n type IndexesGroundingConfig,\n} from '../groundings/indexes.grounding.ts';\n\ntype PrimaryKeyRow = {\n name: string;\n};\n\ntype DataSkippingIndexRow = {\n name: string;\n type: string;\n expression: string;\n};\n\nexport class ClickHouseIndexesGrounding extends IndexesGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: IndexesGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getIndexes(\n tableName: string,\n ): Promise<TableIndex[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n if (!schema) return [];\n\n const [primaryKeyRows, indexRows] = await Promise.all([\n this.#adapter.runQuery<PrimaryKeyRow>(`\n SELECT name\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n AND is_in_primary_key = 1\n ORDER BY position\n `),\n this.#adapter.runQuery<DataSkippingIndexRow>(`\n SELECT name, type_full AS type, expr AS expression\n FROM system.data_skipping_indices\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY name\n `),\n ]);\n\n const indexes: TableIndex[] = [];\n if (primaryKeyRows.length > 0) {\n indexes.push({\n name: 'PRIMARY_KEY',\n columns: primaryKeyRows.map((row) => row.name),\n type: 'PRIMARY_KEY',\n });\n }\n indexes.push(\n ...indexRows.map((row) => ({\n name: row.name,\n columns: splitTopLevelExpressions(row.expression),\n type: row.type,\n })),\n );\n return indexes;\n }\n}\n\nfunction splitTopLevelExpressions(expression: string): string[] {\n const parts: string[] = [];\n let start = 0;\n let depth = 0;\n for (let index = 0; index < expression.length; index++) {\n const character = expression[index];\n if (character === '(' || character === '[') depth++;\n if (character === ')' || character === ']') depth--;\n if (character === ',' && depth === 0) {\n parts.push(expression.slice(start, index).trim());\n start = index + 1;\n }\n }\n parts.push(expression.slice(start).trim());\n return parts.filter(Boolean);\n}\n", "import type { AdapterInfo } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for InfoGrounding.\n */\nexport interface InfoGroundingConfig {\n // Future: options to control what info to collect\n}\n\n/**\n * Abstract base class for database info grounding.\n *\n * Collects database dialect, version, and connection info.\n *\n * Subclasses implement the database-specific hook:\n * - `collectInfo()` - collect database info\n */\nexport abstract class InfoGrounding extends AbstractGrounding {\n constructor(config: InfoGroundingConfig = {}) {\n super('dialectInfo', 'info');\n }\n\n /**\n * Collect database dialect, version, and other info.\n */\n protected abstract collectInfo(): Promise<AdapterInfo>;\n\n /**\n * Execute the grounding process.\n * Writes database info to ctx.info.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n ctx.info = await this.collectInfo();\n }\n}\n", "import type { Adapter, AdapterInfo } from '../adapter.ts';\nimport {\n InfoGrounding,\n type InfoGroundingConfig,\n} from '../groundings/info.grounding.ts';\n\ntype InfoRow = {\n version: string;\n database: string;\n};\n\nexport class ClickHouseInfoGrounding extends InfoGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: InfoGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async collectInfo(): Promise<AdapterInfo> {\n const rows = await this.#adapter.runQuery<InfoRow>(\n 'SELECT version() AS version, currentDatabase() AS database',\n );\n const row = rows[0];\n return {\n dialect: 'clickhouse',\n version: row?.version,\n database: row?.database || undefined,\n details: {\n identifierQuote: '`',\n qualifiedTable: 'database.table',\n },\n };\n }\n}\n", "import type { Table } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for RowCountGrounding.\n */\nexport interface RowCountGroundingConfig {\n // Future: filter which tables to count\n}\n\n/**\n * Abstract base class for row count grounding.\n *\n * Reads tables from the context and annotates them with row counts and size hints.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getRowCount()` - get row count for a table\n */\nexport abstract class RowCountGrounding extends AbstractGrounding {\n constructor(config: RowCountGroundingConfig = {}) {\n super('rowCount', 'row_counts');\n }\n\n /**\n * Get row count for a specific table.\n */\n protected abstract getRowCount(\n tableName: string,\n ): Promise<number | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with row counts and size hints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'row_counts',\n table: table.name,\n message: `Counting rows in ${table.name}...`,\n current: i + 1,\n total,\n });\n const count = await this.getRowCount(table.name);\n if (count != null) {\n table.rowCount = count;\n table.sizeHint = this.#classifyRowCount(count);\n }\n }\n }\n\n /**\n * Classify row count into a size hint category.\n */\n #classifyRowCount(count: number): Table['sizeHint'] {\n if (count < 100) return 'tiny';\n if (count < 1000) return 'small';\n if (count < 10000) return 'medium';\n if (count < 100000) return 'large';\n return 'huge';\n }\n}\n", "import type { Adapter } from '../adapter.ts';\nimport {\n RowCountGrounding,\n type RowCountGroundingConfig,\n} from '../groundings/row-count.grounding.ts';\n\nexport class ClickHouseRowCountGrounding extends RowCountGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: RowCountGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getRowCount(\n tableName: string,\n ): Promise<number | undefined> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const relation = schema\n ? `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`\n : this.#adapter.quoteIdentifier(table);\n\n try {\n const rows = await this.#adapter.runQuery<{\n count: number | string | bigint | null;\n }>(`SELECT count() AS count FROM ${relation}`);\n return toNumber(rows[0]?.count);\n } catch {\n return undefined;\n }\n }\n}\n\nfunction toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'bigint') return Number(value);\n if (typeof value === 'string' && value.trim()) {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) return parsed;\n }\n return undefined;\n}\n", "import type { Filter, Relationship, Table } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n filterColumns,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for TableGrounding.\n */\nexport interface TableGroundingConfig {\n /** Filter to select seed tables */\n filter?: Filter;\n /**\n * Per-table column filter.\n * Maps table name to a Filter that selects which columns to keep.\n * Tables not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /**\n * Traverse forward (child\u2192parent) following FK direction.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no forward traversal\n */\n forward?: boolean | number;\n /**\n * Traverse backward (parent\u2192child) finding tables that reference us.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no backward traversal\n */\n backward?: boolean | number;\n}\n\n/**\n * Abstract base class for table grounding.\n *\n * The `execute()` method implements a BFS traversal algorithm that discovers\n * tables and relationships. Subclasses implement the database-specific hooks:\n * - `getAllTableNames()` - list all tables\n * - `getTable()` - get table metadata\n * - `findOutgoingRelations()` - find FKs FROM a table\n * - `findIncomingRelations()` - find FKs TO a table\n */\nexport abstract class TableGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n #forward?: boolean | number;\n #backward?: boolean | number;\n\n constructor(config: TableGroundingConfig = {}) {\n super('table', 'tables');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.#forward = config.forward;\n this.#backward = config.backward;\n }\n\n /** Get all table names in the database */\n protected abstract getAllTableNames(): Promise<string[]>;\n\n /** Get full table metadata for a single table */\n protected abstract getTable(tableName: string): Promise<Table>;\n\n /** Find FKs FROM this table (outgoing relationships) */\n protected abstract findOutgoingRelations(\n tableName: string,\n ): Promise<Relationship[]>;\n\n /** Find FKs TO this table (incoming relationships) */\n protected abstract findIncomingRelations(\n tableName: string,\n ): Promise<Relationship[]>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered tables and relationships to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const seedTables = await this.applyFilter();\n const forward = this.#forward;\n const backward = this.#backward;\n\n // No traversal at all - just add the seed tables\n if (!forward && !backward) {\n const tables = await Promise.all(\n seedTables.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: index + 1,\n total: seedTables.length,\n });\n return applyColumnFilter(await this.getTable(name), this.#columns);\n }),\n );\n ctx.tables.push(...tables);\n return;\n }\n\n const tables: Record<string, Table> = {};\n const allRelationships: Relationship[] = [];\n const seenRelationships = new Set<string>();\n\n // Track depth separately for forward/backward using BFS\n const forwardQueue: Array<{ name: string; depth: number }> = [];\n const backwardQueue: Array<{ name: string; depth: number }> = [];\n const forwardVisited = new Set<string>();\n const backwardVisited = new Set<string>();\n let loadedCount = 0;\n\n // Initialize queues with seed tables at depth 0\n for (const name of seedTables) {\n if (forward) forwardQueue.push({ name, depth: 0 });\n if (backward) backwardQueue.push({ name, depth: 0 });\n }\n\n // Process forward (child\u2192parent)\n const forwardLimit = forward === true ? Infinity : forward || 0;\n while (forwardQueue.length > 0) {\n const item = forwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (forwardVisited.has(name)) continue;\n forwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < forwardLimit) {\n const rels = await this.findOutgoingRelations(name);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!forwardVisited.has(rel.referenced_table)) {\n forwardQueue.push({ name: rel.referenced_table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Process backward (parent\u2192child)\n const backwardLimit = backward === true ? Infinity : backward || 0;\n while (backwardQueue.length > 0) {\n const item = backwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (backwardVisited.has(name)) continue;\n backwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < backwardLimit) {\n const rels = await this.findIncomingRelations(name);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!backwardVisited.has(rel.table)) {\n backwardQueue.push({ name: rel.table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Write to context\n const tablesList = Object.values(tables);\n ctx.tables.push(...tablesList);\n ctx.relationships.push(...allRelationships);\n }\n\n /**\n * Apply the filter to get seed table names.\n * If filter is an explicit array, skip querying all table names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllTableNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n\n /**\n * Add a relationship to the collection, deduplicating by key.\n */\n protected addRelationship(\n rel: Relationship,\n all: Relationship[],\n seen: Set<string>,\n ): void {\n const key = `${rel.table}:${rel.from.join(',')}:${rel.referenced_table}:${rel.to.join(',')}`;\n if (!seen.has(key)) {\n seen.add(key);\n all.push(rel);\n }\n }\n\n protected isRelationshipVisible(rel: Relationship): boolean {\n return (\n this.areColumnsVisible(rel.from, this.#columns?.[rel.table]) &&\n this.areColumnsVisible(rel.to, this.#columns?.[rel.referenced_table])\n );\n }\n\n protected areColumnsVisible(names: string[], filter?: Filter): boolean {\n if (!filter) return true;\n return (\n filterColumns(\n names.map((name) => ({ name })),\n filter,\n ).length === names.length\n );\n }\n}\n", "import type { Adapter, Relationship, Table } from '../adapter.ts';\nimport {\n TableGrounding,\n type TableGroundingConfig,\n} from '../groundings/table.grounding.ts';\n\ntype ColumnRow = {\n name: string;\n type: string;\n};\n\nexport class ClickHouseTableGrounding extends TableGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: TableGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getAllTableNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery<{ name: string }>(`\n SELECT concat(database, '.', name) AS name\n FROM system.tables\n WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA')\n AND is_temporary = 0\n AND engine != 'View'\n ORDER BY database, name\n `);\n return rows.map((row) => row.name);\n }\n\n protected override async getTable(tableName: string): Promise<Table> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n if (!schema) {\n throw new Error(\n `ClickHouse table grounding requires a qualified table name: ${tableName}`,\n );\n }\n const rows = await this.#adapter.runQuery<ColumnRow>(`\n SELECT name, type\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY position\n `);\n return {\n name: tableName,\n schema,\n rawName: table,\n columns: rows.map((row) => ({ name: row.name, type: row.type })),\n };\n }\n\n protected override async findOutgoingRelations(): Promise<Relationship[]> {\n return [];\n }\n\n protected override async findIncomingRelations(): Promise<Relationship[]> {\n return [];\n }\n}\n", "import type { ColumnStats, Filter } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Represents a database view with its metadata.\n */\nexport interface View {\n name: string;\n schema?: string;\n rawName?: string;\n /** The SQL definition of the view (CREATE VIEW statement or query) */\n definition?: string;\n columns: {\n name: string;\n type: string;\n /** Low cardinality marker */\n kind?: 'LowCardinality';\n /** Distinct values for low cardinality columns */\n values?: string[];\n /** Column statistics (min, max, nullFraction) */\n stats?: ColumnStats;\n }[];\n}\n\n/**\n * Configuration for ViewGrounding.\n */\nexport interface ViewGroundingConfig {\n /** Filter to select views */\n filter?: Filter;\n /**\n * Per-view column filter.\n * Maps view name to a Filter that selects which columns to keep.\n * Views not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /** Whether to fetch the SQL definition of each view (default: true) */\n includeDefinition?: boolean;\n}\n\n/**\n * Abstract base class for view grounding\n *\n * The `execute()` method implements the algorithm that discovers views.\n * Subclasses implement the database-specific hooks:\n * - `getAllViewNames()` - list all views\n * - `getView()` - get view metadata\n */\nexport abstract class ViewGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n protected includeDefinition: boolean;\n\n constructor(config: ViewGroundingConfig = {}) {\n super('view', 'views');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.includeDefinition = config.includeDefinition ?? true;\n }\n\n /** Get all view names in the database */\n protected abstract getAllViewNames(): Promise<string[]>;\n\n /** Get full view metadata for a single view */\n protected abstract getView(viewName: string): Promise<View>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered views to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const viewNames = await this.applyFilter();\n const views = await Promise.all(\n viewNames.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'views',\n table: name,\n message: `Loading view ${name}...`,\n current: index + 1,\n total: viewNames.length,\n });\n return applyColumnFilter(await this.getView(name), this.#columns);\n }),\n );\n ctx.views.push(...views);\n }\n\n /**\n * Apply the filter to get view names.\n * If filter is an explicit array, skip querying all view names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllViewNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n}\n", "import type { Adapter } from '../adapter.ts';\nimport {\n type View,\n ViewGrounding,\n type ViewGroundingConfig,\n} from '../groundings/view.grounding.ts';\n\ntype ColumnRow = {\n name: string;\n type: string;\n};\n\nexport class ClickHouseViewGrounding extends ViewGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: ViewGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getAllViewNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery<{ name: string }>(`\n SELECT concat(database, '.', name) AS name\n FROM system.tables\n WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA')\n AND is_temporary = 0\n AND endsWith(engine, 'View')\n ORDER BY database, name\n `);\n return rows.map((row) => row.name);\n }\n\n protected override async getView(viewName: string): Promise<View> {\n const { schema, table } = this.#adapter.parseTableName(viewName);\n if (!schema) {\n throw new Error(\n `ClickHouse view grounding requires a qualified view name: ${viewName}`,\n );\n }\n\n const [columns, definitionRows] = await Promise.all([\n this.#adapter.runQuery<ColumnRow>(`\n SELECT name, type\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY position\n `),\n this.includeDefinition\n ? this.#adapter.runQuery<{ definition: string }>(`\n SELECT create_table_query AS definition\n FROM system.tables\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND name = '${this.#adapter.escapeString(table)}'\n AND endsWith(engine, 'View')\n `)\n : Promise.resolve([]),\n ]);\n\n return {\n name: viewName,\n schema,\n rawName: table,\n definition: definitionRows[0]?.definition,\n columns: columns.map((column) => ({\n name: column.name,\n type: column.type,\n })),\n };\n }\n}\n", "import type { Adapter } from '../adapter.ts';\nimport type { ConstraintGroundingConfig } from '../groundings/constraint.grounding.ts';\nimport type { IndexesGroundingConfig } from '../groundings/indexes.grounding.ts';\nimport type { InfoGroundingConfig } from '../groundings/info.grounding.ts';\nimport type { RowCountGroundingConfig } from '../groundings/row-count.grounding.ts';\nimport type { TableGroundingConfig } from '../groundings/table.grounding.ts';\nimport type { ViewGroundingConfig } from '../groundings/view.grounding.ts';\nimport { ClickHouse } from './clickhouse.ts';\nimport { ClickHouseConstraintGrounding } from './constraint.clickhouse.grounding.ts';\nimport { ClickHouseIndexesGrounding } from './indexes.clickhouse.grounding.ts';\nimport { ClickHouseInfoGrounding } from './info.clickhouse.grounding.ts';\nimport { ClickHouseRowCountGrounding } from './row-count.clickhouse.grounding.ts';\nimport { ClickHouseTableGrounding } from './table.clickhouse.grounding.ts';\nimport { ClickHouseViewGrounding } from './view.clickhouse.grounding.ts';\n\nexport * from './clickhouse.ts';\nexport { ClickHouseSqlPolicyAnalyzer } from './clickhouse.sql-policy.ts';\n\nexport function tables(config: TableGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseTableGrounding(adapter, config);\n}\n\nexport function views(config: ViewGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseViewGrounding(adapter, config);\n}\n\nexport function info(config: InfoGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseInfoGrounding(adapter, config);\n}\n\nexport function indexes(config: IndexesGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseIndexesGrounding(adapter, config);\n}\n\nexport function rowCount(config: RowCountGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseRowCountGrounding(adapter, config);\n}\n\nexport function constraints(config: ConstraintGroundingConfig = {}) {\n return (adapter: Adapter) =>\n new ClickHouseConstraintGrounding(adapter, config);\n}\n\nexport default {\n ClickHouse,\n constraints,\n indexes,\n info,\n rowCount,\n tables,\n views,\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { type SqlLanguage, format as formatSql } from 'sql-formatter';\n\nimport type { ContextFragment, FragmentObject } from '@deepagents/context';\n\nimport { SQLReadOnlyError, SQLScopeError } from '../agents/exceptions.ts';\nimport {\n column,\n constraint,\n dialectInfo,\n index,\n relationship,\n table,\n view,\n} from '../fragments/schema.ts';\nimport type { AbstractGrounding } from './groundings/abstract.grounding.ts';\nimport {\n type GroundingContext,\n createGroundingContext,\n} from './groundings/context.ts';\nimport type { View } from './groundings/view.grounding.ts';\nimport {\n type SqlPolicyAnalyzer,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport {\n type SqlPolicyAnalyzer,\n type SqlPolicyContext,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\n/**\n * Filter type for view/table names.\n * - string[]: explicit list of view names\n * - RegExp: pattern to match view names\n * - function: predicate to filter view names\n */\nexport type Filter = string[] | RegExp | ((viewName: string) => boolean);\n\nexport interface Table {\n name: string;\n schema?: string;\n rawName?: string;\n columns: {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n isIndexed?: boolean;\n stats?: ColumnStats;\n }[];\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n indexes?: TableIndex[];\n constraints?: TableConstraint[];\n}\n\nexport interface TableIndex {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}\n\nexport interface TableConstraint {\n name: string;\n type:\n 'CHECK' | 'UNIQUE' | 'NOT_NULL' | 'DEFAULT' | 'PRIMARY_KEY' | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}\n\nexport interface ColumnStats {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n}\n\nexport type Relationship = {\n table: string;\n from: string[];\n referenced_table: string;\n to: string[];\n};\n\nexport type TablesFilter = string[] | RegExp;\n\nexport interface Introspection {\n tables: Table[];\n relationships: Relationship[];\n}\n\nexport interface AdapterInfo {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}\n\nexport type AdapterInfoProvider =\n AdapterInfo | (() => Promise<AdapterInfo> | AdapterInfo);\n\nexport type IntrospectionPhase =\n | 'info'\n | 'tables'\n | 'views'\n | 'row_counts'\n | 'constraints'\n | 'indexes'\n | 'column_stats'\n | 'column_values'\n | 'low_cardinality'\n | 'relationships'\n | 'definitions';\n\nexport type IntrospectionProgressType =\n 'phase:start' | 'phase:progress' | 'phase:end';\n\nexport interface IntrospectionProgress {\n type: IntrospectionProgressType;\n phase: IntrospectionPhase;\n message: string;\n table?: string;\n current?: number;\n total?: number;\n timestampMs?: number;\n}\n\nexport type OnProgress = (progress: IntrospectionProgress) => void;\n\nexport type GroundingFn = (adapter: Adapter) => AbstractGrounding;\n\nexport type ExecuteFunction = (sql: string) => Promise<any> | any;\nexport type ValidateFunction = (\n sql: string,\n) => Promise<string | void> | string | void;\n\nexport abstract class Adapter {\n readonly #policyAnalyzer: SqlPolicyAnalyzer;\n\n /**\n * Injects the strategy that guards validate() and execute().\n */\n protected constructor(policyAnalyzer: SqlPolicyAnalyzer) {\n this.#policyAnalyzer = policyAnalyzer;\n }\n\n abstract grounding: GroundingFn[];\n\n abstract readonly formatterLanguage: SqlLanguage;\n\n /**\n * Default schema name for this database.\n * PostgreSQL: 'public', SQL Server: 'dbo', SQLite: undefined\n */\n abstract readonly defaultSchema: string | undefined;\n\n /**\n * System schemas to exclude from introspection by default.\n */\n abstract readonly systemSchemas: string[];\n\n /**\n * Introspect the database schema and return context fragments.\n *\n * Executes all configured groundings to populate the context, then\n * generates fragments from the complete context data.\n *\n * @param ctx - Optional grounding context for sharing state between groundings\n * @returns Array of context fragments representing the database schema\n */\n async introspect(ctx = createGroundingContext()): Promise<ContextFragment[]> {\n // Phase 1: All groundings populate ctx\n for (const fn of this.grounding) {\n const grounding = fn(this);\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:start',\n phase: grounding.phase,\n message: `Starting ${grounding.name} introspection...`,\n });\n }\n try {\n await grounding.execute(ctx);\n } finally {\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:end',\n phase: grounding.phase,\n message: `Finished ${grounding.name} introspection.`,\n });\n }\n }\n }\n\n // Phase 2: Generate fragments from complete ctx\n return this.#toSchemaFragments(ctx);\n }\n\n /**\n * Resolve the allowed entity names (tables + views) from grounding config.\n * Asks each grounding to contribute its entities; annotators contribute\n * nothing, so their metadata scans are skipped.\n * Results are NOT cached \u2014 call once and store the result.\n */\n async resolveAllowedEntities(): Promise<string[]> {\n const ctx = createGroundingContext();\n for (const fn of this.grounding) {\n await fn(this).contributeEntities(ctx);\n }\n return [...ctx.tables.map((t) => t.name), ...ctx.views.map((v) => v.name)];\n }\n\n /**\n * Convert complete grounding context to schema fragments.\n * Called after all groundings have populated ctx with data.\n */\n #toSchemaFragments(ctx: GroundingContext): ContextFragment[] {\n const fragments: ContextFragment[] = [];\n\n // Dialect info\n if (ctx.info) {\n fragments.push(\n dialectInfo({\n dialect: ctx.info.dialect,\n version: ctx.info.version,\n database: ctx.info.database,\n details: ctx.info.details,\n }),\n );\n }\n\n // Tables (with all annotations now included)\n for (const t of ctx.tables) {\n fragments.push(this.#tableToFragment(t));\n }\n\n // Views\n for (const v of ctx.views) {\n fragments.push(this.#viewToFragment(v));\n }\n\n // Relationships \u2014 filter out FK columns that were removed by column restriction\n const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));\n const tableColumnSets = new Map(\n ctx.tables.map((t) => [t.name, new Set(t.columns.map((c) => c.name))]),\n );\n for (const rel of ctx.relationships) {\n const sourceColumns = tableColumnSets.get(rel.table);\n const targetColumns = tableColumnSets.get(rel.referenced_table);\n if (\n sourceColumns &&\n rel.from.some((column) => !sourceColumns.has(column))\n ) {\n continue;\n }\n if (\n targetColumns &&\n rel.to.some((column) => !targetColumns.has(column))\n ) {\n continue;\n }\n\n const sourceTable = tableMap.get(rel.table);\n const targetTable = tableMap.get(rel.referenced_table);\n fragments.push(\n this.#relationshipToFragment(rel, sourceTable, targetTable),\n );\n }\n\n fragments.push(...(ctx.fragments ?? []));\n\n return fragments;\n }\n\n /**\n * Convert a Table to a table fragment with nested column, index, and constraint fragments.\n */\n #tableToFragment(t: Table): ContextFragment {\n // Build constraint lookup maps for column-level annotations\n const pkConstraint = t.constraints?.find((c) => c.type === 'PRIMARY_KEY');\n const pkColumns = new Set(pkConstraint?.columns ?? []);\n\n const notNullColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'NOT_NULL')\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n const defaultByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'DEFAULT') ?? []) {\n for (const col of c.columns ?? []) {\n if (c.defaultValue != null) {\n defaultByColumn.set(col, c.defaultValue);\n }\n }\n }\n\n // Single-column UNIQUE constraints\n const uniqueColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'UNIQUE' && c.columns?.length === 1)\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n // Foreign key lookup: column -> referenced table.column\n const fkByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'FOREIGN_KEY') ??\n []) {\n const cols = c.columns ?? [];\n const refCols = c.referencedColumns ?? [];\n for (let i = 0; i < cols.length; i++) {\n const refCol = refCols[i] ?? refCols[0] ?? cols[i];\n fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);\n }\n }\n\n // Build column fragments\n const columnFragments = t.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n pk: pkColumns.has(col.name) || undefined,\n fk: fkByColumn.get(col.name),\n unique: uniqueColumns.has(col.name) || undefined,\n notNull: notNullColumns.has(col.name) || undefined,\n default: defaultByColumn.get(col.name),\n indexed: col.isIndexed || undefined,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n // Set of present column names for cascade-cleaning indexes/constraints\n const presentColumns = new Set(t.columns.map((c) => c.name));\n\n // Build index fragments\n const indexFragments = (t.indexes ?? [])\n .filter((idx) =>\n idx.columns.every((column) => presentColumns.has(column)),\n )\n .map((idx) =>\n index({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n type: idx.type,\n }),\n );\n\n // Build constraint fragments for multi-column UNIQUE and CHECK constraints\n const constraintFragments = (t.constraints ?? [])\n .filter(\n (c) =>\n c.type === 'CHECK' ||\n (c.type === 'UNIQUE' && (c.columns?.length ?? 0) > 1),\n )\n .filter(\n (c) =>\n !c.columns?.length ||\n c.columns.every((column) => presentColumns.has(column)),\n )\n .map((c) =>\n constraint({\n name: c.name,\n type: c.type,\n columns: c.columns,\n definition: c.definition,\n }),\n );\n\n return table({\n name: t.name,\n schema: t.schema,\n rowCount: t.rowCount,\n sizeHint: t.sizeHint,\n columns: columnFragments,\n indexes: indexFragments.length > 0 ? indexFragments : undefined,\n constraints:\n constraintFragments.length > 0 ? constraintFragments : undefined,\n });\n }\n\n /**\n * Convert a View to a view fragment with nested column fragments.\n */\n #viewToFragment(v: View): ContextFragment {\n const columnFragments = v.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n return view({\n name: v.name,\n schema: v.schema,\n columns: columnFragments,\n definition: v.definition,\n });\n }\n\n /**\n * Convert a Relationship to a relationship fragment.\n * Infers cardinality from row counts if available.\n */\n #relationshipToFragment(\n rel: Relationship,\n sourceTable?: Table,\n targetTable?: Table,\n ): ContextFragment {\n const sourceCount = sourceTable?.rowCount;\n const targetCount = targetTable?.rowCount;\n\n let cardinality:\n 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many' | undefined;\n\n if (sourceCount != null && targetCount != null && targetCount > 0) {\n const ratio = sourceCount / targetCount;\n if (ratio > 5) {\n cardinality = 'many-to-one';\n } else if (ratio < 1.2 && ratio > 0.8) {\n cardinality = 'one-to-one';\n } else if (ratio < 0.2) {\n cardinality = 'one-to-many';\n }\n }\n\n return relationship({\n from: { table: rel.table, columns: rel.from },\n to: { table: rel.referenced_table, columns: rel.to },\n cardinality,\n });\n }\n format(sql: string): string {\n const decoded = this.#decodeShellEscapes(sql);\n try {\n return formatSql(decoded, { language: this.formatterLanguage });\n } catch {\n return decoded;\n }\n }\n\n #decodeShellEscapes(sql: string): string {\n return sql\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([().*$])/g, '$1')\n .replace(/\\\\(?=$)/gm, '');\n }\n\n #cachedAllowedEntities: string[] | null = null;\n\n async #resolveScope(): Promise<string[]> {\n if (this.#cachedAllowedEntities) return this.#cachedAllowedEntities;\n this.#cachedAllowedEntities = await this.resolveAllowedEntities();\n return this.#cachedAllowedEntities;\n }\n\n async #analyzePolicy(sql: string): Promise<SqlPolicyViolation | null> {\n return this.#policyAnalyzer.analyze(sql, {\n resolveAllowedEntities: () => this.#resolveScope(),\n });\n }\n\n async validate(sql: string): Promise<string | void> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') return violation.message;\n if (violation?.kind === 'scope') return JSON.stringify(violation.payload);\n return this.validateImpl(decoded);\n }\n\n async execute(sql: string): Promise<any[]> {\n return this.executeImpl(await this.enforceExecutionPolicy(sql));\n }\n\n protected async enforceExecutionPolicy(sql: string): Promise<string> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') {\n throw new SQLReadOnlyError(violation.message);\n }\n if (violation?.kind === 'scope') {\n throw new SQLScopeError(violation.payload);\n }\n return decoded;\n }\n\n abstract executeImpl(sql: string): Promise<any[]> | any[];\n abstract validateImpl(sql: string): Promise<string | void> | string | void;\n abstract runQuery<Row>(sql: string): Promise<Row[]> | Row[];\n\n /**\n * Quote an identifier (table/column name) for safe use in SQL.\n * Each database uses different quoting styles.\n */\n abstract quoteIdentifier(name: string): string;\n\n /**\n * Escape a string value for safe use in SQL.\n * Each database escapes different characters.\n */\n abstract escape(value: string): string;\n\n /**\n * Build a SELECT query to sample rows from a table.\n * Each database uses different syntax for limiting rows (LIMIT vs TOP).\n */\n abstract buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string;\n\n /**\n * Convert unknown database value to number.\n * Handles number, bigint, and string types.\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'bigint') {\n return Number(value);\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n }\n\n /**\n * Parse a potentially qualified table name into schema and table parts.\n */\n parseTableName(name: string): { schema: string; table: string } {\n if (name.includes('.')) {\n const [schema, ...rest] = name.split('.');\n return { schema, table: rest.join('.') };\n }\n return { schema: this.defaultSchema ?? '', table: name };\n }\n\n /**\n * Escape a string value for use in SQL string literals (single quotes).\n * Used in WHERE clauses like: WHERE name = '${escapeString(value)}'\n */\n escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n /**\n * Build a SQL filter clause to include/exclude schemas.\n * @param columnName - The schema column name (e.g., 'TABLE_SCHEMA')\n * @param allowedSchemas - If provided, filter to these schemas only\n */\n buildSchemaFilter(columnName: string, allowedSchemas?: string[]): string {\n if (allowedSchemas && allowedSchemas.length > 0) {\n const values = allowedSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} IN (${values})`;\n }\n if (this.systemSchemas.length > 0) {\n const values = this.systemSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} NOT IN (${values})`;\n }\n return '';\n }\n}\n\nexport function filterTablesByName<T extends { name: string }>(\n tables: T[],\n filter: TablesFilter | undefined,\n): T[] {\n if (!filter) return tables;\n return tables.filter((table) => matchesFilter(table.name, filter));\n}\n\nexport function filterRelationshipsByTables(\n relationships: Relationship[],\n tableNames: Set<string> | undefined,\n): Relationship[] {\n if (tableNames === undefined) {\n return relationships;\n }\n if (tableNames.size === 0) {\n return [];\n }\n return relationships.filter(\n (it) => tableNames.has(it.table) || tableNames.has(it.referenced_table),\n );\n}\n\nexport function applyTablesFilter(\n tables: Table[],\n relationships: Relationship[],\n filter: TablesFilter | undefined,\n): { tables: Table[]; relationships: Relationship[] } {\n if (!filter) {\n return { tables, relationships };\n }\n\n const allowedNames = new Set(\n getTablesWithRelated(tables, relationships, filter),\n );\n\n return {\n tables: tables.filter((table) => allowedNames.has(table.name)),\n relationships: filterRelationshipsByTables(relationships, allowedNames),\n };\n}\n\nexport function matchesFilter(\n tableName: string,\n filter: TablesFilter,\n): boolean {\n if (Array.isArray(filter)) {\n return filter.includes(tableName);\n }\n return filter.test(tableName);\n}\n\nexport function getTablesWithRelated(\n allTables: Table[],\n relationships: Relationship[],\n filter: TablesFilter,\n): string[] {\n const matchedTables = filterTablesByName(allTables, filter).map(\n (it) => it.name,\n );\n\n if (matchedTables.length === 0) {\n return [];\n }\n\n const adjacency = new Map<string, Set<string>>();\n\n for (const rel of relationships) {\n if (!adjacency.has(rel.table)) {\n adjacency.set(rel.table, new Set());\n }\n if (!adjacency.has(rel.referenced_table)) {\n adjacency.set(rel.referenced_table, new Set());\n }\n adjacency.get(rel.table)!.add(rel.referenced_table);\n adjacency.get(rel.referenced_table)!.add(rel.table);\n }\n\n const result = new Set<string>(matchedTables);\n const queue = [...matchedTables];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const neighbors = adjacency.get(current);\n\n if (!neighbors) {\n continue;\n }\n\n for (const neighbor of neighbors) {\n if (!result.has(neighbor)) {\n result.add(neighbor);\n queue.push(neighbor);\n }\n }\n }\n\n return Array.from(result);\n}\n", "const sqlValidationMarker = Symbol('SQLValidationError');\nconst unanswerableSqlMarker = Symbol('UnanswerableSQLError');\nconst sqlScopeMarker = Symbol('SQLScopeError');\nconst sqlReadOnlyMarker = Symbol('SQLReadOnlyError');\n\nexport type SQLScopeErrorType = 'OUT_OF_SCOPE' | 'SQL_SCOPE_PARSE_ERROR';\n\nexport interface SQLScopeErrorPayload {\n error: string;\n error_type: SQLScopeErrorType;\n suggestion: string;\n sql_attempted: string;\n referenced_entities?: string[];\n allowed_entities?: string[];\n parser_dialect?: string;\n parser_error?: string;\n}\n\n/**\n * Error thrown when SQL validation fails.\n */\nexport class SQLValidationError extends Error {\n [sqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLValidationError';\n this[sqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLValidationError {\n return (\n error instanceof SQLValidationError && error[sqlValidationMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when the question cannot be answered with the given schema.\n */\nexport class UnanswerableSQLError extends Error {\n [unanswerableSqlMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'UnanswerableSQLError';\n this[unanswerableSqlMarker] = true;\n }\n\n static isInstance(error: unknown): error is UnanswerableSQLError {\n return (\n error instanceof UnanswerableSQLError &&\n error[unanswerableSqlMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when a query falls outside the grounded SQL scope.\n */\nexport class SQLScopeError extends Error {\n [sqlScopeMarker]: true;\n readonly payload: SQLScopeErrorPayload;\n readonly errorType: SQLScopeErrorType;\n\n constructor(payload: SQLScopeErrorPayload) {\n super(JSON.stringify(payload));\n this.name = 'SQLScopeError';\n this.payload = payload;\n this.errorType = payload.error_type;\n this[sqlScopeMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLScopeError {\n return error instanceof SQLScopeError && error[sqlScopeMarker] === true;\n }\n}\n\n/**\n * Error thrown when a query is not read-only (does not start with SELECT or WITH).\n */\nexport class SQLReadOnlyError extends Error {\n [sqlReadOnlyMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLReadOnlyError';\n this[sqlReadOnlyMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLReadOnlyError {\n return (\n error instanceof SQLReadOnlyError && error[sqlReadOnlyMarker] === true\n );\n }\n}\n", "import type { ContextFragment, FragmentObject } from '@deepagents/context';\n\n/**\n * Schema fragment builders.\n *\n * These fragments represent database schema metadata that can be injected\n * into AI prompts. Use with renderers (XML, Markdown, TOML, TOON) to format.\n *\n * @example\n * ```ts\n * import { dialectInfo, table, column, relationship } from '@deepagents/text2sql';\n *\n * const schemaFragments = [\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5' }),\n * table({\n * name: 'users',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true }),\n * ],\n * }),\n * ];\n * ```\n */\n\n/**\n * Database dialect and version information.\n *\n * @param input.dialect - Database type (PostgreSQL, SQLite, SQL Server, etc.)\n * @param input.version - Database version string\n * @param input.database - Database name\n *\n * @example\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5', database: 'myapp' })\n */\nexport function dialectInfo(input: {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}): ContextFragment {\n return {\n name: 'dialectInfo',\n data: {\n dialect: input.dialect,\n ...(input.version && { version: input.version }),\n ...(input.database && { database: input.database }),\n ...(input.details && { details: input.details }),\n },\n };\n}\n\n/**\n * Database table with columns and optional metadata.\n *\n * @param input.name - Table name\n * @param input.schema - Schema name (e.g., 'public' for PostgreSQL)\n * @param input.rowCount - Approximate row count\n * @param input.sizeHint - Size category for query optimization hints\n * @param input.columns - Array of column() fragments\n * @param input.indexes - Array of index() fragments\n * @param input.constraints - Array of constraint() fragments\n *\n * @example\n * table({\n * name: 'users',\n * rowCount: 1500,\n * sizeHint: 'medium',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true, indexed: true }),\n * ],\n * indexes: [\n * index({ name: 'idx_email', columns: ['email'], unique: true }),\n * ],\n * })\n */\nexport function table(input: {\n name: string;\n schema?: string;\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n columns: ContextFragment[];\n indexes?: ContextFragment[];\n constraints?: ContextFragment[];\n}): ContextFragment {\n return {\n name: 'table',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n ...(input.rowCount != null && { rowCount: input.rowCount }),\n ...(input.sizeHint && { sizeHint: input.sizeHint }),\n columns: input.columns,\n ...(input.indexes?.length && { indexes: input.indexes }),\n ...(input.constraints?.length && { constraints: input.constraints }),\n },\n };\n}\n\n/**\n * Table column with type and annotations.\n *\n * @param input.name - Column name\n * @param input.type - Column data type (e.g., 'integer', 'varchar(255)')\n * @param input.pk - Is primary key\n * @param input.fk - Foreign key reference in \"table.column\" format\n * @param input.unique - Has unique constraint\n * @param input.notNull - Has NOT NULL constraint\n * @param input.default - Default value expression\n * @param input.indexed - Has index on this column\n * @param input.values - Enum or low cardinality values\n * @param input.stats - Column statistics (min, max, null fraction)\n *\n * @example\n * column({\n * name: 'status',\n * type: 'varchar',\n * notNull: true,\n * indexed: true,\n * values: ['active', 'inactive', 'suspended'],\n * })\n */\nexport function column(input: {\n name: string;\n type: string;\n pk?: boolean;\n fk?: string;\n unique?: boolean;\n notNull?: boolean;\n default?: string;\n indexed?: boolean;\n values?: string[];\n stats?: {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n };\n}): ContextFragment {\n return {\n name: 'column',\n data: {\n name: input.name,\n type: input.type,\n ...(input.pk && { pk: true }),\n ...(input.fk && { fk: input.fk }),\n ...(input.unique && { unique: true }),\n ...(input.notNull && { notNull: true }),\n ...(input.default && { default: input.default }),\n ...(input.indexed && { indexed: true }),\n ...(input.values?.length && { values: input.values }),\n ...(input.stats && { stats: input.stats }),\n },\n };\n}\n\n/**\n * Table index.\n *\n * @param input.name - Index name\n * @param input.columns - Columns included in the index\n * @param input.unique - Is unique index\n * @param input.type - Index type (BTREE, HASH, GIN, etc.)\n *\n * @example\n * index({ name: 'idx_user_email', columns: ['email'], unique: true, type: 'BTREE' })\n */\nexport function index(input: {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}): ContextFragment {\n return {\n name: 'index',\n data: {\n name: input.name,\n columns: input.columns,\n ...(input.unique && { unique: true }),\n ...(input.type && { type: input.type }),\n },\n };\n}\n\n/**\n * Table constraint (CHECK, UNIQUE, PRIMARY_KEY, FOREIGN_KEY, etc).\n *\n * @param input.name - Constraint name\n * @param input.type - Constraint type\n * @param input.columns - Columns involved in the constraint\n * @param input.definition - CHECK constraint SQL definition\n * @param input.defaultValue - DEFAULT constraint value\n * @param input.referencedTable - For FK: referenced table name\n * @param input.referencedColumns - For FK: referenced column names\n *\n * @example\n * constraint({\n * name: 'chk_amount_positive',\n * type: 'CHECK',\n * definition: 'amount > 0',\n * })\n *\n * @example\n * constraint({\n * name: 'fk_order_user',\n * type: 'FOREIGN_KEY',\n * columns: ['user_id'],\n * referencedTable: 'users',\n * referencedColumns: ['id'],\n * })\n */\nexport function constraint(input: {\n name: string;\n type:\n | 'CHECK'\n | 'UNIQUE'\n | 'NOT_NULL'\n | 'DEFAULT'\n | 'PRIMARY_KEY'\n | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}): ContextFragment {\n return {\n name: 'constraint',\n data: {\n name: input.name,\n type: input.type,\n ...(input.columns?.length && { columns: input.columns }),\n ...(input.definition && { definition: input.definition }),\n ...(input.defaultValue && { defaultValue: input.defaultValue }),\n ...(input.referencedTable && { referencedTable: input.referencedTable }),\n ...(input.referencedColumns?.length && {\n referencedColumns: input.referencedColumns,\n }),\n },\n };\n}\n\n/**\n * Database view.\n *\n * @param input.name - View name\n * @param input.schema - Schema name\n * @param input.columns - Array of column() fragments\n * @param input.definition - View SQL definition\n *\n * @example\n * view({\n * name: 'active_users',\n * columns: [\n * column({ name: 'id', type: 'integer' }),\n * column({ name: 'email', type: 'varchar' }),\n * ],\n * definition: \"SELECT id, email FROM users WHERE status = 'active'\",\n * })\n */\nexport function view(input: {\n name: string;\n schema?: string;\n columns: ContextFragment[];\n definition?: string;\n}): ContextFragment {\n return {\n name: 'view',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n columns: input.columns,\n ...(input.definition && { definition: input.definition }),\n },\n };\n}\n\n/**\n * Relationship between tables (foreign key connection).\n *\n * @param input.from - Source table and columns\n * @param input.to - Referenced table and columns\n * @param input.cardinality - Relationship cardinality\n *\n * @example\n * relationship({\n * from: { table: 'orders', columns: ['user_id'] },\n * to: { table: 'users', columns: ['id'] },\n * cardinality: 'many-to-one',\n * })\n */\nexport function relationship(input: {\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n cardinality?: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';\n}): ContextFragment {\n return {\n name: 'relationship',\n data: {\n from: input.from,\n to: input.to,\n ...(input.cardinality && { cardinality: input.cardinality }),\n },\n };\n}\n", "import type { ContextFragment } from '@deepagents/context';\n\nimport type {\n AdapterInfo,\n ColumnStats,\n OnProgress,\n Relationship,\n Table,\n} from '../adapter.ts';\nimport type { View } from './view.grounding.ts';\n\n/**\n * Column type for grounding operations.\n * Common interface between Table.columns and View.columns.\n */\nexport interface Column {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n stats?: ColumnStats;\n}\n\n/**\n * Entity with columns (Table or View).\n */\nexport interface ColumnContainer {\n name: string;\n columns: Column[];\n}\n\n/**\n * Shared context object passed to all groundings.\n * Groundings read from and write to this context.\n */\nexport interface GroundingContext {\n /** Tables discovered by TableGrounding */\n tables: Table[];\n\n /** Views discovered by ViewGrounding */\n views: View[];\n\n /** Relationships discovered by TableGrounding */\n relationships: Relationship[];\n\n /** Database info collected by InfoGrounding */\n info?: AdapterInfo;\n\n /** Adapter-specific fragments contributed during grounding. */\n fragments?: ContextFragment[];\n\n /** Shared cache for cross-grounding deduplication. Keyed by `type:key`. */\n cache: Map<string, unknown>;\n\n /** Progress sink for long-running introspection work. */\n onProgress: OnProgress;\n}\n\nconst noopProgress: OnProgress = () => {};\n\nfunction timestampProgress(onProgress?: OnProgress): OnProgress {\n if (!onProgress) return noopProgress;\n return (progress) => {\n onProgress({\n ...progress,\n timestampMs: progress.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Create a new empty grounding context.\n */\nexport function createGroundingContext(\n options: { onProgress?: OnProgress } = {},\n): GroundingContext {\n return {\n tables: [],\n views: [],\n relationships: [],\n info: undefined,\n fragments: [],\n cache: new Map(),\n onProgress: timestampProgress(options.onProgress),\n };\n}\n", "import type { SQLScopeErrorPayload } from './agents/exceptions.ts';\n\nexport function buildScopeParseErrorPayload(\n sql: string,\n parserDialect: string,\n error: unknown,\n): SQLScopeErrorPayload {\n const parserError =\n error instanceof Error ? error.message : String(error ?? 'Unknown error');\n\n return {\n error: `SQL scope analysis failed before validation/execution: ${parserError}`,\n error_type: 'SQL_SCOPE_PARSE_ERROR',\n suggestion:\n 'Rewrite the query into simpler SQL that can be analyzed safely, or extend parser coverage for this dialect feature.',\n sql_attempted: sql,\n parser_dialect: parserDialect,\n parser_error: parserError,\n };\n}\n", "import type { SQLScopeErrorPayload } from '../../agents/exceptions.ts';\nimport { buildScopeParseErrorPayload } from '../../sql-scope-error.ts';\nimport type { ExecuteFunction } from '../adapter.ts';\nimport type {\n SqlPolicyAnalyzer,\n SqlPolicyContext,\n SqlPolicyViolation,\n} from '../sql-policy.ts';\n\nconst READ_ONLY_MESSAGE = 'only SELECT queries allowed';\n\ntype ExplainNode = {\n text: string;\n children: ExplainNode[];\n};\n\nexport class ClickHouseSqlPolicyAnalyzer implements SqlPolicyAnalyzer {\n readonly #query: ExecuteFunction;\n #readonlyCheck?: Promise<void>;\n #currentDatabase?: string;\n\n constructor(query: ExecuteFunction) {\n this.#query = query;\n }\n\n async analyze(\n sql: string,\n context: SqlPolicyContext,\n ): Promise<SqlPolicyViolation | null> {\n try {\n await (this.#readonlyCheck ??= this.#verifyReadonly());\n\n const ast = await this.#explain(`EXPLAIN AST ${sql}`);\n const astAnalysis = analyzeAst(ast);\n if (!astAnalysis.isSelect) {\n return { kind: 'read-only', message: READ_ONLY_MESSAGE };\n }\n if (await this.#hasUnsafeFunction(astAnalysis.functions)) {\n return { kind: 'read-only', message: READ_ONLY_MESSAGE };\n }\n\n const syntacticTree = await this.#explain(\n `EXPLAIN QUERY TREE run_passes = 0 ${sql}`,\n );\n const analyzedTree = await this.#explain(`EXPLAIN QUERY TREE ${sql}`);\n const syntacticRelations = readQueryTreeRelations(\n syntacticTree,\n 'syntactic',\n );\n const analyzedRelations = readQueryTreeRelations(\n analyzedTree,\n 'analyzed',\n );\n if (!this.#currentDatabase) {\n throw new Error('ClickHouse current database was not established.');\n }\n const relations = [\n ...new Set(\n [...syntacticRelations, ...analyzedRelations].map((relation) =>\n qualifyRelation(relation, this.#currentDatabase!),\n ),\n ),\n ];\n const allowed = await context.resolveAllowedEntities();\n const rejected = relations.filter(\n (relation) => !isAllowedRelation(relation, allowed),\n );\n\n return rejected.length\n ? {\n kind: 'scope',\n payload: buildOutOfScopePayload(sql, rejected, [...allowed]),\n }\n : null;\n } catch (error) {\n return {\n kind: 'scope',\n payload: buildScopeParseErrorPayload(sql, 'clickhouse', error),\n };\n }\n }\n\n async #verifyReadonly(): Promise<void> {\n const rows = readRows(\n await this.#query(\n \"SELECT getSetting('readonly') AS readonly, currentDatabase() AS database\",\n ),\n );\n const row = rows[0];\n if (\n rows.length !== 1 ||\n !row ||\n Object.keys(row).length !== 2 ||\n typeof row.database !== 'string' ||\n row.database.length === 0\n ) {\n throw new Error(\n 'ClickHouse readonly probe returned an unknown row shape.',\n );\n }\n const value = row.readonly;\n if (value !== 1 && value !== '1') {\n throw new Error(\n `ClickHouse connection must have effective readonly = 1; received ${String(value)}.`,\n );\n }\n this.#currentDatabase = row.database;\n }\n\n async #explain(sql: string): Promise<string[]> {\n const rows = readRows(await this.#query(sql));\n if (rows.length === 0) {\n throw new Error('ClickHouse EXPLAIN returned no rows.');\n }\n return rows.map((row) => {\n if (Object.keys(row).length !== 1 || typeof row.explain !== 'string') {\n throw new Error(\n 'ClickHouse EXPLAIN must return rows with exactly one string `explain` column.',\n );\n }\n return row.explain;\n });\n }\n\n async #hasUnsafeFunction(functions: readonly string[]): Promise<boolean> {\n if (functions.some(isScopeBypassingFunction)) return true;\n if (functions.length === 0) return false;\n const names = [...new Set(functions)]\n .map((name) => `'${name.replaceAll(\"'\", \"''\")}'`)\n .join(', ');\n const rows = readRows(\n await this.#query(`\n SELECT name, toString(origin) AS origin\n FROM system.functions\n WHERE name IN (${names})\n AND origin != 'System'\n `),\n );\n for (const row of rows) {\n if (typeof row.name !== 'string' || typeof row.origin !== 'string') {\n throw new Error(\n 'ClickHouse system.functions returned an unknown row shape.',\n );\n }\n if (\n row.origin !== 'SQLUserDefined' &&\n row.origin !== 'ExecutableUserDefined' &&\n row.origin !== 'WasmUserDefined'\n ) {\n throw new Error(`Unknown ClickHouse function origin: ${row.origin}`);\n }\n }\n return rows.length > 0;\n }\n}\n\nfunction isScopeBypassingFunction(name: string): boolean {\n const normalized = name.toLocaleLowerCase('en-US');\n return normalized.startsWith('dict') || normalized.startsWith('joinget');\n}\n\nfunction readRows(result: unknown): Record<string, unknown>[] {\n const rows = Array.isArray(result)\n ? result\n : result && typeof result === 'object' && 'data' in result\n ? (result as { data: unknown }).data\n : result && typeof result === 'object' && 'rows' in result\n ? (result as { rows: unknown }).rows\n : undefined;\n if (!Array.isArray(rows) || rows.some((row) => !isRecord(row))) {\n throw new Error(\n 'ClickHouse query callback must return row objects as an array, { data }, or { rows }.',\n );\n }\n return rows;\n}\n\nfunction analyzeAst(lines: string[]): {\n isSelect: boolean;\n functions: string[];\n} {\n const rootLines = lines.filter(\n (line) => line.length - line.trimStart().length === 0,\n );\n if (\n rootLines.length !== 1 ||\n !rootLines[0]?.startsWith('SelectWithUnionQuery')\n ) {\n return { isSelect: false, functions: [] };\n }\n const roots = parseIndentedTree(lines, validateAstLine);\n const root = roots[0];\n const isSelect =\n roots.length === 1 &&\n !!root &&\n !root.children.some((child) => child.text.startsWith('Literal ')) &&\n !containsTableFunction(root);\n return {\n isSelect,\n functions: isSelect && root ? collectAstFunctions(root) : [],\n };\n}\n\nfunction validateAstLine(text: string): void {\n const type = /^([A-Za-z][A-Za-z0-9]*)/.exec(text)?.[1];\n const allowed = new Set([\n 'ArrayJoin',\n 'Asterisk',\n 'ExpressionList',\n 'Function',\n 'Identifier',\n 'Literal',\n 'OrderByElement',\n 'SelectQuery',\n 'SelectWithUnionQuery',\n 'Subquery',\n 'TableExpression',\n 'TableIdentifier',\n 'TableJoin',\n 'TablesInSelectQuery',\n 'TablesInSelectQueryElement',\n 'WithElement',\n 'WindowDefinition',\n ]);\n if (!type || !allowed.has(type)) {\n throw new Error(`Unknown ClickHouse AST node: ${text}`);\n }\n}\n\nfunction containsTableFunction(node: ExplainNode): boolean {\n if (\n node.text.startsWith('TableExpression') &&\n node.children.some((child) => child.text.startsWith('Function '))\n ) {\n return true;\n }\n return node.children.some(containsTableFunction);\n}\n\nfunction collectAstFunctions(node: ExplainNode): string[] {\n const functions: string[] = [];\n if (node.text.startsWith('Function ')) {\n const name = /^Function (\\S+)/.exec(node.text)?.[1];\n if (!name) throw new Error(`Unknown ClickHouse AST function: ${node.text}`);\n functions.push(name);\n }\n for (const child of node.children)\n functions.push(...collectAstFunctions(child));\n return functions;\n}\n\nfunction readQueryTreeRelations(\n lines: string[],\n phase: 'syntactic' | 'analyzed',\n): string[] {\n const roots = parseIndentedTree(lines, (text, parent) =>\n validateQueryTreeLine(text, parent),\n );\n if (\n roots.length !== 1 ||\n (!roots[0]?.text.startsWith('QUERY ') &&\n !roots[0]?.text.startsWith('UNION '))\n ) {\n throw new Error(`Unknown ClickHouse ${phase} query-tree root.`);\n }\n\n const relations: string[] = [];\n const cteNames = new Set<string>();\n collectCteNames(roots[0], cteNames);\n visitQueryTree(roots[0], false, phase, cteNames, relations);\n return relations;\n}\n\nfunction validateQueryTreeLine(text: string, parent?: ExplainNode): void {\n const nodePatterns = [\n /^QUERY id:/,\n /^UNION id:/,\n /^QUERIES$/,\n /^PROJECTION(?: COLUMNS)?$/,\n /^WITH$/,\n /^LIST id:/,\n /^MATCHER id:/,\n /^COLUMN id:/,\n /^JOIN TREE$/,\n /^ARRAY_JOIN id:/,\n /^IDENTIFIER id:/,\n /^TABLE id:/,\n /^JOIN id:/,\n /^(?:(?:LEFT|RIGHT) )?TABLE EXPRESSION$/,\n /^JOIN EXPRESSIONS?$/,\n /^FUNCTION id:/,\n /^ARGUMENTS$/,\n /^CONSTANT id:/,\n /^PREWHERE$/,\n /^WHERE$/,\n /^WINDOW$/,\n /^WINDOW id:/,\n /^PARTITION BY$/,\n /^QUALIFY$/,\n /^GROUP BY$/,\n /^HAVING$/,\n /^ORDER BY$/,\n /^SORT id:/,\n /^EXPRESSION(?: .*)?$/,\n /^LIMIT BY LIMIT$/,\n /^LIMIT BY$/,\n /^LIMIT$/,\n /^OFFSET$/,\n ];\n if (nodePatterns.some((pattern) => pattern.test(text))) return;\n if (parent?.text === 'PROJECTION COLUMNS' && /^\\S+\\s+\\S+/.test(text)) {\n return;\n }\n throw new Error(`Unknown ClickHouse query-tree node: ${text}`);\n}\n\nfunction visitQueryTree(\n node: ExplainNode,\n relationPosition: boolean,\n phase: 'syntactic' | 'analyzed',\n cteNames: ReadonlySet<string>,\n relations: string[],\n): void {\n if (relationPosition && node.text.startsWith('IDENTIFIER ')) {\n const identifier = /(?:^|, )identifier: (.+)$/.exec(node.text)?.[1];\n if (!identifier) {\n throw new Error(`Unknown ClickHouse ${phase} relation: ${node.text}`);\n }\n if (!cteNames.has(identifier)) {\n relations.push(identifier);\n }\n } else if (relationPosition && node.text.startsWith('TABLE ')) {\n const table = /(?:^|, )table_name: ([^,]+)(?:,|$)/.exec(node.text)?.[1];\n if (!table) {\n throw new Error(`Unknown ClickHouse ${phase} relation: ${node.text}`);\n }\n relations.push(table);\n }\n\n for (const child of node.children) {\n const childrenAreRelations =\n node.text === 'JOIN TREE' ||\n node.text === 'LEFT TABLE EXPRESSION' ||\n node.text === 'RIGHT TABLE EXPRESSION' ||\n node.text === 'TABLE EXPRESSION';\n visitQueryTree(child, childrenAreRelations, phase, cteNames, relations);\n }\n}\n\nfunction collectCteNames(node: ExplainNode, cteNames: Set<string>): void {\n const name = /(?:^|, )cte_name: ([^,]+)(?:,|$)/.exec(node.text)?.[1];\n if (name) cteNames.add(name);\n for (const child of node.children) collectCteNames(child, cteNames);\n}\n\nfunction parseIndentedTree(\n lines: string[],\n validate: (text: string, parent?: ExplainNode) => void,\n): ExplainNode[] {\n const roots: ExplainNode[] = [];\n const stack: Array<{ indent: number; node: ExplainNode }> = [];\n\n for (const line of lines) {\n if (!line.trim())\n throw new Error('ClickHouse EXPLAIN returned an empty line.');\n const indent = line.length - line.trimStart().length;\n const text = line.trimStart();\n while (stack.length && stack.at(-1)!.indent >= indent) stack.pop();\n const parent = stack.at(-1)?.node;\n validate(text, parent);\n const node = { text, children: [] };\n if (parent) parent.children.push(node);\n else roots.push(node);\n stack.push({ indent, node });\n }\n\n return roots;\n}\n\nfunction isAllowedRelation(\n relation: string,\n allowedEntities: readonly string[],\n): boolean {\n return allowedEntities.includes(relation);\n}\n\nfunction qualifyRelation(relation: string, database: string): string {\n return relation.includes('.') ? relation : `${database}.${relation}`;\n}\n\nfunction buildOutOfScopePayload(\n sql: string,\n referencedEntities: string[],\n allowedEntities: string[],\n): SQLScopeErrorPayload {\n return {\n error: `Query references entities outside grounded scope: ${referencedEntities.join(', ')}`,\n error_type: 'OUT_OF_SCOPE',\n suggestion:\n 'Restrict the query to grounded tables/views or expand grounding to include the referenced entities.',\n sql_attempted: sql,\n referenced_entities: referencedEntities,\n allowed_entities: allowedEntities,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n", "import {\n Adapter,\n type ExecuteFunction,\n type GroundingFn,\n type ValidateFunction,\n} from '../adapter.ts';\nimport { ClickHouseSqlPolicyAnalyzer } from './clickhouse.sql-policy.ts';\n\nexport interface ClickHouseAdapterOptions {\n execute: ExecuteFunction;\n validate: ValidateFunction;\n grounding?: GroundingFn[];\n defaultDatabase?: string;\n}\n\ntype RowResult<Row> = Row[] | { data: Row[] } | { rows: Row[] };\n\nexport class ClickHouse extends Adapter {\n readonly #options: ClickHouseAdapterOptions;\n\n override readonly grounding: GroundingFn[];\n override readonly defaultSchema: string | undefined;\n override readonly systemSchemas = [\n 'system',\n 'information_schema',\n 'INFORMATION_SCHEMA',\n ];\n override readonly formatterLanguage = 'clickhouse';\n\n constructor(options: ClickHouseAdapterOptions) {\n if (!options || typeof options.execute !== 'function') {\n throw new Error('ClickHouse adapter requires an execute(sql) function.');\n }\n if (typeof options.validate !== 'function') {\n throw new Error('ClickHouse adapter requires a validate(sql) function.');\n }\n\n super(new ClickHouseSqlPolicyAnalyzer(options.execute));\n this.#options = options;\n this.grounding = options.grounding ?? [];\n this.defaultSchema = options.defaultDatabase;\n }\n\n override async executeImpl(sql: string): Promise<unknown[]> {\n return rowsFromResult(await this.#options.execute(sql));\n }\n\n override async validateImpl(sql: string): Promise<string | void> {\n try {\n return await this.#options.validate(sql);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return JSON.stringify({\n error: message,\n error_type: 'CLICKHOUSE_ERROR',\n suggestion:\n 'Review the ClickHouse syntax and verify referenced databases, tables, columns, and functions.',\n sql_attempted: sql,\n });\n }\n }\n\n override async runQuery<Row>(sql: string): Promise<Row[]> {\n return rowsFromResult<Row>(await this.#options.execute(sql));\n }\n\n override quoteIdentifier(name: string): string {\n return `\\`${name.replace(/`/g, '``')}\\``;\n }\n\n override escape(value: string): string {\n return value.replace(/`/g, '``');\n }\n\n override buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string {\n const { schema, table } = this.parseTableName(tableName);\n const relation = schema\n ? `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table)}`\n : this.quoteIdentifier(table);\n const projection = columns?.length\n ? columns.map((column) => this.quoteIdentifier(column)).join(', ')\n : '*';\n return `SELECT ${projection} FROM ${relation} LIMIT ${limit}`;\n }\n}\n\nfunction rowsFromResult<Row>(result: unknown): Row[] {\n if (Array.isArray(result)) return result as Row[];\n if (result && typeof result === 'object') {\n const candidate = result as Partial<RowResult<Row>> & {\n data?: unknown;\n rows?: unknown;\n };\n if (Array.isArray(candidate.data)) return candidate.data as Row[];\n if (Array.isArray(candidate.rows)) return candidate.rows as Row[];\n }\n throw new Error(\n 'ClickHouse execute() must return an array of rows, { data: rows }, or { rows }.',\n );\n}\n", "import type { Filter, IntrospectionPhase } from '../adapter.ts';\nimport type { GroundingContext } from './context.ts';\n\nexport type { AdapterInfo, AdapterInfoProvider, Filter } from '../adapter.ts';\n\n/**\n * Per-entity column filter.\n * Maps entity name (table or view) to a Filter that selects which columns to keep.\n * Entities not listed in the record keep all their columns.\n */\nexport type ColumnsFilter = Record<string, Filter>;\n\n/**\n * Filter a columns array using a Filter.\n * Keeps columns whose name matches the filter.\n */\nexport function filterColumns<T extends { name: string }>(\n columns: T[],\n filter: Filter,\n): T[] {\n if (Array.isArray(filter)) {\n return columns.filter((col) => filter.includes(col.name));\n }\n if (filter instanceof RegExp) {\n return columns.filter((col) => filter.test(col.name));\n }\n return columns.filter((col) => filter(col.name));\n}\n\n/**\n * Apply per-entity column filtering.\n * Returns the entity unchanged if no filter matches its name.\n */\nexport function applyColumnFilter<\n T extends { name: string; columns: { name: string }[] },\n>(entity: T, columnsConfig?: ColumnsFilter): T {\n if (!columnsConfig) return entity;\n const filter = columnsConfig[entity.name];\n if (!filter) return entity;\n return { ...entity, columns: filterColumns(entity.columns, filter) } as T;\n}\n\n/**\n * Abstract base class for database schema groundings.\n *\n * Groundings collect schema metadata into the shared GroundingContext.\n * Fragment generation is centralized in Adapter.introspect().\n */\nexport abstract class AbstractGrounding {\n /**\n * Grounding identifier for debugging/logging.\n */\n name: string;\n phase?: IntrospectionPhase;\n\n constructor(name: string, phase?: IntrospectionPhase) {\n this.name = name;\n this.phase = phase;\n }\n\n /**\n * Execute grounding to populate the shared context.\n * Groundings mutate ctx to add their collected data (tables, views, indexes, etc).\n * Fragment generation happens centrally in Adapter after all groundings complete.\n *\n * @param ctx - Shared context for accumulating schema data\n */\n abstract execute(ctx: GroundingContext): Promise<void>;\n\n /**\n * Populate ctx with the tables/views this grounding makes available for scope\n * resolution. Annotators decorate entities other groundings produced and add\n * no membership, so the default is a no-op; entity-producing groundings\n * override it. This lets scope resolution skip the annotators' metadata scans.\n *\n * @param _ctx - Shared context for accumulating entity membership\n */\n async contributeEntities(_ctx: GroundingContext): Promise<void> {}\n}\n", "import type { TableConstraint } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for ConstraintGrounding.\n */\nexport interface ConstraintGroundingConfig {\n // Future: filter which tables/constraint types to collect\n}\n\n/**\n * Abstract base class for constraint grounding.\n *\n * Reads tables from the context and annotates them with constraints\n * (CHECK, UNIQUE, NOT_NULL, DEFAULT).\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getConstraints()` - fetch constraints for a table\n */\nexport abstract class ConstraintGrounding extends AbstractGrounding {\n constructor(config: ConstraintGroundingConfig = {}) {\n super('constraint', 'constraints');\n }\n\n /**\n * Fetch constraints for a specific table.\n */\n protected abstract getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their constraints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'constraints',\n table: table.name,\n message: `Loading constraints for ${table.name}...`,\n current: i + 1,\n total,\n });\n try {\n table.constraints = await this.getConstraints(table.name);\n } catch (error) {\n // Skip on error - table might not exist or be inaccessible\n console.warn('Error collecting constraints for', table.name, error);\n }\n }\n }\n}\n", "import type { Adapter, TableConstraint } from '../adapter.ts';\nimport {\n ConstraintGrounding,\n type ConstraintGroundingConfig,\n} from '../groundings/constraint.grounding.ts';\n\ntype ColumnMetadataRow = {\n name: string;\n type: string;\n default_kind: string;\n default_expression: string;\n is_in_primary_key: number | string;\n};\n\nexport class ClickHouseConstraintGrounding extends ConstraintGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: ConstraintGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n if (!schema) return [];\n\n const rows = await this.#adapter.runQuery<ColumnMetadataRow>(`\n SELECT name, type, default_kind, default_expression, is_in_primary_key\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY position\n `);\n const constraints: TableConstraint[] = [];\n const primaryKey = rows\n .filter((row) => Number(row.is_in_primary_key) === 1)\n .map((row) => row.name);\n\n if (primaryKey.length > 0) {\n constraints.push({\n name: 'PRIMARY_KEY',\n type: 'PRIMARY_KEY',\n columns: primaryKey,\n });\n }\n\n for (const row of rows) {\n if (!hasNullableType(row.type)) {\n constraints.push({\n name: `${row.name}_not_null`,\n type: 'NOT_NULL',\n columns: [row.name],\n });\n }\n if (row.default_kind === 'DEFAULT' && row.default_expression) {\n constraints.push({\n name: `${row.name}_default`,\n type: 'DEFAULT',\n columns: [row.name],\n defaultValue: row.default_expression,\n });\n }\n }\n\n return constraints;\n }\n}\n\nfunction hasNullableType(type: string): boolean {\n return /(?:^|\\()Nullable\\(/.test(type);\n}\n", "import type { TableIndex } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for IndexesGrounding.\n */\nexport interface IndexesGroundingConfig {\n // Future: filter which tables to collect indexes for\n}\n\n/**\n * Abstract base class for indexes grounding.\n *\n * Reads tables from the context and annotates them with index metadata.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getIndexes()` - fetch indexes for a table\n */\nexport abstract class IndexesGrounding extends AbstractGrounding {\n constructor(config: IndexesGroundingConfig = {}) {\n super('index', 'indexes');\n }\n\n /**\n * Fetch indexes for a specific table.\n */\n protected abstract getIndexes(tableName: string): Promise<TableIndex[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their indexes and marks indexed columns.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'indexes',\n table: table.name,\n message: `Loading indexes for ${table.name}...`,\n current: i + 1,\n total,\n });\n table.indexes = await this.getIndexes(table.name);\n // Mark columns that are part of indexes\n for (const index of table.indexes ?? []) {\n for (const colName of index.columns) {\n const column = table.columns.find((c) => c.name === colName);\n if (column) {\n column.isIndexed = true;\n }\n }\n }\n }\n }\n}\n", "import type { Adapter, TableIndex } from '../adapter.ts';\nimport {\n IndexesGrounding,\n type IndexesGroundingConfig,\n} from '../groundings/indexes.grounding.ts';\n\ntype PrimaryKeyRow = {\n name: string;\n};\n\ntype DataSkippingIndexRow = {\n name: string;\n type: string;\n expression: string;\n};\n\nexport class ClickHouseIndexesGrounding extends IndexesGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: IndexesGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getIndexes(\n tableName: string,\n ): Promise<TableIndex[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n if (!schema) return [];\n\n const [primaryKeyRows, indexRows] = await Promise.all([\n this.#adapter.runQuery<PrimaryKeyRow>(`\n SELECT name\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n AND is_in_primary_key = 1\n ORDER BY position\n `),\n this.#adapter.runQuery<DataSkippingIndexRow>(`\n SELECT name, type_full AS type, expr AS expression\n FROM system.data_skipping_indices\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY name\n `),\n ]);\n\n const indexes: TableIndex[] = [];\n if (primaryKeyRows.length > 0) {\n indexes.push({\n name: 'PRIMARY_KEY',\n columns: primaryKeyRows.map((row) => row.name),\n type: 'PRIMARY_KEY',\n });\n }\n indexes.push(\n ...indexRows.map((row) => ({\n name: row.name,\n columns: splitTopLevelExpressions(row.expression),\n type: row.type,\n })),\n );\n return indexes;\n }\n}\n\nfunction splitTopLevelExpressions(expression: string): string[] {\n const parts: string[] = [];\n let start = 0;\n let depth = 0;\n for (let index = 0; index < expression.length; index++) {\n const character = expression[index];\n if (character === '(' || character === '[') depth++;\n if (character === ')' || character === ']') depth--;\n if (character === ',' && depth === 0) {\n parts.push(expression.slice(start, index).trim());\n start = index + 1;\n }\n }\n parts.push(expression.slice(start).trim());\n return parts.filter(Boolean);\n}\n", "import type { AdapterInfo } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for InfoGrounding.\n */\nexport interface InfoGroundingConfig {\n // Future: options to control what info to collect\n}\n\n/**\n * Abstract base class for database info grounding.\n *\n * Collects database dialect, version, and connection info.\n *\n * Subclasses implement the database-specific hook:\n * - `collectInfo()` - collect database info\n */\nexport abstract class InfoGrounding extends AbstractGrounding {\n constructor(config: InfoGroundingConfig = {}) {\n super('dialectInfo', 'info');\n }\n\n /**\n * Collect database dialect, version, and other info.\n */\n protected abstract collectInfo(): Promise<AdapterInfo>;\n\n /**\n * Execute the grounding process.\n * Writes database info to ctx.info.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n ctx.info = await this.collectInfo();\n }\n}\n", "import type { Adapter, AdapterInfo } from '../adapter.ts';\nimport {\n InfoGrounding,\n type InfoGroundingConfig,\n} from '../groundings/info.grounding.ts';\n\ntype InfoRow = {\n version: string;\n database: string;\n};\n\nexport class ClickHouseInfoGrounding extends InfoGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: InfoGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async collectInfo(): Promise<AdapterInfo> {\n const rows = await this.#adapter.runQuery<InfoRow>(\n 'SELECT version() AS version, currentDatabase() AS database',\n );\n const row = rows[0];\n return {\n dialect: 'clickhouse',\n version: row?.version,\n database: row?.database || undefined,\n details: {\n identifierQuote: '`',\n qualifiedTable: 'database.table',\n },\n };\n }\n}\n", "import type { Table } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for RowCountGrounding.\n */\nexport interface RowCountGroundingConfig {\n // Future: filter which tables to count\n}\n\n/**\n * Abstract base class for row count grounding.\n *\n * Reads tables from the context and annotates them with row counts and size hints.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getRowCount()` - get row count for a table\n */\nexport abstract class RowCountGrounding extends AbstractGrounding {\n constructor(config: RowCountGroundingConfig = {}) {\n super('rowCount', 'row_counts');\n }\n\n /**\n * Get row count for a specific table.\n */\n protected abstract getRowCount(\n tableName: string,\n ): Promise<number | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with row counts and size hints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'row_counts',\n table: table.name,\n message: `Counting rows in ${table.name}...`,\n current: i + 1,\n total,\n });\n const count = await this.getRowCount(table.name);\n if (count != null) {\n table.rowCount = count;\n table.sizeHint = this.#classifyRowCount(count);\n }\n }\n }\n\n /**\n * Classify row count into a size hint category.\n */\n #classifyRowCount(count: number): Table['sizeHint'] {\n if (count < 100) return 'tiny';\n if (count < 1000) return 'small';\n if (count < 10000) return 'medium';\n if (count < 100000) return 'large';\n return 'huge';\n }\n}\n", "import type { Adapter } from '../adapter.ts';\nimport {\n RowCountGrounding,\n type RowCountGroundingConfig,\n} from '../groundings/row-count.grounding.ts';\n\nexport class ClickHouseRowCountGrounding extends RowCountGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: RowCountGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getRowCount(\n tableName: string,\n ): Promise<number | undefined> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const relation = schema\n ? `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`\n : this.#adapter.quoteIdentifier(table);\n\n try {\n const rows = await this.#adapter.runQuery<{\n count: number | string | bigint | null;\n }>(`SELECT count() AS count FROM ${relation}`);\n return toNumber(rows[0]?.count);\n } catch {\n return undefined;\n }\n }\n}\n\nfunction toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'bigint') return Number(value);\n if (typeof value === 'string' && value.trim()) {\n const parsed = Number(value);\n if (Number.isFinite(parsed)) return parsed;\n }\n return undefined;\n}\n", "import type { Filter, Relationship, Table } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n filterColumns,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for TableGrounding.\n */\nexport interface TableGroundingConfig {\n /** Filter to select seed tables */\n filter?: Filter;\n /**\n * Per-table column filter.\n * Maps table name to a Filter that selects which columns to keep.\n * Tables not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /**\n * Traverse forward (child\u2192parent) following FK direction.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no forward traversal\n */\n forward?: boolean | number;\n /**\n * Traverse backward (parent\u2192child) finding tables that reference us.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no backward traversal\n */\n backward?: boolean | number;\n}\n\n/**\n * Abstract base class for table grounding.\n *\n * The `execute()` method implements a BFS traversal algorithm that discovers\n * tables and relationships. Subclasses implement the database-specific hooks:\n * - `getAllTableNames()` - list all tables\n * - `getTable()` - get table metadata\n * - `findOutgoingRelations()` - find FKs FROM a table\n * - `findIncomingRelations()` - find FKs TO a table\n */\nexport abstract class TableGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n #forward?: boolean | number;\n #backward?: boolean | number;\n\n constructor(config: TableGroundingConfig = {}) {\n super('table', 'tables');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.#forward = config.forward;\n this.#backward = config.backward;\n }\n\n /** Get all table names in the database */\n protected abstract getAllTableNames(): Promise<string[]>;\n\n /** Get full table metadata for a single table */\n protected abstract getTable(tableName: string): Promise<Table>;\n\n /** Find FKs FROM this table (outgoing relationships) */\n protected abstract findOutgoingRelations(\n tableName: string,\n ): Promise<Relationship[]>;\n\n /** Find FKs TO this table (incoming relationships) */\n protected abstract findIncomingRelations(\n tableName: string,\n ): Promise<Relationship[]>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered tables and relationships to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const seedTables = await this.applyFilter();\n const forward = this.#forward;\n const backward = this.#backward;\n\n // No traversal at all - just add the seed tables\n if (!forward && !backward) {\n const tables = await Promise.all(\n seedTables.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: index + 1,\n total: seedTables.length,\n });\n return applyColumnFilter(await this.getTable(name), this.#columns);\n }),\n );\n ctx.tables.push(...tables);\n return;\n }\n\n const tables: Record<string, Table> = {};\n const allRelationships: Relationship[] = [];\n const seenRelationships = new Set<string>();\n\n // Track depth separately for forward/backward using BFS\n const forwardQueue: Array<{ name: string; depth: number }> = [];\n const backwardQueue: Array<{ name: string; depth: number }> = [];\n const forwardVisited = new Set<string>();\n const backwardVisited = new Set<string>();\n let loadedCount = 0;\n\n // Initialize queues with seed tables at depth 0\n for (const name of seedTables) {\n if (forward) forwardQueue.push({ name, depth: 0 });\n if (backward) backwardQueue.push({ name, depth: 0 });\n }\n\n // Process forward (child\u2192parent)\n const forwardLimit = forward === true ? Infinity : forward || 0;\n while (forwardQueue.length > 0) {\n const item = forwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (forwardVisited.has(name)) continue;\n forwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < forwardLimit) {\n const rels = await this.findOutgoingRelations(name);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!forwardVisited.has(rel.referenced_table)) {\n forwardQueue.push({ name: rel.referenced_table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Process backward (parent\u2192child)\n const backwardLimit = backward === true ? Infinity : backward || 0;\n while (backwardQueue.length > 0) {\n const item = backwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (backwardVisited.has(name)) continue;\n backwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < backwardLimit) {\n const rels = await this.findIncomingRelations(name);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!backwardVisited.has(rel.table)) {\n backwardQueue.push({ name: rel.table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Write to context\n const tablesList = Object.values(tables);\n ctx.tables.push(...tablesList);\n ctx.relationships.push(...allRelationships);\n }\n\n /**\n * Apply the filter to get seed table names.\n * If filter is an explicit array, skip querying all table names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllTableNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n\n /**\n * Add a relationship to the collection, deduplicating by key.\n */\n protected addRelationship(\n rel: Relationship,\n all: Relationship[],\n seen: Set<string>,\n ): void {\n const key = `${rel.table}:${rel.from.join(',')}:${rel.referenced_table}:${rel.to.join(',')}`;\n if (!seen.has(key)) {\n seen.add(key);\n all.push(rel);\n }\n }\n\n protected isRelationshipVisible(rel: Relationship): boolean {\n return (\n this.areColumnsVisible(rel.from, this.#columns?.[rel.table]) &&\n this.areColumnsVisible(rel.to, this.#columns?.[rel.referenced_table])\n );\n }\n\n protected areColumnsVisible(names: string[], filter?: Filter): boolean {\n if (!filter) return true;\n return (\n filterColumns(\n names.map((name) => ({ name })),\n filter,\n ).length === names.length\n );\n }\n}\n", "import type { Adapter, Relationship, Table } from '../adapter.ts';\nimport {\n TableGrounding,\n type TableGroundingConfig,\n} from '../groundings/table.grounding.ts';\n\ntype ColumnRow = {\n name: string;\n type: string;\n};\n\nexport class ClickHouseTableGrounding extends TableGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: TableGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getAllTableNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery<{ name: string }>(`\n SELECT concat(database, '.', name) AS name\n FROM system.tables\n WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA')\n AND is_temporary = 0\n AND engine != 'View'\n ORDER BY database, name\n `);\n return rows.map((row) => row.name);\n }\n\n protected override async getTable(tableName: string): Promise<Table> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n if (!schema) {\n throw new Error(\n `ClickHouse table grounding requires a qualified table name: ${tableName}`,\n );\n }\n const rows = await this.#adapter.runQuery<ColumnRow>(`\n SELECT name, type\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY position\n `);\n return {\n name: tableName,\n schema,\n rawName: table,\n columns: rows.map((row) => ({ name: row.name, type: row.type })),\n };\n }\n\n protected override async findOutgoingRelations(): Promise<Relationship[]> {\n return [];\n }\n\n protected override async findIncomingRelations(): Promise<Relationship[]> {\n return [];\n }\n}\n", "import type { ColumnStats, Filter } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Represents a database view with its metadata.\n */\nexport interface View {\n name: string;\n schema?: string;\n rawName?: string;\n /** The SQL definition of the view (CREATE VIEW statement or query) */\n definition?: string;\n columns: {\n name: string;\n type: string;\n /** Low cardinality marker */\n kind?: 'LowCardinality';\n /** Distinct values for low cardinality columns */\n values?: string[];\n /** Column statistics (min, max, nullFraction) */\n stats?: ColumnStats;\n }[];\n}\n\n/**\n * Configuration for ViewGrounding.\n */\nexport interface ViewGroundingConfig {\n /** Filter to select views */\n filter?: Filter;\n /**\n * Per-view column filter.\n * Maps view name to a Filter that selects which columns to keep.\n * Views not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /** Whether to fetch the SQL definition of each view (default: true) */\n includeDefinition?: boolean;\n}\n\n/**\n * Abstract base class for view grounding\n *\n * The `execute()` method implements the algorithm that discovers views.\n * Subclasses implement the database-specific hooks:\n * - `getAllViewNames()` - list all views\n * - `getView()` - get view metadata\n */\nexport abstract class ViewGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n protected includeDefinition: boolean;\n\n constructor(config: ViewGroundingConfig = {}) {\n super('view', 'views');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.includeDefinition = config.includeDefinition ?? true;\n }\n\n /** Get all view names in the database */\n protected abstract getAllViewNames(): Promise<string[]>;\n\n /** Get full view metadata for a single view */\n protected abstract getView(viewName: string): Promise<View>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered views to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const viewNames = await this.applyFilter();\n const views = await Promise.all(\n viewNames.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'views',\n table: name,\n message: `Loading view ${name}...`,\n current: index + 1,\n total: viewNames.length,\n });\n return applyColumnFilter(await this.getView(name), this.#columns);\n }),\n );\n ctx.views.push(...views);\n }\n\n /**\n * Apply the filter to get view names.\n * If filter is an explicit array, skip querying all view names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllViewNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n}\n", "import type { Adapter } from '../adapter.ts';\nimport {\n type View,\n ViewGrounding,\n type ViewGroundingConfig,\n} from '../groundings/view.grounding.ts';\n\ntype ColumnRow = {\n name: string;\n type: string;\n};\n\nexport class ClickHouseViewGrounding extends ViewGrounding {\n readonly #adapter: Adapter;\n\n constructor(adapter: Adapter, config: ViewGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getAllViewNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery<{ name: string }>(`\n SELECT concat(database, '.', name) AS name\n FROM system.tables\n WHERE database NOT IN ('system', 'information_schema', 'INFORMATION_SCHEMA')\n AND is_temporary = 0\n AND endsWith(engine, 'View')\n ORDER BY database, name\n `);\n return rows.map((row) => row.name);\n }\n\n protected override async getView(viewName: string): Promise<View> {\n const { schema, table } = this.#adapter.parseTableName(viewName);\n if (!schema) {\n throw new Error(\n `ClickHouse view grounding requires a qualified view name: ${viewName}`,\n );\n }\n\n const [columns, definitionRows] = await Promise.all([\n this.#adapter.runQuery<ColumnRow>(`\n SELECT name, type\n FROM system.columns\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND table = '${this.#adapter.escapeString(table)}'\n ORDER BY position\n `),\n this.includeDefinition\n ? this.#adapter.runQuery<{ definition: string }>(`\n SELECT create_table_query AS definition\n FROM system.tables\n WHERE database = '${this.#adapter.escapeString(schema)}'\n AND name = '${this.#adapter.escapeString(table)}'\n AND endsWith(engine, 'View')\n `)\n : Promise.resolve([]),\n ]);\n\n return {\n name: viewName,\n schema,\n rawName: table,\n definition: definitionRows[0]?.definition,\n columns: columns.map((column) => ({\n name: column.name,\n type: column.type,\n })),\n };\n }\n}\n", "import type { Adapter } from '../adapter.ts';\nimport type { ConstraintGroundingConfig } from '../groundings/constraint.grounding.ts';\nimport type { IndexesGroundingConfig } from '../groundings/indexes.grounding.ts';\nimport type { InfoGroundingConfig } from '../groundings/info.grounding.ts';\nimport type { RowCountGroundingConfig } from '../groundings/row-count.grounding.ts';\nimport type { TableGroundingConfig } from '../groundings/table.grounding.ts';\nimport type { ViewGroundingConfig } from '../groundings/view.grounding.ts';\nimport { ClickHouse } from './clickhouse.ts';\nimport { ClickHouseConstraintGrounding } from './constraint.clickhouse.grounding.ts';\nimport { ClickHouseIndexesGrounding } from './indexes.clickhouse.grounding.ts';\nimport { ClickHouseInfoGrounding } from './info.clickhouse.grounding.ts';\nimport { ClickHouseRowCountGrounding } from './row-count.clickhouse.grounding.ts';\nimport { ClickHouseTableGrounding } from './table.clickhouse.grounding.ts';\nimport { ClickHouseViewGrounding } from './view.clickhouse.grounding.ts';\n\nexport * from './clickhouse.ts';\nexport { ClickHouseSqlPolicyAnalyzer } from './clickhouse.sql-policy.ts';\n\nexport function tables(config: TableGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseTableGrounding(adapter, config);\n}\n\nexport function views(config: ViewGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseViewGrounding(adapter, config);\n}\n\nexport function info(config: InfoGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseInfoGrounding(adapter, config);\n}\n\nexport function indexes(config: IndexesGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseIndexesGrounding(adapter, config);\n}\n\nexport function rowCount(config: RowCountGroundingConfig = {}) {\n return (adapter: Adapter) => new ClickHouseRowCountGrounding(adapter, config);\n}\n\nexport function constraints(config: ConstraintGroundingConfig = {}) {\n return (adapter: Adapter) =>\n new ClickHouseConstraintGrounding(adapter, config);\n}\n\nexport default {\n ClickHouse,\n constraints,\n indexes,\n info,\n rowCount,\n tables,\n views,\n};\n"],
|
|
5
|
+
"mappings": ";AAAA,SAA2B,UAAU,iBAAiB;;;ACAtD,IAAM,sBAAsB,uBAAO,oBAAoB;AACvD,IAAM,wBAAwB,uBAAO,sBAAsB;AAC3D,IAAM,iBAAiB,uBAAO,eAAe;AAC7C,IAAM,oBAAoB,uBAAO,kBAAkB;AAkB5C,IAAM,qBAAN,MAAM,4BAA2B,MAAM;AAAA,EAC5C,CAAC,mBAAmB;AAAA,EAEpB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,mBAAmB,IAAI;AAAA,EAC9B;AAAA,EAEA,OAAO,WAAW,OAA6C;AAC7D,WACE,iBAAiB,uBAAsB,MAAM,mBAAmB,MAAM;AAAA,EAE1E;AACF;AAKO,IAAM,uBAAN,MAAM,8BAA6B,MAAM;AAAA,EAC9C,CAAC,qBAAqB;AAAA,EAEtB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,qBAAqB,IAAI;AAAA,EAChC;AAAA,EAEA,OAAO,WAAW,OAA+C;AAC/D,WACE,iBAAiB,yBACjB,MAAM,qBAAqB,MAAM;AAAA,EAErC;AACF;AAKO,IAAM,gBAAN,MAAM,uBAAsB,MAAM;AAAA,EACvC,CAAC,cAAc;AAAA,EACN;AAAA,EACA;AAAA,EAET,YAAY,SAA+B;AACzC,UAAM,KAAK,UAAU,OAAO,CAAC;AAC7B,SAAK,OAAO;AACZ,SAAK,UAAU;AACf,SAAK,YAAY,QAAQ;AACzB,SAAK,cAAc,IAAI;AAAA,EACzB;AAAA,EAEA,OAAO,WAAW,OAAwC;AACxD,WAAO,iBAAiB,kBAAiB,MAAM,cAAc,MAAM;AAAA,EACrE;AACF;AAKO,IAAM,mBAAN,MAAM,0BAAyB,MAAM;AAAA,EAC1C,CAAC,iBAAiB;AAAA,EAElB,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,iBAAiB,IAAI;AAAA,EAC5B;AAAA,EAEA,OAAO,WAAW,OAA2C;AAC3D,WACE,iBAAiB,qBAAoB,MAAM,iBAAiB,MAAM;AAAA,EAEtE;AACF;;;AC5DO,SAAS,YAAY,OAKR;AAClB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,SAAS,MAAM;AAAA,MACf,GAAI,MAAM,WAAW,EAAE,SAAS,MAAM,QAAQ;AAAA,MAC9C,GAAI,MAAM,YAAY,EAAE,UAAU,MAAM,SAAS;AAAA,MACjD,GAAI,MAAM,WAAW,EAAE,SAAS,MAAM,QAAQ;AAAA,IAChD;AAAA,EACF;AACF;AA2BO,SAAS,MAAM,OAQF;AAClB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,UAAU,EAAE,QAAQ,MAAM,OAAO;AAAA,MAC3C,GAAI,MAAM,YAAY,QAAQ,EAAE,UAAU,MAAM,SAAS;AAAA,MACzD,GAAI,MAAM,YAAY,EAAE,UAAU,MAAM,SAAS;AAAA,MACjD,SAAS,MAAM;AAAA,MACf,GAAI,MAAM,SAAS,UAAU,EAAE,SAAS,MAAM,QAAQ;AAAA,MACtD,GAAI,MAAM,aAAa,UAAU,EAAE,aAAa,MAAM,YAAY;AAAA,IACpE;AAAA,EACF;AACF;AAyBO,SAAS,OAAO,OAiBH;AAClB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,MAAM,EAAE,IAAI,KAAK;AAAA,MAC3B,GAAI,MAAM,MAAM,EAAE,IAAI,MAAM,GAAG;AAAA,MAC/B,GAAI,MAAM,UAAU,EAAE,QAAQ,KAAK;AAAA,MACnC,GAAI,MAAM,WAAW,EAAE,SAAS,KAAK;AAAA,MACrC,GAAI,MAAM,WAAW,EAAE,SAAS,MAAM,QAAQ;AAAA,MAC9C,GAAI,MAAM,WAAW,EAAE,SAAS,KAAK;AAAA,MACrC,GAAI,MAAM,QAAQ,UAAU,EAAE,QAAQ,MAAM,OAAO;AAAA,MACnD,GAAI,MAAM,SAAS,EAAE,OAAO,MAAM,MAAM;AAAA,IAC1C;AAAA,EACF;AACF;AAaO,SAAS,MAAM,OAKF;AAClB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,MAAM,MAAM;AAAA,MACZ,SAAS,MAAM;AAAA,MACf,GAAI,MAAM,UAAU,EAAE,QAAQ,KAAK;AAAA,MACnC,GAAI,MAAM,QAAQ,EAAE,MAAM,MAAM,KAAK;AAAA,IACvC;AAAA,EACF;AACF;AA6BO,SAAS,WAAW,OAcP;AAClB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,SAAS,UAAU,EAAE,SAAS,MAAM,QAAQ;AAAA,MACtD,GAAI,MAAM,cAAc,EAAE,YAAY,MAAM,WAAW;AAAA,MACvD,GAAI,MAAM,gBAAgB,EAAE,cAAc,MAAM,aAAa;AAAA,MAC7D,GAAI,MAAM,mBAAmB,EAAE,iBAAiB,MAAM,gBAAgB;AAAA,MACtE,GAAI,MAAM,mBAAmB,UAAU;AAAA,QACrC,mBAAmB,MAAM;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACF;AAoBO,SAAS,KAAK,OAKD;AAClB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,MAAM,MAAM;AAAA,MACZ,GAAI,MAAM,UAAU,EAAE,QAAQ,MAAM,OAAO;AAAA,MAC3C,SAAS,MAAM;AAAA,MACf,GAAI,MAAM,cAAc,EAAE,YAAY,MAAM,WAAW;AAAA,IACzD;AAAA,EACF;AACF;AAgBO,SAAS,aAAa,OAIT;AAClB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,GAAI,MAAM,eAAe,EAAE,aAAa,MAAM,YAAY;AAAA,IAC5D;AAAA,EACF;AACF;;;ACxPA,IAAM,eAA2B,MAAM;AAAC;AAExC,SAAS,kBAAkB,YAAqC;AAC9D,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,CAAC,aAAa;AACnB,eAAW;AAAA,MACT,GAAG;AAAA,MACH,aAAa,SAAS,eAAe,KAAK,IAAI;AAAA,IAChD,CAAC;AAAA,EACH;AACF;AAKO,SAAS,uBACd,UAAuC,CAAC,GACtB;AAClB,SAAO;AAAA,IACL,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,eAAe,CAAC;AAAA,IAChB,MAAM;AAAA,IACN,WAAW,CAAC;AAAA,IACZ,OAAO,oBAAI,IAAI;AAAA,IACf,YAAY,kBAAkB,QAAQ,UAAU;AAAA,EAClD;AACF;;;AHyDO,IAAe,UAAf,MAAuB;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKC,YAAY,gBAAmC;AACvD,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,MAAM,WAAW,MAAM,uBAAuB,GAA+B;AAE3E,eAAW,MAAM,KAAK,WAAW;AAC/B,YAAM,YAAY,GAAG,IAAI;AACzB,UAAI,UAAU,OAAO;AACnB,YAAI,WAAW;AAAA,UACb,MAAM;AAAA,UACN,OAAO,UAAU;AAAA,UACjB,SAAS,YAAY,UAAU,IAAI;AAAA,QACrC,CAAC;AAAA,MACH;AACA,UAAI;AACF,cAAM,UAAU,QAAQ,GAAG;AAAA,MAC7B,UAAE;AACA,YAAI,UAAU,OAAO;AACnB,cAAI,WAAW;AAAA,YACb,MAAM;AAAA,YACN,OAAO,UAAU;AAAA,YACjB,SAAS,YAAY,UAAU,IAAI;AAAA,UACrC,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,WAAO,KAAK,mBAAmB,GAAG;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,yBAA4C;AAChD,UAAM,MAAM,uBAAuB;AACnC,eAAW,MAAM,KAAK,WAAW;AAC/B,YAAM,GAAG,IAAI,EAAE,mBAAmB,GAAG;AAAA,IACvC;AACA,WAAO,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,GAAG,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAmB,KAA0C;AAC3D,UAAM,YAA+B,CAAC;AAGtC,QAAI,IAAI,MAAM;AACZ,gBAAU;AAAA,QACR,YAAY;AAAA,UACV,SAAS,IAAI,KAAK;AAAA,UAClB,SAAS,IAAI,KAAK;AAAA,UAClB,UAAU,IAAI,KAAK;AAAA,UACnB,SAAS,IAAI,KAAK;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,eAAW,KAAK,IAAI,QAAQ;AAC1B,gBAAU,KAAK,KAAK,iBAAiB,CAAC,CAAC;AAAA,IACzC;AAGA,eAAW,KAAK,IAAI,OAAO;AACzB,gBAAU,KAAK,KAAK,gBAAgB,CAAC,CAAC;AAAA,IACxC;AAGA,UAAM,WAAW,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3D,UAAM,kBAAkB,IAAI;AAAA,MAC1B,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,IAAI,EAAE,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AAAA,IACvE;AACA,eAAW,OAAO,IAAI,eAAe;AACnC,YAAM,gBAAgB,gBAAgB,IAAI,IAAI,KAAK;AACnD,YAAM,gBAAgB,gBAAgB,IAAI,IAAI,gBAAgB;AAC9D,UACE,iBACA,IAAI,KAAK,KAAK,CAACA,YAAW,CAAC,cAAc,IAAIA,OAAM,CAAC,GACpD;AACA;AAAA,MACF;AACA,UACE,iBACA,IAAI,GAAG,KAAK,CAACA,YAAW,CAAC,cAAc,IAAIA,OAAM,CAAC,GAClD;AACA;AAAA,MACF;AAEA,YAAM,cAAc,SAAS,IAAI,IAAI,KAAK;AAC1C,YAAM,cAAc,SAAS,IAAI,IAAI,gBAAgB;AACrD,gBAAU;AAAA,QACR,KAAK,wBAAwB,KAAK,aAAa,WAAW;AAAA,MAC5D;AAAA,IACF;AAEA,cAAU,KAAK,GAAI,IAAI,aAAa,CAAC,CAAE;AAEvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,GAA2B;AAE1C,UAAM,eAAe,EAAE,aAAa,KAAK,CAAC,MAAM,EAAE,SAAS,aAAa;AACxE,UAAM,YAAY,IAAI,IAAI,cAAc,WAAW,CAAC,CAAC;AAErD,UAAM,iBAAiB,IAAI;AAAA,MACzB,EAAE,aACE,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU,EACpC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC;AAAA,IACzC;AAEA,UAAM,kBAAkB,oBAAI,IAAoB;AAChD,eAAW,KAAK,EAAE,aAAa,OAAO,CAACC,OAAMA,GAAE,SAAS,SAAS,KAAK,CAAC,GAAG;AACxE,iBAAW,OAAO,EAAE,WAAW,CAAC,GAAG;AACjC,YAAI,EAAE,gBAAgB,MAAM;AAC1B,0BAAgB,IAAI,KAAK,EAAE,YAAY;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAGA,UAAM,gBAAgB,IAAI;AAAA,MACxB,EAAE,aACE,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,SAAS,WAAW,CAAC,EAC7D,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,KAAK,CAAC;AAAA,IACzC;AAGA,UAAM,aAAa,oBAAI,IAAoB;AAC3C,eAAW,KAAK,EAAE,aAAa,OAAO,CAACA,OAAMA,GAAE,SAAS,aAAa,KACnE,CAAC,GAAG;AACJ,YAAM,OAAO,EAAE,WAAW,CAAC;AAC3B,YAAM,UAAU,EAAE,qBAAqB,CAAC;AACxC,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAM,SAAS,QAAQ,CAAC,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;AACjD,mBAAW,IAAI,KAAK,CAAC,GAAG,GAAG,EAAE,eAAe,IAAI,MAAM,EAAE;AAAA,MAC1D;AAAA,IACF;AAGA,UAAM,kBAAkB,EAAE,QAAQ;AAAA,MAAI,CAAC,QACrC,OAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,MAAM,IAAI;AAAA,QACV,IAAI,UAAU,IAAI,IAAI,IAAI,KAAK;AAAA,QAC/B,IAAI,WAAW,IAAI,IAAI,IAAI;AAAA,QAC3B,QAAQ,cAAc,IAAI,IAAI,IAAI,KAAK;AAAA,QACvC,SAAS,eAAe,IAAI,IAAI,IAAI,KAAK;AAAA,QACzC,SAAS,gBAAgB,IAAI,IAAI,IAAI;AAAA,QACrC,SAAS,IAAI,aAAa;AAAA,QAC1B,QAAQ,IAAI;AAAA,QACZ,OAAO,IAAI;AAAA,MACb,CAAC;AAAA,IACH;AAGA,UAAM,iBAAiB,IAAI,IAAI,EAAE,QAAQ,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAG3D,UAAM,kBAAkB,EAAE,WAAW,CAAC,GACnC;AAAA,MAAO,CAAC,QACP,IAAI,QAAQ,MAAM,CAACD,YAAW,eAAe,IAAIA,OAAM,CAAC;AAAA,IAC1D,EACC;AAAA,MAAI,CAAC,QACJ,MAAM;AAAA,QACJ,MAAM,IAAI;AAAA,QACV,SAAS,IAAI;AAAA,QACb,QAAQ,IAAI;AAAA,QACZ,MAAM,IAAI;AAAA,MACZ,CAAC;AAAA,IACH;AAGF,UAAM,uBAAuB,EAAE,eAAe,CAAC,GAC5C;AAAA,MACC,CAAC,MACC,EAAE,SAAS,WACV,EAAE,SAAS,aAAa,EAAE,SAAS,UAAU,KAAK;AAAA,IACvD,EACC;AAAA,MACC,CAAC,MACC,CAAC,EAAE,SAAS,UACZ,EAAE,QAAQ,MAAM,CAACA,YAAW,eAAe,IAAIA,OAAM,CAAC;AAAA,IAC1D,EACC;AAAA,MAAI,CAAC,MACJ,WAAW;AAAA,QACT,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,SAAS,EAAE;AAAA,QACX,YAAY,EAAE;AAAA,MAChB,CAAC;AAAA,IACH;AAEF,WAAO,MAAM;AAAA,MACX,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,UAAU,EAAE;AAAA,MACZ,UAAU,EAAE;AAAA,MACZ,SAAS;AAAA,MACT,SAAS,eAAe,SAAS,IAAI,iBAAiB;AAAA,MACtD,aACE,oBAAoB,SAAS,IAAI,sBAAsB;AAAA,IAC3D,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,GAA0B;AACxC,UAAM,kBAAkB,EAAE,QAAQ;AAAA,MAAI,CAAC,QACrC,OAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,MAAM,IAAI;AAAA,QACV,QAAQ,IAAI;AAAA,QACZ,OAAO,IAAI;AAAA,MACb,CAAC;AAAA,IACH;AAEA,WAAO,KAAK;AAAA,MACV,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,MACV,SAAS;AAAA,MACT,YAAY,EAAE;AAAA,IAChB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,wBACE,KACA,aACA,aACiB;AACjB,UAAM,cAAc,aAAa;AACjC,UAAM,cAAc,aAAa;AAEjC,QAAI;AAGJ,QAAI,eAAe,QAAQ,eAAe,QAAQ,cAAc,GAAG;AACjE,YAAM,QAAQ,cAAc;AAC5B,UAAI,QAAQ,GAAG;AACb,sBAAc;AAAA,MAChB,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACrC,sBAAc;AAAA,MAChB,WAAW,QAAQ,KAAK;AACtB,sBAAc;AAAA,MAChB;AAAA,IACF;AAEA,WAAO,aAAa;AAAA,MAClB,MAAM,EAAE,OAAO,IAAI,OAAO,SAAS,IAAI,KAAK;AAAA,MAC5C,IAAI,EAAE,OAAO,IAAI,kBAAkB,SAAS,IAAI,GAAG;AAAA,MACnD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,OAAO,KAAqB;AAC1B,UAAM,UAAU,KAAK,oBAAoB,GAAG;AAC5C,QAAI;AACF,aAAO,UAAU,SAAS,EAAE,UAAU,KAAK,kBAAkB,CAAC;AAAA,IAChE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,oBAAoB,KAAqB;AACvC,WAAO,IACJ,QAAQ,QAAQ,IAAI,EACpB,QAAQ,QAAQ,GAAI,EACpB,QAAQ,gBAAgB,IAAI,EAC5B,QAAQ,aAAa,EAAE;AAAA,EAC5B;AAAA,EAEA,yBAA0C;AAAA,EAE1C,MAAM,gBAAmC;AACvC,QAAI,KAAK,uBAAwB,QAAO,KAAK;AAC7C,SAAK,yBAAyB,MAAM,KAAK,uBAAuB;AAChE,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,eAAe,KAAiD;AACpE,WAAO,KAAK,gBAAgB,QAAQ,KAAK;AAAA,MACvC,wBAAwB,MAAM,KAAK,cAAc;AAAA,IACnD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,SAAS,KAAqC;AAClD,UAAM,UAAU,KAAK,oBAAoB,GAAG;AAC5C,UAAM,YAAY,MAAM,KAAK,eAAe,OAAO;AACnD,QAAI,WAAW,SAAS,YAAa,QAAO,UAAU;AACtD,QAAI,WAAW,SAAS,QAAS,QAAO,KAAK,UAAU,UAAU,OAAO;AACxE,WAAO,KAAK,aAAa,OAAO;AAAA,EAClC;AAAA,EAEA,MAAM,QAAQ,KAA6B;AACzC,WAAO,KAAK,YAAY,MAAM,KAAK,uBAAuB,GAAG,CAAC;AAAA,EAChE;AAAA,EAEA,MAAgB,uBAAuB,KAA8B;AACnE,UAAM,UAAU,KAAK,oBAAoB,GAAG;AAC5C,UAAM,YAAY,MAAM,KAAK,eAAe,OAAO;AACnD,QAAI,WAAW,SAAS,aAAa;AACnC,YAAM,IAAI,iBAAiB,UAAU,OAAO;AAAA,IAC9C;AACA,QAAI,WAAW,SAAS,SAAS;AAC/B,YAAM,IAAI,cAAc,UAAU,OAAO;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAgCA,SAAS,OAAoC;AAC3C,QAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG;AACvD,aAAO;AAAA,IACT;AACA,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,OAAO,KAAK;AAAA,IACrB;AACA,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,YAAM,SAAS,OAAO,KAAK;AAC3B,aAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,MAAiD;AAC9D,QAAI,KAAK,SAAS,GAAG,GAAG;AACtB,YAAM,CAAC,QAAQ,GAAG,IAAI,IAAI,KAAK,MAAM,GAAG;AACxC,aAAO,EAAE,QAAQ,OAAO,KAAK,KAAK,GAAG,EAAE;AAAA,IACzC;AACA,WAAO,EAAE,QAAQ,KAAK,iBAAiB,IAAI,OAAO,KAAK;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,OAAuB;AAClC,WAAO,MAAM,QAAQ,MAAM,IAAI;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,kBAAkB,YAAoB,gBAAmC;AACvE,QAAI,kBAAkB,eAAe,SAAS,GAAG;AAC/C,YAAM,SAAS,eACZ,IAAI,CAAC,MAAM,IAAI,KAAK,aAAa,CAAC,CAAC,GAAG,EACtC,KAAK,IAAI;AACZ,aAAO,OAAO,UAAU,QAAQ,MAAM;AAAA,IACxC;AACA,QAAI,KAAK,cAAc,SAAS,GAAG;AACjC,YAAM,SAAS,KAAK,cACjB,IAAI,CAAC,MAAM,IAAI,KAAK,aAAa,CAAC,CAAC,GAAG,EACtC,KAAK,IAAI;AACZ,aAAO,OAAO,UAAU,YAAY,MAAM;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AACF;;;AIjkBO,SAAS,4BACd,KACA,eACA,OACsB;AACtB,QAAM,cACJ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,SAAS,eAAe;AAE1E,SAAO;AAAA,IACL,OAAO,0DAA0D,WAAW;AAAA,IAC5E,YAAY;AAAA,IACZ,YACE;AAAA,IACF,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,cAAc;AAAA,EAChB;AACF;;;ACVA,IAAM,oBAAoB;AAOnB,IAAM,8BAAN,MAA+D;AAAA,EAC3D;AAAA,EACT;AAAA,EACA;AAAA,EAEA,YAAY,OAAwB;AAClC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,MAAM,QACJ,KACA,SACoC;AACpC,QAAI;AACF,aAAO,KAAK,mBAAmB,KAAK,gBAAgB;AAEpD,YAAM,MAAM,MAAM,KAAK,SAAS,eAAe,GAAG,EAAE;AACpD,YAAM,cAAc,WAAW,GAAG;AAClC,UAAI,CAAC,YAAY,UAAU;AACzB,eAAO,EAAE,MAAM,aAAa,SAAS,kBAAkB;AAAA,MACzD;AACA,UAAI,MAAM,KAAK,mBAAmB,YAAY,SAAS,GAAG;AACxD,eAAO,EAAE,MAAM,aAAa,SAAS,kBAAkB;AAAA,MACzD;AAEA,YAAM,gBAAgB,MAAM,KAAK;AAAA,QAC/B,qCAAqC,GAAG;AAAA,MAC1C;AACA,YAAM,eAAe,MAAM,KAAK,SAAS,sBAAsB,GAAG,EAAE;AACpE,YAAM,qBAAqB;AAAA,QACzB;AAAA,QACA;AAAA,MACF;AACA,YAAM,oBAAoB;AAAA,QACxB;AAAA,QACA;AAAA,MACF;AACA,UAAI,CAAC,KAAK,kBAAkB;AAC1B,cAAM,IAAI,MAAM,kDAAkD;AAAA,MACpE;AACA,YAAM,YAAY;AAAA,QAChB,GAAG,IAAI;AAAA,UACL,CAAC,GAAG,oBAAoB,GAAG,iBAAiB,EAAE;AAAA,YAAI,CAAC,aACjD,gBAAgB,UAAU,KAAK,gBAAiB;AAAA,UAClD;AAAA,QACF;AAAA,MACF;AACA,YAAM,UAAU,MAAM,QAAQ,uBAAuB;AACrD,YAAM,WAAW,UAAU;AAAA,QACzB,CAAC,aAAa,CAAC,kBAAkB,UAAU,OAAO;AAAA,MACpD;AAEA,aAAO,SAAS,SACZ;AAAA,QACE,MAAM;AAAA,QACN,SAAS,uBAAuB,KAAK,UAAU,CAAC,GAAG,OAAO,CAAC;AAAA,MAC7D,IACA;AAAA,IACN,SAAS,OAAO;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,SAAS,4BAA4B,KAAK,cAAc,KAAK;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,kBAAiC;AACrC,UAAM,OAAO;AAAA,MACX,MAAM,KAAK;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,UAAM,MAAM,KAAK,CAAC;AAClB,QACE,KAAK,WAAW,KAChB,CAAC,OACD,OAAO,KAAK,GAAG,EAAE,WAAW,KAC5B,OAAO,IAAI,aAAa,YACxB,IAAI,SAAS,WAAW,GACxB;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,QAAQ,IAAI;AAClB,QAAI,UAAU,KAAK,UAAU,KAAK;AAChC,YAAM,IAAI;AAAA,QACR,oEAAoE,OAAO,KAAK,CAAC;AAAA,MACnF;AAAA,IACF;AACA,SAAK,mBAAmB,IAAI;AAAA,EAC9B;AAAA,EAEA,MAAM,SAAS,KAAgC;AAC7C,UAAM,OAAO,SAAS,MAAM,KAAK,OAAO,GAAG,CAAC;AAC5C,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,WAAO,KAAK,IAAI,CAAC,QAAQ;AACvB,UAAI,OAAO,KAAK,GAAG,EAAE,WAAW,KAAK,OAAO,IAAI,YAAY,UAAU;AACpE,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,aAAO,IAAI;AAAA,IACb,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,mBAAmB,WAAgD;AACvE,QAAI,UAAU,KAAK,wBAAwB,EAAG,QAAO;AACrD,QAAI,UAAU,WAAW,EAAG,QAAO;AACnC,UAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EACjC,IAAI,CAAC,SAAS,IAAI,KAAK,WAAW,KAAK,IAAI,CAAC,GAAG,EAC/C,KAAK,IAAI;AACZ,UAAM,OAAO;AAAA,MACX,MAAM,KAAK,OAAO;AAAA;AAAA;AAAA,yBAGC,KAAK;AAAA;AAAA,OAEvB;AAAA,IACH;AACA,eAAW,OAAO,MAAM;AACtB,UAAI,OAAO,IAAI,SAAS,YAAY,OAAO,IAAI,WAAW,UAAU;AAClE,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,UACE,IAAI,WAAW,oBACf,IAAI,WAAW,2BACf,IAAI,WAAW,mBACf;AACA,cAAM,IAAI,MAAM,uCAAuC,IAAI,MAAM,EAAE;AAAA,MACrE;AAAA,IACF;AACA,WAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAEA,SAAS,yBAAyB,MAAuB;AACvD,QAAM,aAAa,KAAK,kBAAkB,OAAO;AACjD,SAAO,WAAW,WAAW,MAAM,KAAK,WAAW,WAAW,SAAS;AACzE;AAEA,SAAS,SAAS,QAA4C;AAC5D,QAAM,OAAO,MAAM,QAAQ,MAAM,IAC7B,SACA,UAAU,OAAO,WAAW,YAAY,UAAU,SAC/C,OAA6B,OAC9B,UAAU,OAAO,WAAW,YAAY,UAAU,SAC/C,OAA6B,OAC9B;AACR,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,KAAK,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC,GAAG;AAC9D,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAGlB;AACA,QAAM,YAAY,MAAM;AAAA,IACtB,CAAC,SAAS,KAAK,SAAS,KAAK,UAAU,EAAE,WAAW;AAAA,EACtD;AACA,MACE,UAAU,WAAW,KACrB,CAAC,UAAU,CAAC,GAAG,WAAW,sBAAsB,GAChD;AACA,WAAO,EAAE,UAAU,OAAO,WAAW,CAAC,EAAE;AAAA,EAC1C;AACA,QAAM,QAAQ,kBAAkB,OAAO,eAAe;AACtD,QAAM,OAAO,MAAM,CAAC;AACpB,QAAM,WACJ,MAAM,WAAW,KACjB,CAAC,CAAC,QACF,CAAC,KAAK,SAAS,KAAK,CAAC,UAAU,MAAM,KAAK,WAAW,UAAU,CAAC,KAChE,CAAC,sBAAsB,IAAI;AAC7B,SAAO;AAAA,IACL;AAAA,IACA,WAAW,YAAY,OAAO,oBAAoB,IAAI,IAAI,CAAC;AAAA,EAC7D;AACF;AAEA,SAAS,gBAAgB,MAAoB;AAC3C,QAAM,OAAO,0BAA0B,KAAK,IAAI,IAAI,CAAC;AACrD,QAAM,UAAU,oBAAI,IAAI;AAAA,IACtB;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,CAAC;AACD,MAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,GAAG;AAC/B,UAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAAA,EACxD;AACF;AAEA,SAAS,sBAAsB,MAA4B;AACzD,MACE,KAAK,KAAK,WAAW,iBAAiB,KACtC,KAAK,SAAS,KAAK,CAAC,UAAU,MAAM,KAAK,WAAW,WAAW,CAAC,GAChE;AACA,WAAO;AAAA,EACT;AACA,SAAO,KAAK,SAAS,KAAK,qBAAqB;AACjD;AAEA,SAAS,oBAAoB,MAA6B;AACxD,QAAM,YAAsB,CAAC;AAC7B,MAAI,KAAK,KAAK,WAAW,WAAW,GAAG;AACrC,UAAM,OAAO,kBAAkB,KAAK,KAAK,IAAI,IAAI,CAAC;AAClD,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,oCAAoC,KAAK,IAAI,EAAE;AAC1E,cAAU,KAAK,IAAI;AAAA,EACrB;AACA,aAAW,SAAS,KAAK;AACvB,cAAU,KAAK,GAAG,oBAAoB,KAAK,CAAC;AAC9C,SAAO;AACT;AAEA,SAAS,uBACP,OACA,OACU;AACV,QAAM,QAAQ;AAAA,IAAkB;AAAA,IAAO,CAAC,MAAM,WAC5C,sBAAsB,MAAM,MAAM;AAAA,EACpC;AACA,MACE,MAAM,WAAW,KAChB,CAAC,MAAM,CAAC,GAAG,KAAK,WAAW,QAAQ,KAClC,CAAC,MAAM,CAAC,GAAG,KAAK,WAAW,QAAQ,GACrC;AACA,UAAM,IAAI,MAAM,sBAAsB,KAAK,mBAAmB;AAAA,EAChE;AAEA,QAAM,YAAsB,CAAC;AAC7B,QAAM,WAAW,oBAAI,IAAY;AACjC,kBAAgB,MAAM,CAAC,GAAG,QAAQ;AAClC,iBAAe,MAAM,CAAC,GAAG,OAAO,OAAO,UAAU,SAAS;AAC1D,SAAO;AACT;AAEA,SAAS,sBAAsB,MAAc,QAA4B;AACvE,QAAM,eAAe;AAAA,IACnB;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;AACA,MAAI,aAAa,KAAK,CAAC,YAAY,QAAQ,KAAK,IAAI,CAAC,EAAG;AACxD,MAAI,QAAQ,SAAS,wBAAwB,aAAa,KAAK,IAAI,GAAG;AACpE;AAAA,EACF;AACA,QAAM,IAAI,MAAM,uCAAuC,IAAI,EAAE;AAC/D;AAEA,SAAS,eACP,MACA,kBACA,OACA,UACA,WACM;AACN,MAAI,oBAAoB,KAAK,KAAK,WAAW,aAAa,GAAG;AAC3D,UAAM,aAAa,4BAA4B,KAAK,KAAK,IAAI,IAAI,CAAC;AAClE,QAAI,CAAC,YAAY;AACf,YAAM,IAAI,MAAM,sBAAsB,KAAK,cAAc,KAAK,IAAI,EAAE;AAAA,IACtE;AACA,QAAI,CAAC,SAAS,IAAI,UAAU,GAAG;AAC7B,gBAAU,KAAK,UAAU;AAAA,IAC3B;AAAA,EACF,WAAW,oBAAoB,KAAK,KAAK,WAAW,QAAQ,GAAG;AAC7D,UAAME,SAAQ,qCAAqC,KAAK,KAAK,IAAI,IAAI,CAAC;AACtE,QAAI,CAACA,QAAO;AACV,YAAM,IAAI,MAAM,sBAAsB,KAAK,cAAc,KAAK,IAAI,EAAE;AAAA,IACtE;AACA,cAAU,KAAKA,MAAK;AAAA,EACtB;AAEA,aAAW,SAAS,KAAK,UAAU;AACjC,UAAM,uBACJ,KAAK,SAAS,eACd,KAAK,SAAS,2BACd,KAAK,SAAS,4BACd,KAAK,SAAS;AAChB,mBAAe,OAAO,sBAAsB,OAAO,UAAU,SAAS;AAAA,EACxE;AACF;AAEA,SAAS,gBAAgB,MAAmB,UAA6B;AACvE,QAAM,OAAO,mCAAmC,KAAK,KAAK,IAAI,IAAI,CAAC;AACnE,MAAI,KAAM,UAAS,IAAI,IAAI;AAC3B,aAAW,SAAS,KAAK,SAAU,iBAAgB,OAAO,QAAQ;AACpE;AAEA,SAAS,kBACP,OACA,UACe;AACf,QAAM,QAAuB,CAAC;AAC9B,QAAM,QAAsD,CAAC;AAE7D,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,KAAK,KAAK;AACb,YAAM,IAAI,MAAM,4CAA4C;AAC9D,UAAM,SAAS,KAAK,SAAS,KAAK,UAAU,EAAE;AAC9C,UAAM,OAAO,KAAK,UAAU;AAC5B,WAAO,MAAM,UAAU,MAAM,GAAG,EAAE,EAAG,UAAU,OAAQ,OAAM,IAAI;AACjE,UAAM,SAAS,MAAM,GAAG,EAAE,GAAG;AAC7B,aAAS,MAAM,MAAM;AACrB,UAAM,OAAO,EAAE,MAAM,UAAU,CAAC,EAAE;AAClC,QAAI,OAAQ,QAAO,SAAS,KAAK,IAAI;AAAA,QAChC,OAAM,KAAK,IAAI;AACpB,UAAM,KAAK,EAAE,QAAQ,KAAK,CAAC;AAAA,EAC7B;AAEA,SAAO;AACT;AAEA,SAAS,kBACP,UACA,iBACS;AACT,SAAO,gBAAgB,SAAS,QAAQ;AAC1C;AAEA,SAAS,gBAAgB,UAAkB,UAA0B;AACnE,SAAO,SAAS,SAAS,GAAG,IAAI,WAAW,GAAG,QAAQ,IAAI,QAAQ;AACpE;AAEA,SAAS,uBACP,KACA,oBACA,iBACsB;AACtB,SAAO;AAAA,IACL,OAAO,qDAAqD,mBAAmB,KAAK,IAAI,CAAC;AAAA,IACzF,YAAY;AAAA,IACZ,YACE;AAAA,IACF,eAAe;AAAA,IACf,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,EACpB;AACF;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;ACvYO,IAAM,aAAN,cAAyB,QAAQ;AAAA,EAC7B;AAAA,EAES;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACkB,oBAAoB;AAAA,EAEtC,YAAY,SAAmC;AAC7C,QAAI,CAAC,WAAW,OAAO,QAAQ,YAAY,YAAY;AACrD,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AACA,QAAI,OAAO,QAAQ,aAAa,YAAY;AAC1C,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAEA,UAAM,IAAI,4BAA4B,QAAQ,OAAO,CAAC;AACtD,SAAK,WAAW;AAChB,SAAK,YAAY,QAAQ,aAAa,CAAC;AACvC,SAAK,gBAAgB,QAAQ;AAAA,EAC/B;AAAA,EAEA,MAAe,YAAY,KAAiC;AAC1D,WAAO,eAAe,MAAM,KAAK,SAAS,QAAQ,GAAG,CAAC;AAAA,EACxD;AAAA,EAEA,MAAe,aAAa,KAAqC;AAC/D,QAAI;AACF,aAAO,MAAM,KAAK,SAAS,SAAS,GAAG;AAAA,IACzC,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,aAAO,KAAK,UAAU;AAAA,QACpB,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,YACE;AAAA,QACF,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAe,SAAc,KAA6B;AACxD,WAAO,eAAoB,MAAM,KAAK,SAAS,QAAQ,GAAG,CAAC;AAAA,EAC7D;AAAA,EAES,gBAAgB,MAAsB;AAC7C,WAAO,KAAK,KAAK,QAAQ,MAAM,IAAI,CAAC;AAAA,EACtC;AAAA,EAES,OAAO,OAAuB;AACrC,WAAO,MAAM,QAAQ,MAAM,IAAI;AAAA,EACjC;AAAA,EAES,qBACP,WACA,SACA,OACQ;AACR,UAAM,EAAE,QAAQ,OAAAC,OAAM,IAAI,KAAK,eAAe,SAAS;AACvD,UAAM,WAAW,SACb,GAAG,KAAK,gBAAgB,MAAM,CAAC,IAAI,KAAK,gBAAgBA,MAAK,CAAC,KAC9D,KAAK,gBAAgBA,MAAK;AAC9B,UAAM,aAAa,SAAS,SACxB,QAAQ,IAAI,CAACC,YAAW,KAAK,gBAAgBA,OAAM,CAAC,EAAE,KAAK,IAAI,IAC/D;AACJ,WAAO,UAAU,UAAU,SAAS,QAAQ,UAAU,KAAK;AAAA,EAC7D;AACF;AAEA,SAAS,eAAoB,QAAwB;AACnD,MAAI,MAAM,QAAQ,MAAM,EAAG,QAAO;AAClC,MAAI,UAAU,OAAO,WAAW,UAAU;AACxC,UAAM,YAAY;AAIlB,QAAI,MAAM,QAAQ,UAAU,IAAI,EAAG,QAAO,UAAU;AACpD,QAAI,MAAM,QAAQ,UAAU,IAAI,EAAG,QAAO,UAAU;AAAA,EACtD;AACA,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;;;ACvFO,SAAS,cACd,SACA,QACK;AACL,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO,QAAQ,OAAO,CAAC,QAAQ,OAAO,SAAS,IAAI,IAAI,CAAC;AAAA,EAC1D;AACA,MAAI,kBAAkB,QAAQ;AAC5B,WAAO,QAAQ,OAAO,CAAC,QAAQ,OAAO,KAAK,IAAI,IAAI,CAAC;AAAA,EACtD;AACA,SAAO,QAAQ,OAAO,CAAC,QAAQ,OAAO,IAAI,IAAI,CAAC;AACjD;AAMO,SAAS,kBAEd,QAAW,eAAkC;AAC7C,MAAI,CAAC,cAAe,QAAO;AAC3B,QAAM,SAAS,cAAc,OAAO,IAAI;AACxC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,EAAE,GAAG,QAAQ,SAAS,cAAc,OAAO,SAAS,MAAM,EAAE;AACrE;AAQO,IAAe,oBAAf,MAAiC;AAAA;AAAA;AAAA;AAAA,EAItC;AAAA,EACA;AAAA,EAEA,YAAY,MAAc,OAA4B;AACpD,SAAK,OAAO;AACZ,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBA,MAAM,mBAAmB,MAAuC;AAAA,EAAC;AACnE;;;ACzDO,IAAe,sBAAf,cAA2C,kBAAkB;AAAA,EAClE,YAAY,SAAoC,CAAC,GAAG;AAClD,UAAM,cAAc,aAAa;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,QAAQ,KAAsC;AAClD,UAAM,QAAQ,IAAI,OAAO;AACzB,aAAS,IAAI,GAAG,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC1C,YAAMC,SAAQ,IAAI,OAAO,CAAC;AAC1B,UAAI,WAAW;AAAA,QACb,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAOA,OAAM;AAAA,QACb,SAAS,2BAA2BA,OAAM,IAAI;AAAA,QAC9C,SAAS,IAAI;AAAA,QACb;AAAA,MACF,CAAC;AACD,UAAI;AACF,QAAAA,OAAM,cAAc,MAAM,KAAK,eAAeA,OAAM,IAAI;AAAA,MAC1D,SAAS,OAAO;AAEd,gBAAQ,KAAK,oCAAoCA,OAAM,MAAM,KAAK;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AACF;;;AC3CO,IAAM,gCAAN,cAA4C,oBAAoB;AAAA,EAC5D;AAAA,EAET,YAAY,SAAkB,SAAoC,CAAC,GAAG;AACpE,UAAM,MAAM;AACZ,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAyB,eACvB,WAC4B;AAC5B,UAAM,EAAE,QAAQ,OAAAC,OAAM,IAAI,KAAK,SAAS,eAAe,SAAS;AAChE,QAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,UAAM,OAAO,MAAM,KAAK,SAAS,SAA4B;AAAA;AAAA;AAAA,0BAGvC,KAAK,SAAS,aAAa,MAAM,CAAC;AAAA,uBACrC,KAAK,SAAS,aAAaA,MAAK,CAAC;AAAA;AAAA,KAEnD;AACD,UAAMC,eAAiC,CAAC;AACxC,UAAM,aAAa,KAChB,OAAO,CAAC,QAAQ,OAAO,IAAI,iBAAiB,MAAM,CAAC,EACnD,IAAI,CAAC,QAAQ,IAAI,IAAI;AAExB,QAAI,WAAW,SAAS,GAAG;AACzB,MAAAA,aAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,eAAW,OAAO,MAAM;AACtB,UAAI,CAAC,gBAAgB,IAAI,IAAI,GAAG;AAC9B,QAAAA,aAAY,KAAK;AAAA,UACf,MAAM,GAAG,IAAI,IAAI;AAAA,UACjB,MAAM;AAAA,UACN,SAAS,CAAC,IAAI,IAAI;AAAA,QACpB,CAAC;AAAA,MACH;AACA,UAAI,IAAI,iBAAiB,aAAa,IAAI,oBAAoB;AAC5D,QAAAA,aAAY,KAAK;AAAA,UACf,MAAM,GAAG,IAAI,IAAI;AAAA,UACjB,MAAM;AAAA,UACN,SAAS,CAAC,IAAI,IAAI;AAAA,UAClB,cAAc,IAAI;AAAA,QACpB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAOA;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,MAAuB;AAC9C,SAAO,qBAAqB,KAAK,IAAI;AACvC;;;ACpDO,IAAe,mBAAf,cAAwC,kBAAkB;AAAA,EAC/D,YAAY,SAAiC,CAAC,GAAG;AAC/C,UAAM,SAAS,SAAS;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,QAAQ,KAAsC;AAClD,UAAM,QAAQ,IAAI,OAAO;AACzB,aAAS,IAAI,GAAG,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC1C,YAAMC,SAAQ,IAAI,OAAO,CAAC;AAC1B,UAAI,WAAW;AAAA,QACb,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAOA,OAAM;AAAA,QACb,SAAS,uBAAuBA,OAAM,IAAI;AAAA,QAC1C,SAAS,IAAI;AAAA,QACb;AAAA,MACF,CAAC;AACD,MAAAA,OAAM,UAAU,MAAM,KAAK,WAAWA,OAAM,IAAI;AAEhD,iBAAWC,UAASD,OAAM,WAAW,CAAC,GAAG;AACvC,mBAAW,WAAWC,OAAM,SAAS;AACnC,gBAAMC,UAASF,OAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,OAAO;AAC3D,cAAIE,SAAQ;AACV,YAAAA,QAAO,YAAY;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC1CO,IAAM,6BAAN,cAAyC,iBAAiB;AAAA,EACtD;AAAA,EAET,YAAY,SAAkB,SAAiC,CAAC,GAAG;AACjE,UAAM,MAAM;AACZ,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAyB,WACvB,WACuB;AACvB,UAAM,EAAE,QAAQ,OAAAC,OAAM,IAAI,KAAK,SAAS,eAAe,SAAS;AAChE,QAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,UAAM,CAAC,gBAAgB,SAAS,IAAI,MAAM,QAAQ,IAAI;AAAA,MACpD,KAAK,SAAS,SAAwB;AAAA;AAAA;AAAA,4BAGhB,KAAK,SAAS,aAAa,MAAM,CAAC;AAAA,yBACrC,KAAK,SAAS,aAAaA,MAAK,CAAC;AAAA;AAAA;AAAA,OAGnD;AAAA,MACD,KAAK,SAAS,SAA+B;AAAA;AAAA;AAAA,4BAGvB,KAAK,SAAS,aAAa,MAAM,CAAC;AAAA,yBACrC,KAAK,SAAS,aAAaA,MAAK,CAAC;AAAA;AAAA,OAEnD;AAAA,IACH,CAAC;AAED,UAAMC,WAAwB,CAAC;AAC/B,QAAI,eAAe,SAAS,GAAG;AAC7B,MAAAA,SAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,SAAS,eAAe,IAAI,CAAC,QAAQ,IAAI,IAAI;AAAA,QAC7C,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA,IAAAA,SAAQ;AAAA,MACN,GAAG,UAAU,IAAI,CAAC,SAAS;AAAA,QACzB,MAAM,IAAI;AAAA,QACV,SAAS,yBAAyB,IAAI,UAAU;AAAA,QAChD,MAAM,IAAI;AAAA,MACZ,EAAE;AAAA,IACJ;AACA,WAAOA;AAAA,EACT;AACF;AAEA,SAAS,yBAAyB,YAA8B;AAC9D,QAAM,QAAkB,CAAC;AACzB,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,WAASC,SAAQ,GAAGA,SAAQ,WAAW,QAAQA,UAAS;AACtD,UAAM,YAAY,WAAWA,MAAK;AAClC,QAAI,cAAc,OAAO,cAAc,IAAK;AAC5C,QAAI,cAAc,OAAO,cAAc,IAAK;AAC5C,QAAI,cAAc,OAAO,UAAU,GAAG;AACpC,YAAM,KAAK,WAAW,MAAM,OAAOA,MAAK,EAAE,KAAK,CAAC;AAChD,cAAQA,SAAQ;AAAA,IAClB;AAAA,EACF;AACA,QAAM,KAAK,WAAW,MAAM,KAAK,EAAE,KAAK,CAAC;AACzC,SAAO,MAAM,OAAO,OAAO;AAC7B;;;AC/DO,IAAe,gBAAf,cAAqC,kBAAkB;AAAA,EAC5D,YAAY,SAA8B,CAAC,GAAG;AAC5C,UAAM,eAAe,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,QAAQ,KAAsC;AAClD,QAAI,OAAO,MAAM,KAAK,YAAY;AAAA,EACpC;AACF;;;ACzBO,IAAM,0BAAN,cAAsC,cAAc;AAAA,EAChD;AAAA,EAET,YAAY,SAAkB,SAA8B,CAAC,GAAG;AAC9D,UAAM,MAAM;AACZ,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAyB,cAAoC;AAC3D,UAAM,OAAO,MAAM,KAAK,SAAS;AAAA,MAC/B;AAAA,IACF;AACA,UAAM,MAAM,KAAK,CAAC;AAClB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,KAAK;AAAA,MACd,UAAU,KAAK,YAAY;AAAA,MAC3B,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;;;ACdO,IAAe,oBAAf,cAAyC,kBAAkB;AAAA,EAChE,YAAY,SAAkC,CAAC,GAAG;AAChD,UAAM,YAAY,YAAY;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,QAAQ,KAAsC;AAClD,UAAM,QAAQ,IAAI,OAAO;AACzB,aAAS,IAAI,GAAG,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC1C,YAAMC,SAAQ,IAAI,OAAO,CAAC;AAC1B,UAAI,WAAW;AAAA,QACb,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAOA,OAAM;AAAA,QACb,SAAS,oBAAoBA,OAAM,IAAI;AAAA,QACvC,SAAS,IAAI;AAAA,QACb;AAAA,MACF,CAAC;AACD,YAAM,QAAQ,MAAM,KAAK,YAAYA,OAAM,IAAI;AAC/C,UAAI,SAAS,MAAM;AACjB,QAAAA,OAAM,WAAW;AACjB,QAAAA,OAAM,WAAW,KAAK,kBAAkB,KAAK;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,OAAkC;AAClD,QAAI,QAAQ,IAAK,QAAO;AACxB,QAAI,QAAQ,IAAM,QAAO;AACzB,QAAI,QAAQ,IAAO,QAAO;AAC1B,QAAI,QAAQ,IAAQ,QAAO;AAC3B,WAAO;AAAA,EACT;AACF;;;AC5DO,IAAM,8BAAN,cAA0C,kBAAkB;AAAA,EACxD;AAAA,EAET,YAAY,SAAkB,SAAkC,CAAC,GAAG;AAClE,UAAM,MAAM;AACZ,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAyB,YACvB,WAC6B;AAC7B,UAAM,EAAE,QAAQ,OAAAC,OAAM,IAAI,KAAK,SAAS,eAAe,SAAS;AAChE,UAAM,WAAW,SACb,GAAG,KAAK,SAAS,gBAAgB,MAAM,CAAC,IAAI,KAAK,SAAS,gBAAgBA,MAAK,CAAC,KAChF,KAAK,SAAS,gBAAgBA,MAAK;AAEvC,QAAI;AACF,YAAM,OAAO,MAAM,KAAK,SAAS,SAE9B,gCAAgC,QAAQ,EAAE;AAC7C,aAAO,SAAS,KAAK,CAAC,GAAG,KAAK;AAAA,IAChC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,SAAS,OAAoC;AACpD,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAClD,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AAC7C,UAAM,SAAS,OAAO,KAAK;AAC3B,QAAI,OAAO,SAAS,MAAM,EAAG,QAAO;AAAA,EACtC;AACA,SAAO;AACT;;;ACMO,IAAe,iBAAf,cAAsC,kBAAkB;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAA+B,CAAC,GAAG;AAC7C,UAAM,SAAS,QAAQ;AACvB,SAAK,UAAU,OAAO;AACtB,SAAK,WAAW,OAAO;AACvB,SAAK,WAAW,OAAO;AACvB,SAAK,YAAY,OAAO;AAAA,EAC1B;AAAA,EAkBA,MAAe,mBAAmB,KAAsC;AACtE,UAAM,KAAK,QAAQ,GAAG;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,KAAsC;AAClD,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,UAAM,UAAU,KAAK;AACrB,UAAM,WAAW,KAAK;AAGtB,QAAI,CAAC,WAAW,CAAC,UAAU;AACzB,YAAMC,UAAS,MAAM,QAAQ;AAAA,QAC3B,WAAW,IAAI,OAAO,MAAMC,WAAU;AACpC,cAAI,WAAW;AAAA,YACb,MAAM;AAAA,YACN,OAAO;AAAA,YACP,OAAO;AAAA,YACP,SAAS,iBAAiB,IAAI;AAAA,YAC9B,SAASA,SAAQ;AAAA,YACjB,OAAO,WAAW;AAAA,UACpB,CAAC;AACD,iBAAO,kBAAkB,MAAM,KAAK,SAAS,IAAI,GAAG,KAAK,QAAQ;AAAA,QACnE,CAAC;AAAA,MACH;AACA,UAAI,OAAO,KAAK,GAAGD,OAAM;AACzB;AAAA,IACF;AAEA,UAAMA,UAAgC,CAAC;AACvC,UAAM,mBAAmC,CAAC;AAC1C,UAAM,oBAAoB,oBAAI,IAAY;AAG1C,UAAM,eAAuD,CAAC;AAC9D,UAAM,gBAAwD,CAAC;AAC/D,UAAM,iBAAiB,oBAAI,IAAY;AACvC,UAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAI,cAAc;AAGlB,eAAW,QAAQ,YAAY;AAC7B,UAAI,QAAS,cAAa,KAAK,EAAE,MAAM,OAAO,EAAE,CAAC;AACjD,UAAI,SAAU,eAAc,KAAK,EAAE,MAAM,OAAO,EAAE,CAAC;AAAA,IACrD;AAGA,UAAM,eAAe,YAAY,OAAO,WAAW,WAAW;AAC9D,WAAO,aAAa,SAAS,GAAG;AAC9B,YAAM,OAAO,aAAa,MAAM;AAChC,UAAI,CAAC,KAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI;AAExB,UAAI,eAAe,IAAI,IAAI,EAAG;AAC9B,qBAAe,IAAI,IAAI;AAEvB,UAAI,CAACA,QAAO,IAAI,GAAG;AACjB;AACA,YAAI,WAAW;AAAA,UACb,MAAM;AAAA,UACN,OAAO;AAAA,UACP,OAAO;AAAA,UACP,SAAS,iBAAiB,IAAI;AAAA,UAC9B,SAAS;AAAA,QACX,CAAC;AACD,QAAAA,QAAO,IAAI,IAAI;AAAA,UACb,MAAM,KAAK,SAAS,IAAI;AAAA,UACxB,KAAK;AAAA,QACP;AAAA,MACF;AAEA,UAAI,QAAQ,cAAc;AACxB,cAAM,OAAO,MAAM,KAAK,sBAAsB,IAAI;AAClD,mBAAW,OAAO,MAAM;AACtB,cAAI,CAAC,KAAK,sBAAsB,GAAG,EAAG;AACtC,eAAK,gBAAgB,KAAK,kBAAkB,iBAAiB;AAC7D,cAAI,CAAC,eAAe,IAAI,IAAI,gBAAgB,GAAG;AAC7C,yBAAa,KAAK,EAAE,MAAM,IAAI,kBAAkB,OAAO,QAAQ,EAAE,CAAC;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,gBAAgB,aAAa,OAAO,WAAW,YAAY;AACjE,WAAO,cAAc,SAAS,GAAG;AAC/B,YAAM,OAAO,cAAc,MAAM;AACjC,UAAI,CAAC,KAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI;AAExB,UAAI,gBAAgB,IAAI,IAAI,EAAG;AAC/B,sBAAgB,IAAI,IAAI;AAExB,UAAI,CAACA,QAAO,IAAI,GAAG;AACjB;AACA,YAAI,WAAW;AAAA,UACb,MAAM;AAAA,UACN,OAAO;AAAA,UACP,OAAO;AAAA,UACP,SAAS,iBAAiB,IAAI;AAAA,UAC9B,SAAS;AAAA,QACX,CAAC;AACD,QAAAA,QAAO,IAAI,IAAI;AAAA,UACb,MAAM,KAAK,SAAS,IAAI;AAAA,UACxB,KAAK;AAAA,QACP;AAAA,MACF;AAEA,UAAI,QAAQ,eAAe;AACzB,cAAM,OAAO,MAAM,KAAK,sBAAsB,IAAI;AAClD,mBAAW,OAAO,MAAM;AACtB,cAAI,CAAC,KAAK,sBAAsB,GAAG,EAAG;AACtC,eAAK,gBAAgB,KAAK,kBAAkB,iBAAiB;AAC7D,cAAI,CAAC,gBAAgB,IAAI,IAAI,KAAK,GAAG;AACnC,0BAAc,KAAK,EAAE,MAAM,IAAI,OAAO,OAAO,QAAQ,EAAE,CAAC;AAAA,UAC1D;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,aAAa,OAAO,OAAOA,OAAM;AACvC,QAAI,OAAO,KAAK,GAAG,UAAU;AAC7B,QAAI,cAAc,KAAK,GAAG,gBAAgB;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,cAAiC;AAC/C,UAAM,SAAS,KAAK;AACpB,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,MAAM,KAAK,iBAAiB;AAC1C,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,QAAI,kBAAkB,QAAQ;AAC5B,aAAO,MAAM,OAAO,CAAC,SAAS,OAAO,KAAK,IAAI,CAAC;AAAA,IACjD;AACA,WAAO,MAAM,OAAO,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKU,gBACR,KACA,KACA,MACM;AACN,UAAM,MAAM,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,gBAAgB,IAAI,IAAI,GAAG,KAAK,GAAG,CAAC;AAC1F,QAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,WAAK,IAAI,GAAG;AACZ,UAAI,KAAK,GAAG;AAAA,IACd;AAAA,EACF;AAAA,EAEU,sBAAsB,KAA4B;AAC1D,WACE,KAAK,kBAAkB,IAAI,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,KAC3D,KAAK,kBAAkB,IAAI,IAAI,KAAK,WAAW,IAAI,gBAAgB,CAAC;AAAA,EAExE;AAAA,EAEU,kBAAkB,OAAiB,QAA0B;AACrE,QAAI,CAAC,OAAQ,QAAO;AACpB,WACE;AAAA,MACE,MAAM,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE;AAAA,MAC9B;AAAA,IACF,EAAE,WAAW,MAAM;AAAA,EAEvB;AACF;;;ACrPO,IAAM,2BAAN,cAAuC,eAAe;AAAA,EAClD;AAAA,EAET,YAAY,SAAkB,SAA+B,CAAC,GAAG;AAC/D,UAAM,MAAM;AACZ,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAyB,mBAAsC;AAC7D,UAAM,OAAO,MAAM,KAAK,SAAS,SAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAO3D;AACD,WAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI;AAAA,EACnC;AAAA,EAEA,MAAyB,SAAS,WAAmC;AACnE,UAAM,EAAE,QAAQ,OAAAE,OAAM,IAAI,KAAK,SAAS,eAAe,SAAS;AAChE,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR,+DAA+D,SAAS;AAAA,MAC1E;AAAA,IACF;AACA,UAAM,OAAO,MAAM,KAAK,SAAS,SAAoB;AAAA;AAAA;AAAA,0BAG/B,KAAK,SAAS,aAAa,MAAM,CAAC;AAAA,uBACrC,KAAK,SAAS,aAAaA,MAAK,CAAC;AAAA;AAAA,KAEnD;AACD,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,SAASA;AAAA,MACT,SAAS,KAAK,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,MAAM,MAAM,IAAI,KAAK,EAAE;AAAA,IACjE;AAAA,EACF;AAAA,EAEA,MAAyB,wBAAiD;AACxE,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAyB,wBAAiD;AACxE,WAAO,CAAC;AAAA,EACV;AACF;;;ACPO,IAAe,gBAAf,cAAqC,kBAAkB;AAAA,EAC5D;AAAA,EACA;AAAA,EACU;AAAA,EAEV,YAAY,SAA8B,CAAC,GAAG;AAC5C,UAAM,QAAQ,OAAO;AACrB,SAAK,UAAU,OAAO;AACtB,SAAK,WAAW,OAAO;AACvB,SAAK,oBAAoB,OAAO,qBAAqB;AAAA,EACvD;AAAA,EAQA,MAAe,mBAAmB,KAAsC;AACtE,UAAM,KAAK,QAAQ,GAAG;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,KAAsC;AAClD,UAAM,YAAY,MAAM,KAAK,YAAY;AACzC,UAAMC,SAAQ,MAAM,QAAQ;AAAA,MAC1B,UAAU,IAAI,OAAO,MAAMC,WAAU;AACnC,YAAI,WAAW;AAAA,UACb,MAAM;AAAA,UACN,OAAO;AAAA,UACP,OAAO;AAAA,UACP,SAAS,gBAAgB,IAAI;AAAA,UAC7B,SAASA,SAAQ;AAAA,UACjB,OAAO,UAAU;AAAA,QACnB,CAAC;AACD,eAAO,kBAAkB,MAAM,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ;AAAA,MAClE,CAAC;AAAA,IACH;AACA,QAAI,MAAM,KAAK,GAAGD,MAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAgB,cAAiC;AAC/C,UAAM,SAAS,KAAK;AACpB,QAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,MAAM,KAAK,gBAAgB;AACzC,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,QAAI,kBAAkB,QAAQ;AAC5B,aAAO,MAAM,OAAO,CAAC,SAAS,OAAO,KAAK,IAAI,CAAC;AAAA,IACjD;AACA,WAAO,MAAM,OAAO,MAAM;AAAA,EAC5B;AACF;;;ACvGO,IAAM,0BAAN,cAAsC,cAAc;AAAA,EAChD;AAAA,EAET,YAAY,SAAkB,SAA8B,CAAC,GAAG;AAC9D,UAAM,MAAM;AACZ,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAyB,kBAAqC;AAC5D,UAAM,OAAO,MAAM,KAAK,SAAS,SAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAO3D;AACD,WAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI;AAAA,EACnC;AAAA,EAEA,MAAyB,QAAQ,UAAiC;AAChE,UAAM,EAAE,QAAQ,OAAAE,OAAM,IAAI,KAAK,SAAS,eAAe,QAAQ;AAC/D,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR,6DAA6D,QAAQ;AAAA,MACvE;AAAA,IACF;AAEA,UAAM,CAAC,SAAS,cAAc,IAAI,MAAM,QAAQ,IAAI;AAAA,MAClD,KAAK,SAAS,SAAoB;AAAA;AAAA;AAAA,4BAGZ,KAAK,SAAS,aAAa,MAAM,CAAC;AAAA,yBACrC,KAAK,SAAS,aAAaA,MAAK,CAAC;AAAA;AAAA,OAEnD;AAAA,MACD,KAAK,oBACD,KAAK,SAAS,SAAiC;AAAA;AAAA;AAAA,gCAGzB,KAAK,SAAS,aAAa,MAAM,CAAC;AAAA,4BACtC,KAAK,SAAS,aAAaA,MAAK,CAAC;AAAA;AAAA,WAElD,IACD,QAAQ,QAAQ,CAAC,CAAC;AAAA,IACxB,CAAC;AAED,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,SAASA;AAAA,MACT,YAAY,eAAe,CAAC,GAAG;AAAA,MAC/B,SAAS,QAAQ,IAAI,CAACC,aAAY;AAAA,QAChC,MAAMA,QAAO;AAAA,QACb,MAAMA,QAAO;AAAA,MACf,EAAE;AAAA,IACJ;AAAA,EACF;AACF;;;ACpDO,SAAS,OAAO,SAA+B,CAAC,GAAG;AACxD,SAAO,CAAC,YAAqB,IAAI,yBAAyB,SAAS,MAAM;AAC3E;AAEO,SAAS,MAAM,SAA8B,CAAC,GAAG;AACtD,SAAO,CAAC,YAAqB,IAAI,wBAAwB,SAAS,MAAM;AAC1E;AAEO,SAAS,KAAK,SAA8B,CAAC,GAAG;AACrD,SAAO,CAAC,YAAqB,IAAI,wBAAwB,SAAS,MAAM;AAC1E;AAEO,SAAS,QAAQ,SAAiC,CAAC,GAAG;AAC3D,SAAO,CAAC,YAAqB,IAAI,2BAA2B,SAAS,MAAM;AAC7E;AAEO,SAAS,SAAS,SAAkC,CAAC,GAAG;AAC7D,SAAO,CAAC,YAAqB,IAAI,4BAA4B,SAAS,MAAM;AAC9E;AAEO,SAAS,YAAY,SAAoC,CAAC,GAAG;AAClE,SAAO,CAAC,YACN,IAAI,8BAA8B,SAAS,MAAM;AACrD;AAEA,IAAO,qBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
|
|
6
6
|
"names": ["column", "c", "table", "table", "column", "table", "table", "constraints", "table", "index", "column", "table", "indexes", "index", "table", "table", "tables", "index", "table", "views", "index", "table", "column"]
|
|
7
7
|
}
|