@hdnax/sqlingo.js 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.repo.md +1 -2
- package/dist/chunk-2YNOERAO.cjs +2 -0
- package/dist/chunk-2YNOERAO.cjs.map +1 -0
- package/dist/chunk-2Z3O2CFM.cjs +19 -0
- package/dist/chunk-2Z3O2CFM.cjs.map +1 -0
- package/dist/chunk-4ZMKB6PV.cjs +2 -0
- package/dist/chunk-4ZMKB6PV.cjs.map +1 -0
- package/dist/chunk-53OWF4GG.js +2 -0
- package/dist/chunk-53OWF4GG.js.map +1 -0
- package/dist/chunk-C4CLTVOW.cjs +2 -0
- package/dist/chunk-C4CLTVOW.cjs.map +1 -0
- package/dist/chunk-DOKMTZYO.cjs +4 -0
- package/dist/chunk-DOKMTZYO.cjs.map +1 -0
- package/dist/chunk-FCGUTI7Y.js +2 -0
- package/dist/chunk-FCGUTI7Y.js.map +1 -0
- package/dist/chunk-IPCIXWCY.js +2 -0
- package/dist/chunk-IPCIXWCY.js.map +1 -0
- package/dist/chunk-KCNOE4DZ.js +19 -0
- package/dist/chunk-KCNOE4DZ.js.map +1 -0
- package/dist/chunk-NRJHX2GZ.js +2 -0
- package/dist/chunk-NRJHX2GZ.js.map +1 -0
- package/dist/chunk-O2J5RKBN.js +2 -0
- package/dist/chunk-O2J5RKBN.js.map +1 -0
- package/dist/chunk-PXUASP5I.js +2 -0
- package/dist/chunk-PXUASP5I.js.map +1 -0
- package/dist/chunk-R7C3ZHVK.cjs +2 -0
- package/dist/chunk-R7C3ZHVK.cjs.map +1 -0
- package/dist/chunk-UHWHUDLE.cjs +2 -0
- package/dist/chunk-UHWHUDLE.cjs.map +1 -0
- package/dist/chunk-WRNYJ54A.cjs +2 -0
- package/dist/chunk-WRNYJ54A.cjs.map +1 -0
- package/dist/chunk-XZQFOICX.cjs +3 -0
- package/dist/chunk-XZQFOICX.cjs.map +1 -0
- package/dist/chunk-YLOQRUXC.js +2 -0
- package/dist/chunk-YLOQRUXC.js.map +1 -0
- package/dist/chunk-YSS2WVCM.cjs +2 -0
- package/dist/chunk-YSS2WVCM.cjs.map +1 -0
- package/dist/chunk-Z5V6VOIN.js +3 -0
- package/dist/chunk-Z5V6VOIN.js.map +1 -0
- package/dist/chunk-ZBFGQPJR.js +4 -0
- package/dist/chunk-ZBFGQPJR.js.map +1 -0
- package/dist/dialects/athena.cjs +2 -0
- package/dist/dialects/athena.cjs.map +1 -0
- package/dist/dialects/athena.d.cts +66 -0
- package/dist/dialects/athena.d.ts +66 -0
- package/dist/dialects/athena.js +2 -0
- package/dist/dialects/athena.js.map +1 -0
- package/dist/dialects/bigquery.cjs +3 -0
- package/dist/dialects/bigquery.cjs.map +1 -0
- package/dist/dialects/bigquery.d.cts +651 -0
- package/dist/dialects/bigquery.d.ts +651 -0
- package/dist/dialects/bigquery.js +3 -0
- package/dist/dialects/bigquery.js.map +1 -0
- package/dist/dialects/clickhouse.cjs +2 -0
- package/dist/dialects/clickhouse.cjs.map +1 -0
- package/dist/dialects/clickhouse.d.cts +634 -0
- package/dist/dialects/clickhouse.d.ts +634 -0
- package/dist/dialects/clickhouse.js +2 -0
- package/dist/dialects/clickhouse.js.map +1 -0
- package/dist/dialects/databricks.cjs +2 -0
- package/dist/dialects/databricks.cjs.map +1 -0
- package/dist/dialects/databricks.d.cts +484 -0
- package/dist/dialects/databricks.d.ts +484 -0
- package/dist/dialects/databricks.js +2 -0
- package/dist/dialects/databricks.js.map +1 -0
- package/dist/dialects/doris.cjs +2 -0
- package/dist/dialects/doris.cjs.map +1 -0
- package/dist/dialects/doris.d.cts +484 -0
- package/dist/dialects/doris.d.ts +484 -0
- package/dist/dialects/doris.js +2 -0
- package/dist/dialects/doris.js.map +1 -0
- package/dist/dialects/dremio.cjs +2 -0
- package/dist/dialects/dremio.cjs.map +1 -0
- package/dist/dialects/dremio.d.cts +522 -0
- package/dist/dialects/dremio.d.ts +522 -0
- package/dist/dialects/dremio.js +2 -0
- package/dist/dialects/dremio.js.map +1 -0
- package/dist/dialects/drill.cjs +2 -0
- package/dist/dialects/drill.cjs.map +1 -0
- package/dist/dialects/drill.d.cts +512 -0
- package/dist/dialects/drill.d.ts +512 -0
- package/dist/dialects/drill.js +2 -0
- package/dist/dialects/drill.js.map +1 -0
- package/dist/dialects/druid.cjs +2 -0
- package/dist/dialects/druid.cjs.map +1 -0
- package/dist/dialects/druid.d.cts +17 -0
- package/dist/dialects/druid.d.ts +17 -0
- package/dist/dialects/druid.js +2 -0
- package/dist/dialects/druid.js.map +1 -0
- package/dist/dialects/duckdb.cjs +86 -0
- package/dist/dialects/duckdb.cjs.map +1 -0
- package/dist/dialects/duckdb.d.cts +756 -0
- package/dist/dialects/duckdb.d.ts +756 -0
- package/dist/dialects/duckdb.js +86 -0
- package/dist/dialects/duckdb.js.map +1 -0
- package/dist/dialects/dune.cjs +2 -0
- package/dist/dialects/dune.cjs.map +1 -0
- package/dist/dialects/dune.d.cts +21 -0
- package/dist/dialects/dune.d.ts +21 -0
- package/dist/dialects/dune.js +2 -0
- package/dist/dialects/dune.js.map +1 -0
- package/dist/dialects/exasol.cjs +2 -0
- package/dist/dialects/exasol.cjs.map +1 -0
- package/dist/dialects/exasol.d.cts +507 -0
- package/dist/dialects/exasol.d.ts +507 -0
- package/dist/dialects/exasol.js +2 -0
- package/dist/dialects/exasol.js.map +1 -0
- package/dist/dialects/fabric.cjs +2 -0
- package/dist/dialects/fabric.cjs.map +1 -0
- package/dist/dialects/fabric.d.cts +463 -0
- package/dist/dialects/fabric.d.ts +463 -0
- package/dist/dialects/fabric.js +2 -0
- package/dist/dialects/fabric.js.map +1 -0
- package/dist/dialects/hive.cjs +2 -0
- package/dist/dialects/hive.cjs.map +1 -0
- package/dist/dialects/hive.d.cts +585 -0
- package/dist/dialects/hive.d.ts +585 -0
- package/dist/dialects/hive.js +2 -0
- package/dist/dialects/hive.js.map +1 -0
- package/dist/dialects/materialize.cjs +2 -0
- package/dist/dialects/materialize.cjs.map +1 -0
- package/dist/dialects/materialize.d.cts +890 -0
- package/dist/dialects/materialize.d.ts +890 -0
- package/dist/dialects/materialize.js +2 -0
- package/dist/dialects/materialize.js.map +1 -0
- package/dist/dialects/mysql.cjs +2 -0
- package/dist/dialects/mysql.cjs.map +1 -0
- package/dist/dialects/mysql.d.cts +292 -0
- package/dist/dialects/mysql.d.ts +292 -0
- package/dist/dialects/mysql.js +2 -0
- package/dist/dialects/mysql.js.map +1 -0
- package/dist/dialects/oracle.cjs +2 -0
- package/dist/dialects/oracle.cjs.map +1 -0
- package/dist/dialects/oracle.d.cts +539 -0
- package/dist/dialects/oracle.d.ts +539 -0
- package/dist/dialects/oracle.js +2 -0
- package/dist/dialects/oracle.js.map +1 -0
- package/dist/dialects/postgres.cjs +2 -0
- package/dist/dialects/postgres.cjs.map +1 -0
- package/dist/dialects/postgres.d.cts +587 -0
- package/dist/dialects/postgres.d.ts +587 -0
- package/dist/dialects/postgres.js +2 -0
- package/dist/dialects/postgres.js.map +1 -0
- package/dist/dialects/presto.cjs +2 -0
- package/dist/dialects/presto.cjs.map +1 -0
- package/dist/dialects/presto.d.cts +173 -0
- package/dist/dialects/presto.d.ts +173 -0
- package/dist/dialects/presto.js +2 -0
- package/dist/dialects/presto.js.map +1 -0
- package/dist/dialects/prql.cjs +2 -0
- package/dist/dialects/prql.cjs.map +1 -0
- package/dist/dialects/prql.d.cts +496 -0
- package/dist/dialects/prql.d.ts +496 -0
- package/dist/dialects/prql.js +2 -0
- package/dist/dialects/prql.js.map +1 -0
- package/dist/dialects/redshift.cjs +2 -0
- package/dist/dialects/redshift.cjs.map +1 -0
- package/dist/dialects/redshift.d.cts +132 -0
- package/dist/dialects/redshift.d.ts +132 -0
- package/dist/dialects/redshift.js +2 -0
- package/dist/dialects/redshift.js.map +1 -0
- package/dist/dialects/risingwave.cjs +2 -0
- package/dist/dialects/risingwave.cjs.map +1 -0
- package/dist/dialects/risingwave.d.cts +478 -0
- package/dist/dialects/risingwave.d.ts +478 -0
- package/dist/dialects/risingwave.js +2 -0
- package/dist/dialects/risingwave.js.map +1 -0
- package/dist/dialects/singlestore.cjs +2 -0
- package/dist/dialects/singlestore.cjs.map +1 -0
- package/dist/dialects/singlestore.d.cts +73 -0
- package/dist/dialects/singlestore.d.ts +73 -0
- package/dist/dialects/singlestore.js +2 -0
- package/dist/dialects/singlestore.js.map +1 -0
- package/dist/dialects/snowflake.cjs +3 -0
- package/dist/dialects/snowflake.cjs.map +1 -0
- package/dist/dialects/snowflake.d.cts +320 -0
- package/dist/dialects/snowflake.d.ts +320 -0
- package/dist/dialects/snowflake.js +3 -0
- package/dist/dialects/snowflake.js.map +1 -0
- package/dist/dialects/solr.cjs +2 -0
- package/dist/dialects/solr.cjs.map +1 -0
- package/dist/dialects/solr.d.cts +458 -0
- package/dist/dialects/solr.d.ts +458 -0
- package/dist/dialects/solr.js +2 -0
- package/dist/dialects/solr.js.map +1 -0
- package/dist/dialects/spark.cjs +2 -0
- package/dist/dialects/spark.cjs.map +1 -0
- package/dist/dialects/spark.d.cts +484 -0
- package/dist/dialects/spark.d.ts +484 -0
- package/dist/dialects/spark.js +2 -0
- package/dist/dialects/spark.js.map +1 -0
- package/dist/dialects/spark2.cjs +2 -0
- package/dist/dialects/spark2.cjs.map +1 -0
- package/dist/dialects/spark2.d.cts +486 -0
- package/dist/dialects/spark2.d.ts +486 -0
- package/dist/dialects/spark2.js +2 -0
- package/dist/dialects/spark2.js.map +1 -0
- package/dist/dialects/sqlite.cjs +2 -0
- package/dist/dialects/sqlite.cjs.map +1 -0
- package/dist/dialects/sqlite.d.cts +510 -0
- package/dist/dialects/sqlite.d.ts +510 -0
- package/dist/dialects/sqlite.js +2 -0
- package/dist/dialects/sqlite.js.map +1 -0
- package/dist/dialects/starrocks.cjs +2 -0
- package/dist/dialects/starrocks.cjs.map +1 -0
- package/dist/dialects/starrocks.d.cts +518 -0
- package/dist/dialects/starrocks.d.ts +518 -0
- package/dist/dialects/starrocks.js +2 -0
- package/dist/dialects/starrocks.js.map +1 -0
- package/dist/dialects/tableau.cjs +2 -0
- package/dist/dialects/tableau.cjs.map +1 -0
- package/dist/dialects/tableau.d.cts +466 -0
- package/dist/dialects/tableau.d.ts +466 -0
- package/dist/dialects/tableau.js +2 -0
- package/dist/dialects/tableau.js.map +1 -0
- package/dist/dialects/teradata.cjs +2 -0
- package/dist/dialects/teradata.cjs.map +1 -0
- package/dist/dialects/teradata.d.cts +539 -0
- package/dist/dialects/teradata.d.ts +539 -0
- package/dist/dialects/teradata.js +2 -0
- package/dist/dialects/teradata.js.map +1 -0
- package/dist/dialects/trino.cjs +2 -0
- package/dist/dialects/trino.cjs.map +1 -0
- package/dist/dialects/trino.d.cts +465 -0
- package/dist/dialects/trino.d.ts +465 -0
- package/dist/dialects/trino.js +2 -0
- package/dist/dialects/trino.js.map +1 -0
- package/dist/dialects/tsql.cjs +2 -0
- package/dist/dialects/tsql.cjs.map +1 -0
- package/dist/dialects/tsql.d.cts +703 -0
- package/dist/dialects/tsql.d.ts +703 -0
- package/dist/dialects/tsql.js +2 -0
- package/dist/dialects/tsql.js.map +1 -0
- package/dist/index.cjs +5 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -14178
- package/dist/index.d.ts +3 -14178
- package/dist/index.js +5 -25
- package/dist/index.js.map +1 -1
- package/dist/tokens-VcMD09XM.d.cts +15805 -0
- package/dist/tokens-VcMD09XM.d.ts +15805 -0
- package/package.json +171 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/optimizer/eliminate_ctes.ts","../src/optimizer/eliminate_joins.ts","../src/optimizer/eliminate_subqueries.ts","../src/optimizer/merge_subqueries.ts","../src/optimizer/pushdown_predicates.ts","../src/optimizer/resolver.ts","../src/optimizer/pushdown_projections.ts","../src/optimizer/isolate_table_selects.ts","../src/optimizer/qualify_columns.ts","../src/optimizer/qualify_tables.ts","../src/optimizer/qualify.ts","../src/optimizer/unnest_subqueries.ts","../src/optimizer/optimizer.ts"],"sourcesContent":["// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/eliminate_ctes.py\n\nimport type {\n Expression,\n} from '../expressions';\nimport {\n buildScope, Scope,\n} from './scope';\n\n/**\n * Remove unused CTEs from an expression.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { eliminateCtes } from 'sqlglot/optimizer';\n *\n * const sql = \"WITH y AS (SELECT a FROM x) SELECT a FROM z\";\n * const expression = parseOne(sql);\n * eliminateCtes(expression).sql();\n * // 'SELECT a FROM z'\n * ```\n *\n * @param expression - Expression to optimize\n * @returns The optimized expression\n */\nexport function eliminateCtes<E extends Expression> (expression: E): E {\n const root = buildScope(expression);\n\n if (root) {\n const refCount = root.refCount();\n\n // Traverse the scope tree in reverse so we can remove chains of unused CTEs\n const scopes: Scope[] = [\n ];\n for (const scope of root.traverse()) {\n scopes.push(scope);\n }\n\n for (let i = scopes.length - 1; 0 <= i; i--) {\n const scope = scopes[i];\n if (scope.isCte) {\n const scopeId = scope;\n const count = refCount.get(scopeId) || 0;\n\n if (count <= 0) {\n const cteNode = scope.expression.parent;\n if (!cteNode) {\n continue;\n }\n\n const withNode = cteNode.parent;\n cteNode.pop();\n\n // Pop the entire WITH clause if this is the last CTE\n if (withNode) {\n const withExpressions = withNode.args.expressions;\n if (!withExpressions || withExpressions.length === 0) {\n withNode.pop();\n }\n }\n\n // Decrement the ref count for all sources this CTE selects from\n for (const [\n , source,\n ] of Object.entries(scope.selectedSources)) {\n const [\n , sourceScope,\n ] = source;\n if (sourceScope instanceof Scope) {\n const currentCount = refCount.get(sourceScope) || 0;\n refCount.set(sourceScope, currentCount - 1);\n }\n }\n }\n }\n }\n }\n\n return expression;\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/eliminate_joins.py\n\nimport {\n AggFuncExpr,\n and,\n AndExpr,\n ColumnExpr,\n EqExpr,\n Expression,\n JoinExpr,\n JoinExprKind,\n LimitExpr,\n SelectExpr,\n true_,\n} from '../expressions';\nimport {\n assertIsInstanceOf,\n} from '../port_internals';\nimport {\n normalized,\n} from './normalize';\nimport {\n Scope, traverseScope,\n} from './scope';\n\n/**\n * Remove unused joins from an expression.\n *\n * This only removes joins when we know that the join condition doesn't produce duplicate rows.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { eliminateJoins } from 'sqlglot/optimizer';\n *\n * const sql = \"SELECT x.a FROM x LEFT JOIN (SELECT DISTINCT y.b FROM y) AS y ON x.b = y.b\";\n * const expression = parseOne(sql);\n * eliminateJoins(expression).sql();\n * // 'SELECT x.a FROM x'\n * ```\n *\n * @param expression - Expression to optimize\n * @returns The optimized expression\n */\nexport function eliminateJoins<E extends Expression> (expression: E): E {\n for (const scope of traverseScope(expression)) {\n // If any columns in this scope aren't qualified, it's hard to determine if a join isn't used.\n // It's probably possible to infer this from the outputs of derived tables.\n // But for now, let's just skip this rule.\n if (0 < scope.unqualifiedColumns.length) {\n continue;\n }\n\n const joins = scope.expression.args.joins;\n if (!joins) {\n continue;\n }\n\n // Reverse the joins so we can remove chains of unused joins\n for (let i = joins.length - 1; 0 <= i; i--) {\n const join: Expression = joins[i];\n assertIsInstanceOf(join, JoinExpr);\n if (join.isSemiOrAntiJoin) {\n continue;\n }\n\n const alias = join.aliasOrName;\n if (alias && shouldEliminateJoin(scope, join, alias)) {\n join.pop();\n scope.removeSource(alias);\n }\n }\n }\n\n return expression;\n}\n\nfunction shouldEliminateJoin (scope: Scope, join: JoinExpr, alias: string): boolean {\n const innerSource = scope.sources.get(alias);\n if (!(innerSource instanceof Scope)) {\n return false;\n }\n\n if (joinIsUsed(scope, join, alias)) {\n return false;\n }\n\n const side = join.args.side;\n const onClause = join.args.on;\n\n return (\n (side === JoinExprKind.LEFT && isJoinedOnAllUniqueOutputs(innerSource, join))\n || (!onClause && hasSingleOutputRow(innerSource))\n );\n}\n\nfunction joinIsUsed (scope: Scope, join: JoinExpr, alias: string): boolean {\n // We need to find all columns that reference this join.\n // But columns in the ON clause shouldn't count.\n const onClause = join.args.on;\n\n const onClauseColumns = new Set<Expression>();\n if (onClause) {\n for (const column of onClause.findAll(ColumnExpr)) {\n onClauseColumns.add(column);\n }\n }\n\n const sourceColumns = scope.sourceColumns(alias);\n return sourceColumns.some((column) => !onClauseColumns.has(column));\n}\n\nfunction isJoinedOnAllUniqueOutputs (scope: Scope, join: JoinExpr): boolean {\n const uniqueOutputs_ = uniqueOutputs(scope);\n if (!uniqueOutputs_ || uniqueOutputs_.size === 0) {\n return false;\n }\n\n const {\n joinKeys,\n } = joinCondition(join);\n const joinKeyNames = new Set(joinKeys.map((k) => k.name));\n\n for (const output of uniqueOutputs_) {\n if (!joinKeyNames.has(output)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction uniqueOutputs (scope: Scope): Set<string> | undefined {\n const expression = scope.expression;\n if (!(expression instanceof SelectExpr)) {\n return undefined;\n }\n\n const select = expression;\n\n // DISTINCT makes all outputs unique\n if (select.args.distinct) {\n return new Set(select.namedSelects);\n }\n\n // GROUP BY makes grouped columns unique\n const group = select.args.group;\n if (group) {\n const groupedSqls = new Set(\n (group.args.expressions ?? [\n ])\n .filter((e): e is Expression => e instanceof Expression)\n .map((e) => e.sql()),\n );\n const groupedOutputSqls = new Set<string>();\n const uniqueOutputs = new Set<string>();\n\n for (const selectExpr of select.selects) {\n if (!(selectExpr instanceof Expression)) {\n continue;\n }\n\n const outputSql = selectExpr.unalias().sql();\n if (groupedSqls.has(outputSql)) {\n groupedOutputSqls.add(outputSql);\n uniqueOutputs.add(selectExpr.aliasOrName);\n }\n }\n\n // All the grouped expressions must be in the output\n const allGroupedInOutput = [\n ...groupedSqls,\n ].every((s) => groupedOutputSqls.has(s));\n\n return allGroupedInOutput ? uniqueOutputs : new Set();\n }\n\n // Single row output makes all outputs unique\n if (hasSingleOutputRow(scope)) {\n return new Set(select.namedSelects);\n }\n\n return new Set();\n}\n\nfunction hasSingleOutputRow (scope: Scope): boolean {\n const expression = scope.expression;\n if (!(expression instanceof SelectExpr)) {\n return false;\n }\n\n const select = expression;\n\n // No FROM clause means single row\n if (!select.args.from) {\n return true;\n }\n\n // All aggregates without GROUP BY means single row\n const allAggregates = select.selects.every((e) => {\n if (!(e instanceof Expression)) {\n return false;\n }\n const unaliased = e.unalias();\n return unaliased instanceof AggFuncExpr;\n });\n\n if (allAggregates) {\n return true;\n }\n\n // LIMIT 1 means single row\n if (isLimit1(scope)) {\n return true;\n }\n\n return false;\n}\n\nfunction isLimit1 (scope: Scope): boolean {\n const limit = scope.expression.getArgKey('limit');\n if (!(limit instanceof LimitExpr)) {\n return false;\n }\n return limit.args.expression?.args.this === '1';\n}\n\n/**\n * Extract the join condition from a join expression.\n *\n * @param join - The join expression\n * @returns Tuple of (source key, join key, remaining predicate)\n */\nexport function joinCondition (\n join: JoinExpr,\n): {\n sourceKeys: Expression[];\n joinKeys: Expression[];\n on: Expression;\n} {\n const name = join.aliasOrName;\n const onClause = join.args.on;\n const on = (onClause || true_()).copy();\n\n const sourceKeys: Expression[] = [\n ];\n const joinKeys: Expression[] = [\n ];\n\n function extractCondition (condition: Expression): void {\n const [\n left,\n right,\n ] = condition.unnestOperands();\n if (!left || !right) {\n return;\n }\n\n const leftTables = columnTableNames(left);\n const rightTables = columnTableNames(right);\n\n if (name && leftTables.has(name) && !rightTables.has(name)) {\n joinKeys.push(left);\n sourceKeys.push(right);\n condition.replace(true_());\n } else if (name && rightTables.has(name) && !leftTables.has(name)) {\n joinKeys.push(right);\n sourceKeys.push(left);\n condition.replace(true_());\n }\n }\n\n if (normalized(on)) {\n // CNF form: AND of EQ conditions\n const andOn = on instanceof AndExpr\n ? on\n : and([\n on,\n true_(),\n ], {\n copy: false,\n });\n for (const condition of andOn.flatten()) {\n if (condition instanceof EqExpr) {\n extractCondition(condition);\n }\n }\n } else if (normalized(on, {\n dnf: true,\n })) {\n // DNF form: OR of ANDs — find EQ conditions present in every OR branch\n let conditions: EqExpr[] | undefined;\n\n for (const orBranch of on.flatten()) {\n const parts = Array.from(orBranch.flatten())\n .filter((p): p is EqExpr => p instanceof EqExpr);\n\n if (conditions === undefined) {\n conditions = parts;\n } else {\n const temp: EqExpr[] = [\n ];\n for (const p of parts) {\n const cs = conditions.filter((c) => p.sql() === c.sql());\n if (0 < cs.length) {\n temp.push(p);\n temp.push(...cs);\n }\n }\n conditions = temp;\n }\n }\n\n if (conditions) {\n for (const condition of conditions) {\n extractCondition(condition);\n }\n }\n }\n\n return {\n sourceKeys,\n joinKeys,\n on,\n };\n}\n\nfunction columnTableNames (expression: Expression): Set<string> {\n const tables = new Set<string>();\n for (const column of expression.findAll(ColumnExpr)) {\n if (column.table) {\n tables.add(column.table);\n }\n }\n return tables;\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/eliminate_subqueries.py\n\nimport type {\n Expression, ExpressionHash,\n} from '../expressions';\nimport {\n alias,\n CteExpr,\n DdlExpr,\n LateralExpr,\n SubqueryExpr,\n table,\n TableAliasExpr,\n TableExpr,\n toIdentifier,\n WithExpr,\n} from '../expressions';\nimport {\n assertIsInstanceOf, isInstanceOf,\n} from '../port_internals';\nimport {\n findNewName,\n} from '../helper';\nimport type {\n Scope,\n} from './scope';\nimport {\n buildScope,\n} from './scope';\n\ntype ExistingCTEsMapping = Map<ExpressionHash, string>;\ntype TakenNameMapping = Map<string, Scope | TableExpr>;\n\n/**\n * Rewrite derived tables as CTEs, deduplicating if possible.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { eliminateSubqueries } from 'sqlglot/optimizer';\n *\n * const expression = parseOne(\"SELECT a FROM (SELECT * FROM x) AS y\");\n * eliminateSubqueries(expression).sql();\n * // 'WITH y AS (SELECT * FROM x) SELECT a FROM y AS y'\n * ```\n *\n * This also deduplicates common subqueries:\n * ```ts\n * const expression = parseOne(\"SELECT a FROM (SELECT * FROM x) AS y CROSS JOIN (SELECT * FROM x) AS z\");\n * eliminateSubqueries(expression).sql();\n * // 'WITH y AS (SELECT * FROM x) SELECT a FROM y AS y CROSS JOIN y AS z'\n * ```\n *\n * @param expression - Expression to optimize\n * @returns The optimized expression\n */\nexport function eliminateSubqueries<E extends Expression> (expression: E): E {\n if (expression instanceof SubqueryExpr && expression.args.this) {\n eliminateSubqueries(expression.args.this);\n return expression;\n }\n\n const root = buildScope(expression);\n\n if (!root) {\n return expression;\n }\n\n const taken: TakenNameMapping = new Map();\n\n // All CTE aliases in the root scope are taken\n for (const scope of root.cteScopes) {\n const parent = scope.expression.parent;\n if (parent) {\n taken.set(parent.alias, scope);\n }\n }\n\n // All table names are taken\n for (const scope of root.traverse()) {\n for (const [\n , source,\n ] of scope.sources) {\n if (source instanceof TableExpr) {\n taken.set(source.name, source);\n }\n }\n }\n\n const existingCtes: ExistingCTEsMapping = new Map();\n\n const withClause = root.expression.args.with;\n let recursive = false;\n\n if (withClause) {\n assertIsInstanceOf(withClause, WithExpr);\n recursive = Boolean(withClause.args.recursive);\n for (const cte of withClause.args.expressions ?? [\n ]) {\n if (isInstanceOf(cte, CteExpr) && cte.args.this) {\n if (cte.args.this) existingCtes.set(cte.args.this.sqlKey, cte.alias);\n }\n }\n }\n\n const newCtes: Expression[] = [\n ];\n\n // We're adding more CTEs, but we want to maintain the DAG order.\n // Derived tables within an existing CTE need to come before the existing CTE.\n for (const cteScope of root.cteScopes) {\n // Append all the new CTEs from this existing CTE\n for (const scope of cteScope.traverse()) {\n if (scope === cteScope) {\n // Don't try to eliminate this CTE itself\n continue;\n }\n const newCte = eliminate(scope, existingCtes, taken);\n if (newCte) {\n newCtes.push(newCte);\n }\n }\n\n // Append the existing CTE itself\n const cteParent = cteScope.expression.parent;\n if (cteParent) {\n newCtes.push(cteParent);\n }\n }\n\n // Now append the rest\n const restScopes = [\n ...root.unionScopes,\n ...root.subqueryScopes,\n ...root.tableScopes,\n ];\n for (const scope of restScopes) {\n for (const childScope of scope.traverse()) {\n const newCte = eliminate(childScope, existingCtes, taken);\n if (newCte) {\n newCtes.push(newCte);\n }\n }\n }\n\n if (0 < newCtes.length) {\n const query = expression instanceof DdlExpr\n ? expression.args.expression\n : expression;\n\n query?.setArgKey('with', new WithExpr({\n expressions: newCtes as CteExpr[],\n recursive,\n }));\n }\n\n return expression;\n}\n\nfunction eliminate (\n scope: Scope,\n existingCtes: ExistingCTEsMapping,\n taken: TakenNameMapping,\n): Expression | undefined {\n if (scope.isDerivedTable) {\n return eliminateDerivedTable(scope, existingCtes, taken);\n }\n\n if (scope.isCte) {\n return eliminateCte(scope, existingCtes, taken);\n }\n\n return undefined;\n}\n\nfunction eliminateDerivedTable (\n scope: Scope,\n existingCtes: ExistingCTEsMapping,\n taken: TakenNameMapping,\n): Expression | undefined {\n // This makes sure that we don't:\n // - drop the \"pivot\" arg from a pivoted subquery\n // - eliminate a lateral correlated subquery\n if (scope.parent && (0 < scope.parent.pivots.length || scope.parent.expression instanceof LateralExpr)) {\n return undefined;\n }\n\n // Get rid of redundant exp.Subquery expressions, i.e. those that are just used as wrappers\n let toReplace = scope.expression.parent;\n if (!toReplace) {\n return undefined;\n }\n\n // Unwrap nested subqueries\n if (toReplace instanceof SubqueryExpr) {\n toReplace = (toReplace as SubqueryExpr).unwrap();\n }\n\n const [\n name,\n cte,\n ] = newCte(scope, existingCtes, taken);\n\n const tableExpr = alias(table(name), toReplace.alias || name, {\n copy: false,\n });\n const toReplaceArgs = toReplace.args as Record<string, unknown>;\n const joins = toReplaceArgs.joins;\n if (joins && Array.isArray(joins)) {\n (tableExpr as TableExpr).setArgKey('joins', joins);\n }\n\n toReplace.replace(tableExpr);\n\n return cte;\n}\n\nfunction eliminateCte (\n scope: Scope,\n existingCtes: ExistingCTEsMapping,\n taken: TakenNameMapping,\n): Expression | undefined {\n const parent = scope.expression.parent;\n if (!parent) {\n return undefined;\n }\n\n const [\n name,\n cte,\n ] = newCte(scope, existingCtes, taken);\n\n const withClause = parent.parent;\n parent.pop();\n\n if (withClause) {\n const withExpressions = withClause.args.expressions;\n if (!withExpressions || withExpressions.length === 0) {\n withClause.pop();\n }\n }\n\n // Rename references to this CTE\n if (scope.parent) {\n for (const childScope of scope.parent.traverse()) {\n for (const [\n , source,\n ] of Object.entries(childScope.selectedSources)) {\n const [\n tableExpr,\n sourceScope,\n ] = source;\n if (sourceScope === scope) {\n const newTable = alias(\n table(name),\n (tableExpr as Expression).aliasOrName,\n {\n copy: false,\n },\n );\n tableExpr.replace(newTable);\n }\n }\n }\n }\n\n return cte;\n}\n\nfunction newCte (\n scope: Scope,\n existingCtes: ExistingCTEsMapping,\n taken: TakenNameMapping,\n): [string, Expression | undefined] {\n /**\n * Returns:\n * tuple of (name, cte)\n * where `name` is a new name for this CTE in the root scope and `cte` is a new CTE instance.\n * If this CTE duplicates an existing CTE, `cte` will be undefined.\n */\n const duplicateCteAlias = existingCtes.get(scope.expression.sqlKey);\n const parent = scope.expression.parent;\n let name = parent?.alias || '';\n\n if (!name) {\n name = findNewName(Array.from(taken.keys()), 'cte');\n }\n\n if (duplicateCteAlias) {\n name = duplicateCteAlias;\n } else if (taken.has(name)) {\n name = findNewName(Array.from(taken.keys()), name);\n }\n\n taken.set(name, scope);\n\n let cte: Expression | undefined;\n if (!duplicateCteAlias) {\n existingCtes.set(scope.expression.sqlKey, name);\n cte = new CteExpr({\n this: scope.expression,\n alias: new TableAliasExpr({\n this: toIdentifier(name),\n }),\n });\n }\n\n return [\n name,\n cte,\n ];\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/merge_subqueries.py\n\nimport {\n isInstanceOf,\n} from '../port_internals';\nimport {\n AggFuncExpr,\n alias as aliasExpr,\n BinaryExpr,\n ColumnExpr,\n columnTableNames,\n EqExpr,\n ExplodeExpr,\n Expression,\n FromExpr,\n FuncExpr,\n GroupExpr,\n HavingExpr,\n JoinExpr,\n JoinExprKind,\n NeqExpr,\n OrderExpr,\n ParenExpr,\n paren as parenExpr,\n QueryTransformExpr,\n SelectExpr,\n SubqueryExpr,\n TableAliasExpr,\n TableExpr,\n toIdentifier,\n UnaryExpr,\n WhereExpr,\n WindowExpr,\n} from '../expressions';\nimport {\n findNewName, seqGet,\n} from '../helper';\nimport {\n Dialect,\n} from '../dialects/dialect';\nimport {\n Scope, traverseScope,\n} from './scope';\n\n/**\n * Rewrite sqlglot AST to merge derived tables into the outer query.\n *\n * This also merges CTEs if they are selected from only once.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { mergeSubqueries } from 'sqlglot/optimizer';\n *\n * const expression = parseOne(\"SELECT a FROM (SELECT x.a FROM x) CROSS JOIN y\");\n * mergeSubqueries(expression).sql();\n * // 'SELECT x.a FROM x CROSS JOIN y'\n * ```\n *\n * If `leaveTablesIsolated` is True, this will not merge inner queries into outer\n * queries if it would result in multiple table selects in a single query.\n *\n * Inspired by https://dev.mysql.com/doc/refman/8.0/en/derived-table-optimization.html\n *\n * @param expression - Expression to optimize\n * @param options - Optimization options\n * @param options.leaveTablesIsolated - Don't merge if it creates multiple table selects (default: false)\n * @returns The optimized expression\n */\nexport function mergeSubqueries<E extends Expression> (\n expression: E,\n options: {\n leaveTablesIsolated?: boolean;\n } = {},\n): E {\n const {\n leaveTablesIsolated = false,\n } = options;\n\n expression = mergeCtes(expression, {\n leaveTablesIsolated,\n }) as E;\n expression = mergeDerivedTables(expression, {\n leaveTablesIsolated,\n }) as E;\n\n return expression;\n}\n\nconst SAFE_TO_REPLACE_UNWRAPPED = [\n ColumnExpr,\n EqExpr,\n FuncExpr,\n NeqExpr,\n ParenExpr,\n] as const;\n\ntype FromOrJoin = FromExpr | JoinExpr;\n\nfunction mergeCtes<E extends Expression> (\n expression: E,\n options: {leaveTablesIsolated: boolean},\n): E {\n const {\n leaveTablesIsolated,\n } = options;\n const scopes = Array.from(traverseScope(expression));\n\n // All places where we select from CTEs\n // Key on CTE scope ID to detect CTEs selected from multiple times\n const cteSelections = new Map<Scope, [Scope, Scope, Expression][]>();\n\n for (const outerScope of scopes) {\n for (const [\n , sourceEntry,\n ] of Object.entries(outerScope.selectedSources)) {\n const [\n table,\n innerSource,\n ] = sourceEntry;\n if (innerSource instanceof Scope && innerSource.isCte) {\n let scopeList = cteSelections.get(innerSource);\n if (!scopeList) {\n scopeList = [\n ];\n cteSelections.set(innerSource, scopeList);\n }\n scopeList.push([\n outerScope,\n innerSource,\n table,\n ]);\n }\n }\n }\n\n // Only merge CTEs that are selected from exactly once\n const singularCteSelections: [Scope, Scope, Expression][] = [\n ];\n for (const [\n , selections,\n ] of cteSelections) {\n if (selections.length === 1) {\n singularCteSelections.push(selections[0]);\n }\n }\n\n for (const [\n outerScope,\n innerScope,\n table,\n ] of singularCteSelections) {\n // Find FromExpr or JoinExpr ancestor\n const fromOrJoin = table.findAncestor<FromExpr | JoinExpr>(FromExpr, JoinExpr);\n if (fromOrJoin && mergeable(outerScope, innerScope, {\n leaveTablesIsolated,\n }, fromOrJoin)) {\n const alias = table.aliasOrName;\n renameInnerSources(outerScope, innerScope, alias);\n mergeFrom(outerScope, innerScope, table as SubqueryExpr | TableExpr, alias);\n mergeExpressions(outerScope, innerScope, alias);\n mergeOrder(outerScope, innerScope);\n mergeJoins(outerScope, innerScope, fromOrJoin);\n mergeWhere(outerScope, innerScope, fromOrJoin);\n mergeHints(outerScope, innerScope);\n popCte(innerScope);\n outerScope.clearCache();\n }\n }\n\n return expression;\n}\n\nfunction mergeDerivedTables<E extends Expression> (\n expression: E,\n options: {leaveTablesIsolated: boolean},\n): E {\n const {\n leaveTablesIsolated,\n } = options;\n for (const outerScope of traverseScope(expression)) {\n for (const subquery of outerScope.derivedTables) {\n // Find FromExpr or JoinExpr ancestor\n const fromOrJoin = subquery.findAncestor<FromExpr | JoinExpr>(FromExpr, JoinExpr);\n\n const alias = subquery.aliasOrName;\n const innerScope = outerScope.sources.get(alias);\n\n if (\n innerScope instanceof Scope\n && fromOrJoin\n && mergeable(outerScope, innerScope, {\n leaveTablesIsolated,\n }, fromOrJoin)\n ) {\n renameInnerSources(outerScope, innerScope, alias);\n mergeFrom(outerScope, innerScope, subquery, alias);\n mergeExpressions(outerScope, innerScope, alias);\n mergeOrder(outerScope, innerScope);\n mergeJoins(outerScope, innerScope, fromOrJoin);\n mergeWhere(outerScope, innerScope, fromOrJoin);\n mergeHints(outerScope, innerScope);\n outerScope.clearCache();\n }\n }\n }\n\n return expression;\n}\n\nfunction mergeable (\n outerScope: Scope,\n innerScope: Scope,\n options: {leaveTablesIsolated: boolean},\n fromOrJoin: FromOrJoin,\n): boolean {\n const {\n leaveTablesIsolated,\n } = options;\n const innerSelect = innerScope.expression.unnest();\n\n // Check if window expressions are in unmergable operations\n function isWindowExpressionInUnmergableOperation (): boolean {\n const windowAliases = new Set<string>();\n if (!(innerSelect instanceof SelectExpr)) {\n return false;\n }\n const innerSelectExpr = innerSelect;\n\n for (const s of innerSelectExpr.selects) {\n if (!(s instanceof Expression)) {\n continue;\n }\n if (s.find(WindowExpr)) {\n windowAliases.add(s.aliasOrName);\n }\n }\n\n const innerSelectName = fromOrJoin.aliasOrName;\n const unmergableWindowColumns: ColumnExpr[] = [\n ];\n\n for (const column of outerScope.columns) {\n // Check if column has unmergable ancestor\n const hasUnmergableAncestor = column.findAncestor(\n WhereExpr,\n GroupExpr,\n OrderExpr,\n JoinExpr,\n HavingExpr,\n AggFuncExpr,\n ) !== undefined;\n\n if (hasUnmergableAncestor) {\n unmergableWindowColumns.push(column);\n }\n }\n\n const windowExpressionsInUnmergable = unmergableWindowColumns.filter(\n (column) => column.table === innerSelectName && windowAliases.has(column.name),\n );\n\n return 0 < windowExpressionsInUnmergable.length;\n }\n\n // Check if outer select joins on inner select's join\n function outerSelectJoinsOnInnerSelectJoin (): boolean {\n if (!(fromOrJoin instanceof JoinExpr)) {\n return false;\n }\n\n const alias = fromOrJoin.aliasOrName;\n const on = fromOrJoin.args.on;\n\n if (!on) {\n return false;\n }\n\n const selections = Array.from(on.findAll(ColumnExpr))\n .filter((c) => c.table === alias)\n .map((c) => c.name);\n\n const innerFrom = innerScope.expression.getArgKey('from') as FromExpr | undefined;\n\n if (!innerFrom) {\n return false;\n }\n\n const innerFromTable = innerFrom.aliasOrName;\n\n if (!(innerScope.expression instanceof SelectExpr)) {\n return false;\n }\n\n const innerSelectExpr = innerScope.expression;\n const innerProjections = new Map<string, Expression>();\n\n for (const s of innerSelectExpr.selects) {\n if (!(s instanceof Expression)) {\n continue;\n }\n innerProjections.set(s.aliasOrName, s);\n }\n\n return selections.some((selection) => {\n const projection = innerProjections.get(selection);\n if (!projection) {\n return false;\n }\n const columns = Array.from(projection.findAll(ColumnExpr));\n return columns.some((col) => col.table !== innerFromTable);\n });\n }\n\n // Check if this is a recursive CTE\n function isRecursive (): boolean {\n const cte = innerScope.expression.parent;\n let node: Expression | undefined = outerScope.expression.parent;\n\n while (node) {\n if (node === cte) {\n return true;\n }\n node = node.parent;\n }\n return false;\n }\n\n // Main mergeability checks\n if (!(outerScope.expression instanceof SelectExpr)) {\n return false;\n }\n\n const outerSelectExpr = outerScope.expression;\n\n if (outerSelectExpr.isStar) {\n return false;\n }\n\n if (!(innerSelect instanceof SelectExpr)) {\n return false;\n }\n\n const innerSelectExpr = innerSelect;\n\n // Check for unmergable args\n for (const arg of Dialect.UNMERGABLE_ARGS) {\n if (innerSelectExpr.getArgKey(arg)) {\n return false;\n }\n }\n\n if (!innerSelectExpr.args.from) {\n return false;\n }\n\n if (0 < outerScope.pivots.length) {\n return false;\n }\n\n // Check for AggFunc, Select, or Explode in inner expressions\n for (const e of innerSelectExpr.args.expressions ?? [\n ]) {\n if (!(e instanceof Expression)) {\n continue;\n }\n if (e.find(AggFuncExpr) || e.find(SelectExpr) || e.find(ExplodeExpr)) {\n return false;\n }\n }\n\n if (leaveTablesIsolated && 1 < Object.keys(outerScope.selectedSources).length) {\n return false;\n }\n\n if (fromOrJoin instanceof JoinExpr && innerSelectExpr.args.joins && 0 < innerSelectExpr.args.joins.length) {\n return false;\n }\n\n const joinSide = fromOrJoin instanceof JoinExpr ? fromOrJoin.args.side : undefined;\n\n if (\n fromOrJoin instanceof JoinExpr\n && innerSelectExpr.args.where\n && (joinSide === JoinExprKind.FULL || joinSide === JoinExprKind.LEFT || joinSide === JoinExprKind.RIGHT)\n ) {\n return false;\n }\n\n const outerJoins = outerSelectExpr.args.joins;\n\n if (\n fromOrJoin instanceof FromExpr\n && innerSelectExpr.args.where\n && outerJoins\n && outerJoins.some((j) => isInstanceOf(j, JoinExpr) && (j.args.side === JoinExprKind.FULL || j.args.side === JoinExprKind.RIGHT))\n ) {\n return false;\n }\n\n if (outerSelectJoinsOnInnerSelectJoin()) {\n return false;\n }\n\n if (isWindowExpressionInUnmergableOperation()) {\n return false;\n }\n\n if (isRecursive()) {\n return false;\n }\n\n if (innerSelectExpr.args.order && outerScope.isUnion) {\n return false;\n }\n\n const firstExpr = seqGet(innerSelectExpr.args.expressions ?? [\n ], 0);\n if (firstExpr instanceof QueryTransformExpr) {\n return false;\n }\n\n return true;\n}\n\nfunction renameInnerSources (outerScope: Scope, innerScope: Scope, alias: string): void {\n const innerTaken = new Set(Object.keys(innerScope.selectedSources));\n const outerTaken = new Set(Object.keys(outerScope.selectedSources));\n const conflicts = new Set(Array.from(innerTaken).filter((x) => outerTaken.has(x)));\n conflicts.delete(alias);\n\n const taken = new Set([\n ...outerTaken,\n ...innerTaken,\n ]);\n\n for (const conflict of conflicts) {\n const newName = findNewName(Array.from(taken), conflict);\n\n const sourceEntry = innerScope.selectedSources[conflict];\n if (!sourceEntry) {\n continue;\n }\n\n const [\n source,\n ] = sourceEntry;\n const newAlias = toIdentifier(newName);\n\n if (source instanceof TableExpr) {\n if (source.alias) {\n source.setArgKey('alias', newAlias);\n } else {\n source.replace(aliasExpr(source, newAlias, {\n copy: false,\n }));\n }\n } else if (source?.parent instanceof SubqueryExpr) {\n source.parent.setArgKey('alias', new TableAliasExpr({\n this: newAlias,\n }));\n }\n\n for (const column of innerScope.sourceColumns(conflict)) {\n column.setArgKey('table', toIdentifier(newName));\n }\n\n innerScope.renameSource(conflict, newName);\n taken.add(newName);\n }\n}\n\nfunction mergeFrom (\n outerScope: Scope,\n innerScope: Scope,\n nodeToReplace: SubqueryExpr | TableExpr,\n alias: string,\n): void {\n const from = innerScope.expression.getArgKey('from') as FromExpr;\n const newSubquery = from.args.this as Expression;\n\n newSubquery.setArgKey('joins', nodeToReplace.args.joins);\n nodeToReplace.replace(newSubquery);\n\n // Update join hints\n for (const joinHint of outerScope.joinHints) {\n const tables = Array.from(joinHint.findAll(TableExpr));\n for (const table of tables) {\n if (table.aliasOrName === nodeToReplace.aliasOrName) {\n table.setArgKey('this', toIdentifier(newSubquery.aliasOrName));\n }\n }\n }\n\n outerScope.removeSource(alias);\n const newSubquerySource = innerScope.sources.get(newSubquery.aliasOrName);\n if (newSubquerySource !== undefined) {\n outerScope.addSource(newSubquery.aliasOrName, newSubquerySource);\n }\n}\n\nfunction mergeJoins (outerScope: Scope, innerScope: Scope, fromOrJoin: FromOrJoin): void {\n const newJoins: JoinExpr[] = [\n ];\n\n const joins = innerScope.expression.getArgKey('joins') as JoinExpr[] | undefined;\n\n if (joins) {\n for (const join of joins) {\n newJoins.push(join);\n const joinSource = innerScope.sources.get(join.aliasOrName);\n if (joinSource) {\n outerScope.addSource(join.aliasOrName, joinSource);\n }\n }\n }\n\n if (0 < newJoins.length) {\n const outerJoins = (outerScope.expression.getArgKey('joins') as JoinExpr[] | undefined) || [\n ];\n\n // Maintain join order\n let position: number;\n if (fromOrJoin instanceof FromExpr) {\n position = 0;\n } else {\n position = outerJoins.indexOf(fromOrJoin) + 1;\n }\n\n outerJoins.splice(position, 0, ...newJoins);\n (outerScope.expression as SelectExpr).setArgKey('joins', outerJoins);\n }\n}\n\nfunction mergeExpressions (outerScope: Scope, innerScope: Scope, alias: string): void {\n // Collect all columns that reference the alias of the inner query\n const outerColumns = new Map<string, ColumnExpr[]>();\n\n for (const column of outerScope.columns) {\n if (column.table === alias) {\n const name = column.name;\n let columnList = outerColumns.get(name);\n if (!columnList) {\n columnList = [\n ];\n outerColumns.set(name, columnList);\n }\n columnList.push(column);\n }\n }\n\n // Replace columns with the projection expression in the inner query\n if (!(innerScope.expression instanceof SelectExpr)) {\n return;\n }\n\n const innerSelectExpr = innerScope.expression;\n\n for (const expr of innerSelectExpr.args.expressions ?? [\n ]) {\n if (!(expr instanceof Expression)) {\n continue;\n }\n\n const projectionName = expr.aliasOrName;\n\n if (!projectionName) {\n continue;\n }\n\n const columnsToReplace = outerColumns.get(projectionName) || [\n ];\n\n const unaliasedExpr = expr.unalias();\n const mustWrapExpression = !SAFE_TO_REPLACE_UNWRAPPED.some((cls) => unaliasedExpr instanceof cls);\n const isNumber = unaliasedExpr.isNumber;\n\n for (const column of columnsToReplace) {\n const parent = column.parent;\n\n // Don't merge literal numbers in GROUP BY (positional context)\n if (isNumber && parent instanceof GroupExpr) {\n column.replace(toIdentifier(column.name));\n continue;\n }\n\n let replacementExpr = unaliasedExpr;\n\n // Wrap in parens if needed to preserve precedence\n if (\n parent\n && (parent instanceof UnaryExpr || parent instanceof BinaryExpr)\n && mustWrapExpression\n ) {\n replacementExpr = parenExpr(replacementExpr, {\n copy: false,\n });\n }\n\n // Make sure we don't change the column name\n if (parent instanceof SelectExpr && column.name !== replacementExpr.name) {\n replacementExpr = aliasExpr(replacementExpr, column.name, {\n copy: false,\n });\n }\n\n column.replace(replacementExpr.copy());\n }\n }\n}\n\nfunction mergeWhere (outerScope: Scope, innerScope: Scope, fromOrJoin: FromOrJoin): void {\n const where = innerScope.expression.getArgKey('where') as WhereExpr | undefined;\n\n if (!where) {\n return;\n }\n\n const whereThis = where.args.this;\n if (!(whereThis instanceof Expression)) {\n return;\n }\n\n const outerExpression = outerScope.expression as SelectExpr;\n\n if (fromOrJoin instanceof JoinExpr) {\n // Merge predicates from outer join to ON clause if columns are already joined\n const from = outerExpression.args.from;\n const sources = new Set<string>();\n\n if (from) {\n sources.add(from.aliasOrName);\n }\n\n const joins = outerExpression.args.joins;\n if (joins) {\n for (const join of joins) {\n const source = join.aliasOrName;\n sources.add(source);\n if (source === fromOrJoin.aliasOrName) {\n break;\n }\n }\n }\n\n const whereTables = columnTableNames(whereThis);\n const allTablesInSources = Array.from(whereTables).every((t) => sources.has(t));\n\n if (allTablesInSources) {\n fromOrJoin.on(whereThis, {\n copy: false,\n });\n return;\n }\n }\n\n outerExpression.where(whereThis, {\n copy: false,\n });\n}\n\nfunction mergeOrder (outerScope: Scope, innerScope: Scope): void {\n const outerSelectExpr = outerScope.expression as SelectExpr;\n\n if (\n outerSelectExpr.args.group\n || outerSelectExpr.args.distinct\n || outerSelectExpr.args.having\n || outerSelectExpr.args.order\n || Object.keys(outerScope.selectedSources).length !== 1\n ) {\n return;\n }\n\n const hasAgg = outerSelectExpr.args.expressions?.some((expr) => {\n if (!(expr instanceof Expression)) {\n return false;\n }\n return expr.find(AggFuncExpr) !== undefined;\n });\n\n if (hasAgg) {\n return;\n }\n\n outerSelectExpr.setArgKey('order', innerScope.expression.getArgKey('order'));\n}\n\nfunction mergeHints (outerScope: Scope, innerScope: Scope): void {\n const innerScopeHint = innerScope.expression.getArgKey('hint') as Expression | undefined;\n\n if (!innerScopeHint) {\n return;\n }\n\n const outerSelectExpr = outerScope.expression as SelectExpr;\n const outerScopeHint = outerSelectExpr.args.hint;\n\n if (outerScopeHint) {\n const innerHintExpressions = innerScopeHint.args.expressions;\n for (const hintExpression of innerHintExpressions ?? [\n ]) {\n if (hintExpression instanceof Expression) {\n outerScopeHint.append('expressions', hintExpression);\n }\n }\n } else {\n outerSelectExpr.setArgKey('hint', innerScopeHint);\n }\n}\n\nfunction popCte (innerScope: Scope): void {\n const cte = innerScope.expression.parent;\n if (!cte) {\n return;\n }\n\n const with_ = cte.parent;\n if (!with_) {\n return;\n }\n\n const withExpressions = with_.args.expressions;\n if (withExpressions?.length === 1) {\n with_.pop();\n } else {\n cte.pop();\n }\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/pushdown_predicates.py\n\nimport {\n AggFuncExpr,\n AliasExpr,\n Expression,\n AndExpr,\n ColumnExpr,\n FromExpr,\n JoinExpr,\n JoinExprKind,\n or as orExpr,\n OrExpr,\n SelectExpr,\n TableExpr,\n true_ as trueExpr,\n UnnestExpr,\n WhereExpr,\n WindowExpr,\n columnTableNames,\n WithExpr,\n} from '../expressions';\nimport {\n Dialect, type DialectType,\n} from '../dialects/dialect';\nimport {\n narrowInstanceOf,\n} from '../port_internals';\nimport {\n normalized,\n} from './normalize';\nimport {\n buildScope, findInScope, Scope,\n} from './scope';\nimport {\n simplify,\n} from './simplify';\n\n/**\n * Rewrite sqlglot AST to pushdown predicates in FROMs and JOINs.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { pushdownPredicates } from 'sqlglot/optimizer';\n *\n * const sql = \"SELECT y.a AS a FROM (SELECT x.a AS a FROM x AS x) AS y WHERE y.a = 1\";\n * const expression = parseOne(sql);\n * pushdownPredicates(expression).sql();\n * // 'SELECT y.a AS a FROM (SELECT x.a AS a FROM x AS x WHERE x.a = 1) AS y WHERE TRUE'\n * ```\n *\n * @param expression - Expression to optimize\n * @param options - Optimization options\n * @param options.dialect - SQL dialect\n * @returns The optimized expression\n */\nexport function pushdownPredicates<E extends Expression> (\n expression: E,\n options: {\n dialect?: DialectType;\n } = {},\n): E {\n const {\n dialect: dialectArg,\n } = options;\n const root = buildScope(expression);\n\n const dialect = Dialect.getOrRaise(dialectArg);\n\n const unnestRequiresCrossJoin = (dialect.constructor as typeof Dialect).UNNEST_REQUIRES_CROSS_JOIN;\n\n if (root) {\n const scopeRefCount = root.refCount();\n\n for (const scope of Array.from(root.traverse()).reverse()) {\n const select = scope.expression;\n const whereClause = select.getArgKey('where') as WhereExpr | undefined;\n\n if (whereClause) {\n let selectedSources = scope.selectedSources;\n const joins = select.getArgKey('joins') as JoinExpr[] | undefined;\n const joinIndex = new Map<string, number>();\n\n if (joins) {\n joins.forEach((join, i) => {\n const name = join.aliasOrName;\n if (name) {\n joinIndex.set(name, i);\n }\n });\n }\n\n // A right join can only push down to itself and not the source FROM table\n // Presto, Trino and Athena don't support inner joins where the RHS is an UNNEST expression\n let pushdownAllowed = true;\n for (const [\n k,\n source,\n ] of Object.entries(selectedSources)) {\n const [\n node,\n ] = source;\n if (!node) continue;\n\n const parent = node.findAncestor<JoinExpr | FromExpr>(JoinExpr, FromExpr);\n\n if (parent instanceof JoinExpr) {\n const joinParent = parent as JoinExpr;\n if (joinParent.args.side === JoinExprKind.RIGHT) {\n selectedSources = {\n [k]: source,\n };\n break;\n }\n if (node instanceof UnnestExpr && unnestRequiresCrossJoin) {\n pushdownAllowed = false;\n break;\n }\n }\n }\n\n if (pushdownAllowed) {\n const whereThis = whereClause.args.this;\n if (whereThis instanceof Expression) {\n pushdown(whereThis, selectedSources, scopeRefCount, dialect, joinIndex);\n }\n }\n }\n\n // Joins should only pushdown into itself, not to other joins\n // So we limit the selected sources to only itself\n const joins = select.getArgKey('joins') as JoinExpr[] | undefined;\n if (joins) {\n for (const join of joins) {\n const name = join.aliasOrName;\n if (name && name in scope.selectedSources) {\n const onClause = join.args.on;\n pushdown(\n onClause,\n {\n [name]: scope.selectedSources[name],\n },\n scopeRefCount,\n dialect,\n );\n }\n }\n }\n }\n }\n\n return expression;\n}\n\nfunction pushdown (\n condition: Expression | undefined,\n sources: Record<string, [Expression, Scope | Expression]>,\n scopeRefCount: Map<Scope | Expression, number>,\n dialect: Dialect,\n joinIndex?: Map<string, number>,\n): void {\n if (!condition) {\n return;\n }\n\n const simplified = simplify(condition, {\n dialect,\n });\n condition = condition.replace(simplified);\n const cnfLike = normalized(condition) || !normalized(condition, {\n dnf: true,\n });\n\n const predicates = (cnfLike ? condition instanceof AndExpr : condition instanceof OrExpr)\n ? Array.from(condition.flatten())\n : [\n condition,\n ];\n\n if (cnfLike) {\n pushdownCnf(predicates, sources, scopeRefCount, joinIndex);\n } else {\n pushdownDnf(predicates, sources, scopeRefCount);\n }\n}\n\nfunction pushdownCnf (\n predicates: Iterable<Expression>,\n sources: Record<string, [Expression, Scope | Expression]>,\n scopeRefCount: Map<Scope | Expression, number>,\n joinIndex?: Map<string, number>,\n): void {\n /**\n * If the predicates are in CNF like form, we can simply replace each block in the parent.\n */\n const joinIndexMap = joinIndex || new Map();\n\n for (const predicate of predicates) {\n const nodes = nodesForPredicate(predicate, sources, scopeRefCount);\n\n for (const [\n name,\n node,\n ] of Object.entries(nodes)) {\n if (node instanceof JoinExpr) {\n const predicateTables = columnTableNames(predicate, {\n exclude: name,\n });\n\n // Don't push the predicate if it references tables that appear in later joins\n const thisIndex = joinIndexMap.get(name) ?? -1;\n const canPush = Array.from(predicateTables).every((table) => {\n const tableIndex = joinIndexMap.get(table) ?? -1;\n return tableIndex < thisIndex;\n });\n\n if (canPush) {\n predicate.replace(trueExpr());\n node.on(predicate, {\n copy: false,\n });\n break;\n }\n } else if (node instanceof SelectExpr) {\n predicate.replace(trueExpr());\n const innerPredicate = replaceAliases(node, predicate);\n\n if (findInScope(innerPredicate, AggFuncExpr)) {\n // Add to HAVING clause\n node.having(innerPredicate, {\n copy: false,\n });\n } else {\n node.where(innerPredicate, {\n copy: false,\n });\n }\n }\n }\n }\n}\n\nfunction pushdownDnf (\n predicates: Iterable<Expression>,\n sources: Record<string, [Expression, Scope | Expression]>,\n scopeRefCount: Map<Scope | Expression, number>,\n): void {\n /**\n * If the predicates are in DNF form, we can only push down conditions that are in all blocks.\n * Additionally, we can't remove predicates from their original form.\n */\n // Find all the tables that can be pushed down to\n // These are tables that are referenced in all blocks of a DNF\n const pushdownTables = new Set<string>();\n\n for (const a of predicates) {\n let aTables = columnTableNames(a);\n\n for (const b of predicates) {\n const bTables = columnTableNames(b);\n aTables = new Set(Array.from(aTables).filter((t) => bTables.has(t)));\n }\n\n for (const table of aTables) {\n pushdownTables.add(table);\n }\n }\n\n const conditions = new Map<string, Expression>();\n\n let nodes = {};\n\n // Pushdown all predicates to their respective nodes\n for (const table of Array.from(pushdownTables).sort()) {\n for (const predicate of predicates) {\n nodes = nodesForPredicate(predicate, sources, scopeRefCount);\n\n if (!(table in nodes)) {\n continue;\n }\n\n const existing = conditions.get(table);\n conditions.set(table, existing\n ? orExpr([\n existing,\n predicate,\n ])\n : predicate);\n }\n\n for (const [\n name,\n node,\n ] of Object.entries(nodes)) {\n const condition = conditions.get(name);\n if (!condition) {\n continue;\n }\n\n if (node instanceof JoinExpr) {\n node.on(condition, {\n copy: false,\n });\n } else if (node instanceof SelectExpr) {\n const innerPredicate = replaceAliases(node, condition);\n\n if (findInScope(innerPredicate, AggFuncExpr)) {\n // Add to HAVING clause\n node.having(innerPredicate, {\n copy: false,\n });\n } else {\n node.where(innerPredicate, {\n copy: false,\n });\n }\n }\n }\n }\n}\n\nfunction nodesForPredicate (\n predicate: Expression,\n sources: Record<string, [Expression, Scope | Expression]>,\n scopeRefCount: Map<Expression | Scope, number>,\n): Record<string, Expression> {\n const nodes: Record<string, Expression> = {};\n const tables = columnTableNames(predicate);\n const whereCondition = predicate.findAncestor<JoinExpr | WhereExpr>(JoinExpr, WhereExpr) instanceof WhereExpr;\n\n for (const table of Array.from(tables).sort()) {\n const sourceEntry = sources[table];\n if (!sourceEntry) {\n continue;\n }\n\n let node = sourceEntry[0] as Expression | undefined;\n const [\n , source,\n ] = sourceEntry;\n\n // If the predicate is in a where statement we can try to push it down\n // We want to find the root join or from statement\n if (node && whereCondition) {\n node = node.findAncestor<JoinExpr | FromExpr>(JoinExpr, FromExpr);\n }\n\n // A node can reference a CTE which should be pushed down\n if (node instanceof FromExpr && !(source instanceof TableExpr)) {\n const with_ = narrowInstanceOf((source instanceof Scope ? source.parent : (source as Expression).parent?.args)?.expression, Expression)?.getArgKey('with');\n if (with_ instanceof WithExpr && with_?.recursive) {\n return {};\n }\n node = source instanceof Scope ? source.expression : (source as Expression).args.expression as Expression | undefined;\n }\n\n if (node instanceof JoinExpr) {\n const side = node.side;\n if (side && side !== JoinExprKind.RIGHT) {\n return {};\n }\n nodes[table] = node;\n } else if (node instanceof SelectExpr && tables.size === 1) {\n // We can't push down window expressions\n const hasWindowExpression = node.selects.some((sel) => {\n if (!(sel instanceof Expression)) {\n return false;\n }\n return sel.find(WindowExpr) !== undefined;\n });\n\n const hasGroup = Boolean(node.args.group);\n\n // We can't push down predicates to select statements if they are referenced multiple times\n const refCount = scopeRefCount.get(source) || 0;\n\n if (!hasGroup && refCount < 2 && !hasWindowExpression) {\n nodes[table] = node;\n }\n }\n }\n\n return nodes;\n}\n\nfunction replaceAliases (source: SelectExpr, predicate: Expression): Expression {\n const aliases = new Map<string, Expression>();\n\n for (const select of source.selects) {\n if (!(select instanceof Expression)) {\n continue;\n }\n\n if (select instanceof AliasExpr) {\n const aliasThis = select.args.this;\n if (aliasThis instanceof Expression) {\n aliases.set(select.alias, aliasThis);\n }\n } else {\n aliases.set(select.name, select);\n }\n }\n\n function replaceAlias (column: Expression): Expression {\n if (column instanceof ColumnExpr) {\n const replacement = aliases.get(column.name);\n if (replacement) {\n return replacement.copy();\n }\n }\n return column;\n }\n\n return predicate.transform(replaceAlias);\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/resolver.py\n\nimport type {\n DataTypeExpr,\n} from '../expressions';\nimport {\n Expression,\n IdentifierExpr,\n JoinExprKind,\n SetOperationExprKind,\n ColumnExpr,\n DataTypeExprKind,\n JoinExpr,\n QueryExpr,\n SelectExpr,\n SetOperationExpr,\n SubqueryExpr,\n TableAliasExpr,\n TableExpr,\n toIdentifier,\n UnnestExpr,\n ValuesExpr,\n QueryTransformExpr,\n isType,\n} from '../expressions';\nimport {\n Dialect,\n} from '../dialects/dialect';\nimport {\n seqGet, SingleValuedMapping,\n} from '../helper';\nimport type {\n Schema,\n} from '../schema';\nimport {\n MapBinaryTuple,\n} from '../port_internals/binary_tuple_map';\nimport {\n isInstanceOf,\n} from '../port_internals';\nimport {\n OptimizeError,\n} from '../errors';\nimport {\n Scope,\n} from './scope';\n\n/**\n * Helper class for resolving columns to their source tables.\n *\n * This class provides methods to determine which table a column belongs to,\n * handling ambiguous column names, join contexts, and schema inference.\n *\n * Example:\n * ```ts\n * import { buildScope } from 'sqlglot/optimizer';\n * import { Resolver } from 'sqlglot/optimizer';\n *\n * const scope = buildScope(expression);\n * const resolver = new Resolver(scope, schema);\n * const table = resolver.getTable('column_name');\n * ```\n */\nexport class Resolver {\n scope: Scope;\n schema: Schema;\n dialect: Dialect;\n private inferSchema: boolean;\n private sourceColumns?: Map<string, string[]>;\n private unambiguousColumns?: Map<string, string>;\n private allColumnsCache?: Set<string>;\n private getSourceColumnsCache: MapBinaryTuple<[string, boolean], string[]>;\n\n constructor (scope: Scope, schema: Schema, options: {inferSchema?: boolean} = {}) {\n const {\n inferSchema = true,\n } = options;\n this.scope = scope;\n this.schema = schema;\n this.dialect = schema.dialect || new Dialect();\n this.inferSchema = inferSchema;\n this.getSourceColumnsCache = new MapBinaryTuple();\n }\n\n /**\n * Get the table for a column name.\n *\n * @param column - The column expression or column name to find the table for\n * @returns The table identifier if it can be found/inferred\n */\n getTable (column: string | ColumnExpr): Expression | undefined {\n const columnName = typeof column === 'string' ? column : column.name;\n\n let tableName = this.getTableNameFromSources(columnName);\n\n if (!tableName && typeof column !== 'string') {\n const joinContext = this.getColumnJoinContext(column);\n if (joinContext) {\n try {\n const availableSources = this.getAvailableSourceColumns(joinContext);\n tableName = this.getTableNameFromSources(columnName, availableSources);\n } catch (e) {\n if (!(e instanceof OptimizeError)) throw e;\n // Column is still ambiguous, try schema inference below\n }\n }\n }\n\n if (!tableName && this.inferSchema) {\n const allSourceColumns = this.getAllSourceColumns();\n const sourcesWithoutSchema: string[] = [\n ];\n for (const [\n source,\n columns,\n ] of allSourceColumns) {\n if (!columns || columns.length === 0 || columns.includes('*')) {\n sourcesWithoutSchema.push(source);\n }\n }\n if (sourcesWithoutSchema.length === 1) {\n tableName = sourcesWithoutSchema[0];\n }\n }\n\n if (!tableName) {\n return undefined;\n }\n\n const selectedSource = this.scope.selectedSources[tableName];\n if (!selectedSource) {\n return toIdentifier(tableName);\n }\n\n const [\n node,\n ] = selectedSource;\n\n let currentNode: Expression | undefined = node;\n if (currentNode instanceof QueryExpr) {\n while (currentNode && currentNode.alias !== tableName) {\n currentNode = currentNode.parent;\n }\n }\n\n if (currentNode) {\n const nodeAlias = currentNode.getArgKey('alias');\n if (nodeAlias instanceof Expression && (nodeAlias.args.this instanceof IdentifierExpr || typeof nodeAlias.args.this === 'string')) {\n return toIdentifier(nodeAlias.args.this);\n }\n }\n\n return toIdentifier(tableName);\n }\n\n /**\n * All available columns of all sources in this scope\n */\n get allColumns (): Set<string> {\n if (!this.allColumnsCache) {\n this.allColumnsCache = new Set();\n for (const columns of this.getAllSourceColumns().values()) {\n for (const column of columns) {\n this.allColumnsCache.add(column);\n }\n }\n }\n return this.allColumnsCache;\n }\n\n /**\n * Get source columns from a set operation (UNION, INTERSECT, EXCEPT).\n *\n * @param expression - The set operation expression\n * @returns List of column names\n */\n getSourceColumnsFromSetOp (expression: Expression): string[] {\n if (expression instanceof SelectExpr) {\n return (expression as SelectExpr).namedSelects;\n }\n\n if (expression instanceof SubqueryExpr) {\n const subqueryThis = expression.args.this;\n if (subqueryThis instanceof SetOperationExpr) {\n return this.getSourceColumnsFromSetOp(subqueryThis);\n }\n }\n\n if (!(expression instanceof SetOperationExpr)) {\n throw new Error(`Unknown set operation: ${expression}`);\n }\n\n const setOp = expression;\n const onColumnList = setOp.args.on;\n if (onColumnList) {\n return onColumnList.map((col) => col.name);\n }\n\n const side = setOp.args.side;\n const kind = setOp.args.kind;\n\n if (side || kind) {\n const leftExpr = setOp.args.this;\n const rightExpr = setOp.args.expression;\n\n if (!leftExpr || !rightExpr) {\n return [\n ];\n }\n\n const left = this.getSourceColumnsFromSetOp(leftExpr as Expression);\n const right = this.getSourceColumnsFromSetOp(rightExpr as Expression);\n\n if (side === JoinExprKind.LEFT) {\n return left;\n } else if (side === JoinExprKind.FULL) {\n const combined = [\n ...left,\n ...right,\n ];\n return Array.from(new Set(combined));\n } else if (kind === SetOperationExprKind.INNER) {\n const leftSet = new Set(left);\n const rightSet = new Set(right);\n return Array.from(leftSet).filter((col) => rightSet.has(col));\n }\n }\n\n return expression.namedSelects;\n }\n\n /**\n * Resolve the source columns for a given source name.\n *\n * @param name - The source name\n * @param onlyVisible - Whether to only return visible columns\n * @returns List of column names\n */\n getSourceColumns (name: string, options: {onlyVisible?: boolean} = {}): string[] {\n const {\n onlyVisible = false,\n } = options;\n if (this.getSourceColumnsCache.has(name, onlyVisible)) {\n return this.getSourceColumnsCache.get(name, onlyVisible) ?? [\n ];\n }\n\n const source = this.scope.sources.get(name);\n if (!source) {\n throw new OptimizeError(`Unknown table: ${name}`);\n }\n\n let columns: string[] = [\n ];\n\n if (source instanceof TableExpr) {\n columns = this.schema.columnNames?.(source, {\n onlyVisible,\n }) || [\n ];\n } else if (source instanceof Scope) {\n const sourceExpr = source.expression;\n if (sourceExpr instanceof ValuesExpr || sourceExpr instanceof UnnestExpr) {\n columns = sourceExpr.namedSelects;\n\n if (this.dialect._constructor.UNNEST_COLUMN_ONLY && sourceExpr instanceof UnnestExpr) {\n const unnest = sourceExpr;\n\n if (!unnest.type || isType(unnest.type, DataTypeExprKind.UNKNOWN)) {\n const unnestExpressions = unnest.args.expressions;\n const unnestExpr = seqGet(unnestExpressions ?? [\n ], 0);\n if (unnestExpr instanceof ColumnExpr && this.scope.parent) {\n const colType = this.getUnnestColumnType(unnestExpr);\n if (colType?.isType(DataTypeExprKind.ARRAY)) {\n const elementTypes = colType.args.expressions;\n if (elementTypes && 0 < elementTypes.length) {\n unnest.type = elementTypes[0].copy();\n } else {\n unnest.type = colType.copy();\n }\n }\n }\n }\n\n if (unnest.isType(DataTypeExprKind.STRUCT)) {\n for (const field of (unnest.type instanceof Expression ? unnest.type.args.expressions : undefined) || [\n ]) {\n if (isInstanceOf(field, Expression)) {\n columns.push(field.name);\n }\n }\n }\n }\n } else if (sourceExpr instanceof SetOperationExpr) {\n columns = this.getSourceColumnsFromSetOp(sourceExpr);\n } else {\n const select = seqGet(sourceExpr.args.expressions ?? [\n ], 0);\n if (select instanceof QueryTransformExpr) {\n const schema = select.args.schema;\n columns = schema\n ? schema.args.expressions?.map((c) => {\n if (c instanceof Expression) {\n return c.name;\n }\n return String(c);\n }) ?? [\n ]\n : [\n 'key',\n 'value',\n ];\n } else {\n columns = sourceExpr.namedSelects;\n }\n }\n }\n\n const [\n node,\n ] = this.scope.selectedSources[name] || [\n undefined,\n undefined,\n ];\n\n let columnAliases: string[];\n if (node instanceof Scope) {\n columnAliases = node.expression.aliasColumnNames;\n } else if (node instanceof Expression) {\n columnAliases = node.aliasColumnNames;\n } else {\n columnAliases = [\n ];\n }\n\n if (columnAliases.length) {\n const newColumns: string[] = [\n ];\n for (let i = 0; i < Math.max(columns.length, columnAliases.length); i++) {\n const alias = seqGet(columnAliases, i);\n const colName = seqGet(columns, i);\n newColumns.push(alias || colName || '');\n }\n columns = newColumns;\n }\n\n this.getSourceColumnsCache.set(name, onlyVisible, columns);\n return columns;\n }\n\n private getAllSourceColumns (): Map<string, string[]> {\n if (!this.sourceColumns) {\n this.sourceColumns = new Map();\n const allSources = {\n ...this.scope.selectedSources,\n ...Object.fromEntries(this.scope.lateralSources.entries()),\n };\n for (const sourceName of Object.keys(allSources)) {\n this.sourceColumns.set(sourceName, this.getSourceColumns(sourceName));\n }\n }\n return this.sourceColumns;\n }\n\n private getTableNameFromSources (columnName: string, sourceColumns?: Map<string, string[]>): string | undefined {\n let unambiguousColumns: Map<string, string>;\n\n if (!sourceColumns) {\n if (!this.unambiguousColumns) {\n this.unambiguousColumns = this.getUnambiguousColumns(this.getAllSourceColumns());\n }\n unambiguousColumns = this.unambiguousColumns;\n } else {\n unambiguousColumns = this.getUnambiguousColumns(sourceColumns);\n }\n\n return unambiguousColumns.get(columnName);\n }\n\n private getColumnJoinContext (column: ColumnExpr): JoinExpr | undefined {\n const joins = this.scope.expression.args.joins;\n\n if (!joins || this.scope.expression.getArgKey('laterals') || this.scope.expression.getArgKey('pivots')) {\n return undefined;\n }\n\n const joinAncestor = column.findAncestor<JoinExpr | SelectExpr>(JoinExpr, SelectExpr);\n\n if (joinAncestor instanceof JoinExpr && Object.keys(this.scope.selectedSources).includes(joinAncestor.aliasOrName)) {\n return joinAncestor;\n }\n\n return undefined;\n }\n\n private getAvailableSourceColumns (joinAncestor: JoinExpr): Map<string, string[]> {\n const {\n from, joins,\n } = this.scope.expression.args;\n\n if (!from || !joins) {\n return new Map();\n }\n\n const availableSources = new Map<string, string[]>();\n const fromName = from instanceof Expression ? from.aliasOrName : from;\n if (fromName) {\n availableSources.set(fromName, this.getSourceColumns(fromName));\n }\n\n for (const join of joins.slice(0, joins.indexOf(joinAncestor) + 1)) {\n const joinName = join.aliasOrName;\n if (joinName) {\n availableSources.set(joinName, this.getSourceColumns(joinName));\n }\n }\n\n return availableSources;\n }\n\n private getUnambiguousColumns (sourceColumns: Map<string, string[]>): Map<string, string> {\n if (sourceColumns.size === 0) {\n return new Map();\n }\n\n const sourceColumnsPairs = Array.from(sourceColumns.entries());\n const [\n firstTable,\n firstColumns,\n ] = sourceColumnsPairs[0];\n\n if (sourceColumnsPairs.length === 1) {\n return new SingleValuedMapping(firstColumns, firstTable);\n }\n\n const unnestOriginalAliases = new Map<string, string>();\n if (this.dialect._constructor.UNNEST_COLUMN_ONLY) {\n for (const [\n sourceName,\n source,\n ] of this.scope.sources) {\n if (source instanceof Scope && source.expression instanceof UnnestExpr) {\n const aliasArg = source.expression.args.alias;\n if (isInstanceOf(aliasArg, TableAliasExpr) && aliasArg.columns.length) {\n unnestOriginalAliases.set(aliasArg.columns[0].name, sourceName);\n }\n }\n }\n }\n\n const unambiguousColumns = new Map<string, string>();\n for (const col of firstColumns) {\n unambiguousColumns.set(col, firstTable);\n }\n\n const allColumns = new Set(firstColumns);\n\n for (const [\n table,\n columns,\n ] of sourceColumnsPairs.slice(1)) {\n const unique = new Set(columns);\n const ambiguous = new Set([\n ...allColumns,\n ].filter((c) => unique.has(c)));\n for (const col of columns) allColumns.add(col);\n\n for (const column of ambiguous) {\n const unnestAlias = unnestOriginalAliases.get(column);\n if (unnestAlias !== undefined) {\n unambiguousColumns.set(column, unnestAlias);\n continue;\n }\n unambiguousColumns.delete(column);\n }\n\n for (const column of unique) {\n if (!ambiguous.has(column)) {\n unambiguousColumns.set(column, table);\n }\n }\n }\n\n return unambiguousColumns;\n }\n\n private getUnnestColumnType (column: ColumnExpr): DataTypeExpr | undefined {\n const scope = this.scope.parent;\n if (!scope) {\n return undefined;\n }\n\n let tableName: string | undefined;\n if (column.table) {\n tableName = column.table;\n } else {\n const parentResolver = new Resolver(scope, this.schema, {\n inferSchema: this.inferSchema,\n });\n const tableIdentifier = parentResolver.getTable(column);\n if (!tableIdentifier) {\n return undefined;\n }\n tableName = tableIdentifier.name;\n }\n\n const source = scope.sources.get(tableName);\n return source ? this.getColumnTypeFromScope(source, column) : undefined;\n }\n\n private getColumnTypeFromScope (source: Scope | TableExpr, column: ColumnExpr): DataTypeExpr | undefined {\n if (source instanceof TableExpr) {\n const colType = this.schema.getColumnType?.(source, column);\n if (colType) {\n const colTypeThis = typeof colType.args.this === 'string' ? colType.args.this as DataTypeExprKind : DataTypeExprKind.UNKNOWN;\n if (colTypeThis !== DataTypeExprKind.UNKNOWN) {\n return colType;\n }\n }\n } else if (source instanceof Scope) {\n for (const [\n , nestedSource,\n ] of source.sources) {\n const colType = this.getColumnTypeFromScope(nestedSource, column);\n if (colType) {\n const colTypeThis = typeof colType.args.this === 'string' ? colType.args.this as DataTypeExprKind : DataTypeExprKind.UNKNOWN;\n if (colTypeThis !== DataTypeExprKind.UNKNOWN) {\n return colType;\n }\n }\n }\n }\n\n return undefined;\n }\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/pushdown_projections.py\n\nimport {\n Expression,\n\n AggFuncExpr,\n alias,\n column,\n ColumnExpr,\n LiteralExpr,\n MaxExpr,\n QueryTransformExpr,\n SelectExpr,\n SetOperationExpr,\n} from '../expressions';\nimport {\n type DialectType,\n} from '../dialects/dialect';\nimport {\n seqGet,\n} from '../helper';\nimport {\n ensureSchema, type Schema,\n} from '../schema';\nimport {\n Resolver,\n} from './resolver';\nimport {\n Scope, traverseScope,\n} from './scope';\n\n// Sentinel value that means an outer query selecting ALL columns\nconst SELECT_ALL = Symbol('SELECT_ALL');\n\n/**\n * Selection to use if selection list is empty\n */\nfunction defaultSelection (options: {isAgg: boolean}): Expression {\n const {\n isAgg,\n } = options;\n return alias(\n isAgg\n ? new MaxExpr({\n this: LiteralExpr.number(1),\n })\n : '1',\n '_',\n );\n}\n\n/**\n * Rewrite sqlglot AST to remove unused column projections.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { pushdownProjections } from 'sqlglot/optimizer';\n *\n * const sql = \"SELECT y.a AS a FROM (SELECT x.a AS a, x.b AS b FROM x) AS y\";\n * const expression = parseOne(sql);\n * pushdownProjections(expression).sql();\n * // 'SELECT y.a AS a FROM (SELECT x.a AS a FROM x) AS y'\n * ```\n *\n * @param expression - Expression to optimize\n * @param options - Optimization options\n * @param options.schema - Database schema\n * @param options.removeUnusedSelections - Remove unused SELECT columns (default: true)\n * @param options.dialect - SQL dialect\n * @returns The optimized expression\n */\nexport function pushdownProjections<E extends Expression> (\n expression: E,\n options: {\n schema?: Record<string, unknown> | Schema;\n removeUnusedSelections?: boolean;\n dialect?: DialectType;\n } = {},\n): E {\n const {\n schema: schemaArg,\n removeUnusedSelections = true,\n dialect,\n } = options;\n\n // Map of Scope to all columns being selected by outer queries\n const schema = ensureSchema(schemaArg, {\n dialect,\n });\n const sourceColumnAliasCount = new Map<Expression | Scope, number>();\n const referencedColumns = new Map<Scope, Set<string | symbol>>();\n\n // We build the scope tree (which is traversed in DFS postorder), then iterate\n // over the result in reverse order. This should ensure that the set of selected\n // columns for a particular scope are completely built by the time we get to it.\n const scopes = Array.from(traverseScope(expression));\n\n for (let i = scopes.length - 1; 0 <= i; i--) {\n const scope = scopes[i];\n let parentSelections = referencedColumns.get(scope) || new Set([\n SELECT_ALL,\n ]);\n const aliasCount = sourceColumnAliasCount.get(scope) || 0;\n\n // We can't remove columns from SELECT DISTINCT nor UNION DISTINCT\n const scopeExpr = scope.expression;\n if (scopeExpr.getArgKey('distinct')) {\n parentSelections = new Set([\n SELECT_ALL,\n ]);\n }\n\n if (scopeExpr instanceof SetOperationExpr) {\n const kind = scopeExpr.args.kind;\n const side = scopeExpr.args.side;\n\n if (!kind && !side) {\n // Do not optimize this set operation if it's using the BigQuery specific\n // kind / side syntax (e.g INNER UNION ALL BY NAME)\n const [\n left,\n right,\n ] = scope.unionScopes;\n\n if (left.expression.selects.length !== right.expression.selects.length) {\n throw new Error(\n `Invalid set operation due to column mismatch: ${scope.expression.sql({\n dialect,\n })}.`,\n );\n }\n\n referencedColumns.set(left, parentSelections);\n\n if (right.expression.selects.some((select) => select instanceof Expression && select.isStar)) {\n referencedColumns.set(right, parentSelections);\n } else if (!left.expression.selects.some((select) => select instanceof Expression && select.isStar)) {\n if (scopeExpr.args.byName) {\n referencedColumns.set(right, referencedColumns.get(left) || new Set());\n } else {\n const rightSelections = new Set<string | symbol>();\n referencedColumns.set(right, rightSelections);\n for (let j = 0; j < left.expression.selects.length; j++) {\n const leftSelect = left.expression.selects[j];\n if (!(leftSelect instanceof Expression)) {\n continue;\n }\n\n if (parentSelections.has(SELECT_ALL) || parentSelections.has(leftSelect.aliasOrName)) {\n const rightSelect = right.expression.selects[j];\n if (rightSelect instanceof Expression) {\n rightSelections.add(rightSelect.aliasOrName);\n }\n }\n }\n }\n }\n }\n }\n\n if (scopeExpr instanceof SelectExpr) {\n if (removeUnusedSelections) {\n removeUnusedSelections_(scope, parentSelections, schema, aliasCount);\n }\n\n if (scopeExpr.isStar) {\n continue;\n }\n\n // Group columns by source name\n const selects = new Map<string, Set<string>>();\n for (const col of scope.columns) {\n const tableName = col.table || '';\n const colName = col.name;\n\n let selectsForTable = selects.get(tableName);\n if (!selectsForTable) {\n selectsForTable = new Set();\n selects.set(tableName, selectsForTable);\n }\n selectsForTable.add(colName);\n }\n\n // Push the selected columns down to the next scope\n for (const [\n name,\n source,\n ] of Object.entries(scope.selectedSources)) {\n const [\n node,\n sourceScope,\n ] = source;\n\n if (sourceScope instanceof Scope) {\n const firstSelect = seqGet(sourceScope.expression.selects, 0);\n\n let columns: Set<string | symbol>;\n if (0 < scope.pivots.length || firstSelect instanceof QueryTransformExpr) {\n columns = new Set([\n SELECT_ALL,\n ]);\n } else {\n columns = selects.get(name) || new Set();\n }\n\n let referencedCols = referencedColumns.get(sourceScope);\n if (!referencedCols) {\n referencedCols = new Set();\n referencedColumns.set(sourceScope, referencedCols);\n }\n for (const col of columns) {\n referencedCols.add(col);\n }\n }\n\n const columnAliases = node.aliasColumnNames;\n if (columnAliases && 0 < columnAliases.length) {\n sourceColumnAliasCount.set(sourceScope, columnAliases.length);\n }\n }\n }\n }\n\n return expression;\n}\n\nfunction removeUnusedSelections_ (\n scope: Scope,\n parentSelections: Set<string | symbol>,\n schema: Schema,\n aliasCountParam: number,\n): void {\n const scopeArgs = scope.expression.args as Record<string, unknown>;\n const order = scopeArgs.order as Expression | undefined;\n\n const orderRefs = new Set<string>();\n if (order) {\n // Assume columns without a qualified table are references to output columns\n for (const col of order.findAll(ColumnExpr)) {\n if (!col.table) {\n orderRefs.add(col.name);\n }\n }\n }\n\n const newSelections: Expression[] = [\n ];\n let removed = false;\n let star = false;\n let isAgg = false;\n let aliasCount = aliasCountParam;\n\n const selectAll = parentSelections.has(SELECT_ALL);\n const select = scope.expression as SelectExpr;\n\n for (const selection of select.selects) {\n if (typeof selection === 'string' || typeof selection === 'number' || typeof selection === 'boolean') {\n continue;\n }\n\n const selectionExpr = selection as Expression;\n const name = selectionExpr.aliasOrName;\n\n if (selectAll || parentSelections.has(name) || orderRefs.has(name) || 0 < aliasCount) {\n newSelections.push(selectionExpr);\n aliasCount -= 1;\n } else {\n if (selectionExpr.isStar) {\n star = true;\n }\n removed = true;\n }\n\n if (!isAgg && selectionExpr.find(AggFuncExpr)) {\n isAgg = true;\n }\n }\n\n if (star) {\n const resolver = new Resolver(scope, schema, {});\n const names = new Set(newSelections.map((s) => s.aliasOrName));\n\n const sortedSelections = Array.from(parentSelections)\n .filter((name): name is string => typeof name === 'string')\n .sort();\n\n for (const name of sortedSelections) {\n if (!names.has(name)) {\n const table = resolver.getTable(name);\n newSelections.push(\n alias(column({\n col: name,\n table: table?.aliasOrName,\n }), name, {\n copy: false,\n }),\n );\n }\n }\n }\n\n // If there are no remaining selections, just select a single constant\n if (newSelections.length === 0) {\n newSelections.push(defaultSelection({\n isAgg,\n }));\n }\n\n select.select(newSelections, {\n append: false,\n copy: false,\n });\n\n if (removed) {\n scope.clearCache();\n }\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/isolate_table_selects.py\n\nimport type {\n Expression,\n} from '../expressions';\nimport {\n alias as aliasExpr,\n select as selectExpr,\n SubqueryExpr,\n TableExpr,\n} from '../expressions';\nimport {\n OptimizeError,\n} from '../errors';\nimport type {\n DialectType,\n} from '../dialects/dialect';\nimport {\n ensureSchema, type Schema,\n} from '../schema';\nimport {\n traverseScope,\n} from './scope';\n\n/**\n * Isolate table references in queries with multiple sources.\n *\n * This wraps table references in a subquery to avoid ambiguous column references\n * when the same table appears multiple times.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { isolateTableSelects } from 'sqlglot/optimizer';\n *\n * const sql = \"SELECT a FROM t AS t1 JOIN t AS t2 ON t1.id = t2.id\";\n * const expression = parseOne(sql);\n * isolateTableSelects(expression).sql();\n * // Wraps t references in subqueries for isolation\n * ```\n *\n * @param expression - Expression to optimize\n * @param options - Optimization options\n * @param options.schema - Database schema\n * @param options.dialect - SQL dialect\n * @returns The optimized expression\n */\nexport function isolateTableSelects<E extends Expression> (\n expression: E,\n options: {\n schema?: Record<string, unknown> | Schema;\n dialect?: DialectType;\n } = {},\n): E {\n const {\n schema: schemaArg, dialect,\n } = options;\n const schema = ensureSchema(schemaArg, {\n dialect,\n });\n\n for (const scope of traverseScope(expression)) {\n if (Object.keys(scope.selectedSources).length === 1) {\n continue;\n }\n\n for (const [\n , sourceEntry,\n ] of Object.entries(scope.selectedSources)) {\n // sourceEntry is [node, source] where source is TableExpr | Scope\n // We need the actual source (second element) to check if it's a Table\n const [\n node,\n actualSource,\n ] = sourceEntry;\n\n // Only process actual table references, not CTEs (which are Scope objects)\n if (!(actualSource instanceof TableExpr)) {\n continue;\n }\n\n const source = node as TableExpr;\n\n if (!source.parent) {\n continue;\n }\n\n // Skip if:\n // - No column names in schema for this table\n // - Parent is already a Subquery\n // - Parent's parent is a Table (already isolated)\n const columnNames = schema.columnNames?.(actualSource);\n if (!columnNames || columnNames.length === 0) {\n continue;\n }\n\n if (source.parent instanceof SubqueryExpr) {\n continue;\n }\n\n if (source.parent?.parent instanceof TableExpr) {\n continue;\n }\n\n // Table must have an alias for isolation to work\n const tableAlias = source.alias;\n if (!tableAlias) {\n throw new OptimizeError('Tables require an alias. Run qualify_tables optimization.');\n }\n\n // Wrap table in SELECT * FROM table subquery\n const aliasName = source.aliasOrName;\n const subquery = selectExpr('*')\n .from(aliasExpr(source, aliasName, {\n table: true,\n }), {\n copy: false,\n })\n .subquery(aliasName, {\n copy: false,\n });\n\n source.replace(subquery);\n }\n }\n\n return expression;\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/qualify_columns.py\n\nimport type {\n CteExpr,\n SetOperationExpr,\n} from '../expressions';\nimport {\n IdentifierExpr,\n AggFuncExpr,\n ColumnDefExpr,\n DataTypeExpr,\n Expression,\n AliasesExpr,\n AliasExpr,\n alias as aliasExpr,\n and as andExpr,\n column as columnExpr,\n ColumnExpr,\n CONSTANTS,\n CoalesceExpr,\n DistinctExpr,\n DotExpr,\n ExplodeExpr,\n GroupExpr,\n HavingExpr,\n InExpr,\n JoinExpr,\n LiteralExpr,\n paren as parenExpr,\n PivotExpr,\n PropertyEqExpr,\n PseudocolumnExpr,\n QueryTransformExpr,\n SelectExpr,\n StarExpr,\n StructExpr,\n SubqueryExpr,\n TableAliasExpr,\n TableColumnExpr,\n toIdentifier,\n UnnestExpr,\n WindowExpr,\n WithExpr,\n ParenExpr,\n DataTypeExprKind,\n alias,\n} from '../expressions';\nimport {\n assertIsInstanceOf, filterInstanceOf, isInstanceOf,\n} from '../port_internals';\nimport {\n Dialect, type DialectType,\n} from '../dialects/dialect';\nimport {\n ensureSchema, type Schema,\n} from '../schema';\nimport {\n highlightSql, OptimizeError,\n} from '../errors';\nimport {\n seqGet,\n} from '../helper';\nimport {\n TypeAnnotator,\n} from './annotate_types';\nimport {\n Resolver,\n} from './resolver';\nimport {\n buildScope, Scope, traverseScope, walkInScope,\n} from './scope';\nimport {\n simplifyParens,\n} from './simplify';\n\n/**\n * Rewrite sqlglot AST to have fully qualified columns.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { qualifyColumns } from 'sqlglot/optimizer';\n *\n * const schema = { tbl: { col: \"INT\" } };\n * const expression = parseOne(\"SELECT col FROM tbl\");\n * qualifyColumns(expression, schema).sql();\n * // 'SELECT tbl.col AS col FROM tbl'\n * ```\n *\n * @param expression - Expression to qualify\n * @param options - Qualification options\n * @param options.schema - Database schema\n * @param options.expandAliasRefs - Whether to expand references to aliases (default: true)\n * @param options.expandStars - Whether to expand star queries (default: true)\n * @param options.inferSchema - Whether to infer the schema if missing\n * @param options.allowPartialQualification - Whether to allow partial qualification (default: false)\n * @param options.dialect - SQL dialect\n * @returns The qualified expression\n *\n * Notes:\n * - Currently only handles a single PIVOT or UNPIVOT operator\n */\nexport function qualifyColumns<E extends Expression> (\n expression: E,\n options: {\n schema?: Record<string, unknown> | Schema;\n expandAliasRefs?: boolean;\n expandStars?: boolean;\n inferSchema?: boolean;\n allowPartialQualification?: boolean;\n dialect?: DialectType;\n } = {},\n): E {\n const {\n schema: schemaArg,\n expandAliasRefs = true,\n expandStars = true,\n inferSchema: inferSchemaArg,\n allowPartialQualification = false,\n dialect: dialectArg,\n } = options;\n\n const schema = ensureSchema(schemaArg, {\n dialect: dialectArg,\n });\n const annotator = new TypeAnnotator({\n schema,\n });\n const inferSchema = inferSchemaArg ?? Boolean(schema.empty);\n const dialect = schema.dialect || new Dialect();\n const dialectClass = dialect._constructor;\n const pseudocolumns = dialectClass.PSEUDOCOLUMNS;\n\n for (const scope of traverseScope(expression)) {\n if (dialectClass.PREFER_CTE_ALIAS_COLUMN) {\n pushdownCteAliasColumns(scope);\n }\n\n const scopeExpression = scope.expression;\n const isSelect = scopeExpression instanceof SelectExpr;\n\n separatePseudocolumns(scope, pseudocolumns);\n\n const resolver = new Resolver(scope, schema, {\n inferSchema,\n });\n popTableColumnAliases(scope.ctes);\n popTableColumnAliases(scope.derivedTables);\n const usingColumnTables = expandUsing(scope, resolver);\n\n if ((schema.empty || dialectClass.FORCE_EARLY_ALIAS_REF_EXPANSION) && expandAliasRefs) {\n expandAliasRefs_(\n scope,\n resolver,\n dialect,\n {\n expandOnlyGroupby: dialectClass.EXPAND_ONLY_GROUP_ALIAS_REF,\n },\n );\n }\n\n convertColumnsToDots(scope, resolver);\n qualifyColumnsInScope(\n scope,\n resolver,\n {\n allowPartialQualification,\n },\n );\n\n if (!schema.empty && expandAliasRefs) {\n expandAliasRefs_(scope, resolver, dialect, {\n expandOnlyGroupby: false,\n });\n }\n\n if (isSelect) {\n if (expandStars) {\n expandStars_(\n scope,\n resolver,\n usingColumnTables,\n pseudocolumns,\n annotator,\n );\n }\n qualifyOutputs(scope);\n }\n\n expandGroupBy(scope, dialect);\n expandOrderByAndDistinctOn(scope, resolver);\n\n if (dialectClass.ANNOTATE_ALL_SCOPES) {\n annotator.annotateScope(scope);\n }\n }\n\n return expression;\n}\n\n/**\n * Raise an error if any columns aren't qualified\n *\n * @param expression - Expression to validate\n * @param sql - Optional SQL string for error highlighting\n * @returns The validated expression\n * @throws OptimizeError if unqualified columns are found\n */\nexport function validateQualifyColumns<E extends Expression> (\n expression: E,\n sql?: string,\n): E {\n const allUnqualifiedColumns: ColumnExpr[] = [\n ];\n\n for (const scope of traverseScope(expression)) {\n if (!(scope.expression instanceof SelectExpr)) {\n continue;\n }\n\n let unqualifiedColumns = scope.unqualifiedColumns;\n\n if (0 < scope.externalColumns.length && !scope.isCorrelatedSubquery && scope.pivots.length === 0) {\n const column = scope.externalColumns[0];\n const forTable = column.table ? ` for table: '${column.table}'` : '';\n const line = (column.args.this as Expression)?.meta?.['line'] as number | undefined;\n const col = (column.args.this as Expression)?.meta?.['col'] as number | undefined;\n\n const start = (column.args.this as Expression)?.meta?.['start'] as number | undefined;\n const end = (column.args.this as Expression)?.meta?.['end'] as number | undefined;\n\n let errorMsg = `Column '${column.name}' could not be resolved${forTable}.`;\n if (line && col) {\n errorMsg += ` Line: ${line}, Col: ${col}`;\n }\n if (sql && start !== undefined && end !== undefined) {\n const {\n formattedSql,\n } = highlightSql({\n sql,\n positions: [\n [\n start,\n end,\n ],\n ],\n });\n errorMsg += `\\n ${formattedSql}`;\n }\n\n throw new OptimizeError(errorMsg);\n }\n\n if (0 < unqualifiedColumns.length && 0 < scope.pivots.length && scope.pivots[0].unpivot) {\n const unpivotColumnSet = new Set(unpivotColumns(scope.pivots[0]));\n unqualifiedColumns = unqualifiedColumns.filter((c) => !unpivotColumnSet.has(c));\n }\n\n allUnqualifiedColumns.push(...unqualifiedColumns);\n }\n\n if (0 < allUnqualifiedColumns.length) {\n const firstColumn = allUnqualifiedColumns[0];\n const firstColumnThis = firstColumn.args.this;\n const line = isInstanceOf(firstColumnThis, Expression) ? firstColumnThis.meta['line'] : undefined;\n const col = isInstanceOf(firstColumnThis, Expression) ? firstColumnThis.meta['col'] : undefined;\n\n const start = isInstanceOf(firstColumnThis, Expression) ? firstColumnThis.meta['start'] as number | undefined : undefined;\n const end = isInstanceOf(firstColumnThis, Expression) ? firstColumnThis.meta['end'] as number | undefined : undefined;\n\n let errorMsg = `Ambiguous column '${firstColumn.name}'`;\n if (line && col) {\n errorMsg += ` (Line: ${line}, Col: ${col})`;\n }\n if (sql && start !== undefined && end !== undefined) {\n const {\n formattedSql,\n } = highlightSql({\n sql,\n positions: [\n [\n start,\n end,\n ],\n ],\n });\n errorMsg += `\\n ${formattedSql}`;\n }\n\n throw new OptimizeError(errorMsg);\n }\n\n return expression;\n}\n\nfunction separatePseudocolumns (scope: Scope, pseudocolumns: Set<string>): void {\n if (pseudocolumns.size === 0) {\n return;\n }\n\n let hasPseudocolumns = false;\n const scopeExpression = scope.expression;\n\n for (const column of scope.columns) {\n const name = column.name.toUpperCase();\n if (!pseudocolumns.has(name)) {\n continue;\n }\n\n if (name !== 'LEVEL' || (\n scopeExpression instanceof SelectExpr\n && (scopeExpression.args as Record<string, unknown>).connect\n )) {\n column.replace(new PseudocolumnExpr({\n ...column.args,\n }));\n hasPseudocolumns = true;\n }\n }\n\n if (hasPseudocolumns) {\n scope.clearCache();\n }\n}\n\nfunction unpivotColumns (unpivot: PivotExpr): ColumnExpr[] {\n const fields = unpivot.args.fields || [\n ];\n const nameColumns = fields\n .filter((field): field is InExpr => field instanceof InExpr && field.args.this instanceof ColumnExpr)\n .map((field) => field.args.this as ColumnExpr);\n\n const valueColumns: ColumnExpr[] = [\n ];\n for (const e of unpivot.args.expressions as Expression[]) {\n for (const col of e.findAll(ColumnExpr)) {\n valueColumns.push(col);\n }\n }\n\n return [\n ...nameColumns,\n ...valueColumns,\n ];\n}\n\nfunction popTableColumnAliases (derivedTables: Iterable<Expression>): void {\n for (const table of derivedTables) {\n if (table.parent instanceof WithExpr && table.parent.args.recursive) {\n continue;\n }\n const tableAlias = table.getArgKey('alias');\n if (tableAlias instanceof TableAliasExpr) {\n tableAlias.setArgKey('columns', undefined);\n }\n }\n}\n\nfunction expandUsing (scope: Scope, resolver: Resolver): Map<string, string[]> {\n const joins = (scope.expression as SelectExpr).args.joins || [\n ];\n if (joins.length === 0) {\n return new Map();\n }\n\n const names = new Set(joins.map((j) => j.aliasOrName));\n const ordered: string[] = Object.keys(scope.selectedSources).filter((k) => !names.has(k));\n\n if (0 < names.size && ordered.length === 0) {\n throw new OptimizeError(`Joins ${[\n ...names,\n ].join(',')} missing source table ${scope.expression}`);\n }\n\n // column name -> first source name that has it\n const columns: Record<string, string> = {};\n\n const updateSourceColumns = (sourceName: string): void => {\n for (const colName of resolver.getSourceColumns(sourceName)) {\n if (!(colName in columns)) {\n columns[colName] = sourceName;\n }\n }\n };\n\n for (const sourceName of ordered) {\n updateSourceColumns(sourceName);\n }\n\n // column name -> ordered map of table names\n const columnTables = new Map<string, string[]>();\n\n for (let i = 0; i < joins.length; i++) {\n const join = joins[i];\n assertIsInstanceOf(join, JoinExpr);\n const sourceTable = ordered[ordered.length - 1];\n if (sourceTable) {\n updateSourceColumns(sourceTable);\n }\n\n const joinTable = join.aliasOrName;\n ordered.push(joinTable);\n\n const using = join.args.using;\n if (!using) continue;\n\n const joinColumns = resolver.getSourceColumns(joinTable);\n\n const conditions: Expression[] = [\n ];\n const usingIdentifierCount = using.length;\n const isSemiOrAntiJoin = join.isSemiOrAntiJoin;\n\n for (const identifierNode of using) {\n const identifier = (identifierNode as Expression).name;\n let table = columns[identifier];\n\n if (!table || !joinColumns.includes(identifier)) {\n if (0 < Object.keys(columns).length && !('*' in columns) && 0 < joinColumns.length) {\n throw new OptimizeError(`Cannot automatically join: ${identifier}`);\n }\n }\n\n table = table || sourceTable;\n\n let lhs: Expression;\n if (i === 0 || usingIdentifierCount === 1) {\n lhs = columnExpr({\n col: identifier,\n table,\n });\n } else {\n const coalesceColumns = ordered.slice(0, -1)\n .filter((t) => resolver.getSourceColumns(t).includes(identifier))\n .map((t) => columnExpr({\n col: identifier,\n table: t,\n }));\n if (1 < coalesceColumns.length) {\n lhs = new CoalesceExpr({\n this: coalesceColumns[0],\n expressions: coalesceColumns.slice(1),\n });\n } else {\n lhs = columnExpr({\n col: identifier,\n table,\n });\n }\n }\n\n conditions.push(lhs.eq(columnExpr({\n col: identifier,\n table: joinTable,\n })));\n\n if (!isSemiOrAntiJoin) {\n let tables_ = columnTables.get(identifier);\n if (!tables_) {\n tables_ = [\n ];\n columnTables.set(identifier, tables_);\n }\n if (!tables_.includes(table)) tables_.push(table);\n if (!tables_.includes(joinTable)) tables_.push(joinTable);\n }\n }\n\n join.setArgKey('using', undefined);\n join.setArgKey('on', andExpr(conditions, {\n copy: false,\n }));\n }\n\n if (0 < columnTables.size) {\n for (const column of scope.columns) {\n const tables_ = !column.table ? columnTables.get(column.name) : undefined;\n if (tables_ !== undefined) {\n const coalesceArgs = tables_.map((t) => columnExpr({\n col: column.name,\n table: t,\n }));\n let replacement: Expression = new CoalesceExpr({\n this: coalesceArgs[0],\n expressions: coalesceArgs.slice(1),\n });\n\n if (column.parent instanceof SelectExpr) {\n replacement = aliasExpr(replacement, column.name, {\n copy: false,\n }) as Expression;\n } else if (column.parent instanceof StructExpr) {\n replacement = new PropertyEqExpr({\n this: toIdentifier(column.name),\n expression: replacement,\n });\n }\n\n scope.replace(column, replacement);\n }\n }\n }\n\n return columnTables;\n}\n\nfunction expandAliasRefs_ (\n scope: Scope,\n resolver: Resolver,\n dialect: Dialect,\n options: {expandOnlyGroupby: boolean},\n): void {\n const {\n expandOnlyGroupby,\n } = options;\n const expression = scope.expression;\n const dialectClass = dialect._constructor;\n\n if (!(expression instanceof SelectExpr) || dialectClass.DISABLES_ALIAS_REF_EXPANSION) {\n return;\n }\n\n const aliasToExpression = new Map<string, [Expression, number]>();\n const projections = new Set(expression.selects.map((s) => (s as Expression).aliasOrName));\n let replaced = false;\n\n const replaceColumns = (\n node: Expression | undefined,\n options: {resolveTable?: boolean;\n literalIndex?: boolean;} = {},\n ): void => {\n const {\n resolveTable = false, literalIndex = false,\n } = options;\n const isGroupBy = node instanceof GroupExpr;\n const isHaving = node instanceof HavingExpr;\n if (!node || (expandOnlyGroupby && !isGroupBy)) {\n return;\n }\n\n for (const column of walkInScope(node, {\n prune: (n) => n.isStar,\n })) {\n if (!(column instanceof ColumnExpr)) continue;\n\n if (expandOnlyGroupby && isGroupBy && column.parent !== node) {\n continue;\n }\n\n let skipReplace = false;\n const table = (resolveTable && !column.table) ? resolver.getTable(column.name) : undefined;\n const aliasEntry = aliasToExpression.get(column.name);\n const aliasExpr_ = aliasEntry ? aliasEntry[0] : undefined;\n const aliasIdx = aliasEntry ? aliasEntry[1] : 1;\n\n if (aliasExpr_) {\n skipReplace = Boolean(\n aliasExpr_.find(AggFuncExpr)\n && column.findAncestor(AggFuncExpr)\n && !(column.findAncestor<WindowExpr | SelectExpr>(WindowExpr, SelectExpr) instanceof WindowExpr),\n );\n\n if (isHaving && dialectClass.PROJECTION_ALIASES_SHADOW_SOURCE_NAMES) {\n skipReplace = skipReplace || Array.from(aliasExpr_.findAll(ColumnExpr)).some(\n (n) => projections.has(n.parts[0]?.name || ''),\n );\n }\n } else if (dialectClass.PROJECTION_ALIASES_SHADOW_SOURCE_NAMES && (isGroupBy || isHaving)) {\n const columnTable = table ? table.name : column.table;\n if (columnTable && projections.has(columnTable)) {\n column.replace(toIdentifier(column.name));\n replaced = true;\n continue;\n }\n }\n\n if (table && (!aliasExpr_ || skipReplace)) {\n column.setArgKey('table', table);\n } else if (!column.table && aliasExpr_ && !skipReplace) {\n if ((aliasExpr_ instanceof LiteralExpr || aliasExpr_.isNumber) && (literalIndex || resolveTable)) {\n if (literalIndex) {\n column.replace(LiteralExpr.number(aliasIdx));\n replaced = true;\n }\n } else {\n replaced = true;\n const parenNode = column.replace(parenExpr(aliasExpr_)) as Expression;\n const simplified = simplifyParens(parenNode, dialect);\n if (simplified !== parenNode) {\n parenNode.replace(simplified);\n }\n }\n }\n }\n };\n\n for (let i = 0; i < expression.selects.length; i++) {\n const projection = expression.selects[i] as Expression;\n replaceColumns(projection);\n if (projection instanceof AliasExpr) {\n aliasToExpression.set(projection.alias, [\n projection.args.this as Expression,\n i + 1,\n ]);\n }\n }\n\n // Handle recursive CTE alias columns\n let parentScope: Scope | undefined = scope;\n let onRightSubTree = false;\n while (parentScope && !parentScope.isCte) {\n if (parentScope.isUnion && parentScope.parent) {\n onRightSubTree = (parentScope.parent.expression as SetOperationExpr).args.expression === parentScope.expression;\n }\n parentScope = parentScope.parent;\n }\n\n if (parentScope && onRightSubTree) {\n const cteExpr = parentScope.expression.parent;\n if (cteExpr) {\n const withNode = cteExpr.findAncestor(WithExpr);\n if (withNode?.args.recursive) {\n const aliasArg = (cteExpr as CteExpr).args.alias;\n const aliasColumns = aliasArg instanceof TableAliasExpr\n ? aliasArg.columns\n : [\n ];\n const columnsSource: Expression[] = 0 < aliasColumns.length\n ? aliasColumns as Expression[]\n : ((cteExpr as CteExpr).args.this as SelectExpr)?.selects || [\n ];\n for (const col of columnsSource) {\n if (col instanceof Expression) {\n aliasToExpression.delete(col.outputName);\n }\n }\n }\n }\n }\n\n replaceColumns(expression.args.where as Expression | undefined);\n replaceColumns(expression.args.group as Expression | undefined, {\n literalIndex: true,\n });\n replaceColumns(expression.args.having as Expression | undefined, {\n resolveTable: true,\n });\n replaceColumns(expression.args.qualify as Expression | undefined, {\n resolveTable: true,\n });\n\n if (dialectClass.SUPPORTS_ALIAS_REFS_IN_JOIN_CONDITIONS) {\n for (const join of expression.args.joins || [\n ]) {\n replaceColumns(join);\n }\n }\n\n if (replaced) {\n scope.clearCache();\n }\n}\n\nfunction convertColumnsToDots (scope: Scope, resolver: Resolver): void {\n let converted = false;\n const allCols: (ColumnExpr | DotExpr)[] = [\n ...scope.columns,\n ...scope.stars,\n ];\n\n for (const column of allCols) {\n if (column instanceof DotExpr) continue;\n\n const columnTable = column.table;\n const dotParts = (column.meta['dotParts'] as unknown[] | undefined) || [\n ];\n delete column.meta['dotParts'];\n\n if (\n columnTable\n && !scope.sources.has(columnTable)\n && (\n !scope.parent\n || !scope.parent.sources.has(columnTable)\n || !scope.isCorrelatedSubquery\n )\n ) {\n const parts = column.parts;\n if (parts.length < 2) continue;\n\n const firstPart = parts[0];\n const remainingParts = parts.slice(1);\n if (!firstPart) continue;\n\n let newRoot: IdentifierExpr;\n let fieldParts: Expression[];\n let newTable: Expression | undefined;\n let wasQualified: boolean;\n\n if (scope.sources.has(firstPart.name)) {\n // Column is already table-qualified: firstPart is the table, remainingParts[0] is column\n if (remainingParts.length === 0) continue;\n newTable = firstPart;\n newRoot = remainingParts[0] as IdentifierExpr;\n fieldParts = remainingParts.slice(1);\n wasQualified = true;\n } else {\n // firstPart is the column name, resolver finds the table\n newTable = resolver.getTable(firstPart.name);\n newRoot = firstPart as IdentifierExpr;\n fieldParts = remainingParts;\n wasQualified = false;\n }\n\n if (newTable) {\n converted = true;\n const newColumn = columnExpr({\n col: newRoot,\n table: newTable as IdentifierExpr,\n });\n if (0 < dotParts.length) {\n newColumn.meta['dotParts'] = dotParts.slice(wasQualified ? 2 : 1);\n }\n if (0 < fieldParts.length) {\n column.replace(DotExpr.build([\n newColumn,\n ...fieldParts,\n ]));\n } else {\n column.replace(newColumn);\n }\n }\n }\n }\n\n if (converted) {\n scope.clearCache();\n }\n}\n\nfunction qualifyColumnsInScope (\n scope: Scope,\n resolver: Resolver,\n options: {allowPartialQualification: boolean},\n): void {\n const {\n allowPartialQualification,\n } = options;\n const dialectClass = resolver.dialect._constructor;\n\n for (const column of scope.columns) {\n const columnTable = column.table;\n const columnName = column.name;\n\n if (columnTable && scope.sources.has(columnTable)) {\n const sourceColumns = resolver.getSourceColumns(columnTable);\n if (\n !allowPartialQualification\n && 0 < sourceColumns.length\n && !sourceColumns.includes(columnName)\n && !sourceColumns.includes('*')\n ) {\n throw new OptimizeError(`Unknown column: ${columnName}`);\n }\n }\n\n if (!columnTable) {\n if (0 < scope.pivots.length && !column.findAncestor(PivotExpr)) {\n column.setArgKey('table', toIdentifier((scope.pivots[0] as PivotExpr).alias));\n continue;\n }\n\n const table = resolver.getTable(column);\n\n if (table) {\n const source = scope.sources.get(table.name);\n if (source instanceof Scope\n && source.columnIndex.has(column)\n ) {\n continue;\n }\n }\n\n if (table) {\n column.setArgKey('table', table);\n } else if (\n dialectClass.TABLES_REFERENCEABLE_AS_COLUMNS\n && column.parts.length === 1\n && columnName in scope.selectedSources\n ) {\n const colThis = column.args.this;\n scope.replace(column, new TableColumnExpr({\n this: isInstanceOf(colThis, Expression) ? colThis : undefined,\n }));\n }\n }\n }\n\n for (const pivot of scope.pivots) {\n if (pivot instanceof PivotExpr) {\n for (const column of pivot.findAll(ColumnExpr)) {\n if (!column.table && resolver.allColumns.has(column.name)) {\n const table = resolver.getTable(column.name);\n if (table) {\n column.setArgKey('table', table);\n }\n }\n }\n }\n }\n}\n\nfunction addExceptColumns (\n expression: Expression,\n tables: Iterable<string>,\n exceptColumns: Map<string, Set<string>>,\n): void {\n const except_ = expression.getArgKey('except') ?? expression.getArgKey('except');\n if (!except_) return;\n const exceptList = Array.isArray(except_)\n ? except_\n : [\n except_,\n ];\n const columns = new Set(\n (exceptList as Expression[])\n .filter((e): e is Expression => e instanceof Expression)\n .map((e) => e.name),\n );\n for (const table of tables) {\n exceptColumns.set(table, columns);\n }\n}\n\nfunction addRenameColumns (\n expression: Expression,\n tables: Iterable<string>,\n renameColumns: Map<string, Record<string, string>>,\n): void {\n const rename = expression.getArgKey('rename') as Expression[] | undefined;\n if (!rename || rename.length === 0) return;\n const columns: Record<string, string> = {};\n for (const e of rename) {\n if (e instanceof Expression) {\n const thisExpr = e.args.this as Expression | undefined;\n if (thisExpr instanceof Expression) {\n columns[thisExpr.name] = (e as Expression).alias;\n }\n }\n }\n for (const table of tables) {\n renameColumns.set(table, columns);\n }\n}\n\nfunction addReplaceColumns (\n expression: Expression,\n tables: Iterable<string>,\n replaceColumns: Map<string, Record<string, AliasExpr>>,\n): void {\n const replace = expression.getArgKey('replace') as Expression[] | undefined;\n if (!replace || replace.length === 0) return;\n const columns: Record<string, AliasExpr> = {};\n for (const e of replace) {\n if (e instanceof AliasExpr) {\n columns[e.alias] = e;\n }\n }\n for (const table of tables) {\n replaceColumns.set(table, columns);\n }\n}\n\nfunction expandStructStarsNoParens (expression: DotExpr): AliasExpr[] {\n const dotColumn = expression.find(ColumnExpr);\n if (!(dotColumn instanceof ColumnExpr) || !dotColumn.isType(DataTypeExprKind.STRUCT)) {\n return [\n ];\n }\n\n // All nested struct values are ColumnDefs, so normalize the first Column in one\n const dotColumnCopy = dotColumn.copy();\n const dotColumnType = dotColumnCopy.type;\n let startingStruct: IdentifierExpr | DotExpr | DataTypeExpr | ColumnDefExpr | undefined = isInstanceOf(dotColumnType, DataTypeExpr) ? dotColumnType : undefined;\n\n // First part is the table name and last part is the star so they can be dropped\n const dotParts = expression.parts.slice(1, -1);\n\n // If we're expanding a nested struct eg. t.c.f1.f2.* find the last struct (f2 in this case)\n outer: for (const part of dotParts.slice(1)) {\n const fieldExprs = startingStruct?.args.expressions || [\n ];\n for (const field of fieldExprs) {\n // Unable to expand star unless all fields are named\n if (!(field.args.this instanceof IdentifierExpr)) {\n return [\n ];\n }\n\n if (!isInstanceOf(field, ColumnDefExpr)) {\n return [\n ];\n }\n\n const fieldKindRaw: unknown = field.args.kind;\n const fieldKind = isInstanceOf(fieldKindRaw, DataTypeExpr) ? fieldKindRaw : undefined;\n\n if (field.name === part.name && fieldKind?.isType(DataTypeExprKind.STRUCT)) {\n startingStruct = fieldKind;\n break outer;\n }\n }\n // There is no matching field in the struct\n return [\n ];\n }\n\n const takenNames = new Set<string>();\n const newSelections: AliasExpr[] = [\n ];\n\n for (const field of (startingStruct?.args.expressions || [\n ])) {\n const name = field.name;\n const fieldThis = field.args.this;\n\n // Ambiguous or anonymous fields can't be expanded\n if (takenNames.has(name) || !(fieldThis instanceof IdentifierExpr)) {\n return [\n ];\n }\n\n takenNames.add(name);\n\n const thisIdent = fieldThis.copy() as IdentifierExpr;\n const allParts = [\n ...dotParts.map((p) => p.copy()),\n thisIdent,\n ];\n const [\n root,\n ...parts\n ] = allParts;\n\n const newColumn = columnExpr(\n {\n col: root as IdentifierExpr,\n table: dotColumnCopy.args.table as IdentifierExpr | undefined,\n },\n {\n fields: parts as IdentifierExpr[],\n },\n );\n\n newSelections.push(aliasExpr(newColumn, thisIdent, {\n copy: false,\n }) as AliasExpr);\n }\n\n return newSelections;\n}\n\nfunction expandStructStarsWithParens (expression: DotExpr): AliasExpr[] {\n if (!(expression.args.this instanceof ParenExpr)) {\n return [\n ];\n }\n\n const dotColumn = expression.find(ColumnExpr);\n if (!(dotColumn instanceof ColumnExpr) || !dotColumn.isType(DataTypeExprKind.STRUCT)) {\n return [\n ];\n }\n\n let parent = dotColumn.parent;\n const dotColumnType2 = dotColumn.type;\n let startingStruct: string | ColumnDefExpr | DotExpr | IdentifierExpr | DataTypeExpr | undefined = isInstanceOf(dotColumnType2, DataTypeExpr) ? dotColumnType2 : undefined;\n\n while (parent !== undefined) {\n if (parent instanceof ParenExpr) {\n parent = parent.parent;\n continue;\n }\n\n if (!(parent instanceof DotExpr)) {\n return [\n ];\n }\n\n const rhs = parent.right;\n if (rhs instanceof StarExpr) {\n break;\n }\n\n if (!(rhs instanceof IdentifierExpr)) {\n return [\n ];\n }\n\n let matched = false;\n const expressions: (DataTypeExpr | ColumnDefExpr)[] = filterInstanceOf((startingStruct as DataTypeExpr).args.expressions || [\n ], ColumnDefExpr);\n for (const structFieldDef of expressions) {\n if (structFieldDef.name === rhs.name) {\n matched = true;\n startingStruct = structFieldDef.args.kind as DataTypeExpr | undefined;\n break;\n }\n }\n\n if (!matched) return [\n ];\n\n parent = parent.parent;\n }\n\n const newSelections = [\n ];\n\n const outerParen = expression.args.this;\n\n const expressions: (DataTypeExpr | ColumnDefExpr)[] = filterInstanceOf((startingStruct as DataTypeExpr).args.expressions || [\n ], ColumnDefExpr);\n for (const structFieldDef of expressions) {\n const newIdentifier = structFieldDef.args.this instanceof IdentifierExpr\n ? structFieldDef.args.this.copy()\n : new IdentifierExpr({\n this: structFieldDef.args.this?.toString(),\n });\n const newDot = DotExpr.build([\n outerParen.copy(),\n newIdentifier,\n ]);\n const newAlias = alias(newDot, newIdentifier, {\n copy: false,\n }) as AliasExpr;\n newSelections.push(newAlias);\n }\n\n return newSelections;\n}\n\nfunction expandStars_ (\n scope: Scope,\n resolver: Resolver,\n usingColumnTables: Map<string, string[]>,\n pseudocolumns: Set<string>,\n annotator: TypeAnnotator,\n): void {\n const newSelections: Expression[] = [\n ];\n const exceptColumns = new Map<string, Set<string>>();\n const replaceColumnsMap = new Map<string, Record<string, AliasExpr>>();\n const renameColumnsMap = new Map<string, Record<string, string>>();\n const coalesedColumns = new Set<string>();\n const dialectClass = resolver.dialect._constructor;\n\n let pivotOutputColumns: string[] | undefined = undefined;\n const pivotExcludeColumns = new Set<string>();\n\n const pivot = seqGet(scope.pivots, 0);\n if (pivot instanceof PivotExpr && !pivot.aliasColumnNames.length) {\n if (pivot.unpivot) {\n pivotOutputColumns = unpivotColumns(pivot).map((c) => c.outputName);\n\n for (const field of pivot.args.fields || [\n ]) {\n if (field instanceof InExpr) {\n for (const e of field.args.expressions as Expression[]) {\n for (const c of (e as Expression).findAll(ColumnExpr)) {\n pivotExcludeColumns.add(c.outputName);\n }\n }\n }\n }\n } else {\n for (const c of pivot.findAll(ColumnExpr)) {\n pivotExcludeColumns.add(c.outputName);\n }\n\n const pivotColumns = pivot.getArgKey('columns') as Expression[] | undefined;\n pivotOutputColumns = (pivotColumns || [\n ]).map((c) => (c as Expression).outputName);\n if (!pivotOutputColumns.length) {\n pivotOutputColumns = (pivot.args.expressions as Expression[]).map((c) => c.aliasOrName);\n }\n }\n }\n\n if (dialectClass.SUPPORTS_STRUCT_STAR_EXPANSION && scope.stars.some((col) => col instanceof DotExpr)) {\n annotator.annotateScope(scope);\n }\n\n for (const expression of scope.expression.selects) {\n const tables: string[] = [\n ];\n\n if (expression instanceof StarExpr) {\n tables.push(...Object.keys(scope.selectedSources));\n addExceptColumns(expression, tables, exceptColumns);\n addReplaceColumns(expression, tables, replaceColumnsMap);\n addRenameColumns(expression, tables, renameColumnsMap);\n } else if ((expression as Expression).isStar) {\n if (!(expression instanceof DotExpr)) {\n const tableName = expression instanceof ColumnExpr ? expression.table : '';\n if (tableName) tables.push(tableName);\n const exprThis = (expression as Expression).args.this;\n if (exprThis instanceof Expression) {\n addExceptColumns(exprThis, tables, exceptColumns);\n addReplaceColumns(exprThis, tables, replaceColumnsMap);\n addRenameColumns(exprThis, tables, renameColumnsMap);\n }\n } else if (dialectClass.SUPPORTS_STRUCT_STAR_EXPANSION && !dialectClass.REQUIRES_PARENTHESIZED_STRUCT_ACCESS) {\n const structFields = expandStructStarsNoParens(expression as DotExpr);\n if (0 < structFields.length) {\n newSelections.push(...structFields);\n continue;\n }\n } else if (dialectClass.REQUIRES_PARENTHESIZED_STRUCT_ACCESS) {\n const structFields = expandStructStarsWithParens(expression as DotExpr);\n if (0 < structFields.length) {\n newSelections.push(...structFields);\n continue;\n }\n }\n }\n\n if (tables.length === 0) {\n newSelections.push(expression as Expression);\n continue;\n }\n\n for (const table of tables) {\n if (!scope.sources.has(table)) {\n throw new OptimizeError(`Unknown table: ${table}`);\n }\n\n let columns = resolver.getSourceColumns(table, {\n onlyVisible: true,\n });\n if (!columns.length) columns = scope.outerColumns;\n\n if (0 < pseudocolumns.size && dialectClass.EXCLUDES_PSEUDOCOLUMNS_FROM_STAR) {\n columns = columns.filter((name) => !pseudocolumns.has(name.toUpperCase()));\n }\n\n if (!columns.length || columns.includes('*')) {\n return;\n }\n\n const columnsToExclude = exceptColumns.get(table) || new Set<string>();\n const renamedColumns = renameColumnsMap.get(table) || {};\n const replacedColumns = replaceColumnsMap.get(table) || {};\n\n if (pivot instanceof PivotExpr) {\n let pivotColumns: string[] | undefined;\n if (pivotOutputColumns && 0 < pivotExcludeColumns.size) {\n pivotColumns = columns.filter((c) => !pivotExcludeColumns.has(c));\n pivotColumns.push(...pivotOutputColumns);\n } else {\n pivotColumns = pivot.aliasColumnNames;\n }\n\n if (0 < pivotColumns.length) {\n for (const name of pivotColumns) {\n if (!columnsToExclude.has(name)) {\n newSelections.push(\n aliasExpr(columnExpr({\n col: name,\n table: pivot.alias,\n }), name, {\n copy: false,\n }) as Expression,\n );\n }\n }\n continue;\n }\n }\n\n for (const name of columns) {\n if (columnsToExclude.has(name) || coalesedColumns.has(name)) continue;\n\n const tablesForCol = usingColumnTables.get(name);\n if (tablesForCol?.includes(table)) {\n coalesedColumns.add(name);\n const coalesceArgs = tablesForCol.map((t) => columnExpr({\n col: name,\n table: t,\n }));\n newSelections.push(\n aliasExpr(\n new CoalesceExpr({\n this: coalesceArgs[0],\n expressions: coalesceArgs.slice(1),\n }),\n name,\n {\n copy: false,\n },\n ) as Expression,\n );\n } else {\n const alias_ = renamedColumns[name] ?? name;\n const selectionExpr = replacedColumns[name] || columnExpr({\n col: name,\n table,\n });\n newSelections.push(\n alias_ !== name\n ? aliasExpr(selectionExpr, alias_, {\n copy: false,\n }) as Expression\n : selectionExpr,\n );\n }\n }\n }\n }\n\n if (0 < newSelections.length && scope.expression instanceof SelectExpr) {\n scope.expression.setArgKey('expressions', newSelections);\n }\n}\n\nexport function qualifyOutputs (scopeOrExpression: Scope | Expression): void {\n let scopeInstance: Scope;\n\n if (scopeOrExpression instanceof Scope) {\n scopeInstance = scopeOrExpression;\n } else {\n const built = buildScope(scopeOrExpression);\n if (!(built instanceof Scope)) return;\n scopeInstance = built;\n }\n\n if (!(scopeInstance.expression instanceof SelectExpr)) {\n return;\n }\n\n const selects = scopeInstance.expression.selects;\n const outerColumns = scopeInstance.outerColumns;\n const newSelections: Expression[] = [\n ];\n const maxLen = Math.max(selects.length, outerColumns.length);\n\n for (let i = 0; i < maxLen; i++) {\n let selection = selects[i] as Expression | undefined;\n const aliasedColumn = outerColumns[i];\n\n if (!selection || selection instanceof QueryTransformExpr) {\n break;\n }\n\n if (selection instanceof SubqueryExpr) {\n if (!selection.outputName) {\n selection.setArgKey('alias', new TableAliasExpr({\n this: toIdentifier(`_col_${i}`),\n }));\n }\n } else if (!(selection instanceof AliasExpr) && !(selection instanceof AliasesExpr) && !selection.isStar) {\n selection = aliasExpr(\n selection,\n selection.outputName || `_col_${i}`,\n {\n copy: false,\n },\n ) as Expression;\n }\n\n if (aliasedColumn) {\n selection.setArgKey('alias', toIdentifier(aliasedColumn));\n }\n\n newSelections.push(selection);\n }\n\n if (0 < newSelections.length && scopeInstance.expression instanceof SelectExpr) {\n scopeInstance.expression.setArgKey('expressions', newSelections);\n }\n}\n\nfunction selectByPos (scope: Scope, node: LiteralExpr): AliasExpr {\n const index = Number(node.args.this) - 1;\n const select = scope.expression.selects[index] as Expression | undefined;\n if (!(select instanceof AliasExpr)) {\n throw new OptimizeError(`Unknown output column: ${node.name}`);\n }\n return select;\n}\n\nfunction expandPositionalReferences (\n scope: Scope,\n expressions: Iterable<Expression>,\n dialect: Dialect,\n options: {alias?: boolean} = {},\n): Expression[] {\n const {\n alias = false,\n } = options;\n const dialectClass = dialect._constructor;\n const newNodes: Expression[] = [\n ];\n let ambiguousProjections: Set<string> | undefined;\n\n for (const node of expressions) {\n if (node.isInteger) {\n const select = selectByPos(scope, node as LiteralExpr);\n if (alias) {\n const selectAlias = select.alias;\n newNodes.push(selectAlias\n ? columnExpr({\n col: selectAlias,\n })\n : node);\n } else {\n const selectThis = select.args.this as Expression;\n let ambiguous = false;\n\n if (dialectClass.PROJECTION_ALIASES_SHADOW_SOURCE_NAMES) {\n if (ambiguousProjections === undefined) {\n ambiguousProjections = new Set(\n scope.expression.selects\n .map((s) => s.aliasOrName)\n .filter((name) => name in scope.selectedSources),\n );\n }\n ambiguous = Array.from(selectThis.findAll(ColumnExpr)).some(\n (col) => ambiguousProjections?.has(col.parts[0]?.name || ''),\n );\n }\n\n if (\n CONSTANTS.some((C) => selectThis instanceof C)\n || selectThis.isNumber\n || selectThis.find(ExplodeExpr)\n || selectThis.find(UnnestExpr)\n || ambiguous\n ) {\n newNodes.push(node);\n } else {\n newNodes.push(selectThis.copy());\n }\n }\n } else {\n newNodes.push(node);\n }\n }\n\n return newNodes;\n}\n\nfunction expandGroupBy (scope: Scope, dialect: Dialect): void {\n const group = (scope.expression as SelectExpr).args.group;\n if (!group) return;\n\n const groupExpressions = filterInstanceOf(group.args.expressions || [\n ], Expression);\n group.setArgKey('expressions', expandPositionalReferences(scope, groupExpressions, dialect));\n (scope.expression as SelectExpr).setArgKey('group', group);\n}\n\nfunction expandOrderByAndDistinctOn (scope: Scope, resolver: Resolver): void {\n for (const modifierKey of [\n 'order',\n 'distinct',\n ]) {\n let modifier = scope.expression.getArgKey(modifierKey) as Expression | undefined;\n\n if (modifier instanceof DistinctExpr) {\n modifier = modifier.args.on;\n }\n\n if (!(modifier instanceof Expression)) {\n continue;\n }\n\n let modifierExpressions = modifier.args.expressions as Expression[];\n\n if (modifierKey === 'order') {\n modifierExpressions = modifierExpressions.map(\n (ordered) => ordered.args.this as Expression,\n );\n }\n\n const expanded = expandPositionalReferences(scope, modifierExpressions, resolver.dialect, {\n alias: true,\n });\n\n for (let j = 0; j < modifierExpressions.length; j++) {\n const original = modifierExpressions[j];\n const expandedNode = expanded[j];\n\n for (const agg of original.findAll(AggFuncExpr)) {\n for (const col of agg.findAll(ColumnExpr)) {\n if (!col.table) {\n const table = resolver.getTable(col.name);\n if (table) {\n col.setArgKey('table', table);\n }\n }\n }\n }\n\n original.replace(expandedNode);\n }\n\n if (scope.expression.getArgKey('group')) {\n const selectsMap = new Map<string, Expression>(\n scope.expression.selects\n .filter((s): s is AliasExpr => s instanceof AliasExpr)\n .map((s) => [\n (s.args.this as Expression).sql(),\n columnExpr({\n col: s.aliasOrName,\n }),\n ]),\n );\n\n for (const expr of modifierExpressions) {\n if (expr.isInteger) {\n expr.replace(toIdentifier(selectByPos(scope, expr as LiteralExpr).alias));\n } else {\n const match = selectsMap.get(expr.sql());\n if (match) expr.replace(match);\n }\n }\n }\n }\n}\n\nexport function quoteIdentifiers (\n expression: Expression,\n options: {\n dialect?: DialectType;\n identify?: boolean;\n } = {},\n): Expression {\n const {\n dialect: dialectArg, identify = true,\n } = options;\n const dialect = Dialect.getOrRaise(dialectArg);\n return expression.transform(\n dialect.quoteIdentifier.bind(dialect),\n {\n identify,\n copy: false,\n },\n );\n}\n\nexport function pushdownCteAliasColumns (scope: Scope): void {\n for (const cte of scope.ctes) {\n const aliasColumnNames = cte.aliasColumnNames;\n if (0 < aliasColumnNames.length && cte.args.this instanceof SelectExpr) {\n const selectExpr = cte.args.this;\n const expressions = selectExpr.args.expressions || [\n ];\n const newExpressions: Expression[] = [\n ];\n\n for (let i = 0; i < aliasColumnNames.length; i++) {\n const alias_ = aliasColumnNames[i];\n const projection = expressions[i];\n if (!projection) break;\n\n let newProjection: Expression;\n if (projection instanceof AliasExpr) {\n projection.setArgKey('alias', toIdentifier(alias_));\n newProjection = projection;\n } else {\n newProjection = aliasExpr(projection, alias_) as Expression;\n }\n newExpressions.push(newProjection);\n }\n\n selectExpr.setArgKey('expressions', newExpressions);\n }\n }\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/qualify_tables.py\n\nimport {\n Expression,\n FromExpr,\n FuncExpr,\n IdentifierExpr,\n JoinExpr,\n parseIdentifier,\n QueryExpr,\n select,\n SubqueryExpr,\n TableAliasExpr,\n TableExpr,\n toIdentifier,\n ValuesExpr,\n WithExpr,\n} from '../expressions';\nimport {\n Dialect, type DialectType,\n} from '../dialects/dialect';\nimport {\n ensureList, nameSequence, seqGet,\n} from '../helper';\nimport {\n normalizeIdentifiers,\n} from './normalize_identifiers';\nimport {\n Scope, traverseScope,\n} from './scope';\n\n/**\n * Rewrite sqlglot AST to have fully qualified tables. Join constructs such as\n * (t1 JOIN t2) AS t will be expanded into (SELECT * FROM t1 AS t1, t2 AS t2) AS t.\n *\n * Examples:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { qualifyTables } from 'sqlglot/optimizer';\n *\n * const expression = parseOne(\"SELECT 1 FROM tbl\");\n * qualifyTables(expression, { db: \"db\" }).sql();\n * // 'SELECT 1 FROM db.tbl AS tbl'\n *\n * const expression2 = parseOne(\"SELECT 1 FROM (t1 JOIN t2) AS t\");\n * qualifyTables(expression2).sql();\n * // 'SELECT 1 FROM (SELECT * FROM t1 AS t1, t2 AS t2) AS t'\n * ```\n *\n * @param expression - Expression to qualify\n * @param options - Qualification options\n * @param options.db - Database name\n * @param options.catalog - Catalog name\n * @param options.onQualify - Callback after a table has been qualified\n * @param options.dialect - The dialect to parse catalog and schema into\n * @param options.canonicalizeTableAliases - Whether to use canonical aliases (_0, _1, ...)\n * for all sources instead of preserving table names. Defaults to false.\n * @returns The qualified expression\n */\nexport function qualifyTables<E extends Expression> (\n expression: E,\n options: {\n db?: string | IdentifierExpr;\n catalog?: string | IdentifierExpr;\n onQualify?: (table: TableExpr) => void;\n dialect?: DialectType;\n canonicalizeTableAliases?: boolean;\n } = {},\n): E {\n const {\n db: dbArg,\n catalog: catalogArg,\n onQualify,\n dialect: dialectArg,\n canonicalizeTableAliases = false,\n } = options;\n\n const dialect = Dialect.getOrRaise(dialectArg);\n const nextAliasName = nameSequence('_');\n\n let db: IdentifierExpr | undefined;\n if (dbArg) {\n db = parseIdentifier(dbArg, {\n dialect,\n });\n db.meta.isTable = true;\n db = normalizeIdentifiers(db, {\n dialect,\n });\n }\n\n let catalog: IdentifierExpr | undefined;\n if (catalogArg) {\n catalog = parseIdentifier(catalogArg, {\n dialect,\n });\n catalog.meta.isTable = true;\n catalog = normalizeIdentifiers(catalog, {\n dialect,\n });\n }\n\n const qualify = (table: TableExpr): void => {\n if (table.args.this instanceof IdentifierExpr) {\n if (db && !table.args.db) {\n table.setArgKey('db', db.copy());\n }\n if (catalog && !table.args.catalog && table.args.db) {\n table.setArgKey('catalog', catalog.copy());\n }\n }\n };\n\n if ((db || catalog) && !(expression instanceof QueryExpr)) {\n const withClause = expression.getArgKey('with') as WithExpr | undefined;\n const with_ = withClause || new WithExpr({\n expressions: [\n ],\n });\n const cteNames = new Set(\n (with_.args.expressions || [\n ]).map((cte) => cte.aliasOrName),\n );\n\n for (const node of expression.walk({\n prune: (n) => n instanceof QueryExpr,\n })) {\n if (node instanceof TableExpr) {\n if (!cteNames.has(node.name)) {\n qualify(node);\n }\n }\n }\n }\n\n const setAlias = (\n expr: Expression,\n canonicalAliases: Map<string, string>,\n options: {\n targetAlias?: string;\n scope?: Scope;\n normalize?: boolean;\n columns?: (string | IdentifierExpr)[];\n } = {},\n ): void => {\n const {\n targetAlias, scope, normalize = false, columns,\n } = options;\n\n let alias = expr.getArgKey('alias') as TableAliasExpr | undefined;\n if (!alias) {\n alias = new TableAliasExpr({});\n }\n\n let newAliasName: string;\n if (canonicalizeTableAliases) {\n newAliasName = nextAliasName();\n canonicalAliases.set(alias.name || targetAlias || '', newAliasName);\n } else if (!alias.name) {\n newAliasName = targetAlias || nextAliasName();\n if (normalize && targetAlias) {\n newAliasName = normalizeIdentifiers(newAliasName, {\n dialect,\n }).name;\n }\n } else {\n return;\n }\n\n alias.setArgKey('this', toIdentifier(newAliasName));\n\n if (columns) {\n alias.setArgKey('columns', columns.map((c) => toIdentifier(c)));\n }\n\n expr.setArgKey('alias', alias);\n\n if (scope) {\n scope.renameSource('', newAliasName);\n }\n };\n\n for (const scope of traverseScope(expression)) {\n const localColumns = scope.localColumns;\n const canonicalAliases = new Map<string, string>();\n\n for (const query of scope.subqueries) {\n const subquery = query.parent;\n if (subquery && subquery instanceof SubqueryExpr) {\n subquery.unwrap().replace(subquery);\n }\n }\n\n for (const derivedTable of scope.derivedTables) {\n const unnested = derivedTable.unnest();\n if (unnested instanceof TableExpr) {\n const joins = unnested.args.joins;\n unnested.setArgKey('joins', undefined);\n\n const derivedThis = derivedTable.args.this;\n if (derivedThis instanceof Expression) {\n const newSelect = select('*').from(unnested.copy(), {\n copy: false,\n });\n derivedThis.replace(newSelect);\n // After replace, set joins on the new expression (mirrors Python behavior\n // where derivedTable.this refers to the new expression after replace)\n newSelect.setArgKey('joins', joins);\n }\n }\n\n setAlias(derivedTable, canonicalAliases, {\n scope,\n });\n\n const pivot = seqGet(derivedTable.getArgKey('pivots') as Expression[] || [\n ], 0);\n if (pivot) {\n setAlias(pivot, canonicalAliases);\n }\n }\n\n const tableAliases = new Map<string, IdentifierExpr>();\n\n for (const [\n name,\n source,\n ] of scope.sources) {\n if (source instanceof TableExpr) {\n const isRealTableSource = Boolean(name);\n\n const pivots = source.args.pivots;\n const pivot = pivots ? seqGet(pivots, 0) : undefined;\n let sourceName = name;\n if (pivot) {\n sourceName = source.name;\n }\n\n const tableThis = source.args.this;\n const tableAlias = source.args.alias;\n let functionColumns: (string | IdentifierExpr)[] = [\n ];\n\n if (tableThis && tableThis instanceof FuncExpr) {\n const func = tableThis as FuncExpr;\n const funcTypeName = func.constructor.name;\n\n if (!tableAlias) {\n const defaultCols = dialect._constructor.DEFAULT_FUNCTIONS_COLUMN_NAMES.get(funcTypeName);\n functionColumns = defaultCols\n ? Array.from(ensureList(defaultCols))\n : [\n ];\n } else if (tableAlias instanceof TableAliasExpr && tableAlias.args.columns?.length) {\n functionColumns = tableAlias.columns as IdentifierExpr[];\n } else if (dialect._constructor.DEFAULT_FUNCTIONS_COLUMN_NAMES.has(funcTypeName)) {\n functionColumns = Array.from(ensureList(source.aliasOrName));\n source.setArgKey('alias', undefined);\n sourceName = '';\n }\n }\n\n setAlias(source, canonicalAliases, {\n targetAlias: sourceName || source.name || undefined,\n normalize: true,\n columns: functionColumns,\n });\n\n const sourceFqn = source.parts?.map((p) => p.name).join('.');\n const sourceAliasThis = source.args.alias?.args.this;\n if (sourceAliasThis instanceof IdentifierExpr) {\n tableAliases.set(sourceFqn, sourceAliasThis.copy());\n }\n\n if (pivot) {\n const targetAlias = pivot.getArgKey('unpivot') ? source.alias : undefined;\n setAlias(pivot, canonicalAliases, {\n targetAlias,\n normalize: true,\n });\n\n if (scope.sources.get(source.aliasOrName) instanceof Scope) {\n continue;\n }\n }\n\n if (isRealTableSource) {\n qualify(source);\n\n if (onQualify) {\n onQualify(source);\n }\n }\n } else if (source instanceof Scope && source.isUdtf) {\n const udtf = source.expression;\n setAlias(udtf, canonicalAliases);\n\n if (udtf instanceof ValuesExpr) {\n const tableAlias = udtf.getArgKey('alias');\n if (tableAlias instanceof TableAliasExpr && !tableAlias.args.columns?.length) {\n tableAlias.setArgKey('columns', dialect\n .generateValuesAliases(udtf)\n .map((i: IdentifierExpr) => normalizeIdentifiers(i, {\n dialect,\n })));\n }\n }\n }\n }\n\n for (const table of scope.tables) {\n if (!table.alias && table.parent) {\n const parent = table.parent;\n if (parent instanceof FromExpr || parent instanceof JoinExpr) {\n setAlias(table, canonicalAliases, {\n targetAlias: table.name,\n });\n }\n }\n }\n\n for (const column of localColumns) {\n const table = column.table;\n\n if (column.args.db) {\n const columnParts = column.parts.slice(0, -1).map((p) => p.name)\n .join('.');\n const tableAlias = tableAliases.get(columnParts);\n\n if (tableAlias) {\n column.setArgKey('table', undefined);\n column.setArgKey('db', undefined);\n column.setArgKey('catalog', undefined);\n column.setArgKey('table', tableAlias.copy());\n }\n } else if (0 < canonicalAliases.size && table) {\n const canonicalTable = canonicalAliases.get(table);\n if (canonicalTable && canonicalTable !== column.table) {\n column.setArgKey('table', toIdentifier(canonicalTable));\n }\n }\n }\n }\n\n return expression;\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/qualify.py\n\nimport type {\n Expression,\n} from '../expressions';\nimport {\n Dialect, type DialectType,\n} from '../dialects/dialect';\nimport {\n ensureSchema, type Schema,\n} from '../schema';\nimport {\n isolateTableSelects,\n} from './isolate_table_selects';\nimport {\n normalizeIdentifiers,\n} from './normalize_identifiers';\nimport {\n qualifyColumns,\n quoteIdentifiers,\n validateQualifyColumns,\n} from './qualify_columns';\nimport {\n qualifyTables,\n} from './qualify_tables';\n\n/**\n * Rewrite sqlglot AST to have normalized and qualified tables and columns.\n *\n * This step is necessary for all further SQLGlot optimizations.\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { qualify } from 'sqlglot/optimizer';\n *\n * const schema = { tbl: { col: \"INT\" } };\n * const expression = parseOne(\"SELECT col FROM tbl\");\n * qualify(expression, { schema }).sql();\n * // 'SELECT \"tbl\".\"col\" AS \"col\" FROM \"tbl\" AS \"tbl\"'\n * ```\n *\n * @param expression - Expression to qualify\n * @param options - Qualification options\n * @param options.dialect - SQL dialect\n * @param options.db - Default database name for tables\n * @param options.catalog - Default catalog name for tables\n * @param options.schema - Schema to infer column names and types\n * @param options.expandAliasRefs - Whether to expand references to aliases (default: true)\n * @param options.expandStars - Whether to expand star queries (default: true). This is necessary for most optimizer rules!\n * @param options.inferSchema - Whether to infer the schema if missing\n * @param options.isolateTables - Whether to isolate table selects (default: false)\n * @param options.qualifyColumns - Whether to qualify columns (default: true)\n * @param options.allowPartialQualification - Whether to allow partial qualification (default: false)\n * @param options.validateQualifyColumns - Whether to validate columns (default: true)\n * @param options.quoteIdentifiers - Whether to quote identifiers (default: true). This is necessary for case-sensitive queries!\n * @param options.identify - If true, quote all identifiers, else only necessary ones (default: true)\n * @param options.canonicalizeTableAliases - Use canonical aliases (_0, _1, ...) instead of preserving table names (default: false)\n * @param options.onQualify - Callback after a table has been qualified\n * @param options.sql - Original SQL string for error highlighting\n * @returns The qualified expression\n */\nexport function qualify<E extends Expression> (\n expression: E,\n options: {\n dialect?: DialectType;\n db?: string;\n catalog?: string;\n schema?: Record<string, unknown> | Schema;\n expandAliasRefs?: boolean;\n expandStars?: boolean;\n inferSchema?: boolean;\n isolateTables?: boolean;\n qualifyColumns?: boolean;\n allowPartialQualification?: boolean;\n validateQualifyColumns?: boolean;\n quoteIdentifiers?: boolean;\n identify?: boolean;\n canonicalizeTableAliases?: boolean;\n onQualify?: (expression: Expression) => void;\n sql?: string;\n } = {},\n): E {\n const {\n dialect: dialectArg,\n db,\n catalog,\n schema: schemaArg,\n expandAliasRefs = true,\n expandStars = true,\n inferSchema,\n isolateTables = false,\n qualifyColumns: qualifyColumnsFlag = true,\n allowPartialQualification = false,\n validateQualifyColumns: validateQualifyColumnsFlag = true,\n quoteIdentifiers: quoteIdentifiersFlag = true,\n identify = true,\n canonicalizeTableAliases = false,\n onQualify,\n sql,\n } = options;\n\n const schema = ensureSchema(schemaArg, {\n dialect: dialectArg,\n });\n const dialect = Dialect.getOrRaise(dialectArg);\n\n expression = normalizeIdentifiers(expression, {\n dialect,\n storeOriginalColumnIdentifiers: true,\n }) as E;\n\n expression = qualifyTables(expression, {\n db,\n catalog,\n dialect,\n onQualify,\n canonicalizeTableAliases,\n }) as E;\n\n if (isolateTables) {\n expression = isolateTableSelects(expression, {\n schema,\n dialect,\n }) as E;\n }\n\n if (qualifyColumnsFlag) {\n expression = qualifyColumns(expression, {\n schema,\n expandAliasRefs,\n expandStars,\n inferSchema,\n allowPartialQualification,\n }) as E;\n }\n\n if (quoteIdentifiersFlag) {\n expression = quoteIdentifiers(expression, {\n dialect,\n identify,\n }) as E;\n }\n\n if (validateQualifyColumnsFlag) {\n validateQualifyColumns(expression, sql);\n }\n\n return expression;\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/unnest_subqueries.py\n\nimport type {\n ColumnExpr,\n} from '../expressions';\nimport {\n Expression,\n InExpr,\n SelectExpr,\n SetOperationExpr,\n WhereExpr,\n HavingExpr,\n JoinExpr,\n AnyExpr,\n FuncExpr,\n TableExpr,\n FromExpr,\n AggFuncExpr,\n ArrayAggExpr,\n BinaryExpr,\n CoalesceExpr,\n column,\n alias,\n condition,\n CountExpr,\n LimitExpr,\n LiteralExpr,\n MaxExpr,\n null_,\n OffsetExpr,\n OrExpr,\n PredicateExpr,\n select,\n toIdentifier,\n true_,\n EqExpr,\n AllExpr,\n SubqueryExpr,\n ExistsExpr,\n JoinExprKind,\n ConditionExpr,\n} from '../expressions';\nimport {\n isInstanceOf,\n} from '../port_internals';\nimport {\n nameSequence,\n} from '../helper';\nimport {\n findInScope, ScopeType, traverseScope,\n} from './scope';\n\n/**\n * Rewrite sqlglot AST to convert some predicates with subqueries into joins.\n *\n * - Convert scalar subqueries into cross joins\n * - Convert correlated or vectorized subqueries into a group by so it is not a many-to-many left join\n *\n * Example:\n * ```ts\n * import { parseOne } from 'sqlglot';\n * import { unnestSubqueries } from 'sqlglot/optimizer';\n *\n * const expression = parseOne(\"SELECT * FROM x AS x WHERE (SELECT y.a AS a FROM y AS y WHERE x.a = y.a) = 1\");\n * unnestSubqueries(expression).sql();\n * // 'SELECT * FROM x AS x LEFT JOIN (SELECT y.a AS a FROM y AS y WHERE TRUE GROUP BY y.a) AS _u_0 ON x.a = _u_0.a WHERE _u_0.a = 1'\n * ```\n *\n * @param expression - Expression to unnest\n * @returns The unnested expression\n */\nexport function unnestSubqueries<E extends Expression> (expression: E): E {\n const nextAliasName = nameSequence('_u_');\n\n for (const scope of traverseScope(expression)) {\n const select = scope.expression;\n const parent = select.parentSelect;\n\n if (!parent || !isInstanceOf(parent, SelectExpr)) {\n continue;\n }\n\n if (!isInstanceOf(select, SelectExpr)) {\n continue;\n }\n\n const selectExpr: SelectExpr = select;\n\n if (0 < scope.externalColumns.length) {\n decorrelate(selectExpr, parent, scope.externalColumns, nextAliasName);\n } else if (scope.scopeType === ScopeType.SUBQUERY) {\n unnest(selectExpr, parent, nextAliasName);\n }\n }\n\n return expression;\n}\n\nfunction unnest (\n selectExpr: SelectExpr,\n parentSelect: SelectExpr,\n nextAliasName: () => string,\n): void {\n if (1 < selectExpr.selects.length) {\n return;\n }\n\n const predicate = selectExpr.findAncestor(ConditionExpr);\n if (\n !predicate\n // Do not unnest subqueries inside table-valued functions such as\n // FROM GENERATE_SERIES(...), FROM UNNEST(...) etc in order to preserve join order\n || (\n predicate instanceof FuncExpr\n && (predicate.parent instanceof TableExpr\n || predicate.parent instanceof FromExpr\n || predicate.parent instanceof JoinExpr)\n )\n || parentSelect !== predicate.parentSelect\n || !parentSelect.args.from\n ) {\n return;\n }\n\n let selectToUse = selectExpr;\n if (selectExpr instanceof SetOperationExpr) {\n selectToUse = select(selectExpr.selects).from(selectExpr.subquery(nextAliasName()), {\n copy: false,\n });\n }\n\n const aliasExpr = nextAliasName();\n const clause = predicate.findAncestor(HavingExpr, WhereExpr, JoinExpr);\n\n // This subquery returns a scalar and can just be converted to a cross join\n if (!(predicate instanceof InExpr || predicate instanceof AnyExpr)) {\n let columnExpr: Expression = column({\n col: selectToUse.selects[0].aliasOrName,\n table: aliasExpr,\n });\n\n const clauseParentSelect = clause?.parentSelect;\n\n if (\n (clause instanceof HavingExpr && clauseParentSelect === parentSelect)\n || (\n (!clause || clauseParentSelect !== parentSelect)\n && (\n parentSelect.args.group\n || parentSelect.selects.some((sel) => findInScope(sel, AggFuncExpr))\n )\n )\n ) {\n columnExpr = new MaxExpr({\n this: columnExpr,\n });\n } else if (!(selectExpr.parent instanceof SubqueryExpr)) {\n return;\n }\n\n let joinType = JoinExprKind.CROSS;\n let onClause: Expression | undefined;\n if (predicate instanceof ExistsExpr) {\n // If a subquery returns no rows, cross-joining against it incorrectly eliminates all rows\n // from the parent query. Therefore, we use a LEFT JOIN that always matches (ON TRUE), then\n // check for non-NULL column values to determine whether the subquery contained rows.\n columnExpr = columnExpr.is(null_()).not();\n joinType = JoinExprKind.LEFT;\n onClause = true_();\n }\n\n replace(selectExpr.parent as Expression, columnExpr);\n parentSelect.join(selectToUse, {\n on: onClause,\n joinType,\n joinAlias: aliasExpr,\n copy: false,\n });\n\n return;\n }\n\n if (selectToUse.find([\n LimitExpr,\n OffsetExpr,\n ])) {\n return;\n }\n\n let predicateToUse: InExpr | AnyExpr | EqExpr = predicate;\n if (predicate instanceof AnyExpr) {\n const eqPredicate = predicate.findAncestor(EqExpr);\n\n if (!eqPredicate || parentSelect !== eqPredicate.parentSelect) {\n return;\n }\n\n predicateToUse = eqPredicate;\n }\n\n const columnExpr = otherOperand(predicateToUse);\n const value = selectToUse.selects[0];\n const valueThis = value.args.this;\n if (!(valueThis instanceof Expression)) {\n return;\n }\n\n const joinKey = column({\n col: value.alias,\n table: aliasExpr,\n });\n const joinKeyNotNull = joinKey.is(null_()).not();\n\n if (clause instanceof JoinExpr) {\n replace(predicateToUse, true_());\n parentSelect.where(joinKeyNotNull, {\n copy: false,\n });\n } else {\n replace(predicateToUse, joinKeyNotNull);\n }\n\n const group = selectToUse.args.group;\n\n if (group) {\n // Simulate set comparison in sqlglot (Python: {value.this} != set(group.expressions))\n const groupExprSqls = new Set((group.args.expressions ?? [\n ]).map((e) => (e instanceof Expression ? e.sql() : String(e))));\n if (groupExprSqls.size !== 1 || !groupExprSqls.has((value.args.this as Expression).sql())) {\n selectToUse = select(\n alias(column({\n col: value.alias,\n table: '_q',\n }), value.alias, {\n copy: false,\n }),\n )\n .from(selectToUse.subquery('_q', {\n copy: false,\n }), {\n copy: false,\n })\n .groupBy(column({\n col: value.alias,\n table: '_q',\n }), {\n copy: false,\n });\n }\n } else if (!findInScope(valueThis, AggFuncExpr)) {\n selectToUse = selectToUse.groupBy(valueThis, {\n copy: false,\n });\n }\n\n if (!columnExpr) return;\n\n parentSelect.join(\n selectToUse,\n {\n on: columnExpr.eq(joinKey),\n joinType: JoinExprKind.LEFT,\n joinAlias: aliasExpr,\n copy: false,\n },\n );\n}\n\nfunction decorrelate (\n select: SelectExpr,\n parentSelect: SelectExpr,\n externalColumns: Iterable<ColumnExpr>,\n nextAliasName: () => string,\n): void {\n const where = select.args.where;\n\n if (!where || where.find(OrExpr) || select.find([\n LimitExpr,\n OffsetExpr,\n ])) {\n return;\n }\n\n const tableAlias = nextAliasName();\n const keys: [Expression, ColumnExpr, Expression][] = [\n ];\n\n // for all external columns in the where statement, find the relevant predicate\n // keys to convert it into a join\n for (const column of externalColumns) {\n if (column.findAncestor(WhereExpr) !== where) {\n return;\n }\n\n const predicate = column.findAncestor(PredicateExpr);\n\n if (!predicate || predicate.findAncestor(WhereExpr) !== where) {\n return;\n }\n\n let key: Expression | undefined;\n\n if (predicate instanceof BinaryExpr) {\n key = Array.from(predicate.left?.walk() || [\n ]).some((node) => node === column)\n ? predicate.right\n : predicate.left;\n } else {\n return;\n }\n\n if (!key) return;\n\n keys.push([\n key,\n column,\n predicate,\n ]);\n }\n\n if (!keys.some(([\n , , predicate,\n ]) => predicate instanceof EqExpr)) {\n return;\n }\n\n const isSubqueryProjection = parentSelect.selects\n .map((s) => s.unalias())\n .some((node) => node instanceof SubqueryExpr && node === select.parent);\n\n const value = select.selects[0];\n const valueThis = value.args.this;\n if (!(valueThis instanceof Expression)) return;\n\n // Use SQL string as key for structural equality (mirrors Python's expression __eq__ / __hash__)\n const keyAliasesBySql = new Map<string, string>();\n const keyByAliasSql = new Map<string, Expression>(); // reverse: sql -> expression node\n const groupBySqls = new Set<string>(); // SQL strings for groupBy members\n const groupBy: Expression[] = [\n ];\n\n const exprInGroupBy = (expr: Expression): boolean => groupBySqls.has(expr.sql());\n\n for (const [\n key, , predicate,\n ] of keys) {\n const keySql = key.sql();\n // if we filter on the value of the subquery, it needs to be unique\n if (keySql === valueThis.sql()) {\n keyAliasesBySql.set(keySql, value.alias);\n keyByAliasSql.set(keySql, key);\n if (!groupBySqls.has(keySql)) {\n groupBySqls.add(keySql);\n groupBy.push(key);\n }\n } else {\n if (!keyAliasesBySql.has(keySql)) {\n keyAliasesBySql.set(keySql, nextAliasName());\n keyByAliasSql.set(keySql, key);\n }\n // all predicates that are equalities must also be in the unique\n // so that we don't do a many to many join\n if (predicate instanceof EqExpr && !groupBySqls.has(keySql)) {\n groupBySqls.add(keySql);\n groupBy.push(key);\n }\n }\n }\n\n let parentPredicate = select.findAncestor(PredicateExpr);\n\n // if the value of the subquery is not an agg or a key, we need to collect it into an array\n // so that it can be grouped. For subquery projections, we use a MAX aggregation instead.\n const aggFunc = isSubqueryProjection ? MaxExpr : ArrayAggExpr;\n if (!value.find(AggFuncExpr) && !exprInGroupBy(valueThis)) {\n select.select(\n alias(new aggFunc({\n this: valueThis,\n }), value.alias, {\n quoted: false,\n }),\n {\n append: false,\n copy: false,\n },\n );\n }\n\n // exists queries should not have any selects as it only checks if there are any rows\n // all selects will be added by the optimizer and only used for join keys\n if (parentPredicate instanceof ExistsExpr) {\n select.setArgKey('expressions', [\n ]);\n }\n\n for (const [\n keySql,\n keyAlias,\n ] of keyAliasesBySql) {\n const key = keyByAliasSql.get(keySql)!;\n if (groupBySqls.has(keySql)) {\n // add all keys to the projections of the subquery\n // so that we can use it as a join key\n if (parentPredicate instanceof ExistsExpr || keySql !== (value.args.this as Expression).sql()) {\n select.select(`${key} AS ${keyAlias}`, {\n copy: false,\n });\n }\n } else {\n select.select(alias(new aggFunc({\n this: key.copy(),\n }), keyAlias, {\n quoted: false,\n }), {\n copy: false,\n });\n }\n }\n\n let aliasExpr: Expression = column({\n col: value.alias,\n table: tableAlias,\n });\n const other = otherOperand(parentPredicate);\n const opType = parentPredicate?.parent?._constructor;\n\n if (parentPredicate instanceof ExistsExpr) {\n aliasExpr = column({\n col: Array.from(keyAliasesBySql.values())[0],\n table: tableAlias,\n });\n parentPredicate = replace(parentPredicate, `NOT ${aliasExpr} IS NULL`);\n } else if (parentPredicate instanceof AllExpr) {\n if (!opType || !(opType.prototype instanceof BinaryExpr || opType === BinaryExpr)) return;\n const predicateExpr = new opType({\n this: other,\n expression: column({\n col: '_x',\n }),\n });\n if (parentPredicate.parent) parentPredicate = replace(parentPredicate.parent, `ARRAY_ALL(${aliasExpr}, _x -> ${predicateExpr})`);\n } else if (parentPredicate instanceof AnyExpr) {\n if (!opType || !(opType.prototype instanceof BinaryExpr || opType === BinaryExpr)) return;\n if (exprInGroupBy(value.args.this as Expression)) {\n const predicateExpr = new opType({\n this: other,\n expression: aliasExpr,\n });\n if (parentPredicate.parent) parentPredicate = replace(parentPredicate.parent, predicateExpr);\n } else {\n const predicateExpr = new opType({\n this: other,\n expression: column({\n col: '_x',\n }),\n });\n parentPredicate = replace(parentPredicate, `ARRAY_ANY(${aliasExpr}, _x -> ${predicateExpr})`);\n }\n } else if (parentPredicate instanceof InExpr) {\n if (exprInGroupBy(value.args.this as Expression)) {\n parentPredicate = replace(parentPredicate, `${other} = ${aliasExpr}`);\n } else {\n parentPredicate = replace(parentPredicate, `ARRAY_ANY(${aliasExpr}, _x -> _x = ${parentPredicate.args.this})`);\n }\n } else {\n if (isSubqueryProjection && select.parent?.alias) {\n aliasExpr = alias(aliasExpr, select.parent.alias, {\n copy: false,\n });\n }\n\n // COUNT always returns 0 on empty datasets, so we need take that into consideration here\n // by transforming all counts into 0 and using that as the coalesced value\n if (value.find(CountExpr)) {\n const removeAggs = (node: Expression): Expression => {\n if (node instanceof CountExpr) {\n return LiteralExpr.number(0);\n } else if (node instanceof AggFuncExpr) {\n return null_();\n }\n return node;\n };\n\n aliasExpr = new CoalesceExpr({\n this: aliasExpr,\n expressions: [\n (value.args.this as Expression).transform(removeAggs),\n ],\n });\n }\n\n select.parent?.replace(aliasExpr);\n }\n\n for (const [\n key,\n columnExpr,\n predicate,\n ] of keys) {\n predicate.replace(true_());\n const keyAlias = keyAliasesBySql.get(key.sql());\n if (!keyAlias) continue;\n const nested = column({\n col: keyAlias,\n table: tableAlias,\n });\n\n if (isSubqueryProjection) {\n key.replace(nested);\n if (!(predicate instanceof EqExpr)) {\n parentSelect.where(predicate, {\n copy: false,\n });\n }\n continue;\n }\n\n if (exprInGroupBy(key)) {\n key.replace(nested);\n } else if (predicate instanceof EqExpr) {\n if (parentPredicate) parentPredicate = replace(parentPredicate, `(${parentPredicate} AND ARRAY_CONTAINS(${nested}, ${columnExpr}))`);\n } else {\n key.replace(toIdentifier('_x'));\n if (parentPredicate) parentPredicate = replace(parentPredicate, `(${parentPredicate} AND ARRAY_ANY(${nested}, _x -> ${predicate}))`);\n }\n }\n\n parentSelect.join(\n select.groupBy(groupBy, {\n copy: false,\n }),\n {\n on: keys.filter(([\n , , predicate,\n ]) => predicate instanceof EqExpr).map(([\n , , predicate,\n ]) => predicate),\n joinType: JoinExprKind.LEFT,\n joinAlias: tableAlias,\n copy: false,\n },\n );\n}\n\nfunction replace (expression: Expression, conditionExpr: string | Expression): Expression {\n return expression.replace(condition(conditionExpr));\n}\n\nfunction otherOperand (expression: Expression | undefined): Expression | undefined {\n if (expression instanceof InExpr) {\n return expression.args.this as Expression;\n }\n\n if (expression instanceof AnyExpr || expression instanceof AllExpr) {\n return otherOperand(expression.parent);\n }\n\n if (expression instanceof BinaryExpr) {\n return (\n expression.left instanceof SubqueryExpr\n || expression.left instanceof AnyExpr\n || expression.left instanceof ExistsExpr\n || expression.left instanceof AllExpr\n )\n ? expression.right as Expression\n : expression.left as Expression;\n }\n\n return undefined;\n}\n","// https://github.com/tobymao/sqlglot/blob/main/sqlglot/optimizer/optimizer.py\n\nimport {\n maybeParse, type Expression,\n} from '../expressions';\nimport type {\n DialectType,\n} from '../dialects/dialect';\nimport type {\n Schema,\n} from '../schema';\nimport {\n ensureSchema,\n} from '../schema';\nimport type {\n Pojo,\n} from '../port_internals/type_utils';\nimport {\n annotateTypes,\n} from './annotate_types';\nimport {\n canonicalize,\n} from './canonicalize';\nimport {\n eliminateCtes,\n} from './eliminate_ctes';\nimport {\n eliminateJoins,\n} from './eliminate_joins';\nimport {\n eliminateSubqueries,\n} from './eliminate_subqueries';\nimport {\n mergeSubqueries,\n} from './merge_subqueries';\nimport {\n normalize,\n} from './normalize';\nimport {\n optimizeJoins,\n} from './optimize_joins';\nimport {\n pushdownPredicates,\n} from './pushdown_predicates';\nimport {\n pushdownProjections,\n} from './pushdown_projections';\nimport {\n qualify,\n} from './qualify';\nimport {\n quoteIdentifiers,\n} from './qualify_columns';\nimport {\n simplify,\n} from './simplify';\nimport {\n unnestSubqueries,\n} from './unnest_subqueries';\n\n/**\n * Optimizer rule function type.\n */\ntype OptimizerRule = (expression: Expression, options?: Record<string, unknown>) => Expression;\n\n/**\n * Default sequence of optimizer rules.\n */\nexport const RULES: OptimizerRule[] = [\n qualify,\n pushdownProjections,\n normalize,\n unnestSubqueries,\n pushdownPredicates,\n optimizeJoins,\n eliminateSubqueries,\n mergeSubqueries,\n eliminateJoins,\n eliminateCtes,\n quoteIdentifiers,\n annotateTypes,\n canonicalize,\n simplify,\n];\n\n/**\n * Rewrite a sqlglot AST into an optimized form.\n *\n * Example:\n * ```ts\n * import { optimize } from 'sqlglot/optimizer';\n *\n * const optimized = optimize(\n * \"SELECT a FROM (SELECT x.a FROM x) CROSS JOIN y\",\n * { schema: { x: { a: \"INT\" }, y: { b: \"INT\" } } }\n * );\n * optimized.sql();\n * // 'SELECT x.a FROM x CROSS JOIN y'\n * ```\n *\n * @param expression - Expression to optimize (string or Expression)\n * @param options - Optimization options\n * @param options.schema - Database schema (table -> column -> type mapping)\n * @param options.db - Default database name\n * @param options.catalog - Default catalog name\n * @param options.dialect - SQL dialect\n * @param options.rules - Sequence of optimizer rules to use (default: RULES)\n * @param options.sql - Original SQL string for error highlighting\n * @param options.isolateTables - Whether to isolate tables (default: true)\n * @param options.quoteIdentifiers - Whether to quote identifiers (default: false)\n * @returns The optimized expression\n */\nexport function optimize (\n expression: string | Expression,\n options: {\n schema?: Pojo | Schema;\n db?: string;\n catalog?: string;\n dialect?: DialectType;\n rules?: OptimizerRule[];\n sql?: string;\n isolateTables?: boolean;\n quoteIdentifiers?: boolean;\n [key: string]: unknown;\n } = {},\n): Expression {\n const {\n schema: schemaArg,\n db,\n catalog,\n dialect,\n rules = RULES,\n sql,\n isolateTables = true,\n quoteIdentifiers: quoteIdentifiersFlag = false,\n ...extraOptions\n } = options;\n\n const schema = ensureSchema(schemaArg, {\n dialect,\n });\n\n // Base options passed to rules\n const possibleOptions: Record<string, unknown> = {\n db,\n catalog,\n schema,\n dialect,\n sql,\n isolateTables,\n quoteIdentifiers: quoteIdentifiersFlag,\n ...extraOptions,\n };\n\n // Parse expression if it's a string\n let optimized = maybeParse(expression, {\n dialect,\n copy: true,\n });\n\n // Apply each rule in sequence\n for (const rule of rules) {\n optimized = rule(optimized, possibleOptions);\n }\n\n return optimized;\n}\n"],"mappings":"q4BA0BO,SAASA,GAAqCC,EAAkB,CACrE,IAAMC,EAAOC,EAAWF,CAAU,EAElC,GAAIC,EAAM,CACR,IAAME,EAAWF,EAAK,SAAS,EAGzBG,EAAkB,CACxB,EACA,QAAWC,KAASJ,EAAK,SAAS,EAChCG,EAAO,KAAKC,CAAK,EAGnB,QAASC,EAAIF,EAAO,OAAS,EAAG,GAAKE,EAAGA,IAAK,CAC3C,IAAMD,EAAQD,EAAOE,CAAC,EACtB,GAAID,EAAM,MAAO,CACf,IAAME,EAAUF,EAGhB,IAFcF,EAAS,IAAII,CAAO,GAAK,IAE1B,EAAG,CACd,IAAMC,EAAUH,EAAM,WAAW,OACjC,GAAI,CAACG,EACH,SAGF,IAAMC,EAAWD,EAAQ,OAIzB,GAHAA,EAAQ,IAAI,EAGRC,EAAU,CACZ,IAAMC,EAAkBD,EAAS,KAAK,aAClC,CAACC,GAAmBA,EAAgB,SAAW,IACjDD,EAAS,IAAI,CAEjB,CAGA,OAAW,CACT,CAAEE,CACJ,IAAK,OAAO,QAAQN,EAAM,eAAe,EAAG,CAC1C,GAAM,CACJ,CAAEO,CACJ,EAAID,EACJ,GAAIC,aAAuBC,EAAO,CAChC,IAAMC,EAAeX,EAAS,IAAIS,CAAW,GAAK,EAClDT,EAAS,IAAIS,EAAaE,EAAe,CAAC,CAC5C,CACF,CACF,CACF,CACF,CACF,CAEA,OAAOd,CACT,CCpCO,SAASe,GAAsCC,EAAkB,CACtE,QAAWC,KAASC,EAAcF,CAAU,EAAG,CAI7C,GAAI,EAAIC,EAAM,mBAAmB,OAC/B,SAGF,IAAME,EAAQF,EAAM,WAAW,KAAK,MACpC,GAAKE,EAKL,QAASC,EAAID,EAAM,OAAS,EAAG,GAAKC,EAAGA,IAAK,CAC1C,IAAMC,EAAmBF,EAAMC,CAAC,EAEhC,GADAE,GAAmBD,EAAME,CAAQ,EAC7BF,EAAK,iBACP,SAGF,IAAMG,EAAQH,EAAK,YACfG,GAASC,GAAoBR,EAAOI,EAAMG,CAAK,IACjDH,EAAK,IAAI,EACTJ,EAAM,aAAaO,CAAK,EAE5B,CACF,CAEA,OAAOR,CACT,CAEA,SAASS,GAAqBR,EAAcI,EAAgBG,EAAwB,CAClF,IAAME,EAAcT,EAAM,QAAQ,IAAIO,CAAK,EAK3C,GAJI,EAAEE,aAAuBC,IAIzBC,GAAWX,EAAOI,EAAMG,CAAK,EAC/B,MAAO,GAGT,IAAMK,EAAOR,EAAK,KAAK,KACjBS,EAAWT,EAAK,KAAK,GAE3B,OACGQ,IAAS,QAAqBE,GAA2BL,EAAaL,CAAI,GACvE,CAACS,GAAYE,GAAmBN,CAAW,CAEnD,CAEA,SAASE,GAAYX,EAAcI,EAAgBG,EAAwB,CAGzE,IAAMM,EAAWT,EAAK,KAAK,GAErBY,EAAkB,IAAI,IAC5B,GAAIH,EACF,QAAWI,KAAUJ,EAAS,QAAQK,CAAU,EAC9CF,EAAgB,IAAIC,CAAM,EAK9B,OADsBjB,EAAM,cAAcO,CAAK,EAC1B,KAAMU,GAAW,CAACD,EAAgB,IAAIC,CAAM,CAAC,CACpE,CAEA,SAASH,GAA4Bd,EAAcI,EAAyB,CAC1E,IAAMe,EAAiBC,GAAcpB,CAAK,EAC1C,GAAI,CAACmB,GAAkBA,EAAe,OAAS,EAC7C,MAAO,GAGT,GAAM,CACJ,SAAAE,CACF,EAAIC,GAAclB,CAAI,EAChBmB,EAAe,IAAI,IAAIF,EAAS,IAAKG,GAAMA,EAAE,IAAI,CAAC,EAExD,QAAWC,KAAUN,EACnB,GAAI,CAACI,EAAa,IAAIE,CAAM,EAC1B,MAAO,GAIX,MAAO,EACT,CAEA,SAASL,GAAepB,EAAuC,CAC7D,IAAMD,EAAaC,EAAM,WACzB,GAAI,EAAED,aAAsB2B,GAC1B,OAGF,IAAMC,EAAS5B,EAGf,GAAI4B,EAAO,KAAK,SACd,OAAO,IAAI,IAAIA,EAAO,YAAY,EAIpC,IAAMC,EAAQD,EAAO,KAAK,MAC1B,GAAIC,EAAO,CACT,IAAMC,EAAc,IAAI,KACrBD,EAAM,KAAK,aAAe,CAC3B,GACG,OAAQE,GAAuBA,aAAaC,CAAU,EACtD,IAAKD,GAAMA,EAAE,IAAI,CAAC,CACvB,EACME,EAAoB,IAAI,IACxBZ,EAAgB,IAAI,IAE1B,QAAWa,KAAcN,EAAO,QAAS,CACvC,GAAI,EAAEM,aAAsBF,GAC1B,SAGF,IAAMG,EAAYD,EAAW,QAAQ,EAAE,IAAI,EACvCJ,EAAY,IAAIK,CAAS,IAC3BF,EAAkB,IAAIE,CAAS,EAC/Bd,EAAc,IAAIa,EAAW,WAAW,EAE5C,CAOA,MAJ2B,CACzB,GAAGJ,CACL,EAAE,MAAOM,GAAMH,EAAkB,IAAIG,CAAC,CAAC,EAEXf,EAAgB,IAAI,GAClD,CAGA,OAAIL,GAAmBf,CAAK,EACnB,IAAI,IAAI2B,EAAO,YAAY,EAG7B,IAAI,GACb,CAEA,SAASZ,GAAoBf,EAAuB,CAClD,IAAMD,EAAaC,EAAM,WACzB,GAAI,EAAED,aAAsB2B,GAC1B,MAAO,GAGT,IAAMC,EAAS5B,EAqBf,MAlBI,IAAC4B,EAAO,KAAK,MAKKA,EAAO,QAAQ,MAAOG,GACpCA,aAAaC,EAGDD,EAAE,QAAQ,YACAM,EAHnB,EAIV,GAOGC,GAASrC,CAAK,EAKpB,CAEA,SAASqC,GAAUrC,EAAuB,CACxC,IAAMsC,EAAQtC,EAAM,WAAW,UAAU,OAAO,EAChD,OAAMsC,aAAiBC,GAGhBD,EAAM,KAAK,YAAY,KAAK,OAAS,IAFnC,EAGX,CAQO,SAAShB,GACdlB,EAKA,CACA,IAAMoC,EAAOpC,EAAK,YAEZqC,GADWrC,EAAK,KAAK,IACHsC,EAAM,GAAG,KAAK,EAEhCC,EAA2B,CACjC,EACMtB,EAAyB,CAC/B,EAEA,SAASuB,EAAkBC,EAA6B,CACtD,GAAM,CACJC,EACAC,CACF,EAAIF,EAAU,eAAe,EAC7B,GAAI,CAACC,GAAQ,CAACC,EACZ,OAGF,IAAMC,EAAaC,GAAiBH,CAAI,EAClCI,EAAcD,GAAiBF,CAAK,EAEtCP,GAAQQ,EAAW,IAAIR,CAAI,GAAK,CAACU,EAAY,IAAIV,CAAI,GACvDnB,EAAS,KAAKyB,CAAI,EAClBH,EAAW,KAAKI,CAAK,EACrBF,EAAU,QAAQH,EAAM,CAAC,GAChBF,GAAQU,EAAY,IAAIV,CAAI,GAAK,CAACQ,EAAW,IAAIR,CAAI,IAC9DnB,EAAS,KAAK0B,CAAK,EACnBJ,EAAW,KAAKG,CAAI,EACpBD,EAAU,QAAQH,EAAM,CAAC,EAE7B,CAEA,GAAIS,GAAWV,CAAE,EAAG,CAElB,IAAMW,EAAQX,aAAcY,GACxBZ,EACAa,GAAI,CACJb,EACAC,EAAM,CACR,EAAG,CACD,KAAM,EACR,CAAC,EACH,QAAWG,KAAaO,EAAM,QAAQ,EAChCP,aAAqBU,GACvBX,EAAiBC,CAAS,CAGhC,SAAWM,GAAWV,EAAI,CACxB,IAAK,EACP,CAAC,EAAG,CAEF,IAAIe,EAEJ,QAAWC,KAAYhB,EAAG,QAAQ,EAAG,CACnC,IAAMiB,EAAQ,MAAM,KAAKD,EAAS,QAAQ,CAAC,EACxC,OAAQE,GAAmBA,aAAaJ,CAAM,EAEjD,GAAIC,IAAe,OACjBA,EAAaE,MACR,CACL,IAAME,EAAiB,CACvB,EACA,QAAW,KAAKF,EAAO,CACrB,IAAMG,EAAKL,EAAW,OAAQM,GAAM,EAAE,IAAI,IAAMA,EAAE,IAAI,CAAC,EACnD,EAAID,EAAG,SACTD,EAAK,KAAK,CAAC,EACXA,EAAK,KAAK,GAAGC,CAAE,EAEnB,CACAL,EAAaI,CACf,CACF,CAEA,GAAIJ,EACF,QAAWX,KAAaW,EACtBZ,EAAiBC,CAAS,CAGhC,CAEA,MAAO,CACL,WAAAF,EACA,SAAAtB,EACA,GAAAoB,CACF,CACF,CAEA,SAASQ,GAAkBlD,EAAqC,CAC9D,IAAMgE,EAAS,IAAI,IACnB,QAAW9C,KAAUlB,EAAW,QAAQmB,CAAU,EAC5CD,EAAO,OACT8C,EAAO,IAAI9C,EAAO,KAAK,EAG3B,OAAO8C,CACT,CCvRO,SAASC,GAA2CC,EAAkB,CAC3E,GAAIA,aAAsBC,GAAgBD,EAAW,KAAK,KACxD,OAAAD,GAAoBC,EAAW,KAAK,IAAI,EACjCA,EAGT,IAAME,EAAOC,EAAWH,CAAU,EAElC,GAAI,CAACE,EACH,OAAOF,EAGT,IAAMI,EAA0B,IAAI,IAGpC,QAAWC,KAASH,EAAK,UAAW,CAClC,IAAMI,EAASD,EAAM,WAAW,OAC5BC,GACFF,EAAM,IAAIE,EAAO,MAAOD,CAAK,CAEjC,CAGA,QAAWA,KAASH,EAAK,SAAS,EAChC,OAAW,CACT,CAAEK,CACJ,IAAKF,EAAM,QACLE,aAAkBC,GACpBJ,EAAM,IAAIG,EAAO,KAAMA,CAAM,EAKnC,IAAME,EAAoC,IAAI,IAExCC,EAAaR,EAAK,WAAW,KAAK,KACpCS,EAAY,GAEhB,GAAID,EAAY,CACdE,GAAmBF,EAAYG,CAAQ,EACvCF,EAAY,EAAQD,EAAW,KAAK,UACpC,QAAWI,KAAOJ,EAAW,KAAK,aAAe,CACjD,EACMK,EAAaD,EAAKE,EAAO,GAAKF,EAAI,KAAK,MACrCA,EAAI,KAAK,MAAML,EAAa,IAAIK,EAAI,KAAK,KAAK,OAAQA,EAAI,KAAK,CAGzE,CAEA,IAAMG,EAAwB,CAC9B,EAIA,QAAWC,KAAYhB,EAAK,UAAW,CAErC,QAAWG,KAASa,EAAS,SAAS,EAAG,CACvC,GAAIb,IAAUa,EAEZ,SAEF,IAAMC,EAASC,GAAUf,EAAOI,EAAcL,CAAK,EAC/Ce,GACFF,EAAQ,KAAKE,CAAM,CAEvB,CAGA,IAAME,EAAYH,EAAS,WAAW,OAClCG,GACFJ,EAAQ,KAAKI,CAAS,CAE1B,CAGA,IAAMC,EAAa,CACjB,GAAGpB,EAAK,YACR,GAAGA,EAAK,eACR,GAAGA,EAAK,WACV,EACA,QAAWG,KAASiB,EAClB,QAAWC,KAAclB,EAAM,SAAS,EAAG,CACzC,IAAMc,EAASC,GAAUG,EAAYd,EAAcL,CAAK,EACpDe,GACFF,EAAQ,KAAKE,CAAM,CAEvB,CAGF,MAAI,GAAIF,EAAQ,SACAjB,aAAsBwB,GAChCxB,EAAW,KAAK,WAChBA,IAEG,UAAU,OAAQ,IAAIa,EAAS,CACpC,YAAaI,EACb,UAAAN,CACF,CAAC,CAAC,EAGGX,CACT,CAEA,SAASoB,GACPf,EACAI,EACAL,EACwB,CACxB,GAAIC,EAAM,eACR,OAAOoB,GAAsBpB,EAAOI,EAAcL,CAAK,EAGzD,GAAIC,EAAM,MACR,OAAOqB,GAAarB,EAAOI,EAAcL,CAAK,CAIlD,CAEA,SAASqB,GACPpB,EACAI,EACAL,EACwB,CAIxB,GAAIC,EAAM,SAAW,EAAIA,EAAM,OAAO,OAAO,QAAUA,EAAM,OAAO,sBAAsBsB,IACxF,OAIF,IAAIC,EAAYvB,EAAM,WAAW,OACjC,GAAI,CAACuB,EACH,OAIEA,aAAqB3B,IACvB2B,EAAaA,EAA2B,OAAO,GAGjD,GAAM,CACJC,EACAf,CACF,EAAIK,GAAOd,EAAOI,EAAcL,CAAK,EAE/B0B,EAAYC,EAAMC,GAAMH,CAAI,EAAGD,EAAU,OAASC,EAAM,CAC5D,KAAM,EACR,CAAC,EAEKI,EADgBL,EAAU,KACJ,MAC5B,OAAIK,GAAS,MAAM,QAAQA,CAAK,GAC7BH,EAAwB,UAAU,QAASG,CAAK,EAGnDL,EAAU,QAAQE,CAAS,EAEpBhB,CACT,CAEA,SAASY,GACPrB,EACAI,EACAL,EACwB,CACxB,IAAME,EAASD,EAAM,WAAW,OAChC,GAAI,CAACC,EACH,OAGF,GAAM,CACJuB,EACAf,CACF,EAAIK,GAAOd,EAAOI,EAAcL,CAAK,EAE/BM,EAAaJ,EAAO,OAG1B,GAFAA,EAAO,IAAI,EAEPI,EAAY,CACd,IAAMwB,EAAkBxB,EAAW,KAAK,aACpC,CAACwB,GAAmBA,EAAgB,SAAW,IACjDxB,EAAW,IAAI,CAEnB,CAGA,GAAIL,EAAM,OACR,QAAWkB,KAAclB,EAAM,OAAO,SAAS,EAC7C,OAAW,CACT,CAAEE,CACJ,IAAK,OAAO,QAAQgB,EAAW,eAAe,EAAG,CAC/C,GAAM,CACJO,EACAK,CACF,EAAI5B,EACJ,GAAI4B,IAAgB9B,EAAO,CACzB,IAAM+B,EAAWL,EACfC,GAAMH,CAAI,EACTC,EAAyB,YAC1B,CACE,KAAM,EACR,CACF,EACAA,EAAU,QAAQM,CAAQ,CAC5B,CACF,CAIJ,OAAOtB,CACT,CAEA,SAASK,GACPd,EACAI,EACAL,EACkC,CAOlC,IAAMiC,EAAoB5B,EAAa,IAAIJ,EAAM,WAAW,MAAM,EAE9DwB,EADWxB,EAAM,WAAW,QACb,OAAS,GAEvBwB,IACHA,EAAOS,GAAY,MAAM,KAAKlC,EAAM,KAAK,CAAC,EAAG,KAAK,GAGhDiC,EACFR,EAAOQ,EACEjC,EAAM,IAAIyB,CAAI,IACvBA,EAAOS,GAAY,MAAM,KAAKlC,EAAM,KAAK,CAAC,EAAGyB,CAAI,GAGnDzB,EAAM,IAAIyB,EAAMxB,CAAK,EAErB,IAAIS,EACJ,OAAKuB,IACH5B,EAAa,IAAIJ,EAAM,WAAW,OAAQwB,CAAI,EAC9Cf,EAAM,IAAIE,GAAQ,CAChB,KAAMX,EAAM,WACZ,MAAO,IAAIkC,EAAe,CACxB,KAAMC,EAAaX,CAAI,CACzB,CAAC,CACH,CAAC,GAGI,CACLA,EACAf,CACF,CACF,CClPO,SAAS2B,GACdC,EACAC,EAEI,CAAC,EACF,CACH,GAAM,CACJ,oBAAAC,EAAsB,EACxB,EAAID,EAEJ,OAAAD,EAAaG,GAAUH,EAAY,CACjC,oBAAAE,CACF,CAAC,EACDF,EAAaI,GAAmBJ,EAAY,CAC1C,oBAAAE,CACF,CAAC,EAEMF,CACT,CAEA,IAAMK,GAA4B,CAChCC,EACAC,EACAC,GACAC,GACAC,EACF,EAIA,SAASP,GACPH,EACAC,EACG,CACH,GAAM,CACJ,oBAAAC,CACF,EAAID,EACEU,EAAS,MAAM,KAAKC,EAAcZ,CAAU,CAAC,EAI7Ca,EAAgB,IAAI,IAE1B,QAAWC,KAAcH,EACvB,OAAW,CACT,CAAEI,CACJ,IAAK,OAAO,QAAQD,EAAW,eAAe,EAAG,CAC/C,GAAM,CACJE,EACAC,CACF,EAAIF,EACJ,GAAIE,aAAuBC,GAASD,EAAY,MAAO,CACrD,IAAIE,EAAYN,EAAc,IAAII,CAAW,EACxCE,IACHA,EAAY,CACZ,EACAN,EAAc,IAAII,EAAaE,CAAS,GAE1CA,EAAU,KAAK,CACbL,EACAG,EACAD,CACF,CAAC,CACH,CACF,CAIF,IAAMI,EAAsD,CAC5D,EACA,OAAW,CACT,CAAEC,CACJ,IAAKR,EACCQ,EAAW,SAAW,GACxBD,EAAsB,KAAKC,EAAW,CAAC,CAAC,EAI5C,OAAW,CACTP,EACAQ,EACAN,CACF,IAAKI,EAAuB,CAE1B,IAAMG,EAAaP,EAAM,aAAkCQ,EAAUC,CAAQ,EAC7E,GAAIF,GAAcG,GAAUZ,EAAYQ,EAAY,CAClD,oBAAApB,CACF,EAAGqB,CAAU,EAAG,CACd,IAAMI,EAAQX,EAAM,YACpBY,GAAmBd,EAAYQ,EAAYK,CAAK,EAChDE,GAAUf,EAAYQ,EAAYN,EAAmCW,CAAK,EAC1EG,GAAiBhB,EAAYQ,EAAYK,CAAK,EAC9CI,GAAWjB,EAAYQ,CAAU,EACjCU,GAAWlB,EAAYQ,EAAYC,CAAU,EAC7CU,GAAWnB,EAAYQ,EAAYC,CAAU,EAC7CW,GAAWpB,EAAYQ,CAAU,EACjCa,GAAOb,CAAU,EACjBR,EAAW,WAAW,CACxB,CACF,CAEA,OAAOd,CACT,CAEA,SAASI,GACPJ,EACAC,EACG,CACH,GAAM,CACJ,oBAAAC,CACF,EAAID,EACJ,QAAWa,KAAcF,EAAcZ,CAAU,EAC/C,QAAWoC,KAAYtB,EAAW,cAAe,CAE/C,IAAMS,EAAaa,EAAS,aAAkCZ,EAAUC,CAAQ,EAE1EE,EAAQS,EAAS,YACjBd,EAAaR,EAAW,QAAQ,IAAIa,CAAK,EAG7CL,aAAsBJ,GACnBK,GACAG,GAAUZ,EAAYQ,EAAY,CACnC,oBAAApB,CACF,EAAGqB,CAAU,IAEbK,GAAmBd,EAAYQ,EAAYK,CAAK,EAChDE,GAAUf,EAAYQ,EAAYc,EAAUT,CAAK,EACjDG,GAAiBhB,EAAYQ,EAAYK,CAAK,EAC9CI,GAAWjB,EAAYQ,CAAU,EACjCU,GAAWlB,EAAYQ,EAAYC,CAAU,EAC7CU,GAAWnB,EAAYQ,EAAYC,CAAU,EAC7CW,GAAWpB,EAAYQ,CAAU,EACjCR,EAAW,WAAW,EAE1B,CAGF,OAAOd,CACT,CAEA,SAAS0B,GACPZ,EACAQ,EACArB,EACAsB,EACS,CACT,GAAM,CACJ,oBAAArB,CACF,EAAID,EACEoC,EAAcf,EAAW,WAAW,OAAO,EAGjD,SAASgB,GAAoD,CAC3D,IAAMC,EAAgB,IAAI,IAC1B,GAAI,EAAEF,aAAuBG,GAC3B,MAAO,GAET,IAAMC,EAAkBJ,EAExB,QAAWK,KAAKD,EAAgB,QACxBC,aAAaC,GAGfD,EAAE,KAAKE,EAAU,GACnBL,EAAc,IAAIG,EAAE,WAAW,EAInC,IAAMG,EAAkBtB,EAAW,YAC7BuB,EAAwC,CAC9C,EAEA,QAAWC,KAAUjC,EAAW,QAEAiC,EAAO,aACnCC,EACAC,GACAC,GACAzB,EACA0B,GACAC,CACF,IAAM,QAGJN,EAAwB,KAAKC,CAAM,EAQvC,MAAO,GAJ+BD,EAAwB,OAC3DC,GAAWA,EAAO,QAAUF,GAAmBN,EAAc,IAAIQ,EAAO,IAAI,CAC/E,EAEyC,MAC3C,CAGA,SAASM,GAA8C,CACrD,GAAI,EAAE9B,aAAsBE,GAC1B,MAAO,GAGT,IAAME,EAAQJ,EAAW,YACnB+B,EAAK/B,EAAW,KAAK,GAE3B,GAAI,CAAC+B,EACH,MAAO,GAGT,IAAMjC,EAAa,MAAM,KAAKiC,EAAG,QAAQhD,CAAU,CAAC,EACjD,OAAQiD,GAAMA,EAAE,QAAU5B,CAAK,EAC/B,IAAK4B,GAAMA,EAAE,IAAI,EAEdC,EAAYlC,EAAW,WAAW,UAAU,MAAM,EAExD,GAAI,CAACkC,EACH,MAAO,GAGT,IAAMC,EAAiBD,EAAU,YAEjC,GAAI,EAAElC,EAAW,sBAAsBkB,GACrC,MAAO,GAGT,IAAMC,EAAkBnB,EAAW,WAC7BoC,EAAmB,IAAI,IAE7B,QAAWhB,KAAKD,EAAgB,QACxBC,aAAaC,GAGnBe,EAAiB,IAAIhB,EAAE,YAAaA,CAAC,EAGvC,OAAOrB,EAAW,KAAMsC,GAAc,CACpC,IAAMC,EAAaF,EAAiB,IAAIC,CAAS,EACjD,OAAKC,EAGW,MAAM,KAAKA,EAAW,QAAQtD,CAAU,CAAC,EAC1C,KAAMuD,GAAQA,EAAI,QAAUJ,CAAc,EAHhD,EAIX,CAAC,CACH,CAGA,SAASK,GAAwB,CAC/B,IAAMC,EAAMzC,EAAW,WAAW,OAC9B0C,EAA+BlD,EAAW,WAAW,OAEzD,KAAOkD,GAAM,CACX,GAAIA,IAASD,EACX,MAAO,GAETC,EAAOA,EAAK,MACd,CACA,MAAO,EACT,CAGA,GAAI,EAAElD,EAAW,sBAAsB0B,GACrC,MAAO,GAGT,IAAMyB,EAAkBnD,EAAW,WAMnC,GAJImD,EAAgB,QAIhB,EAAE5B,aAAuBG,GAC3B,MAAO,GAGT,IAAMC,EAAkBJ,EAGxB,QAAW6B,KAAOC,EAAQ,gBACxB,GAAI1B,EAAgB,UAAUyB,CAAG,EAC/B,MAAO,GAQX,GAJI,CAACzB,EAAgB,KAAK,MAItB,EAAI3B,EAAW,OAAO,OACxB,MAAO,GAIT,QAAWsD,KAAK3B,EAAgB,KAAK,aAAe,CACpD,EACE,GAAM2B,aAAazB,IAGfyB,EAAE,KAAKhB,CAAW,GAAKgB,EAAE,KAAK5B,CAAU,GAAK4B,EAAE,KAAKC,EAAW,GACjE,MAAO,GAQX,GAJInE,GAAuB,EAAI,OAAO,KAAKY,EAAW,eAAe,EAAE,QAInES,aAAsBE,GAAYgB,EAAgB,KAAK,OAAS,EAAIA,EAAgB,KAAK,MAAM,OACjG,MAAO,GAGT,IAAM6B,EAAW/C,aAAsBE,EAAWF,EAAW,KAAK,KAAO,OAEzE,GACEA,aAAsBE,GACnBgB,EAAgB,KAAK,QACpB6B,IAAa,QAAqBA,IAAa,QAAqBA,IAAa,SAErF,MAAO,GAGT,IAAMC,EAAaN,EAAgB,KAAK,MA6BxC,MA1BE,EAAA1C,aAAsBC,GACnBiB,EAAgB,KAAK,OACrB8B,GACAA,EAAW,KAAMC,GAAMC,EAAaD,EAAG/C,CAAQ,IAAM+C,EAAE,KAAK,OAAS,QAAqBA,EAAE,KAAK,OAAS,QAAmB,GAK9HnB,EAAkC,GAIlCf,EAAwC,GAIxCwB,EAAY,GAIZrB,EAAgB,KAAK,OAAS3B,EAAW,SAI3B4D,EAAOjC,EAAgB,KAAK,aAAe,CAC7D,EAAG,CAAC,YACqBkC,GAK3B,CAEA,SAAS/C,GAAoBd,EAAmBQ,EAAmBK,EAAqB,CACtF,IAAMiD,EAAa,IAAI,IAAI,OAAO,KAAKtD,EAAW,eAAe,CAAC,EAC5DuD,EAAa,IAAI,IAAI,OAAO,KAAK/D,EAAW,eAAe,CAAC,EAC5DgE,EAAY,IAAI,IAAI,MAAM,KAAKF,CAAU,EAAE,OAAQG,GAAMF,EAAW,IAAIE,CAAC,CAAC,CAAC,EACjFD,EAAU,OAAOnD,CAAK,EAEtB,IAAMqD,EAAQ,IAAI,IAAI,CACpB,GAAGH,EACH,GAAGD,CACL,CAAC,EAED,QAAWK,KAAYH,EAAW,CAChC,IAAMI,EAAUC,GAAY,MAAM,KAAKH,CAAK,EAAGC,CAAQ,EAEjDlE,EAAcO,EAAW,gBAAgB2D,CAAQ,EACvD,GAAI,CAAClE,EACH,SAGF,GAAM,CACJqE,CACF,EAAIrE,EACEsE,EAAWC,EAAaJ,CAAO,EAEjCE,aAAkBG,EAChBH,EAAO,MACTA,EAAO,UAAU,QAASC,CAAQ,EAElCD,EAAO,QAAQzD,EAAUyD,EAAQC,EAAU,CACzC,KAAM,EACR,CAAC,CAAC,EAEKD,GAAQ,kBAAkBI,GACnCJ,EAAO,OAAO,UAAU,QAAS,IAAIK,EAAe,CAClD,KAAMJ,CACR,CAAC,CAAC,EAGJ,QAAWtC,KAAUzB,EAAW,cAAc2D,CAAQ,EACpDlC,EAAO,UAAU,QAASuC,EAAaJ,CAAO,CAAC,EAGjD5D,EAAW,aAAa2D,EAAUC,CAAO,EACzCF,EAAM,IAAIE,CAAO,CACnB,CACF,CAEA,SAASrD,GACPf,EACAQ,EACAoE,EACA/D,EACM,CAEN,IAAMgE,EADOrE,EAAW,WAAW,UAAU,MAAM,EAC1B,KAAK,KAE9BqE,EAAY,UAAU,QAASD,EAAc,KAAK,KAAK,EACvDA,EAAc,QAAQC,CAAW,EAGjC,QAAWC,KAAY9E,EAAW,UAAW,CAC3C,IAAM+E,EAAS,MAAM,KAAKD,EAAS,QAAQL,CAAS,CAAC,EACrD,QAAWvE,KAAS6E,EACd7E,EAAM,cAAgB0E,EAAc,aACtC1E,EAAM,UAAU,OAAQsE,EAAaK,EAAY,WAAW,CAAC,CAGnE,CAEA7E,EAAW,aAAaa,CAAK,EAC7B,IAAMmE,EAAoBxE,EAAW,QAAQ,IAAIqE,EAAY,WAAW,EACpEG,IAAsB,QACxBhF,EAAW,UAAU6E,EAAY,YAAaG,CAAiB,CAEnE,CAEA,SAAS9D,GAAYlB,EAAmBQ,EAAmBC,EAA8B,CACvF,IAAMwE,EAAuB,CAC7B,EAEMC,EAAQ1E,EAAW,WAAW,UAAU,OAAO,EAErD,GAAI0E,EACF,QAAWC,KAAQD,EAAO,CACxBD,EAAS,KAAKE,CAAI,EAClB,IAAMC,EAAa5E,EAAW,QAAQ,IAAI2E,EAAK,WAAW,EACtDC,GACFpF,EAAW,UAAUmF,EAAK,YAAaC,CAAU,CAErD,CAGF,GAAI,EAAIH,EAAS,OAAQ,CACvB,IAAMxB,EAAczD,EAAW,WAAW,UAAU,OAAO,GAAgC,CAC3F,EAGIqF,EACA5E,aAAsBC,EACxB2E,EAAW,EAEXA,EAAW5B,EAAW,QAAQhD,CAAU,EAAI,EAG9CgD,EAAW,OAAO4B,EAAU,EAAG,GAAGJ,CAAQ,EACzCjF,EAAW,WAA0B,UAAU,QAASyD,CAAU,CACrE,CACF,CAEA,SAASzC,GAAkBhB,EAAmBQ,EAAmBK,EAAqB,CAEpF,IAAMyE,EAAe,IAAI,IAEzB,QAAWrD,KAAUjC,EAAW,QAC9B,GAAIiC,EAAO,QAAUpB,EAAO,CAC1B,IAAM0E,EAAOtD,EAAO,KAChBuD,EAAaF,EAAa,IAAIC,CAAI,EACjCC,IACHA,EAAa,CACb,EACAF,EAAa,IAAIC,EAAMC,CAAU,GAEnCA,EAAW,KAAKvD,CAAM,CACxB,CAIF,GAAI,EAAEzB,EAAW,sBAAsBkB,GACrC,OAGF,IAAMC,EAAkBnB,EAAW,WAEnC,QAAWiF,KAAQ9D,EAAgB,KAAK,aAAe,CACvD,EAAG,CACD,GAAI,EAAE8D,aAAgB5D,GACpB,SAGF,IAAM6D,EAAiBD,EAAK,YAE5B,GAAI,CAACC,EACH,SAGF,IAAMC,EAAmBL,EAAa,IAAII,CAAc,GAAK,CAC7D,EAEME,EAAgBH,EAAK,QAAQ,EAC7BI,EAAqB,CAACtG,GAA0B,KAAMuG,GAAQF,aAAyBE,CAAG,EAC1FC,EAAWH,EAAc,SAE/B,QAAW3D,KAAU0D,EAAkB,CACrC,IAAMK,EAAS/D,EAAO,OAGtB,GAAI8D,GAAYC,aAAkB7D,GAAW,CAC3CF,EAAO,QAAQuC,EAAavC,EAAO,IAAI,CAAC,EACxC,QACF,CAEA,IAAIgE,EAAkBL,EAIpBI,IACIA,aAAkBE,IAAaF,aAAkBG,IAClDN,IAEHI,EAAkBG,GAAUH,EAAiB,CAC3C,KAAM,EACR,CAAC,GAICD,aAAkBtE,GAAcO,EAAO,OAASgE,EAAgB,OAClEA,EAAkBpF,EAAUoF,EAAiBhE,EAAO,KAAM,CACxD,KAAM,EACR,CAAC,GAGHA,EAAO,QAAQgE,EAAgB,KAAK,CAAC,CACvC,CACF,CACF,CAEA,SAAS9E,GAAYnB,EAAmBQ,EAAmBC,EAA8B,CACvF,IAAM4F,EAAQ7F,EAAW,WAAW,UAAU,OAAO,EAErD,GAAI,CAAC6F,EACH,OAGF,IAAMC,EAAYD,EAAM,KAAK,KAC7B,GAAI,EAAEC,aAAqBzE,GACzB,OAGF,IAAM0E,EAAkBvG,EAAW,WAEnC,GAAIS,aAAsBE,EAAU,CAElC,IAAM6F,EAAOD,EAAgB,KAAK,KAC5BE,EAAU,IAAI,IAEhBD,GACFC,EAAQ,IAAID,EAAK,WAAW,EAG9B,IAAMtB,EAAQqB,EAAgB,KAAK,MACnC,GAAIrB,EACF,QAAWC,KAAQD,EAAO,CACxB,IAAMZ,EAASa,EAAK,YAEpB,GADAsB,EAAQ,IAAInC,CAAM,EACdA,IAAW7D,EAAW,YACxB,KAEJ,CAGF,IAAMiG,EAAcC,GAAiBL,CAAS,EAG9C,GAF2B,MAAM,KAAKI,CAAW,EAAE,MAAOE,GAAMH,EAAQ,IAAIG,CAAC,CAAC,EAEtD,CACtBnG,EAAW,GAAG6F,EAAW,CACvB,KAAM,EACR,CAAC,EACD,MACF,CACF,CAEAC,EAAgB,MAAMD,EAAW,CAC/B,KAAM,EACR,CAAC,CACH,CAEA,SAASrF,GAAYjB,EAAmBQ,EAAyB,CAC/D,IAAM2C,EAAkBnD,EAAW,WAGjCmD,EAAgB,KAAK,OAClBA,EAAgB,KAAK,UACrBA,EAAgB,KAAK,QACrBA,EAAgB,KAAK,OACrB,OAAO,KAAKnD,EAAW,eAAe,EAAE,SAAW,GAKzCmD,EAAgB,KAAK,aAAa,KAAMsC,GAC/CA,aAAgB5D,EAGf4D,EAAK,KAAKnD,CAAW,IAAM,OAFzB,EAGV,GAMDa,EAAgB,UAAU,QAAS3C,EAAW,WAAW,UAAU,OAAO,CAAC,CAC7E,CAEA,SAASY,GAAYpB,EAAmBQ,EAAyB,CAC/D,IAAMqG,EAAiBrG,EAAW,WAAW,UAAU,MAAM,EAE7D,GAAI,CAACqG,EACH,OAGF,IAAM1D,EAAkBnD,EAAW,WAC7B8G,EAAiB3D,EAAgB,KAAK,KAE5C,GAAI2D,EAAgB,CAClB,IAAMC,EAAuBF,EAAe,KAAK,YACjD,QAAWG,KAAkBD,GAAwB,CACrD,EACMC,aAA0BnF,GAC5BiF,EAAe,OAAO,cAAeE,CAAc,CAGzD,MACE7D,EAAgB,UAAU,OAAQ0D,CAAc,CAEpD,CAEA,SAASxF,GAAQb,EAAyB,CACxC,IAAMyC,EAAMzC,EAAW,WAAW,OAClC,GAAI,CAACyC,EACH,OAGF,IAAMgE,EAAQhE,EAAI,OAClB,GAAI,CAACgE,EACH,OAGsBA,EAAM,KAAK,aACd,SAAW,EAC9BA,EAAM,IAAI,EAEVhE,EAAI,IAAI,CAEZ,CC/pBO,SAASiE,GACdC,EACAC,EAEI,CAAC,EACF,CACH,GAAM,CACJ,QAASC,CACX,EAAID,EACEE,EAAOC,EAAWJ,CAAU,EAE5BK,EAAUC,EAAQ,WAAWJ,CAAU,EAEvCK,EAA2BF,EAAQ,YAA+B,2BAExE,GAAIF,EAAM,CACR,IAAMK,EAAgBL,EAAK,SAAS,EAEpC,QAAWM,KAAS,MAAM,KAAKN,EAAK,SAAS,CAAC,EAAE,QAAQ,EAAG,CACzD,IAAMO,EAASD,EAAM,WACfE,EAAcD,EAAO,UAAU,OAAO,EAE5C,GAAIC,EAAa,CACf,IAAIC,EAAkBH,EAAM,gBACtBI,EAAQH,EAAO,UAAU,OAAO,EAChCI,EAAY,IAAI,IAElBD,GACFA,EAAM,QAAQ,CAACE,EAAMC,IAAM,CACzB,IAAMC,EAAOF,EAAK,YACdE,GACFH,EAAU,IAAIG,EAAMD,CAAC,CAEzB,CAAC,EAKH,IAAIE,EAAkB,GACtB,OAAW,CACTC,EACAC,CACF,IAAK,OAAO,QAAQR,CAAe,EAAG,CACpC,GAAM,CACJS,CACF,EAAID,EACJ,GAAI,CAACC,EAAM,SAEX,IAAMC,EAASD,EAAK,aAAkCE,EAAUC,CAAQ,EAExE,GAAIF,aAAkBC,EAAU,CAE9B,GADmBD,EACJ,KAAK,OAAS,QAAoB,CAC/CV,EAAkB,CAChB,CAACO,CAAC,EAAGC,CACP,EACA,KACF,CACA,GAAIC,aAAgBI,IAAclB,EAAyB,CACzDW,EAAkB,GAClB,KACF,CACF,CACF,CAEA,GAAIA,EAAiB,CACnB,IAAMQ,EAAYf,EAAY,KAAK,KAC/Be,aAAqBC,GACvBC,GAASF,EAAWd,EAAiBJ,EAAeH,EAASS,CAAS,CAE1E,CACF,CAIA,IAAMD,EAAQH,EAAO,UAAU,OAAO,EACtC,GAAIG,EACF,QAAWE,KAAQF,EAAO,CACxB,IAAMI,EAAOF,EAAK,YAClB,GAAIE,GAAQA,KAAQR,EAAM,gBAAiB,CACzC,IAAMoB,EAAWd,EAAK,KAAK,GAC3Ba,GACEC,EACA,CACE,CAACZ,CAAI,EAAGR,EAAM,gBAAgBQ,CAAI,CACpC,EACAT,EACAH,CACF,CACF,CACF,CAEJ,CACF,CAEA,OAAOL,CACT,CAEA,SAAS4B,GACPE,EACAC,EACAvB,EACAH,EACAS,EACM,CACN,GAAI,CAACgB,EACH,OAGF,IAAME,EAAaC,GAASH,EAAW,CACrC,QAAAzB,CACF,CAAC,EACDyB,EAAYA,EAAU,QAAQE,CAAU,EACxC,IAAME,EAAUC,GAAWL,CAAS,GAAK,CAACK,GAAWL,EAAW,CAC9D,IAAK,EACP,CAAC,EAEKM,GAAcF,EAAUJ,aAAqBO,GAAUP,aAAqBQ,IAC9E,MAAM,KAAKR,EAAU,QAAQ,CAAC,EAC9B,CACAA,CACF,EAEEI,EACFK,GAAYH,EAAYL,EAASvB,EAAeM,CAAS,EAEzD0B,GAAYJ,EAAYL,EAASvB,CAAa,CAElD,CAEA,SAAS+B,GACPH,EACAL,EACAvB,EACAM,EACM,CAIN,IAAM2B,EAAe3B,GAAa,IAAI,IAEtC,QAAW4B,KAAaN,EAAY,CAClC,IAAMO,EAAQC,GAAkBF,EAAWX,EAASvB,CAAa,EAEjE,OAAW,CACTS,EACAI,CACF,IAAK,OAAO,QAAQsB,CAAK,EACvB,GAAItB,aAAgBE,EAAU,CAC5B,IAAMsB,EAAkBC,GAAiBJ,EAAW,CAClD,QAASzB,CACX,CAAC,EAGK8B,EAAYN,EAAa,IAAIxB,CAAI,GAAK,GAM5C,GALgB,MAAM,KAAK4B,CAAe,EAAE,MAAOG,IAC9BP,EAAa,IAAIO,CAAK,GAAK,IAC1BD,CACrB,EAEY,CACXL,EAAU,QAAQO,EAAS,CAAC,EAC5B5B,EAAK,GAAGqB,EAAW,CACjB,KAAM,EACR,CAAC,EACD,KACF,CACF,SAAWrB,aAAgB6B,EAAY,CACrCR,EAAU,QAAQO,EAAS,CAAC,EAC5B,IAAME,EAAiBC,GAAe/B,EAAMqB,CAAS,EAEjDW,GAAYF,EAAgBG,CAAW,EAEzCjC,EAAK,OAAO8B,EAAgB,CAC1B,KAAM,EACR,CAAC,EAED9B,EAAK,MAAM8B,EAAgB,CACzB,KAAM,EACR,CAAC,CAEL,CAEJ,CACF,CAEA,SAASX,GACPJ,EACAL,EACAvB,EACM,CAON,IAAM+C,EAAiB,IAAI,IAE3B,QAAWC,KAAKpB,EAAY,CAC1B,IAAIqB,EAAUX,GAAiBU,CAAC,EAEhC,QAAWE,KAAKtB,EAAY,CAC1B,IAAMuB,EAAUb,GAAiBY,CAAC,EAClCD,EAAU,IAAI,IAAI,MAAM,KAAKA,CAAO,EAAE,OAAQG,GAAMD,EAAQ,IAAIC,CAAC,CAAC,CAAC,CACrE,CAEA,QAAWZ,KAASS,EAClBF,EAAe,IAAIP,CAAK,CAE5B,CAEA,IAAMa,EAAa,IAAI,IAEnBlB,EAAQ,CAAC,EAGb,QAAWK,KAAS,MAAM,KAAKO,CAAc,EAAE,KAAK,EAAG,CACrD,QAAWb,KAAaN,EAAY,CAGlC,GAFAO,EAAQC,GAAkBF,EAAWX,EAASvB,CAAa,EAEvD,EAAEwC,KAASL,GACb,SAGF,IAAMmB,EAAWD,EAAW,IAAIb,CAAK,EACrCa,EAAW,IAAIb,EAAOc,EAClBC,GAAO,CACPD,EACApB,CACF,CAAC,EACCA,CAAS,CACf,CAEA,OAAW,CACTzB,EACAI,CACF,IAAK,OAAO,QAAQsB,CAAK,EAAG,CAC1B,IAAMb,EAAY+B,EAAW,IAAI5C,CAAI,EACrC,GAAKa,GAIL,GAAIT,aAAgBE,EAClBF,EAAK,GAAGS,EAAW,CACjB,KAAM,EACR,CAAC,UACQT,aAAgB6B,EAAY,CACrC,IAAMC,EAAiBC,GAAe/B,EAAMS,CAAS,EAEjDuB,GAAYF,EAAgBG,CAAW,EAEzCjC,EAAK,OAAO8B,EAAgB,CAC1B,KAAM,EACR,CAAC,EAED9B,EAAK,MAAM8B,EAAgB,CACzB,KAAM,EACR,CAAC,CAEL,EACF,CACF,CACF,CAEA,SAASP,GACPF,EACAX,EACAvB,EAC4B,CAC5B,IAAMmC,EAAoC,CAAC,EACrCqB,EAASlB,GAAiBJ,CAAS,EACnCuB,EAAiBvB,EAAU,aAAmCnB,EAAU2C,CAAS,YAAaA,EAEpG,QAAWlB,KAAS,MAAM,KAAKgB,CAAM,EAAE,KAAK,EAAG,CAC7C,IAAMG,EAAcpC,EAAQiB,CAAK,EACjC,GAAI,CAACmB,EACH,SAGF,IAAI9C,EAAO8C,EAAY,CAAC,EAClB,CACJ,CAAE/C,CACJ,EAAI+C,EASJ,GALI9C,GAAQ4C,IACV5C,EAAOA,EAAK,aAAkCE,EAAUC,CAAQ,GAI9DH,aAAgBG,GAAY,EAAEJ,aAAkBgD,GAAY,CAC9D,IAAMC,EAAQC,IAAkBlD,aAAkBmD,EAAQnD,EAAO,OAAUA,EAAsB,QAAQ,OAAO,WAAYO,CAAU,GAAG,UAAU,MAAM,EACzJ,GAAI0C,aAAiBG,GAAYH,GAAO,UACtC,MAAO,CAAC,EAEVhD,EAAOD,aAAkBmD,EAAQnD,EAAO,WAAcA,EAAsB,KAAK,UACnF,CAEA,GAAIC,aAAgBE,EAAU,CAC5B,IAAMkD,EAAOpD,EAAK,KAClB,GAAIoD,GAAQA,IAAS,QACnB,MAAO,CAAC,EAEV9B,EAAMK,CAAK,EAAI3B,CACjB,SAAWA,aAAgB6B,GAAcc,EAAO,OAAS,EAAG,CAE1D,IAAMU,EAAsBrD,EAAK,QAAQ,KAAMsD,GACvCA,aAAehD,EAGdgD,EAAI,KAAKC,EAAU,IAAM,OAFvB,EAGV,EAEKC,EAAW,EAAQxD,EAAK,KAAK,MAG7ByD,EAAWtE,EAAc,IAAIY,CAAM,GAAK,EAE1C,CAACyD,GAAYC,EAAW,GAAK,CAACJ,IAChC/B,EAAMK,CAAK,EAAI3B,EAEnB,CACF,CAEA,OAAOsB,CACT,CAEA,SAASS,GAAgBhC,EAAoBsB,EAAmC,CAC9E,IAAMqC,EAAU,IAAI,IAEpB,QAAWrE,KAAUU,EAAO,QAC1B,GAAMV,aAAkBiB,EAIxB,GAAIjB,aAAkBsE,EAAW,CAC/B,IAAMC,EAAYvE,EAAO,KAAK,KAC1BuE,aAAqBtD,GACvBoD,EAAQ,IAAIrE,EAAO,MAAOuE,CAAS,CAEvC,MACEF,EAAQ,IAAIrE,EAAO,KAAMA,CAAM,EAInC,SAASwE,EAAcC,EAAgC,CACrD,GAAIA,aAAkBC,EAAY,CAChC,IAAMC,EAAcN,EAAQ,IAAII,EAAO,IAAI,EAC3C,GAAIE,EACF,OAAOA,EAAY,KAAK,CAE5B,CACA,OAAOF,CACT,CAEA,OAAOzC,EAAU,UAAUwC,CAAY,CACzC,CChWO,IAAMI,GAAN,MAAMC,CAAS,CAUpB,YAAaC,EAAcC,EAAgBC,EAAmC,CAAC,EAAG,CAChF,GAAM,CACJ,YAAAC,EAAc,EAChB,EAAID,EACJ,KAAK,MAAQF,EACb,KAAK,OAASC,EACd,KAAK,QAAUA,EAAO,SAAW,IAAIG,EACrC,KAAK,YAAcD,EACnB,KAAK,sBAAwB,IAAIE,EACnC,CAQA,SAAUC,EAAqD,CAC7D,IAAMC,EAAa,OAAOD,GAAW,SAAWA,EAASA,EAAO,KAE5DE,EAAY,KAAK,wBAAwBD,CAAU,EAEvD,GAAI,CAACC,GAAa,OAAOF,GAAW,SAAU,CAC5C,IAAMG,EAAc,KAAK,qBAAqBH,CAAM,EACpD,GAAIG,EACF,GAAI,CACF,IAAMC,EAAmB,KAAK,0BAA0BD,CAAW,EACnED,EAAY,KAAK,wBAAwBD,EAAYG,CAAgB,CACvE,OAASC,EAAG,CACV,GAAI,EAAEA,aAAaC,GAAgB,MAAMD,CAE3C,CAEJ,CAEA,GAAI,CAACH,GAAa,KAAK,YAAa,CAClC,IAAMK,EAAmB,KAAK,oBAAoB,EAC5CC,EAAiC,CACvC,EACA,OAAW,CACTC,EACAC,CACF,IAAKH,GACC,CAACG,GAAWA,EAAQ,SAAW,GAAKA,EAAQ,SAAS,GAAG,IAC1DF,EAAqB,KAAKC,CAAM,EAGhCD,EAAqB,SAAW,IAClCN,EAAYM,EAAqB,CAAC,EAEtC,CAEA,GAAI,CAACN,EACH,OAGF,IAAMS,EAAiB,KAAK,MAAM,gBAAgBT,CAAS,EAC3D,GAAI,CAACS,EACH,OAAOC,EAAaV,CAAS,EAG/B,GAAM,CACJW,CACF,EAAIF,EAEAG,EAAsCD,EAC1C,GAAIC,aAAuBC,GACzB,KAAOD,GAAeA,EAAY,QAAUZ,GAC1CY,EAAcA,EAAY,OAI9B,GAAIA,EAAa,CACf,IAAME,EAAYF,EAAY,UAAU,OAAO,EAC/C,GAAIE,aAAqBC,IAAeD,EAAU,KAAK,gBAAgBE,GAAkB,OAAOF,EAAU,KAAK,MAAS,UACtH,OAAOJ,EAAaI,EAAU,KAAK,IAAI,CAE3C,CAEA,OAAOJ,EAAaV,CAAS,CAC/B,CAKA,IAAI,YAA2B,CAC7B,GAAI,CAAC,KAAK,gBAAiB,CACzB,KAAK,gBAAkB,IAAI,IAC3B,QAAWQ,KAAW,KAAK,oBAAoB,EAAE,OAAO,EACtD,QAAWV,KAAUU,EACnB,KAAK,gBAAgB,IAAIV,CAAM,CAGrC,CACA,OAAO,KAAK,eACd,CAQA,0BAA2BmB,EAAkC,CAC3D,GAAIA,aAAsBC,EACxB,OAAQD,EAA0B,aAGpC,GAAIA,aAAsBE,EAAc,CACtC,IAAMC,EAAeH,EAAW,KAAK,KACrC,GAAIG,aAAwBC,GAC1B,OAAO,KAAK,0BAA0BD,CAAY,CAEtD,CAEA,GAAI,EAAEH,aAAsBI,IAC1B,MAAM,IAAI,MAAM,0BAA0BJ,CAAU,EAAE,EAGxD,IAAMK,EAAQL,EACRM,EAAeD,EAAM,KAAK,GAChC,GAAIC,EACF,OAAOA,EAAa,IAAKC,GAAQA,EAAI,IAAI,EAG3C,IAAMC,EAAOH,EAAM,KAAK,KAClBI,EAAOJ,EAAM,KAAK,KAExB,GAAIG,GAAQC,EAAM,CAChB,IAAMC,EAAWL,EAAM,KAAK,KACtBM,EAAYN,EAAM,KAAK,WAE7B,GAAI,CAACK,GAAY,CAACC,EAChB,MAAO,CACP,EAGF,IAAMC,EAAO,KAAK,0BAA0BF,CAAsB,EAC5DG,EAAQ,KAAK,0BAA0BF,CAAuB,EAEpE,GAAIH,IAAS,OACX,OAAOI,EACF,GAAIJ,IAAS,OAAmB,CACrC,IAAMM,EAAW,CACf,GAAGF,EACH,GAAGC,CACL,EACA,OAAO,MAAM,KAAK,IAAI,IAAIC,CAAQ,CAAC,CACrC,SAAWL,IAAS,QAA4B,CAC9C,IAAMM,EAAU,IAAI,IAAIH,CAAI,EACtBI,EAAW,IAAI,IAAIH,CAAK,EAC9B,OAAO,MAAM,KAAKE,CAAO,EAAE,OAAQR,GAAQS,EAAS,IAAIT,CAAG,CAAC,CAC9D,CACF,CAEA,OAAOP,EAAW,YACpB,CASA,iBAAkBiB,EAAcxC,EAAmC,CAAC,EAAa,CAC/E,GAAM,CACJ,YAAAyC,EAAc,EAChB,EAAIzC,EACJ,GAAI,KAAK,sBAAsB,IAAIwC,EAAMC,CAAW,EAClD,OAAO,KAAK,sBAAsB,IAAID,EAAMC,CAAW,GAAK,CAC5D,EAGF,IAAM5B,EAAS,KAAK,MAAM,QAAQ,IAAI2B,CAAI,EAC1C,GAAI,CAAC3B,EACH,MAAM,IAAIH,EAAc,kBAAkB8B,CAAI,EAAE,EAGlD,IAAI1B,EAAoB,CACxB,EAEA,GAAID,aAAkB6B,EACpB5B,EAAU,KAAK,OAAO,cAAcD,EAAQ,CAC1C,YAAA4B,CACF,CAAC,GAAK,CACN,UACS5B,aAAkB8B,EAAO,CAClC,IAAMC,EAAa/B,EAAO,WAC1B,GAAI+B,aAAsBC,IAAcD,aAAsBE,IAG5D,GAFAhC,EAAU8B,EAAW,aAEjB,KAAK,QAAQ,aAAa,oBAAsBA,aAAsBE,GAAY,CACpF,IAAMC,EAASH,EAEf,GAAI,CAACG,EAAO,MAAQC,GAAOD,EAAO,cAA8B,EAAG,CACjE,IAAME,EAAoBF,EAAO,KAAK,YAChCG,EAAaC,EAAOF,GAAqB,CAC/C,EAAG,CAAC,EACJ,GAAIC,aAAsBE,GAAc,KAAK,MAAM,OAAQ,CACzD,IAAMC,EAAU,KAAK,oBAAoBH,CAAU,EACnD,GAAIG,GAAS,cAA6B,EAAG,CAC3C,IAAMC,EAAeD,EAAQ,KAAK,YAC9BC,GAAgB,EAAIA,EAAa,OACnCP,EAAO,KAAOO,EAAa,CAAC,EAAE,KAAK,EAEnCP,EAAO,KAAOM,EAAQ,KAAK,CAE/B,CACF,CACF,CAEA,GAAIN,EAAO,eAA8B,EACvC,QAAWQ,KAAUR,EAAO,gBAAgB1B,EAAa0B,EAAO,KAAK,KAAK,YAAc,SAAc,CACtG,EACMS,EAAaD,EAAOlC,CAAU,GAChCP,EAAQ,KAAKyC,EAAM,IAAI,CAI/B,UACSX,aAAsBjB,GAC/Bb,EAAU,KAAK,0BAA0B8B,CAAU,MAC9C,CACL,IAAMa,EAASN,EAAOP,EAAW,KAAK,aAAe,CACrD,EAAG,CAAC,EACJ,GAAIa,aAAkBC,GAAoB,CACxC,IAAM3D,EAAS0D,EAAO,KAAK,OAC3B3C,EAAUf,EACNA,EAAO,KAAK,aAAa,IAAK4D,GAC1BA,aAAatC,EACRsC,EAAE,KAEJ,OAAOA,CAAC,CAChB,GAAK,CACN,EACE,CACA,MACA,OACF,CACJ,MACE7C,EAAU8B,EAAW,YAEzB,CACF,CAEA,GAAM,CACJ3B,CACF,EAAI,KAAK,MAAM,gBAAgBuB,CAAI,GAAK,CACtC,OACA,MACF,EAEIoB,EAUJ,GATI3C,aAAgB0B,EAClBiB,EAAgB3C,EAAK,WAAW,iBACvBA,aAAgBI,EACzBuC,EAAgB3C,EAAK,iBAErB2C,EAAgB,CAChB,EAGEA,EAAc,OAAQ,CACxB,IAAMC,EAAuB,CAC7B,EACA,QAASC,EAAI,EAAGA,EAAI,KAAK,IAAIhD,EAAQ,OAAQ8C,EAAc,MAAM,EAAGE,IAAK,CACvE,IAAMC,EAAQZ,EAAOS,EAAeE,CAAC,EAC/BE,EAAUb,EAAOrC,EAASgD,CAAC,EACjCD,EAAW,KAAKE,GAASC,GAAW,EAAE,CACxC,CACAlD,EAAU+C,CACZ,CAEA,YAAK,sBAAsB,IAAIrB,EAAMC,EAAa3B,CAAO,EAClDA,CACT,CAEQ,qBAA8C,CACpD,GAAI,CAAC,KAAK,cAAe,CACvB,KAAK,cAAgB,IAAI,IACzB,IAAMmD,EAAa,CACjB,GAAG,KAAK,MAAM,gBACd,GAAG,OAAO,YAAY,KAAK,MAAM,eAAe,QAAQ,CAAC,CAC3D,EACA,QAAWC,KAAc,OAAO,KAAKD,CAAU,EAC7C,KAAK,cAAc,IAAIC,EAAY,KAAK,iBAAiBA,CAAU,CAAC,CAExE,CACA,OAAO,KAAK,aACd,CAEQ,wBAAyB7D,EAAoB8D,EAA2D,CAC9G,IAAIC,EAEJ,OAAKD,EAMHC,EAAqB,KAAK,sBAAsBD,CAAa,GALxD,KAAK,qBACR,KAAK,mBAAqB,KAAK,sBAAsB,KAAK,oBAAoB,CAAC,GAEjFC,EAAqB,KAAK,oBAKrBA,EAAmB,IAAI/D,CAAU,CAC1C,CAEQ,qBAAsBD,EAA0C,CAGtE,GAAI,CAFU,KAAK,MAAM,WAAW,KAAK,OAE3B,KAAK,MAAM,WAAW,UAAU,UAAU,GAAK,KAAK,MAAM,WAAW,UAAU,QAAQ,EACnG,OAGF,IAAMiE,EAAejE,EAAO,aAAoCkE,EAAU9C,CAAU,EAEpF,GAAI6C,aAAwBC,GAAY,OAAO,KAAK,KAAK,MAAM,eAAe,EAAE,SAASD,EAAa,WAAW,EAC/G,OAAOA,CAIX,CAEQ,0BAA2BA,EAA+C,CAChF,GAAM,CACJ,KAAAE,EAAM,MAAAC,CACR,EAAI,KAAK,MAAM,WAAW,KAE1B,GAAI,CAACD,GAAQ,CAACC,EACZ,OAAO,IAAI,IAGb,IAAMhE,EAAmB,IAAI,IACvBiE,EAAWF,aAAgBlD,EAAakD,EAAK,YAAcA,EAC7DE,GACFjE,EAAiB,IAAIiE,EAAU,KAAK,iBAAiBA,CAAQ,CAAC,EAGhE,QAAWC,KAAQF,EAAM,MAAM,EAAGA,EAAM,QAAQH,CAAY,EAAI,CAAC,EAAG,CAClE,IAAMM,EAAWD,EAAK,YAClBC,GACFnE,EAAiB,IAAImE,EAAU,KAAK,iBAAiBA,CAAQ,CAAC,CAElE,CAEA,OAAOnE,CACT,CAEQ,sBAAuB2D,EAA2D,CACxF,GAAIA,EAAc,OAAS,EACzB,OAAO,IAAI,IAGb,IAAMS,EAAqB,MAAM,KAAKT,EAAc,QAAQ,CAAC,EACvD,CACJU,EACAC,CACF,EAAIF,EAAmB,CAAC,EAExB,GAAIA,EAAmB,SAAW,EAChC,OAAO,IAAIG,GAAoBD,EAAcD,CAAU,EAGzD,IAAMG,EAAwB,IAAI,IAClC,GAAI,KAAK,QAAQ,aAAa,oBAC5B,OAAW,CACTd,EACArD,CACF,IAAK,KAAK,MAAM,QACd,GAAIA,aAAkB8B,GAAS9B,EAAO,sBAAsBiC,GAAY,CACtE,IAAMmC,EAAWpE,EAAO,WAAW,KAAK,MACpC2C,EAAayB,EAAUC,CAAc,GAAKD,EAAS,QAAQ,QAC7DD,EAAsB,IAAIC,EAAS,QAAQ,CAAC,EAAE,KAAMf,CAAU,CAElE,EAIJ,IAAME,EAAqB,IAAI,IAC/B,QAAWtC,KAAOgD,EAChBV,EAAmB,IAAItC,EAAK+C,CAAU,EAGxC,IAAMM,EAAa,IAAI,IAAIL,CAAY,EAEvC,OAAW,CACTM,EACAtE,CACF,IAAK8D,EAAmB,MAAM,CAAC,EAAG,CAChC,IAAMS,EAAS,IAAI,IAAIvE,CAAO,EACxBwE,EAAY,IAAI,IAAI,CACxB,GAAGH,CACL,EAAE,OAAQxB,GAAM0B,EAAO,IAAI1B,CAAC,CAAC,CAAC,EAC9B,QAAW7B,KAAOhB,EAASqE,EAAW,IAAIrD,CAAG,EAE7C,QAAW1B,KAAUkF,EAAW,CAC9B,IAAMC,EAAcP,EAAsB,IAAI5E,CAAM,EACpD,GAAImF,IAAgB,OAAW,CAC7BnB,EAAmB,IAAIhE,EAAQmF,CAAW,EAC1C,QACF,CACAnB,EAAmB,OAAOhE,CAAM,CAClC,CAEA,QAAWA,KAAUiF,EACdC,EAAU,IAAIlF,CAAM,GACvBgE,EAAmB,IAAIhE,EAAQgF,CAAK,CAG1C,CAEA,OAAOhB,CACT,CAEQ,oBAAqBhE,EAA8C,CACzE,IAAMN,EAAQ,KAAK,MAAM,OACzB,GAAI,CAACA,EACH,OAGF,IAAIQ,EACJ,GAAIF,EAAO,MACTE,EAAYF,EAAO,UACd,CAIL,IAAMoF,EAHiB,IAAI3F,EAASC,EAAO,KAAK,OAAQ,CACtD,YAAa,KAAK,WACpB,CAAC,EACsC,SAASM,CAAM,EACtD,GAAI,CAACoF,EACH,OAEFlF,EAAYkF,EAAgB,IAC9B,CAEA,IAAM3E,EAASf,EAAM,QAAQ,IAAIQ,CAAS,EAC1C,OAAOO,EAAS,KAAK,uBAAuBA,EAAQT,CAAM,EAAI,MAChE,CAEQ,uBAAwBS,EAA2BT,EAA8C,CACvG,GAAIS,aAAkB6B,EAAW,CAC/B,IAAMW,EAAU,KAAK,OAAO,gBAAgBxC,EAAQT,CAAM,EAC1D,GAAIiD,IACkB,OAAOA,EAAQ,KAAK,MAAS,SAAWA,EAAQ,KAAK,kBACrD,UAClB,OAAOA,CAGb,SAAWxC,aAAkB8B,EAC3B,OAAW,CACT,CAAE8C,CACJ,IAAK5E,EAAO,QAAS,CACnB,IAAMwC,EAAU,KAAK,uBAAuBoC,EAAcrF,CAAM,EAChE,GAAIiD,IACkB,OAAOA,EAAQ,KAAK,MAAS,SAAWA,EAAQ,KAAK,kBACrD,UAClB,OAAOA,CAGb,CAIJ,CACF,ECxfA,IAAMqC,GAAa,OAAO,YAAY,EAKtC,SAASC,GAAkBC,EAAuC,CAChE,GAAM,CACJ,MAAAC,CACF,EAAID,EACJ,OAAOE,EACLD,EACI,IAAIE,GAAQ,CACZ,KAAMC,GAAY,OAAO,CAAC,CAC5B,CAAC,EACC,IACJ,GACF,CACF,CAuBO,SAASC,GACdC,EACAN,EAII,CAAC,EACF,CACH,GAAM,CACJ,OAAQO,EACR,uBAAAC,EAAyB,GACzB,QAAAC,CACF,EAAIT,EAGEU,EAASC,EAAaJ,EAAW,CACrC,QAAAE,CACF,CAAC,EACKG,EAAyB,IAAI,IAC7BC,EAAoB,IAAI,IAKxBC,EAAS,MAAM,KAAKC,EAAcT,CAAU,CAAC,EAEnD,QAASU,EAAIF,EAAO,OAAS,EAAG,GAAKE,EAAGA,IAAK,CAC3C,IAAMC,EAAQH,EAAOE,CAAC,EAClBE,EAAmBL,EAAkB,IAAII,CAAK,GAAK,IAAI,IAAI,CAC7DnB,EACF,CAAC,EACKqB,EAAaP,EAAuB,IAAIK,CAAK,GAAK,EAGlDG,EAAYH,EAAM,WAOxB,GANIG,EAAU,UAAU,UAAU,IAChCF,EAAmB,IAAI,IAAI,CACzBpB,EACF,CAAC,GAGCsB,aAAqBC,GAAkB,CACzC,IAAMC,EAAOF,EAAU,KAAK,KACtBG,EAAOH,EAAU,KAAK,KAE5B,GAAI,CAACE,GAAQ,CAACC,EAAM,CAGlB,GAAM,CACJC,EACAC,CACF,EAAIR,EAAM,YAEV,GAAIO,EAAK,WAAW,QAAQ,SAAWC,EAAM,WAAW,QAAQ,OAC9D,MAAM,IAAI,MACR,iDAAiDR,EAAM,WAAW,IAAI,CACpE,QAAAR,CACF,CAAC,CAAC,GACJ,EAKF,GAFAI,EAAkB,IAAIW,EAAMN,CAAgB,EAExCO,EAAM,WAAW,QAAQ,KAAMC,GAAWA,aAAkBC,GAAcD,EAAO,MAAM,EACzFb,EAAkB,IAAIY,EAAOP,CAAgB,UACpC,CAACM,EAAK,WAAW,QAAQ,KAAME,GAAWA,aAAkBC,GAAcD,EAAO,MAAM,EAChG,GAAIN,EAAU,KAAK,OACjBP,EAAkB,IAAIY,EAAOZ,EAAkB,IAAIW,CAAI,GAAK,IAAI,GAAK,MAChE,CACL,IAAMI,EAAkB,IAAI,IAC5Bf,EAAkB,IAAIY,EAAOG,CAAe,EAC5C,QAASC,EAAI,EAAGA,EAAIL,EAAK,WAAW,QAAQ,OAAQK,IAAK,CACvD,IAAMC,EAAaN,EAAK,WAAW,QAAQK,CAAC,EAC5C,GAAMC,aAAsBH,IAIxBT,EAAiB,IAAIpB,EAAU,GAAKoB,EAAiB,IAAIY,EAAW,WAAW,GAAG,CACpF,IAAMC,EAAcN,EAAM,WAAW,QAAQI,CAAC,EAC1CE,aAAuBJ,GACzBC,EAAgB,IAAIG,EAAY,WAAW,CAE/C,CACF,CACF,CAEJ,CACF,CAEA,GAAIX,aAAqBY,EAAY,CAKnC,GAJIxB,GACFyB,GAAwBhB,EAAOC,EAAkBR,EAAQS,CAAU,EAGjEC,EAAU,OACZ,SAIF,IAAMc,EAAU,IAAI,IACpB,QAAWC,KAAOlB,EAAM,QAAS,CAC/B,IAAMmB,EAAYD,EAAI,OAAS,GACzBE,EAAUF,EAAI,KAEhBG,EAAkBJ,EAAQ,IAAIE,CAAS,EACtCE,IACHA,EAAkB,IAAI,IACtBJ,EAAQ,IAAIE,EAAWE,CAAe,GAExCA,EAAgB,IAAID,CAAO,CAC7B,CAGA,OAAW,CACTE,EACAC,CACF,IAAK,OAAO,QAAQvB,EAAM,eAAe,EAAG,CAC1C,GAAM,CACJwB,EACAC,CACF,EAAIF,EAEJ,GAAIE,aAAuBC,EAAO,CAChC,IAAMC,EAAcC,EAAOH,EAAY,WAAW,QAAS,CAAC,EAExDI,EACA,EAAI7B,EAAM,OAAO,QAAU2B,aAAuBG,GACpDD,EAAU,IAAI,IAAI,CAChBhD,EACF,CAAC,EAEDgD,EAAUZ,EAAQ,IAAIK,CAAI,GAAK,IAAI,IAGrC,IAAIS,EAAiBnC,EAAkB,IAAI6B,CAAW,EACjDM,IACHA,EAAiB,IAAI,IACrBnC,EAAkB,IAAI6B,EAAaM,CAAc,GAEnD,QAAWb,KAAOW,EAChBE,EAAe,IAAIb,CAAG,CAE1B,CAEA,IAAMc,EAAgBR,EAAK,iBACvBQ,GAAiB,EAAIA,EAAc,QACrCrC,EAAuB,IAAI8B,EAAaO,EAAc,MAAM,CAEhE,CACF,CACF,CAEA,OAAO3C,CACT,CAEA,SAAS2B,GACPhB,EACAC,EACAR,EACAwC,EACM,CAEN,IAAMC,EADYlC,EAAM,WAAW,KACX,MAElBmC,EAAY,IAAI,IACtB,GAAID,EAEF,QAAWhB,KAAOgB,EAAM,QAAQE,CAAU,EACnClB,EAAI,OACPiB,EAAU,IAAIjB,EAAI,IAAI,EAK5B,IAAMmB,EAA8B,CACpC,EACIC,EAAU,GACVC,EAAO,GACPvD,EAAQ,GACRkB,EAAa+B,EAEXO,EAAYvC,EAAiB,IAAIpB,EAAU,EAC3C4B,EAAST,EAAM,WAErB,QAAWyC,KAAahC,EAAO,QAAS,CACtC,GAAI,OAAOgC,GAAc,UAAY,OAAOA,GAAc,UAAY,OAAOA,GAAc,UACzF,SAGF,IAAMC,EAAgBD,EAChBnB,EAAOoB,EAAc,YAEvBF,GAAavC,EAAiB,IAAIqB,CAAI,GAAKa,EAAU,IAAIb,CAAI,GAAK,EAAIpB,GACxEmC,EAAc,KAAKK,CAAa,EAChCxC,GAAc,IAEVwC,EAAc,SAChBH,EAAO,IAETD,EAAU,IAGR,CAACtD,GAAS0D,EAAc,KAAKC,CAAW,IAC1C3D,EAAQ,GAEZ,CAEA,GAAIuD,EAAM,CACR,IAAMK,EAAW,IAAIC,GAAS7C,EAAOP,EAAQ,CAAC,CAAC,EACzCqD,EAAQ,IAAI,IAAIT,EAAc,IAAKU,GAAMA,EAAE,WAAW,CAAC,EAEvDC,EAAmB,MAAM,KAAK/C,CAAgB,EACjD,OAAQqB,GAAyB,OAAOA,GAAS,QAAQ,EACzD,KAAK,EAER,QAAWA,KAAQ0B,EACjB,GAAI,CAACF,EAAM,IAAIxB,CAAI,EAAG,CACpB,IAAM2B,EAAQL,EAAS,SAAStB,CAAI,EACpCe,EAAc,KACZpD,EAAMiE,EAAO,CACX,IAAK5B,EACL,MAAO2B,GAAO,WAChB,CAAC,EAAG3B,EAAM,CACR,KAAM,EACR,CAAC,CACH,CACF,CAEJ,CAGIe,EAAc,SAAW,GAC3BA,EAAc,KAAKvD,GAAiB,CAClC,MAAAE,CACF,CAAC,CAAC,EAGJyB,EAAO,OAAO4B,EAAe,CAC3B,OAAQ,GACR,KAAM,EACR,CAAC,EAEGC,GACFtC,EAAM,WAAW,CAErB,CC9QO,SAASmD,GACdC,EACAC,EAGI,CAAC,EACF,CACH,GAAM,CACJ,OAAQC,EAAW,QAAAC,CACrB,EAAIF,EACEG,EAASC,EAAaH,EAAW,CACrC,QAAAC,CACF,CAAC,EAED,QAAWG,KAASC,EAAcP,CAAU,EAC1C,GAAI,OAAO,KAAKM,EAAM,eAAe,EAAE,SAAW,EAIlD,OAAW,CACT,CAAEE,CACJ,IAAK,OAAO,QAAQF,EAAM,eAAe,EAAG,CAG1C,GAAM,CACJG,EACAC,CACF,EAAIF,EAGJ,GAAI,EAAEE,aAAwBC,GAC5B,SAGF,IAAMC,EAASH,EAEf,GAAI,CAACG,EAAO,OACV,SAOF,IAAMC,EAAcT,EAAO,cAAcM,CAAY,EASrD,GARI,CAACG,GAAeA,EAAY,SAAW,GAIvCD,EAAO,kBAAkBE,GAIzBF,EAAO,QAAQ,kBAAkBD,EACnC,SAKF,GAAI,CADeC,EAAO,MAExB,MAAM,IAAIG,EAAc,2DAA2D,EAIrF,IAAMC,EAAYJ,EAAO,YACnBK,EAAWC,GAAW,GAAG,EAC5B,KAAKC,EAAUP,EAAQI,EAAW,CACjC,MAAO,EACT,CAAC,EAAG,CACF,KAAM,EACR,CAAC,EACA,SAASA,EAAW,CACnB,KAAM,EACR,CAAC,EAEHJ,EAAO,QAAQK,CAAQ,CACzB,CAGF,OAAOjB,CACT,CCzBO,SAASoB,GACdC,EACAC,EAOI,CAAC,EACF,CACH,GAAM,CACJ,OAAQC,EACR,gBAAAC,EAAkB,GAClB,YAAAC,EAAc,GACd,YAAaC,EACb,0BAAAC,EAA4B,GAC5B,QAASC,CACX,EAAIN,EAEEO,EAASC,EAAaP,EAAW,CACrC,QAASK,CACX,CAAC,EACKG,EAAY,IAAIC,GAAc,CAClC,OAAAH,CACF,CAAC,EACKI,EAAcP,GAAkB,EAAQG,EAAO,MAC/CK,EAAUL,EAAO,SAAW,IAAIM,EAChCC,EAAeF,EAAQ,aACvBG,EAAgBD,EAAa,cAEnC,QAAWE,KAASC,EAAclB,CAAU,EAAG,CACzCe,EAAa,yBACfI,GAAwBF,CAAK,EAI/B,IAAMG,EADkBH,EAAM,sBACcI,EAE5CC,GAAsBL,EAAOD,CAAa,EAE1C,IAAMO,EAAW,IAAIC,GAASP,EAAOT,EAAQ,CAC3C,YAAAI,CACF,CAAC,EACDa,GAAsBR,EAAM,IAAI,EAChCQ,GAAsBR,EAAM,aAAa,EACzC,IAAMS,EAAoBC,GAAYV,EAAOM,CAAQ,GAEhDf,EAAO,OAASO,EAAa,kCAAoCZ,GACpEyB,GACEX,EACAM,EACAV,EACA,CACE,kBAAmBE,EAAa,2BAClC,CACF,EAGFc,GAAqBZ,EAAOM,CAAQ,EACpCO,GACEb,EACAM,EACA,CACE,0BAAAjB,CACF,CACF,EAEI,CAACE,EAAO,OAASL,GACnByB,GAAiBX,EAAOM,EAAUV,EAAS,CACzC,kBAAmB,EACrB,CAAC,EAGCO,IACEhB,GACF2B,GACEd,EACAM,EACAG,EACAV,EACAN,CACF,EAEFsB,GAAef,CAAK,GAGtBgB,GAAchB,EAAOJ,CAAO,EAC5BqB,GAA2BjB,EAAOM,CAAQ,EAEtCR,EAAa,qBACfL,EAAU,cAAcO,CAAK,CAEjC,CAEA,OAAOjB,CACT,CAUO,SAASmC,GACdnC,EACAoC,EACG,CACH,IAAMC,EAAsC,CAC5C,EAEA,QAAWpB,KAASC,EAAclB,CAAU,EAAG,CAC7C,GAAI,EAAEiB,EAAM,sBAAsBI,GAChC,SAGF,IAAIiB,EAAqBrB,EAAM,mBAE/B,GAAI,EAAIA,EAAM,gBAAgB,QAAU,CAACA,EAAM,sBAAwBA,EAAM,OAAO,SAAW,EAAG,CAChG,IAAMsB,EAAStB,EAAM,gBAAgB,CAAC,EAChCuB,EAAWD,EAAO,MAAQ,gBAAgBA,EAAO,KAAK,IAAM,GAC5DE,EAAQF,EAAO,KAAK,MAAqB,MAAO,KAChDG,EAAOH,EAAO,KAAK,MAAqB,MAAO,IAE/CI,EAASJ,EAAO,KAAK,MAAqB,MAAO,MACjDK,EAAOL,EAAO,KAAK,MAAqB,MAAO,IAEjDM,EAAW,WAAWN,EAAO,IAAI,0BAA0BC,CAAQ,IAIvE,GAHIC,GAAQC,IACVG,GAAY,UAAUJ,CAAI,UAAUC,CAAG,IAErCN,GAAOO,IAAU,QAAaC,IAAQ,OAAW,CACnD,GAAM,CACJ,aAAAE,CACF,EAAIC,GAAa,CACf,IAAAX,EACA,UAAW,CACT,CACEO,EACAC,CACF,CACF,CACF,CAAC,EACDC,GAAY;AAAA,IAAOC,CAAY,EACjC,CAEA,MAAM,IAAIE,EAAcH,CAAQ,CAClC,CAEA,GAAI,EAAIP,EAAmB,QAAU,EAAIrB,EAAM,OAAO,QAAUA,EAAM,OAAO,CAAC,EAAE,QAAS,CACvF,IAAMgC,EAAmB,IAAI,IAAIC,GAAejC,EAAM,OAAO,CAAC,CAAC,CAAC,EAChEqB,EAAqBA,EAAmB,OAAQ,GAAM,CAACW,EAAiB,IAAI,CAAC,CAAC,CAChF,CAEAZ,EAAsB,KAAK,GAAGC,CAAkB,CAClD,CAEA,GAAI,EAAID,EAAsB,OAAQ,CACpC,IAAMc,EAAcd,EAAsB,CAAC,EACrCe,EAAkBD,EAAY,KAAK,KACnCV,EAAOY,EAAaD,EAAiBE,CAAU,EAAIF,EAAgB,KAAK,KAAU,OAClFV,EAAMW,EAAaD,EAAiBE,CAAU,EAAIF,EAAgB,KAAK,IAAS,OAEhFT,EAAQU,EAAaD,EAAiBE,CAAU,EAAIF,EAAgB,KAAK,MAAiC,OAC1GR,EAAMS,EAAaD,EAAiBE,CAAU,EAAIF,EAAgB,KAAK,IAA+B,OAExGP,EAAW,qBAAqBM,EAAY,IAAI,IAIpD,GAHIV,GAAQC,IACVG,GAAY,WAAWJ,CAAI,UAAUC,CAAG,KAEtCN,GAAOO,IAAU,QAAaC,IAAQ,OAAW,CACnD,GAAM,CACJ,aAAAE,CACF,EAAIC,GAAa,CACf,IAAAX,EACA,UAAW,CACT,CACEO,EACAC,CACF,CACF,CACF,CAAC,EACDC,GAAY;AAAA,IAAOC,CAAY,EACjC,CAEA,MAAM,IAAIE,EAAcH,CAAQ,CAClC,CAEA,OAAO7C,CACT,CAEA,SAASsB,GAAuBL,EAAcD,EAAkC,CAC9E,GAAIA,EAAc,OAAS,EACzB,OAGF,IAAIuC,EAAmB,GACjBC,EAAkBvC,EAAM,WAE9B,QAAWsB,KAAUtB,EAAM,QAAS,CAClC,IAAMwC,EAAOlB,EAAO,KAAK,YAAY,EAChCvB,EAAc,IAAIyC,CAAI,IAIvBA,IAAS,SACXD,aAA2BnC,GACvBmC,EAAgB,KAAiC,WAErDjB,EAAO,QAAQ,IAAImB,GAAiB,CAClC,GAAGnB,EAAO,IACZ,CAAC,CAAC,EACFgB,EAAmB,GAEvB,CAEIA,GACFtC,EAAM,WAAW,CAErB,CAEA,SAASiC,GAAgBS,EAAkC,CAGzD,IAAMC,GAFSD,EAAQ,KAAK,QAAU,CACtC,GAEG,OAAQE,GAA2BA,aAAiBC,IAAUD,EAAM,KAAK,gBAAgBE,CAAU,EACnG,IAAKF,GAAUA,EAAM,KAAK,IAAkB,EAEzCG,EAA6B,CACnC,EACA,QAAWC,KAAKN,EAAQ,KAAK,YAC3B,QAAWjB,KAAOuB,EAAE,QAAQF,CAAU,EACpCC,EAAa,KAAKtB,CAAG,EAIzB,MAAO,CACL,GAAGkB,EACH,GAAGI,CACL,CACF,CAEA,SAASvC,GAAuByC,EAA2C,CACzE,QAAWC,KAASD,EAAe,CACjC,GAAIC,EAAM,kBAAkBC,GAAYD,EAAM,OAAO,KAAK,UACxD,SAEF,IAAME,EAAaF,EAAM,UAAU,OAAO,EACtCE,aAAsBC,GACxBD,EAAW,UAAU,UAAW,MAAS,CAE7C,CACF,CAEA,SAAS1C,GAAaV,EAAcM,EAA2C,CAC7E,IAAMgD,EAAStD,EAAM,WAA0B,KAAK,OAAS,CAC7D,EACA,GAAIsD,EAAM,SAAW,EACnB,OAAO,IAAI,IAGb,IAAMC,EAAQ,IAAI,IAAID,EAAM,IAAKE,GAAMA,EAAE,WAAW,CAAC,EAC/CC,EAAoB,OAAO,KAAKzD,EAAM,eAAe,EAAE,OAAQ0D,GAAM,CAACH,EAAM,IAAIG,CAAC,CAAC,EAExF,GAAI,EAAIH,EAAM,MAAQE,EAAQ,SAAW,EACvC,MAAM,IAAI1B,EAAc,SAAS,CAC/B,GAAGwB,CACL,EAAE,KAAK,GAAG,CAAC,yBAAyBvD,EAAM,UAAU,EAAE,EAIxD,IAAM2D,EAAkC,CAAC,EAEnCC,EAAuBC,GAA6B,CACxD,QAAWC,KAAWxD,EAAS,iBAAiBuD,CAAU,EAClDC,KAAWH,IACfA,EAAQG,CAAO,EAAID,EAGzB,EAEA,QAAWA,KAAcJ,EACvBG,EAAoBC,CAAU,EAIhC,IAAME,EAAe,IAAI,IAEzB,QAASC,EAAI,EAAGA,EAAIV,EAAM,OAAQU,IAAK,CACrC,IAAMC,EAAOX,EAAMU,CAAC,EACpBE,GAAmBD,EAAME,CAAQ,EACjC,IAAMC,EAAcX,EAAQA,EAAQ,OAAS,CAAC,EAC1CW,GACFR,EAAoBQ,CAAW,EAGjC,IAAMC,EAAYJ,EAAK,YACvBR,EAAQ,KAAKY,CAAS,EAEtB,IAAMC,EAAQL,EAAK,KAAK,MACxB,GAAI,CAACK,EAAO,SAEZ,IAAMC,EAAcjE,EAAS,iBAAiB+D,CAAS,EAEjDG,EAA2B,CACjC,EACMC,EAAuBH,EAAM,OAC7BI,EAAmBT,EAAK,iBAE9B,QAAWU,KAAkBL,EAAO,CAClC,IAAMM,EAAcD,EAA8B,KAC9CzB,EAAQS,EAAQiB,CAAU,EAE9B,IAAI,CAAC1B,GAAS,CAACqB,EAAY,SAASK,CAAU,IACxC,EAAI,OAAO,KAAKjB,CAAO,EAAE,QAAU,EAAE,MAAOA,IAAY,EAAIY,EAAY,OAC1E,MAAM,IAAIxC,EAAc,8BAA8B6C,CAAU,EAAE,EAItE1B,EAAQA,GAASkB,EAEjB,IAAIS,EACJ,GAAIb,IAAM,GAAKS,IAAyB,EACtCI,EAAMvD,EAAW,CACf,IAAKsD,EACL,MAAA1B,CACF,CAAC,MACI,CACL,IAAM4B,EAAkBrB,EAAQ,MAAM,EAAG,EAAE,EACxC,OAAQsB,GAAMzE,EAAS,iBAAiByE,CAAC,EAAE,SAASH,CAAU,CAAC,EAC/D,IAAKG,GAAMzD,EAAW,CACrB,IAAKsD,EACL,MAAOG,CACT,CAAC,CAAC,EACA,EAAID,EAAgB,OACtBD,EAAM,IAAIG,GAAa,CACrB,KAAMF,EAAgB,CAAC,EACvB,YAAaA,EAAgB,MAAM,CAAC,CACtC,CAAC,EAEDD,EAAMvD,EAAW,CACf,IAAKsD,EACL,MAAA1B,CACF,CAAC,CAEL,CAOA,GALAsB,EAAW,KAAKK,EAAI,GAAGvD,EAAW,CAChC,IAAKsD,EACL,MAAOP,CACT,CAAC,CAAC,CAAC,EAEC,CAACK,EAAkB,CACrB,IAAIO,EAAUlB,EAAa,IAAIa,CAAU,EACpCK,IACHA,EAAU,CACV,EACAlB,EAAa,IAAIa,EAAYK,CAAO,GAEjCA,EAAQ,SAAS/B,CAAK,GAAG+B,EAAQ,KAAK/B,CAAK,EAC3C+B,EAAQ,SAASZ,CAAS,GAAGY,EAAQ,KAAKZ,CAAS,CAC1D,CACF,CAEAJ,EAAK,UAAU,QAAS,MAAS,EACjCA,EAAK,UAAU,KAAMiB,GAAQV,EAAY,CACvC,KAAM,EACR,CAAC,CAAC,CACJ,CAEA,GAAI,EAAIT,EAAa,KACnB,QAAWzC,KAAUtB,EAAM,QAAS,CAClC,IAAMiF,EAAW3D,EAAO,MAAwC,OAAhCyC,EAAa,IAAIzC,EAAO,IAAI,EAC5D,GAAI2D,IAAY,OAAW,CACzB,IAAME,EAAeF,EAAQ,IAAKF,GAAMzD,EAAW,CACjD,IAAKA,EAAO,KACZ,MAAOyD,CACT,CAAC,CAAC,EACEK,EAA0B,IAAIJ,GAAa,CAC7C,KAAMG,EAAa,CAAC,EACpB,YAAaA,EAAa,MAAM,CAAC,CACnC,CAAC,EAEG7D,EAAO,kBAAkBlB,EAC3BgF,EAAcC,EAAUD,EAAa9D,EAAO,KAAM,CAChD,KAAM,EACR,CAAC,EACQA,EAAO,kBAAkBgE,KAClCF,EAAc,IAAIG,GAAe,CAC/B,KAAMC,EAAalE,EAAO,IAAI,EAC9B,WAAY8D,CACd,CAAC,GAGHpF,EAAM,QAAQsB,EAAQ8D,CAAW,CACnC,CACF,CAGF,OAAOrB,CACT,CAEA,SAASpD,GACPX,EACAM,EACAV,EACAZ,EACM,CACN,GAAM,CACJ,kBAAAyG,CACF,EAAIzG,EACED,EAAaiB,EAAM,WACnBF,EAAeF,EAAQ,aAE7B,GAAI,EAAEb,aAAsBqB,IAAeN,EAAa,6BACtD,OAGF,IAAM4F,EAAoB,IAAI,IACxBC,EAAc,IAAI,IAAI5G,EAAW,QAAQ,IAAK6G,GAAOA,EAAiB,WAAW,CAAC,EACpFC,EAAW,GAETC,EAAiB,CACrBC,EACA/G,EAC6B,CAAC,IACrB,CACT,GAAM,CACJ,aAAAgH,EAAe,GAAO,aAAAC,EAAe,EACvC,EAAIjH,EACEkH,EAAYH,aAAgBI,GAC5BC,EAAWL,aAAgBM,GACjC,GAAI,GAACN,GAASN,GAAqB,CAACS,GAIpC,QAAW5E,KAAUgF,GAAYP,EAAM,CACrC,MAAQQ,GAAMA,EAAE,MAClB,CAAC,EAAG,CAGF,GAFI,EAAEjF,aAAkBwB,IAEpB2C,GAAqBS,GAAa5E,EAAO,SAAWyE,EACtD,SAGF,IAAIS,EAAc,GACZtD,EAAS8C,GAAgB,CAAC1E,EAAO,MAAShB,EAAS,SAASgB,EAAO,IAAI,EAAI,OAC3EmF,EAAaf,EAAkB,IAAIpE,EAAO,IAAI,EAC9CoF,EAAaD,EAAaA,EAAW,CAAC,EAAI,OAC1CE,EAAWF,EAAaA,EAAW,CAAC,EAAI,EAE9C,GAAIC,EACFF,EAAc,GACZE,EAAW,KAAKE,CAAW,GACxBtF,EAAO,aAAasF,CAAW,GAC/B,EAAEtF,EAAO,aAAsCuF,GAAYzG,CAAU,YAAayG,KAGnFT,GAAYtG,EAAa,yCAC3B0G,EAAcA,GAAe,MAAM,KAAKE,EAAW,QAAQ5D,CAAU,CAAC,EAAE,KACrEyD,GAAMZ,EAAY,IAAIY,EAAE,MAAM,CAAC,GAAG,MAAQ,EAAE,CAC/C,WAEOzG,EAAa,yCAA2CoG,GAAaE,GAAW,CACzF,IAAMU,EAAc5D,EAAQA,EAAM,KAAO5B,EAAO,MAChD,GAAIwF,GAAenB,EAAY,IAAImB,CAAW,EAAG,CAC/CxF,EAAO,QAAQkE,EAAalE,EAAO,IAAI,CAAC,EACxCuE,EAAW,GACX,QACF,CACF,CAEA,GAAI3C,IAAU,CAACwD,GAAcF,GAC3BlF,EAAO,UAAU,QAAS4B,CAAK,UACtB,CAAC5B,EAAO,OAASoF,GAAc,CAACF,EACzC,IAAKE,aAAsBK,IAAeL,EAAW,YAAcT,GAAgBD,GAC7EC,IACF3E,EAAO,QAAQyF,GAAY,OAAOJ,CAAQ,CAAC,EAC3Cd,EAAW,QAER,CACLA,EAAW,GACX,IAAMmB,EAAY1F,EAAO,QAAQ2F,GAAUP,CAAU,CAAC,EAChDQ,GAAaC,GAAeH,EAAWpH,CAAO,EAChDsH,KAAeF,GACjBA,EAAU,QAAQE,EAAU,CAEhC,CAEJ,CACF,EAEA,QAASlD,EAAI,EAAGA,EAAIjF,EAAW,QAAQ,OAAQiF,IAAK,CAClD,IAAMoD,EAAarI,EAAW,QAAQiF,CAAC,EACvC8B,EAAesB,CAAU,EACrBA,aAAsBC,GACxB3B,EAAkB,IAAI0B,EAAW,MAAO,CACtCA,EAAW,KAAK,KAChBpD,EAAI,CACN,CAAC,CAEL,CAGA,IAAIsD,EAAiCtH,EACjCuH,EAAiB,GACrB,KAAOD,GAAe,CAACA,EAAY,OAC7BA,EAAY,SAAWA,EAAY,SACrCC,EAAkBD,EAAY,OAAO,WAAgC,KAAK,aAAeA,EAAY,YAEvGA,EAAcA,EAAY,OAG5B,GAAIA,GAAeC,EAAgB,CACjC,IAAMC,EAAUF,EAAY,WAAW,OACvC,GAAIE,GACeA,EAAQ,aAAarE,CAAQ,GAChC,KAAK,UAAW,CAC5B,IAAMsE,EAAYD,EAAoB,KAAK,MACrCE,EAAeD,aAAoBpE,EACrCoE,EAAS,QACT,CACF,EACIE,EAA8B,EAAID,EAAa,OACjDA,EACEF,EAAoB,KAAK,MAAqB,SAAW,CAC7D,EACF,QAAW/F,KAAOkG,EACZlG,aAAeY,GACjBqD,EAAkB,OAAOjE,EAAI,UAAU,CAG7C,CAEJ,CAaA,GAXAqE,EAAe/G,EAAW,KAAK,KAA+B,EAC9D+G,EAAe/G,EAAW,KAAK,MAAiC,CAC9D,aAAc,EAChB,CAAC,EACD+G,EAAe/G,EAAW,KAAK,OAAkC,CAC/D,aAAc,EAChB,CAAC,EACD+G,EAAe/G,EAAW,KAAK,QAAmC,CAChE,aAAc,EAChB,CAAC,EAEGe,EAAa,uCACf,QAAWmE,KAAQlF,EAAW,KAAK,OAAS,CAC5C,EACE+G,EAAe7B,CAAI,EAInB4B,GACF7F,EAAM,WAAW,CAErB,CAEA,SAASY,GAAsBZ,EAAcM,EAA0B,CACrE,IAAIsH,EAAY,GACVC,EAAoC,CACxC,GAAG7H,EAAM,QACT,GAAGA,EAAM,KACX,EAEA,QAAWsB,KAAUuG,EAAS,CAC5B,GAAIvG,aAAkBwG,GAAS,SAE/B,IAAMhB,EAAcxF,EAAO,MACrByG,EAAYzG,EAAO,KAAK,UAAyC,CACvE,EAGA,GAFA,OAAOA,EAAO,KAAK,SAGjBwF,GACG,CAAC9G,EAAM,QAAQ,IAAI8G,CAAW,IAE/B,CAAC9G,EAAM,QACJ,CAACA,EAAM,OAAO,QAAQ,IAAI8G,CAAW,GACrC,CAAC9G,EAAM,sBAEZ,CACA,IAAMgI,EAAQ1G,EAAO,MACrB,GAAI0G,EAAM,OAAS,EAAG,SAEtB,IAAMC,EAAYD,EAAM,CAAC,EACnBE,EAAiBF,EAAM,MAAM,CAAC,EACpC,GAAI,CAACC,EAAW,SAEhB,IAAIE,EACAC,EACAC,EACAC,EAEJ,GAAItI,EAAM,QAAQ,IAAIiI,EAAU,IAAI,EAAG,CAErC,GAAIC,EAAe,SAAW,EAAG,SACjCG,EAAWJ,EACXE,EAAUD,EAAe,CAAC,EAC1BE,EAAaF,EAAe,MAAM,CAAC,EACnCI,EAAe,EACjB,MAEED,EAAW/H,EAAS,SAAS2H,EAAU,IAAI,EAC3CE,EAAUF,EACVG,EAAaF,EACbI,EAAe,GAGjB,GAAID,EAAU,CACZT,EAAY,GACZ,IAAMW,EAAYjH,EAAW,CAC3B,IAAK6G,EACL,MAAOE,CACT,CAAC,EACG,EAAIN,EAAS,SACfQ,EAAU,KAAK,SAAcR,EAAS,MAAMO,EAAe,EAAI,CAAC,GAE9D,EAAIF,EAAW,OACjB9G,EAAO,QAAQwG,GAAQ,MAAM,CAC3BS,EACA,GAAGH,CACL,CAAC,CAAC,EAEF9G,EAAO,QAAQiH,CAAS,CAE5B,CACF,CACF,CAEIX,GACF5H,EAAM,WAAW,CAErB,CAEA,SAASa,GACPb,EACAM,EACAtB,EACM,CACN,GAAM,CACJ,0BAAAK,CACF,EAAIL,EACEc,EAAeQ,EAAS,QAAQ,aAEtC,QAAWgB,KAAUtB,EAAM,QAAS,CAClC,IAAM8G,EAAcxF,EAAO,MACrBkH,EAAalH,EAAO,KAE1B,GAAIwF,GAAe9G,EAAM,QAAQ,IAAI8G,CAAW,EAAG,CACjD,IAAM2B,EAAgBnI,EAAS,iBAAiBwG,CAAW,EAC3D,GACE,CAACzH,GACE,EAAIoJ,EAAc,QAClB,CAACA,EAAc,SAASD,CAAU,GAClC,CAACC,EAAc,SAAS,GAAG,EAE9B,MAAM,IAAI1G,EAAc,mBAAmByG,CAAU,EAAE,CAE3D,CAEA,GAAI,CAAC1B,EAAa,CAChB,GAAI,EAAI9G,EAAM,OAAO,QAAU,CAACsB,EAAO,aAAaoH,EAAS,EAAG,CAC9DpH,EAAO,UAAU,QAASkE,EAAcxF,EAAM,OAAO,CAAC,EAAgB,KAAK,CAAC,EAC5E,QACF,CAEA,IAAMkD,EAAQ5C,EAAS,SAASgB,CAAM,EAEtC,GAAI4B,EAAO,CACT,IAAMyF,EAAS3I,EAAM,QAAQ,IAAIkD,EAAM,IAAI,EAC3C,GAAIyF,aAAkBC,GACjBD,EAAO,YAAY,IAAIrH,CAAM,EAEhC,QAEJ,CAEA,GAAI4B,EACF5B,EAAO,UAAU,QAAS4B,CAAK,UAE/BpD,EAAa,iCACVwB,EAAO,MAAM,SAAW,GACxBkH,KAAcxI,EAAM,gBACvB,CACA,IAAM6I,EAAUvH,EAAO,KAAK,KAC5BtB,EAAM,QAAQsB,EAAQ,IAAIwH,GAAgB,CACxC,KAAM1G,EAAayG,EAASxG,CAAU,EAAIwG,EAAU,MACtD,CAAC,CAAC,CACJ,CACF,CACF,CAEA,QAAWE,KAAS/I,EAAM,OACxB,GAAI+I,aAAiBL,IACnB,QAAWpH,KAAUyH,EAAM,QAAQjG,CAAU,EAC3C,GAAI,CAACxB,EAAO,OAAShB,EAAS,WAAW,IAAIgB,EAAO,IAAI,EAAG,CACzD,IAAM4B,EAAQ5C,EAAS,SAASgB,EAAO,IAAI,EACvC4B,GACF5B,EAAO,UAAU,QAAS4B,CAAK,CAEnC,EAIR,CAEA,SAAS8F,GACPjK,EACAkK,EACAC,EACM,CACN,IAAMC,EAAUpK,EAAW,UAAU,QAAQ,GAAKA,EAAW,UAAU,QAAQ,EAC/E,GAAI,CAACoK,EAAS,OACd,IAAMC,EAAa,MAAM,QAAQD,CAAO,EACpCA,EACA,CACAA,CACF,EACIxF,EAAU,IAAI,IACjByF,EACE,OAAQpG,GAAuBA,aAAaX,CAAU,EACtD,IAAKW,GAAMA,EAAE,IAAI,CACtB,EACA,QAAWE,KAAS+F,EAClBC,EAAc,IAAIhG,EAAOS,CAAO,CAEpC,CAEA,SAAS0F,GACPtK,EACAkK,EACAK,EACM,CACN,IAAMC,EAASxK,EAAW,UAAU,QAAQ,EAC5C,GAAI,CAACwK,GAAUA,EAAO,SAAW,EAAG,OACpC,IAAM5F,EAAkC,CAAC,EACzC,QAAWX,KAAKuG,EACd,GAAIvG,aAAaX,EAAY,CAC3B,IAAMmH,EAAWxG,EAAE,KAAK,KACpBwG,aAAoBnH,IACtBsB,EAAQ6F,EAAS,IAAI,EAAKxG,EAAiB,MAE/C,CAEF,QAAWE,KAAS+F,EAClBK,EAAc,IAAIpG,EAAOS,CAAO,CAEpC,CAEA,SAAS8F,GACP1K,EACAkK,EACAnD,EACM,CACN,IAAM4D,EAAU3K,EAAW,UAAU,SAAS,EAC9C,GAAI,CAAC2K,GAAWA,EAAQ,SAAW,EAAG,OACtC,IAAM/F,EAAqC,CAAC,EAC5C,QAAWX,KAAK0G,EACV1G,aAAaqE,IACf1D,EAAQX,EAAE,KAAK,EAAIA,GAGvB,QAAWE,KAAS+F,EAClBnD,EAAe,IAAI5C,EAAOS,CAAO,CAErC,CAEA,SAASgG,GAA2B5K,EAAkC,CACpE,IAAM6K,EAAY7K,EAAW,KAAK+D,CAAU,EAC5C,GAAI,EAAE8G,aAAqB9G,IAAe,CAAC8G,EAAU,eAA8B,EACjF,MAAO,CACP,EAIF,IAAMC,EAAgBD,EAAU,KAAK,EAC/BE,EAAgBD,EAAc,KAChCE,EAAsF3H,EAAa0H,EAAeE,EAAY,EAAIF,EAAgB,OAGhJ/B,EAAWhJ,EAAW,MAAM,MAAM,EAAG,EAAE,EAG7CkL,EAAO,QAAWC,KAAQnC,EAAS,MAAM,CAAC,EAAG,CAC3C,IAAMoC,EAAaJ,GAAgB,KAAK,aAAe,CACvD,EACA,QAAWnH,KAASuH,EAAY,CAE9B,GAAI,EAAEvH,EAAM,KAAK,gBAAgBwH,GAC/B,MAAO,CACP,EAGF,GAAI,CAAChI,EAAaQ,EAAOyH,EAAa,EACpC,MAAO,CACP,EAGF,IAAMC,EAAwB1H,EAAM,KAAK,KACnC2H,EAAYnI,EAAakI,EAAcN,EAAY,EAAIM,EAAe,OAE5E,GAAI1H,EAAM,OAASsH,EAAK,MAAQK,GAAW,eAA8B,EAAG,CAC1ER,EAAiBQ,EACjB,MAAMN,CACR,CACF,CAEA,MAAO,CACP,CACF,CAEA,IAAMO,EAAa,IAAI,IACjBC,EAA6B,CACnC,EAEA,QAAW7H,KAAUmH,GAAgB,KAAK,aAAe,CACzD,EAAI,CACF,IAAMvH,EAAOI,EAAM,KACb8H,EAAY9H,EAAM,KAAK,KAG7B,GAAI4H,EAAW,IAAIhI,CAAI,GAAK,EAAEkI,aAAqBN,GACjD,MAAO,CACP,EAGFI,EAAW,IAAIhI,CAAI,EAEnB,IAAMmI,EAAYD,EAAU,KAAK,EAC3BE,EAAW,CACf,GAAG7C,EAAS,IAAK8C,GAAMA,EAAE,KAAK,CAAC,EAC/BF,CACF,EACM,CACJG,EACA,GAAG9C,CACL,EAAI4C,EAEErC,EAAYjH,EAChB,CACE,IAAKwJ,EACL,MAAOjB,EAAc,KAAK,KAC5B,EACA,CACE,OAAQ7B,CACV,CACF,EAEAyC,EAAc,KAAKpF,EAAUkD,EAAWoC,EAAW,CACjD,KAAM,EACR,CAAC,CAAc,CACjB,CAEA,OAAOF,CACT,CAEA,SAASM,GAA6BhM,EAAkC,CACtE,GAAI,EAAEA,EAAW,KAAK,gBAAgBiM,IACpC,MAAO,CACP,EAGF,IAAMpB,EAAY7K,EAAW,KAAK+D,CAAU,EAC5C,GAAI,EAAE8G,aAAqB9G,IAAe,CAAC8G,EAAU,eAA8B,EACjF,MAAO,CACP,EAGF,IAAIqB,EAASrB,EAAU,OACjBsB,EAAiBtB,EAAU,KAC7BG,EAA+F3H,EAAa8I,EAAgBlB,EAAY,EAAIkB,EAAiB,OAEjK,KAAOD,IAAW,QAAW,CAC3B,GAAIA,aAAkBD,GAAW,CAC/BC,EAASA,EAAO,OAChB,QACF,CAEA,GAAI,EAAEA,aAAkBnD,IACtB,MAAO,CACP,EAGF,IAAMqD,EAAMF,EAAO,MACnB,GAAIE,aAAeC,GACjB,MAGF,GAAI,EAAED,aAAef,GACnB,MAAO,CACP,EAGF,IAAIiB,EAAU,GACRC,EAAgDC,GAAkBxB,EAAgC,KAAK,aAAe,CAC5H,EAAGM,EAAa,EAChB,QAAWmB,KAAkBF,EAC3B,GAAIE,EAAe,OAASL,EAAI,KAAM,CACpCE,EAAU,GACVtB,EAAiByB,EAAe,KAAK,KACrC,KACF,CAGF,GAAI,CAACH,EAAS,MAAO,CACrB,EAEAJ,EAASA,EAAO,MAClB,CAEA,IAAMR,EAAgB,CACtB,EAEMgB,EAAa1M,EAAW,KAAK,KAE7BuM,EAAgDC,GAAkBxB,EAAgC,KAAK,aAAe,CAC5H,EAAGM,EAAa,EAChB,QAAWmB,KAAkBF,EAAa,CACxC,IAAMI,EAAgBF,EAAe,KAAK,gBAAgBpB,EACtDoB,EAAe,KAAK,KAAK,KAAK,EAC9B,IAAIpB,EAAe,CACnB,KAAMoB,EAAe,KAAK,MAAM,SAAS,CAC3C,CAAC,EACGG,EAAS7D,GAAQ,MAAM,CAC3B2D,EAAW,KAAK,EAChBC,CACF,CAAC,EACKE,EAAWvG,EAAMsG,EAAQD,EAAe,CAC5C,KAAM,EACR,CAAC,EACDjB,EAAc,KAAKmB,CAAQ,CAC7B,CAEA,OAAOnB,CACT,CAEA,SAAS3J,GACPd,EACAM,EACAG,EACAV,EACAN,EACM,CACN,IAAMgL,EAA8B,CACpC,EACMvB,EAAgB,IAAI,IACpB2C,EAAoB,IAAI,IACxBC,EAAmB,IAAI,IACvBC,EAAkB,IAAI,IACtBjM,EAAeQ,EAAS,QAAQ,aAElC0L,EACEC,EAAsB,IAAI,IAE1BlD,EAAQmD,EAAOlM,EAAM,OAAQ,CAAC,EACpC,GAAI+I,aAAiBL,IAAa,CAACK,EAAM,iBAAiB,OACxD,GAAIA,EAAM,QAAS,CACjBiD,EAAqB/J,GAAe8G,CAAK,EAAE,IAAKoD,GAAMA,EAAE,UAAU,EAElE,QAAWvJ,KAASmG,EAAM,KAAK,QAAU,CACzC,EACE,GAAInG,aAAiBC,GACnB,QAAWG,KAAKJ,EAAM,KAAK,YACzB,QAAWuJ,KAAMnJ,EAAiB,QAAQF,CAAU,EAClDmJ,EAAoB,IAAIE,EAAE,UAAU,CAK9C,KAAO,CACL,QAAWA,KAAKpD,EAAM,QAAQjG,CAAU,EACtCmJ,EAAoB,IAAIE,EAAE,UAAU,EAItCH,GADqBjD,EAAM,UAAU,SAAS,GACR,CACtC,GAAG,IAAKoD,GAAOA,EAAiB,UAAU,EACrCH,EAAmB,SACtBA,EAAsBjD,EAAM,KAAK,YAA6B,IAAKoD,GAAMA,EAAE,WAAW,EAE1F,CAGErM,EAAa,gCAAkCE,EAAM,MAAM,KAAMyB,GAAQA,aAAeqG,EAAO,GACjGrI,EAAU,cAAcO,CAAK,EAG/B,QAAWjB,KAAciB,EAAM,WAAW,QAAS,CACjD,IAAMiJ,EAAmB,CACzB,EAEA,GAAIlK,aAAsBqM,GACxBnC,EAAO,KAAK,GAAG,OAAO,KAAKjJ,EAAM,eAAe,CAAC,EACjDgJ,GAAiBjK,EAAYkK,EAAQC,CAAa,EAClDO,GAAkB1K,EAAYkK,EAAQ4C,CAAiB,EACvDxC,GAAiBtK,EAAYkK,EAAQ6C,CAAgB,UAC3C/M,EAA0B,OACpC,GAAMA,aAAsB+I,IASrB,GAAIhI,EAAa,gCAAkC,CAACA,EAAa,qCAAsC,CAC5G,IAAMsM,EAAezC,GAA0B5K,CAAqB,EACpE,GAAI,EAAIqN,EAAa,OAAQ,CAC3B3B,EAAc,KAAK,GAAG2B,CAAY,EAClC,QACF,CACF,SAAWtM,EAAa,qCAAsC,CAC5D,IAAMsM,EAAerB,GAA4BhM,CAAqB,EACtE,GAAI,EAAIqN,EAAa,OAAQ,CAC3B3B,EAAc,KAAK,GAAG2B,CAAY,EAClC,QACF,CACF,MArBsC,CACpC,IAAMC,EAAYtN,aAAsB+D,EAAa/D,EAAW,MAAQ,GACpEsN,GAAWpD,EAAO,KAAKoD,CAAS,EACpC,IAAMC,EAAYvN,EAA0B,KAAK,KAC7CuN,aAAoBjK,IACtB2G,GAAiBsD,EAAUrD,EAAQC,CAAa,EAChDO,GAAkB6C,EAAUrD,EAAQ4C,CAAiB,EACrDxC,GAAiBiD,EAAUrD,EAAQ6C,CAAgB,EAEvD,CAeF,GAAI7C,EAAO,SAAW,EAAG,CACvBwB,EAAc,KAAK1L,CAAwB,EAC3C,QACF,CAEA,QAAWmE,KAAS+F,EAAQ,CAC1B,GAAI,CAACjJ,EAAM,QAAQ,IAAIkD,CAAK,EAC1B,MAAM,IAAInB,EAAc,kBAAkBmB,CAAK,EAAE,EAGnD,IAAIS,EAAUrD,EAAS,iBAAiB4C,EAAO,CAC7C,YAAa,EACf,CAAC,EAOD,GANKS,EAAQ,SAAQA,EAAU3D,EAAM,cAEjC,EAAID,EAAc,MAAQD,EAAa,mCACzC6D,EAAUA,EAAQ,OAAQnB,GAAS,CAACzC,EAAc,IAAIyC,EAAK,YAAY,CAAC,CAAC,GAGvE,CAACmB,EAAQ,QAAUA,EAAQ,SAAS,GAAG,EACzC,OAGF,IAAM4I,EAAmBrD,EAAc,IAAIhG,CAAK,GAAK,IAAI,IACnDsJ,EAAiBV,EAAiB,IAAI5I,CAAK,GAAK,CAAC,EACjDuJ,EAAkBZ,EAAkB,IAAI3I,CAAK,GAAK,CAAC,EAEzD,GAAI6F,aAAiBL,GAAW,CAC9B,IAAIgE,EAQJ,GAPIV,GAAsB,EAAIC,EAAoB,MAChDS,EAAe/I,EAAQ,OAAQwI,GAAM,CAACF,EAAoB,IAAIE,CAAC,CAAC,EAChEO,EAAa,KAAK,GAAGV,CAAkB,GAEvCU,EAAe3D,EAAM,iBAGnB,EAAI2D,EAAa,OAAQ,CAC3B,QAAWlK,KAAQkK,EACZH,EAAiB,IAAI/J,CAAI,GAC5BiI,EAAc,KACZpF,EAAU/D,EAAW,CACnB,IAAKkB,EACL,MAAOuG,EAAM,KACf,CAAC,EAAGvG,EAAM,CACR,KAAM,EACR,CAAC,CACH,EAGJ,QACF,CACF,CAEA,QAAWA,KAAQmB,EAAS,CAC1B,GAAI4I,EAAiB,IAAI/J,CAAI,GAAKuJ,EAAgB,IAAIvJ,CAAI,EAAG,SAE7D,IAAMmK,EAAelM,EAAkB,IAAI+B,CAAI,EAC/C,GAAImK,GAAc,SAASzJ,CAAK,EAAG,CACjC6I,EAAgB,IAAIvJ,CAAI,EACxB,IAAM2C,EAAewH,EAAa,IAAK5H,GAAMzD,EAAW,CACtD,IAAKkB,EACL,MAAOuC,CACT,CAAC,CAAC,EACF0F,EAAc,KACZpF,EACE,IAAIL,GAAa,CACf,KAAMG,EAAa,CAAC,EACpB,YAAaA,EAAa,MAAM,CAAC,CACnC,CAAC,EACD3C,EACA,CACE,KAAM,EACR,CACF,CACF,CACF,KAAO,CACL,IAAMoK,EAASJ,EAAehK,CAAI,GAAKA,EACjCqK,EAAgBJ,EAAgBjK,CAAI,GAAKlB,EAAW,CACxD,IAAKkB,EACL,MAAAU,CACF,CAAC,EACDuH,EAAc,KACZmC,IAAWpK,EACP6C,EAAUwH,EAAeD,EAAQ,CACjC,KAAM,EACR,CAAC,EACCC,CACN,CACF,CACF,CACF,CACF,CAEI,EAAIpC,EAAc,QAAUzK,EAAM,sBAAsBI,GAC1DJ,EAAM,WAAW,UAAU,cAAeyK,CAAa,CAE3D,CAEO,SAAS1J,GAAgB+L,EAA6C,CAC3E,IAAIC,EAEJ,GAAID,aAA6BlE,EAC/BmE,EAAgBD,MACX,CACL,IAAME,EAAQC,EAAWH,CAAiB,EAC1C,GAAI,EAAEE,aAAiBpE,GAAQ,OAC/BmE,EAAgBC,CAClB,CAEA,GAAI,EAAED,EAAc,sBAAsB3M,GACxC,OAGF,IAAM8M,EAAUH,EAAc,WAAW,QACnCI,EAAeJ,EAAc,aAC7BtC,EAA8B,CACpC,EACM2C,EAAS,KAAK,IAAIF,EAAQ,OAAQC,EAAa,MAAM,EAE3D,QAASnJ,EAAI,EAAGA,EAAIoJ,EAAQpJ,IAAK,CAC/B,IAAIqJ,EAAYH,EAAQlJ,CAAC,EACnBsJ,EAAgBH,EAAanJ,CAAC,EAEpC,GAAI,CAACqJ,GAAaA,aAAqBE,GACrC,MAGEF,aAAqBG,EAClBH,EAAU,YACbA,EAAU,UAAU,QAAS,IAAIhK,EAAe,CAC9C,KAAMmC,EAAa,QAAQxB,CAAC,EAAE,CAChC,CAAC,CAAC,EAEK,EAAEqJ,aAAqBhG,IAAc,EAAEgG,aAAqBI,KAAgB,CAACJ,EAAU,SAChGA,EAAYhI,EACVgI,EACAA,EAAU,YAAc,QAAQrJ,CAAC,GACjC,CACE,KAAM,EACR,CACF,GAGEsJ,GACFD,EAAU,UAAU,QAAS7H,EAAa8H,CAAa,CAAC,EAG1D7C,EAAc,KAAK4C,CAAS,CAC9B,CAEI,EAAI5C,EAAc,QAAUsC,EAAc,sBAAsB3M,GAClE2M,EAAc,WAAW,UAAU,cAAetC,CAAa,CAEnE,CAEA,SAASiD,GAAa1N,EAAc+F,EAA8B,CAChE,IAAM4H,EAAQ,OAAO5H,EAAK,KAAK,IAAI,EAAI,EACjC6H,EAAS5N,EAAM,WAAW,QAAQ2N,CAAK,EAC7C,GAAI,EAAEC,aAAkBvG,GACtB,MAAM,IAAItF,EAAc,0BAA0BgE,EAAK,IAAI,EAAE,EAE/D,OAAO6H,CACT,CAEA,SAASC,GACP7N,EACAsL,EACA1L,EACAZ,EAA6B,CAAC,EAChB,CACd,GAAM,CACJ,MAAAqG,EAAQ,EACV,EAAIrG,EACEc,EAAeF,EAAQ,aACvBkO,EAAyB,CAC/B,EACIC,EAEJ,QAAWhI,KAAQuF,EACjB,GAAIvF,EAAK,UAAW,CAClB,IAAM6H,EAASF,GAAY1N,EAAO+F,CAAmB,EACrD,GAAIV,EAAO,CACT,IAAM2I,EAAcJ,EAAO,MAC3BE,EAAS,KAAKE,EACV1M,EAAW,CACX,IAAK0M,CACP,CAAC,EACCjI,CAAI,CACV,KAAO,CACL,IAAMkI,EAAaL,EAAO,KAAK,KAC3BM,EAAY,GAEZpO,EAAa,yCACXiO,IAAyB,SAC3BA,EAAuB,IAAI,IACzB/N,EAAM,WAAW,QACd,IAAK4F,GAAMA,EAAE,WAAW,EACxB,OAAQpD,GAASA,KAAQxC,EAAM,eAAe,CACnD,GAEFkO,EAAY,MAAM,KAAKD,EAAW,QAAQnL,CAAU,CAAC,EAAE,KACpDrB,GAAQsM,GAAsB,IAAItM,EAAI,MAAM,CAAC,GAAG,MAAQ,EAAE,CAC7D,GAIA0M,GAAU,KAAMC,GAAMH,aAAsBG,CAAC,GAC1CH,EAAW,UACXA,EAAW,KAAKI,EAAW,GAC3BJ,EAAW,KAAKK,EAAU,GAC1BJ,EAEHJ,EAAS,KAAK/H,CAAI,EAElB+H,EAAS,KAAKG,EAAW,KAAK,CAAC,CAEnC,CACF,MACEH,EAAS,KAAK/H,CAAI,EAItB,OAAO+H,CACT,CAEA,SAAS9M,GAAehB,EAAcJ,EAAwB,CAC5D,IAAM2O,EAASvO,EAAM,WAA0B,KAAK,MACpD,GAAI,CAACuO,EAAO,OAEZ,IAAMC,EAAmBjD,GAAiBgD,EAAM,KAAK,aAAe,CACpE,EAAGlM,CAAU,EACbkM,EAAM,UAAU,cAAeV,GAA2B7N,EAAOwO,EAAkB5O,CAAO,CAAC,EAC1FI,EAAM,WAA0B,UAAU,QAASuO,CAAK,CAC3D,CAEA,SAAStN,GAA4BjB,EAAcM,EAA0B,CAC3E,QAAWmO,IAAe,CACxB,QACA,UACF,EAAG,CACD,IAAIC,EAAW1O,EAAM,WAAW,UAAUyO,CAAW,EAMrD,GAJIC,aAAoBC,KACtBD,EAAWA,EAAS,KAAK,IAGvB,EAAEA,aAAoBrM,GACxB,SAGF,IAAIuM,EAAsBF,EAAS,KAAK,YAEpCD,IAAgB,UAClBG,EAAsBA,EAAoB,IACvCnL,GAAYA,EAAQ,KAAK,IAC5B,GAGF,IAAMoL,EAAWhB,GAA2B7N,EAAO4O,EAAqBtO,EAAS,QAAS,CACxF,MAAO,EACT,CAAC,EAED,QAASkD,EAAI,EAAGA,EAAIoL,EAAoB,OAAQpL,IAAK,CACnD,IAAMsL,EAAWF,EAAoBpL,CAAC,EAChCuL,EAAeF,EAASrL,CAAC,EAE/B,QAAWwL,KAAOF,EAAS,QAAQlI,CAAW,EAC5C,QAAWnF,KAAOuN,EAAI,QAAQlM,CAAU,EACtC,GAAI,CAACrB,EAAI,MAAO,CACd,IAAMyB,EAAQ5C,EAAS,SAASmB,EAAI,IAAI,EACpCyB,GACFzB,EAAI,UAAU,QAASyB,CAAK,CAEhC,CAIJ4L,EAAS,QAAQC,CAAY,CAC/B,CAEA,GAAI/O,EAAM,WAAW,UAAU,OAAO,EAAG,CACvC,IAAMiP,EAAa,IAAI,IACrBjP,EAAM,WAAW,QACd,OAAQ4F,GAAsBA,aAAayB,CAAS,EACpD,IAAKzB,GAAM,CACTA,EAAE,KAAK,KAAoB,IAAI,EAChCtE,EAAW,CACT,IAAKsE,EAAE,WACT,CAAC,CACH,CAAC,CACL,EAEA,QAAWsJ,KAAQN,EACjB,GAAIM,EAAK,UACPA,EAAK,QAAQ1J,EAAakI,GAAY1N,EAAOkP,CAAmB,EAAE,KAAK,CAAC,MACnE,CACL,IAAMC,EAAQF,EAAW,IAAIC,EAAK,IAAI,CAAC,EACnCC,GAAOD,EAAK,QAAQC,CAAK,CAC/B,CAEJ,CACF,CACF,CAEO,SAASC,GACdrQ,EACAC,EAGI,CAAC,EACO,CACZ,GAAM,CACJ,QAASM,EAAY,SAAA+P,EAAW,EAClC,EAAIrQ,EACEY,EAAUC,EAAQ,WAAWP,CAAU,EAC7C,OAAOP,EAAW,UAChBa,EAAQ,gBAAgB,KAAKA,CAAO,EACpC,CACE,SAAAyP,EACA,KAAM,EACR,CACF,CACF,CAEO,SAASnP,GAAyBF,EAAoB,CAC3D,QAAWsP,KAAOtP,EAAM,KAAM,CAC5B,IAAMuP,EAAmBD,EAAI,iBAC7B,GAAI,EAAIC,EAAiB,QAAUD,EAAI,KAAK,gBAAgBlP,EAAY,CACtE,IAAMoP,EAAaF,EAAI,KAAK,KACtBhE,EAAckE,EAAW,KAAK,aAAe,CACnD,EACMC,EAA+B,CACrC,EAEA,QAASzL,EAAI,EAAGA,EAAIuL,EAAiB,OAAQvL,IAAK,CAChD,IAAM4I,EAAS2C,EAAiBvL,CAAC,EAC3BoD,EAAakE,EAAYtH,CAAC,EAChC,GAAI,CAACoD,EAAY,MAEjB,IAAIsI,EACAtI,aAAsBC,GACxBD,EAAW,UAAU,QAAS5B,EAAaoH,CAAM,CAAC,EAClD8C,EAAgBtI,GAEhBsI,EAAgBrK,EAAU+B,EAAYwF,CAAM,EAE9C6C,EAAe,KAAKC,CAAa,CACnC,CAEAF,EAAW,UAAU,cAAeC,CAAc,CACpD,CACF,CACF,CC54CO,SAASE,GACdC,EACAC,EAMI,CAAC,EACF,CACH,GAAM,CACJ,GAAIC,EACJ,QAASC,EACT,UAAAC,EACA,QAASC,EACT,yBAAAC,EAA2B,EAC7B,EAAIL,EAEEM,EAAUC,EAAQ,WAAWH,CAAU,EACvCI,EAAgBC,GAAa,GAAG,EAElCC,EACAT,IACFS,EAAKC,GAAgBV,EAAO,CAC1B,QAAAK,CACF,CAAC,EACDI,EAAG,KAAK,QAAU,GAClBA,EAAKE,GAAqBF,EAAI,CAC5B,QAAAJ,CACF,CAAC,GAGH,IAAIO,EACAX,IACFW,EAAUF,GAAgBT,EAAY,CACpC,QAAAI,CACF,CAAC,EACDO,EAAQ,KAAK,QAAU,GACvBA,EAAUD,GAAqBC,EAAS,CACtC,QAAAP,CACF,CAAC,GAGH,IAAMQ,EAAWC,GAA2B,CACtCA,EAAM,KAAK,gBAAgBC,IACzBN,GAAM,CAACK,EAAM,KAAK,IACpBA,EAAM,UAAU,KAAML,EAAG,KAAK,CAAC,EAE7BG,GAAW,CAACE,EAAM,KAAK,SAAWA,EAAM,KAAK,IAC/CA,EAAM,UAAU,UAAWF,EAAQ,KAAK,CAAC,EAG/C,EAEA,IAAKH,GAAMG,IAAY,EAAEd,aAAsBkB,IAAY,CAEzD,IAAMC,EADanB,EAAW,UAAU,MAAM,GAClB,IAAIoB,EAAS,CACvC,YAAa,CACb,CACF,CAAC,EACKC,EAAW,IAAI,KAClBF,EAAM,KAAK,aAAe,CAC3B,GAAG,IAAKG,GAAQA,EAAI,WAAW,CACjC,EAEA,QAAWC,KAAQvB,EAAW,KAAK,CACjC,MAAQwB,GAAMA,aAAaN,EAC7B,CAAC,EACKK,aAAgBE,IACbJ,EAAS,IAAIE,EAAK,IAAI,GACzBR,EAAQQ,CAAI,EAIpB,CAEA,IAAMG,EAAW,CACfC,EACAC,EACA3B,EAKI,CAAC,IACI,CACT,GAAM,CACJ,YAAA4B,EAAa,MAAAC,EAAO,UAAAC,EAAY,GAAO,QAAAC,CACzC,EAAI/B,EAEAgC,EAAQN,EAAK,UAAU,OAAO,EAC7BM,IACHA,EAAQ,IAAIC,EAAe,CAAC,CAAC,GAG/B,IAAIC,EACJ,GAAI7B,EACF6B,EAAe1B,EAAc,EAC7BmB,EAAiB,IAAIK,EAAM,MAAQJ,GAAe,GAAIM,CAAY,UACzD,CAACF,EAAM,KAChBE,EAAeN,GAAepB,EAAc,EACxCsB,GAAaF,IACfM,EAAetB,GAAqBsB,EAAc,CAChD,QAAA5B,CACF,CAAC,EAAE,UAGL,QAGF0B,EAAM,UAAU,OAAQG,EAAaD,CAAY,CAAC,EAE9CH,GACFC,EAAM,UAAU,UAAWD,EAAQ,IAAKK,GAAMD,EAAaC,CAAC,CAAC,CAAC,EAGhEV,EAAK,UAAU,QAASM,CAAK,EAEzBH,GACFA,EAAM,aAAa,GAAIK,CAAY,CAEvC,EAEA,QAAWL,KAASQ,EAActC,CAAU,EAAG,CAC7C,IAAMuC,EAAeT,EAAM,aACrBF,EAAmB,IAAI,IAE7B,QAAWY,KAASV,EAAM,WAAY,CACpC,IAAMW,EAAWD,EAAM,OACnBC,GAAYA,aAAoBC,GAClCD,EAAS,OAAO,EAAE,QAAQA,CAAQ,CAEtC,CAEA,QAAWE,KAAgBb,EAAM,cAAe,CAC9C,IAAMc,EAAWD,EAAa,OAAO,EACrC,GAAIC,aAAoBnB,EAAW,CACjC,IAAMoB,EAAQD,EAAS,KAAK,MAC5BA,EAAS,UAAU,QAAS,MAAS,EAErC,IAAME,EAAcH,EAAa,KAAK,KACtC,GAAIG,aAAuBC,EAAY,CACrC,IAAMC,EAAYC,GAAO,GAAG,EAAE,KAAKL,EAAS,KAAK,EAAG,CAClD,KAAM,EACR,CAAC,EACDE,EAAY,QAAQE,CAAS,EAG7BA,EAAU,UAAU,QAASH,CAAK,CACpC,CACF,CAEAnB,EAASiB,EAAcf,EAAkB,CACvC,MAAAE,CACF,CAAC,EAED,IAAMoB,EAAQC,EAAOR,EAAa,UAAU,QAAQ,GAAqB,CACzE,EAAG,CAAC,EACAO,GACFxB,EAASwB,EAAOtB,CAAgB,CAEpC,CAEA,IAAMwB,EAAe,IAAI,IAEzB,OAAW,CACTC,EACAC,CACF,IAAKxB,EAAM,QACT,GAAIwB,aAAkB7B,EAAW,CAC/B,IAAM8B,EAAoB,EAAQF,EAE5BG,EAASF,EAAO,KAAK,OACrBJ,EAAQM,EAASL,EAAOK,EAAQ,CAAC,EAAI,OACvCC,EAAaJ,EACbH,IACFO,EAAaH,EAAO,MAGtB,IAAMI,EAAYJ,EAAO,KAAK,KACxBK,EAAaL,EAAO,KAAK,MAC3BM,EAA+C,CACnD,EAEA,GAAIF,GAAaA,aAAqBG,GAAU,CAE9C,IAAMC,GADOJ,EACa,YAAY,KAEtC,GAAKC,EAMMA,aAAsBzB,GAAkByB,EAAW,KAAK,SAAS,OAC1EC,EAAkBD,EAAW,QACpBpD,EAAQ,aAAa,+BAA+B,IAAIuD,EAAY,IAC7EF,EAAkB,MAAM,KAAKG,GAAWT,EAAO,WAAW,CAAC,EAC3DA,EAAO,UAAU,QAAS,MAAS,EACnCG,EAAa,QAXE,CACf,IAAMO,GAAczD,EAAQ,aAAa,+BAA+B,IAAIuD,EAAY,EACxFF,EAAkBI,GACd,MAAM,KAAKD,GAAWC,EAAW,CAAC,EAClC,CACF,CACJ,CAOF,CAEAtC,EAAS4B,EAAQ1B,EAAkB,CACjC,YAAa6B,GAAcH,EAAO,MAAQ,OAC1C,UAAW,GACX,QAASM,CACX,CAAC,EAED,IAAMK,GAAYX,EAAO,OAAO,IAAKY,IAAMA,GAAE,IAAI,EAAE,KAAK,GAAG,EACrDC,GAAkBb,EAAO,KAAK,OAAO,KAAK,KAKhD,GAJIa,cAA2BlD,GAC7BmC,EAAa,IAAIa,GAAWE,GAAgB,KAAK,CAAC,EAGhDjB,EAAO,CACT,IAAMrB,GAAcqB,EAAM,UAAU,SAAS,EAAII,EAAO,MAAQ,OAMhE,GALA5B,EAASwB,EAAOtB,EAAkB,CAChC,YAAAC,GACA,UAAW,EACb,CAAC,EAEGC,EAAM,QAAQ,IAAIwB,EAAO,WAAW,YAAac,EACnD,QAEJ,CAEIb,IACFxC,EAAQuC,CAAM,EAEVlD,GACFA,EAAUkD,CAAM,EAGtB,SAAWA,aAAkBc,GAASd,EAAO,OAAQ,CACnD,IAAMe,EAAOf,EAAO,WAGpB,GAFA5B,EAAS2C,EAAMzC,CAAgB,EAE3ByC,aAAgBC,GAAY,CAC9B,IAAMX,EAAaU,EAAK,UAAU,OAAO,EACrCV,aAAsBzB,GAAkB,CAACyB,EAAW,KAAK,SAAS,QACpEA,EAAW,UAAU,UAAWpD,EAC7B,sBAAsB8D,CAAI,EAC1B,IAAKE,GAAsB1D,GAAqB0D,EAAG,CAClD,QAAAhE,CACF,CAAC,CAAC,CAAC,CAET,CACF,CAGF,QAAWS,KAASc,EAAM,OACxB,GAAI,CAACd,EAAM,OAASA,EAAM,OAAQ,CAChC,IAAMwD,EAASxD,EAAM,QACjBwD,aAAkBC,GAAYD,aAAkBE,IAClDhD,EAASV,EAAOY,EAAkB,CAChC,YAAaZ,EAAM,IACrB,CAAC,CAEL,CAGF,QAAW2D,KAAUpC,EAAc,CACjC,IAAMvB,EAAQ2D,EAAO,MAErB,GAAIA,EAAO,KAAK,GAAI,CAClB,IAAMC,EAAcD,EAAO,MAAM,MAAM,EAAG,EAAE,EAAE,IAAKT,GAAMA,EAAE,IAAI,EAC5D,KAAK,GAAG,EACLP,EAAaP,EAAa,IAAIwB,CAAW,EAE3CjB,IACFgB,EAAO,UAAU,QAAS,MAAS,EACnCA,EAAO,UAAU,KAAM,MAAS,EAChCA,EAAO,UAAU,UAAW,MAAS,EACrCA,EAAO,UAAU,QAAShB,EAAW,KAAK,CAAC,EAE/C,SAAW,EAAI/B,EAAiB,MAAQZ,EAAO,CAC7C,IAAM6D,EAAiBjD,EAAiB,IAAIZ,CAAK,EAC7C6D,GAAkBA,IAAmBF,EAAO,OAC9CA,EAAO,UAAU,QAASvC,EAAayC,CAAc,CAAC,CAE1D,CACF,CACF,CAEA,OAAO7E,CACT,CC3RO,SAAS8E,GACdC,EACAC,EAiBI,CAAC,EACF,CACH,GAAM,CACJ,QAASC,EACT,GAAAC,EACA,QAAAC,EACA,OAAQC,EACR,gBAAAC,EAAkB,GAClB,YAAAC,EAAc,GACd,YAAAC,EACA,cAAAC,EAAgB,GAChB,eAAgBC,EAAqB,GACrC,0BAAAC,EAA4B,GAC5B,uBAAwBC,EAA6B,GACrD,iBAAkBC,EAAuB,GACzC,SAAAC,EAAW,GACX,yBAAAC,EAA2B,GAC3B,UAAAC,EACA,IAAAC,CACF,EAAIhB,EAEEiB,EAASC,EAAad,EAAW,CACrC,QAASH,CACX,CAAC,EACKkB,EAAUC,EAAQ,WAAWnB,CAAU,EAE7C,OAAAF,EAAasB,GAAqBtB,EAAY,CAC5C,QAAAoB,EACA,+BAAgC,EAClC,CAAC,EAEDpB,EAAauB,GAAcvB,EAAY,CACrC,GAAAG,EACA,QAAAC,EACA,QAAAgB,EACA,UAAAJ,EACA,yBAAAD,CACF,CAAC,EAEGN,IACFT,EAAawB,GAAoBxB,EAAY,CAC3C,OAAAkB,EACA,QAAAE,CACF,CAAC,GAGCV,IACFV,EAAayB,GAAezB,EAAY,CACtC,OAAAkB,EACA,gBAAAZ,EACA,YAAAC,EACA,YAAAC,EACA,0BAAAG,CACF,CAAC,GAGCE,IACFb,EAAa0B,GAAiB1B,EAAY,CACxC,QAAAoB,EACA,SAAAN,CACF,CAAC,GAGCF,GACFe,GAAuB3B,EAAYiB,CAAG,EAGjCjB,CACT,CC9EO,SAAS4B,GAAwCC,EAAkB,CACxE,IAAMC,EAAgBC,GAAa,KAAK,EAExC,QAAWC,KAASC,EAAcJ,CAAU,EAAG,CAC7C,IAAMK,EAASF,EAAM,WACfG,EAASD,EAAO,aAMtB,GAJI,CAACC,GAAU,CAACC,EAAaD,EAAQE,CAAU,GAI3C,CAACD,EAAaF,EAAQG,CAAU,EAClC,SAGF,IAAMC,EAAyBJ,EAE3B,EAAIF,EAAM,gBAAgB,OAC5BO,GAAYD,EAAYH,EAAQH,EAAM,gBAAiBF,CAAa,EAC3DE,EAAM,YAAc,YAC7BQ,GAAOF,EAAYH,EAAQL,CAAa,CAE5C,CAEA,OAAOD,CACT,CAEA,SAASW,GACPF,EACAG,EACAX,EACM,CACN,GAAI,EAAIQ,EAAW,QAAQ,OACzB,OAGF,IAAMI,EAAYJ,EAAW,aAAaK,EAAa,EACvD,GACE,CAACD,GAICA,aAAqBE,KACjBF,EAAU,kBAAkBG,GAC3BH,EAAU,kBAAkBI,GAC5BJ,EAAU,kBAAkBK,IAEhCN,IAAiBC,EAAU,cAC3B,CAACD,EAAa,KAAK,KAEtB,OAGF,IAAIO,EAAcV,EACdA,aAAsBW,KACxBD,EAAcd,GAAOI,EAAW,OAAO,EAAE,KAAKA,EAAW,SAASR,EAAc,CAAC,EAAG,CAClF,KAAM,EACR,CAAC,GAGH,IAAMoB,EAAYpB,EAAc,EAC1BqB,EAAST,EAAU,aAAaU,GAAYC,EAAWN,CAAQ,EAGrE,GAAI,EAAEL,aAAqBY,IAAUZ,aAAqBa,IAAU,CAClE,IAAIC,EAAyBC,EAAO,CAClC,IAAKT,EAAY,QAAQ,CAAC,EAAE,YAC5B,MAAOE,CACT,CAAC,EAEKQ,EAAqBP,GAAQ,aAEnC,GACGA,aAAkBC,IAAcM,IAAuBjB,IAErD,CAACU,GAAUO,IAAuBjB,KAEjCA,EAAa,KAAK,OACfA,EAAa,QAAQ,KAAMkB,GAAQC,GAAYD,EAAKE,CAAW,CAAC,GAIvEL,EAAa,IAAIM,GAAQ,CACvB,KAAMN,CACR,CAAC,UACQ,EAAElB,EAAW,kBAAkByB,GACxC,OAGF,IAAIC,UACAC,EACAvB,aAAqBwB,KAIvBV,EAAaA,EAAW,GAAGW,GAAM,CAAC,EAAE,IAAI,EACxCH,EAAW,OACXC,EAAWG,EAAM,GAGnBC,EAAQ/B,EAAW,OAAsBkB,CAAU,EACnDf,EAAa,KAAKO,EAAa,CAC7B,GAAIiB,EACJ,SAAAD,EACA,UAAWd,EACX,KAAM,EACR,CAAC,EAED,MACF,CAEA,GAAIF,EAAY,KAAK,CACnBsB,GACAC,EACF,CAAC,EACC,OAGF,IAAIC,EAA4C9B,EAChD,GAAIA,aAAqBa,GAAS,CAChC,IAAMkB,EAAc/B,EAAU,aAAagC,CAAM,EAEjD,GAAI,CAACD,GAAehC,IAAiBgC,EAAY,aAC/C,OAGFD,EAAiBC,CACnB,CAEA,IAAMjB,EAAamB,GAAaH,CAAc,EACxCI,EAAQ5B,EAAY,QAAQ,CAAC,EAC7B6B,EAAYD,EAAM,KAAK,KAC7B,GAAI,EAAEC,aAAqBC,GACzB,OAGF,IAAMC,EAAUtB,EAAO,CACrB,IAAKmB,EAAM,MACX,MAAO1B,CACT,CAAC,EACK8B,EAAiBD,EAAQ,GAAGZ,GAAM,CAAC,EAAE,IAAI,EAE3ChB,aAAkBJ,GACpBsB,EAAQG,EAAgBJ,EAAM,CAAC,EAC/B3B,EAAa,MAAMuC,EAAgB,CACjC,KAAM,EACR,CAAC,GAEDX,EAAQG,EAAgBQ,CAAc,EAGxC,IAAMC,EAAQjC,EAAY,KAAK,MAE/B,GAAIiC,EAAO,CAET,IAAMC,EAAgB,IAAI,KAAKD,EAAM,KAAK,aAAe,CACzD,GAAG,IAAKE,GAAOA,aAAaL,EAAaK,EAAE,IAAI,EAAI,OAAOA,CAAC,CAAE,CAAC,GAC1DD,EAAc,OAAS,GAAK,CAACA,EAAc,IAAKN,EAAM,KAAK,KAAoB,IAAI,CAAC,KACtF5B,EAAcd,GACZkD,EAAM3B,EAAO,CACX,IAAKmB,EAAM,MACX,MAAO,IACT,CAAC,EAAGA,EAAM,MAAO,CACf,KAAM,EACR,CAAC,CACH,EACG,KAAK5B,EAAY,SAAS,KAAM,CAC/B,KAAM,EACR,CAAC,EAAG,CACF,KAAM,EACR,CAAC,EACA,QAAQS,EAAO,CACd,IAAKmB,EAAM,MACX,MAAO,IACT,CAAC,EAAG,CACF,KAAM,EACR,CAAC,EAEP,MAAYhB,GAAYiB,EAAWhB,CAAW,IAC5Cb,EAAcA,EAAY,QAAQ6B,EAAW,CAC3C,KAAM,EACR,CAAC,GAGErB,GAELf,EAAa,KACXO,EACA,CACE,GAAIQ,EAAW,GAAGuB,CAAO,EACzB,gBACA,UAAW7B,EACX,KAAM,EACR,CACF,CACF,CAEA,SAASX,GACPL,EACAO,EACA4C,EACAvD,EACM,CACN,IAAMwD,EAAQpD,EAAO,KAAK,MAE1B,GAAI,CAACoD,GAASA,EAAM,KAAKC,EAAM,GAAKrD,EAAO,KAAK,CAC9CoC,GACAC,EACF,CAAC,EACC,OAGF,IAAMiB,EAAa1D,EAAc,EAC3B2D,EAA+C,CACrD,EAIA,QAAWhC,KAAU4B,EAAiB,CACpC,GAAI5B,EAAO,aAAaJ,CAAS,IAAMiC,EACrC,OAGF,IAAM5C,EAAYe,EAAO,aAAaiC,EAAa,EAEnD,GAAI,CAAChD,GAAaA,EAAU,aAAaW,CAAS,IAAMiC,EACtD,OAGF,IAAIK,EAEJ,GAAIjD,aAAqBkD,EACvBD,EAAM,MAAM,KAAKjD,EAAU,MAAM,KAAK,GAAK,CAC3C,CAAC,EAAE,KAAMmD,GAASA,IAASpC,CAAM,EAC7Bf,EAAU,MACVA,EAAU,SAEd,QAGF,GAAI,CAACiD,EAAK,OAEVF,EAAK,KAAK,CACRE,EACAlC,EACAf,CACF,CAAC,CACH,CAEA,GAAI,CAAC+C,EAAK,KAAK,CAAC,CACd,CAAE,CAAE/C,CACN,IAAMA,aAAqBgC,CAAM,EAC/B,OAGF,IAAMoB,EAAuBrD,EAAa,QACvC,IAAKsD,GAAMA,EAAE,QAAQ,CAAC,EACtB,KAAMF,GAASA,aAAgB9B,GAAgB8B,IAAS3D,EAAO,MAAM,EAElE0C,EAAQ1C,EAAO,QAAQ,CAAC,EACxB2C,EAAYD,EAAM,KAAK,KAC7B,GAAI,EAAEC,aAAqBC,GAAa,OAGxC,IAAMkB,EAAkB,IAAI,IACtBC,EAAgB,IAAI,IACpBC,EAAc,IAAI,IAClBC,EAAwB,CAC9B,EAEMC,EAAiBC,GAA8BH,EAAY,IAAIG,EAAK,IAAI,CAAC,EAE/E,OAAW,CACTV,EAAK,CAAEjD,CACT,IAAK+C,EAAM,CACT,IAAMa,EAASX,EAAI,IAAI,EAEnBW,IAAWzB,EAAU,IAAI,GAC3BmB,EAAgB,IAAIM,EAAQ1B,EAAM,KAAK,EACvCqB,EAAc,IAAIK,EAAQX,CAAG,EACxBO,EAAY,IAAII,CAAM,IACzBJ,EAAY,IAAII,CAAM,EACtBH,EAAQ,KAAKR,CAAG,KAGbK,EAAgB,IAAIM,CAAM,IAC7BN,EAAgB,IAAIM,EAAQxE,EAAc,CAAC,EAC3CmE,EAAc,IAAIK,EAAQX,CAAG,GAI3BjD,aAAqBgC,GAAU,CAACwB,EAAY,IAAII,CAAM,IACxDJ,EAAY,IAAII,CAAM,EACtBH,EAAQ,KAAKR,CAAG,GAGtB,CAEA,IAAIY,EAAkBrE,EAAO,aAAawD,EAAa,EAIjDc,EAAUV,EAAuBhC,GAAU2C,GAC7C,CAAC7B,EAAM,KAAKf,CAAW,GAAK,CAACuC,EAAcvB,CAAS,GACtD3C,EAAO,OACLkD,EAAM,IAAIoB,EAAQ,CAChB,KAAM3B,CACR,CAAC,EAAGD,EAAM,MAAO,CACf,OAAQ,EACV,CAAC,EACD,CACE,OAAQ,GACR,KAAM,EACR,CACF,EAKE2B,aAA2BrC,IAC7BhC,EAAO,UAAU,cAAe,CAChC,CAAC,EAGH,OAAW,CACToE,EACAI,CACF,IAAKV,EAAiB,CACpB,IAAML,EAAMM,EAAc,IAAIK,CAAM,EAChCJ,EAAY,IAAII,CAAM,GAGpBC,aAA2BrC,IAAcoC,IAAY1B,EAAM,KAAK,KAAoB,IAAI,IAC1F1C,EAAO,OAAO,GAAGyD,CAAG,OAAOe,CAAQ,GAAI,CACrC,KAAM,EACR,CAAC,EAGHxE,EAAO,OAAOkD,EAAM,IAAIoB,EAAQ,CAC9B,KAAMb,EAAI,KAAK,CACjB,CAAC,EAAGe,EAAU,CACZ,OAAQ,EACV,CAAC,EAAG,CACF,KAAM,EACR,CAAC,CAEL,CAEA,IAAIxD,EAAwBO,EAAO,CACjC,IAAKmB,EAAM,MACX,MAAOY,CACT,CAAC,EACKmB,EAAQhC,GAAa4B,CAAe,EACpCK,EAASL,GAAiB,QAAQ,aAExC,GAAIA,aAA2BrC,GAC7BhB,EAAYO,EAAO,CACjB,IAAK,MAAM,KAAKuC,EAAgB,OAAO,CAAC,EAAE,CAAC,EAC3C,MAAOR,CACT,CAAC,EACDe,EAAkBlC,EAAQkC,EAAiB,OAAOrD,CAAS,UAAU,UAC5DqD,aAA2BM,GAAS,CAC7C,GAAI,CAACD,GAAU,EAAEA,EAAO,qBAAqBhB,GAAcgB,IAAWhB,GAAa,OACnF,IAAMkB,EAAgB,IAAIF,EAAO,CAC/B,KAAMD,EACN,WAAYlD,EAAO,CACjB,IAAK,IACP,CAAC,CACH,CAAC,EACG8C,EAAgB,SAAQA,EAAkBlC,EAAQkC,EAAgB,OAAQ,aAAarD,CAAS,WAAW4D,CAAa,GAAG,EACjI,SAAWP,aAA2BhD,GAAS,CAC7C,GAAI,CAACqD,GAAU,EAAEA,EAAO,qBAAqBhB,GAAcgB,IAAWhB,GAAa,OACnF,GAAIQ,EAAcxB,EAAM,KAAK,IAAkB,EAAG,CAChD,IAAMkC,EAAgB,IAAIF,EAAO,CAC/B,KAAMD,EACN,WAAYzD,CACd,CAAC,EACGqD,EAAgB,SAAQA,EAAkBlC,EAAQkC,EAAgB,OAAQO,CAAa,EAC7F,KAAO,CACL,IAAMA,EAAgB,IAAIF,EAAO,CAC/B,KAAMD,EACN,WAAYlD,EAAO,CACjB,IAAK,IACP,CAAC,CACH,CAAC,EACD8C,EAAkBlC,EAAQkC,EAAiB,aAAarD,CAAS,WAAW4D,CAAa,GAAG,CAC9F,CACF,SAAWP,aAA2BjD,GAChC8C,EAAcxB,EAAM,KAAK,IAAkB,EAC7C2B,EAAkBlC,EAAQkC,EAAiB,GAAGI,CAAK,MAAMzD,CAAS,EAAE,EAEpEqD,EAAkBlC,EAAQkC,EAAiB,aAAarD,CAAS,gBAAgBqD,EAAgB,KAAK,IAAI,GAAG,MAE1G,CASL,GARIT,GAAwB5D,EAAO,QAAQ,QACzCgB,EAAYkC,EAAMlC,EAAWhB,EAAO,OAAO,MAAO,CAChD,KAAM,EACR,CAAC,GAKC0C,EAAM,KAAKmC,EAAS,EAAG,CACzB,IAAMC,EAAcnB,GACdA,aAAgBkB,GACXE,GAAY,OAAO,CAAC,EAClBpB,aAAgBhC,EAClBM,GAAM,EAER0B,EAGT3C,EAAY,IAAIgE,GAAa,CAC3B,KAAMhE,EACN,YAAa,CACV0B,EAAM,KAAK,KAAoB,UAAUoC,CAAU,CACtD,CACF,CAAC,CACH,CAEA9E,EAAO,QAAQ,QAAQgB,CAAS,CAClC,CAEA,OAAW,CACTyC,EACAnC,EACAd,CACF,IAAK+C,EAAM,CACT/C,EAAU,QAAQ0B,EAAM,CAAC,EACzB,IAAMsC,EAAWV,EAAgB,IAAIL,EAAI,IAAI,CAAC,EAC9C,GAAI,CAACe,EAAU,SACf,IAAMS,EAAS1D,EAAO,CACpB,IAAKiD,EACL,MAAOlB,CACT,CAAC,EAED,GAAIM,EAAsB,CACxBH,EAAI,QAAQwB,CAAM,EACZzE,aAAqBgC,GACzBjC,EAAa,MAAMC,EAAW,CAC5B,KAAM,EACR,CAAC,EAEH,QACF,CAEI0D,EAAcT,CAAG,EACnBA,EAAI,QAAQwB,CAAM,EACTzE,aAAqBgC,EAC1B6B,IAAiBA,EAAkBlC,EAAQkC,EAAiB,IAAIA,CAAe,uBAAuBY,CAAM,KAAK3D,CAAU,IAAI,IAEnImC,EAAI,QAAQyB,EAAa,IAAI,CAAC,EAC1Bb,IAAiBA,EAAkBlC,EAAQkC,EAAiB,IAAIA,CAAe,kBAAkBY,CAAM,WAAWzE,CAAS,IAAI,GAEvI,CAEAD,EAAa,KACXP,EAAO,QAAQiE,EAAS,CACtB,KAAM,EACR,CAAC,EACD,CACE,GAAIV,EAAK,OAAO,CAAC,CACf,CAAE,CAAE/C,CACN,IAAMA,aAAqBgC,CAAM,EAAE,IAAI,CAAC,CACtC,CAAE,CAAEhC,CACN,IAAMA,CAAS,EACf,gBACA,UAAW8C,EACX,KAAM,EACR,CACF,CACF,CAEA,SAASnB,EAASxC,EAAwBwF,EAAgD,CACxF,OAAOxF,EAAW,QAAQyF,GAAUD,CAAa,CAAC,CACpD,CAEA,SAAS1C,GAAc9C,EAA4D,CACjF,GAAIA,aAAsByB,GACxB,OAAOzB,EAAW,KAAK,KAGzB,GAAIA,aAAsB0B,IAAW1B,aAAsBgF,GACzD,OAAOlC,GAAa9C,EAAW,MAAM,EAGvC,GAAIA,aAAsB+D,EACxB,OACE/D,EAAW,gBAAgBkC,GACxBlC,EAAW,gBAAgB0B,IAC3B1B,EAAW,gBAAgBqC,IAC3BrC,EAAW,gBAAgBgF,GAE5BhF,EAAW,MACXA,EAAW,IAInB,CCrfO,IAAM0F,GAAyB,CACpCC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC,EACF,EA6BO,SAASC,GACdC,EACAC,EAUI,CAAC,EACO,CACZ,GAAM,CACJ,OAAQC,EACR,GAAAC,EACA,QAAAC,EACA,QAAAC,EACA,MAAAC,EAAQtB,GACR,IAAAuB,EACA,cAAAC,EAAgB,GAChB,iBAAkBC,EAAuB,GACzC,GAAGC,CACL,EAAIT,EAEEU,EAASC,EAAaV,EAAW,CACrC,QAAAG,CACF,CAAC,EAGKQ,EAA2C,CAC/C,GAAAV,EACA,QAAAC,EACA,OAAAO,EACA,QAAAN,EACA,IAAAE,EACA,cAAAC,EACA,iBAAkBC,EAClB,GAAGC,CACL,EAGII,EAAYC,GAAWf,EAAY,CACrC,QAAAK,EACA,KAAM,EACR,CAAC,EAGD,QAAWW,KAAQV,EACjBQ,EAAYE,EAAKF,EAAWD,CAAe,EAG7C,OAAOC,CACT","names":["eliminateCtes","expression","root","buildScope","refCount","scopes","scope","i","scopeId","cteNode","withNode","withExpressions","source","sourceScope","Scope","currentCount","eliminateJoins","expression","scope","traverseScope","joins","i","join","assertIsInstanceOf","JoinExpr","alias","shouldEliminateJoin","innerSource","Scope","joinIsUsed","side","onClause","isJoinedOnAllUniqueOutputs","hasSingleOutputRow","onClauseColumns","column","ColumnExpr","uniqueOutputs_","uniqueOutputs","joinKeys","joinCondition","joinKeyNames","k","output","SelectExpr","select","group","groupedSqls","e","Expression","groupedOutputSqls","selectExpr","outputSql","s","AggFuncExpr","isLimit1","limit","LimitExpr","name","on","true_","sourceKeys","extractCondition","condition","left","right","leftTables","columnTableNames","rightTables","normalized","andOn","AndExpr","and","EqExpr","conditions","orBranch","parts","p","temp","cs","c","tables","eliminateSubqueries","expression","SubqueryExpr","root","buildScope","taken","scope","parent","source","TableExpr","existingCtes","withClause","recursive","assertIsInstanceOf","WithExpr","cte","isInstanceOf","CteExpr","newCtes","cteScope","newCte","eliminate","cteParent","restScopes","childScope","DdlExpr","eliminateDerivedTable","eliminateCte","LateralExpr","toReplace","name","tableExpr","alias","table","joins","withExpressions","sourceScope","newTable","duplicateCteAlias","findNewName","TableAliasExpr","toIdentifier","mergeSubqueries","expression","options","leaveTablesIsolated","mergeCtes","mergeDerivedTables","SAFE_TO_REPLACE_UNWRAPPED","ColumnExpr","EqExpr","FuncExpr","NeqExpr","ParenExpr","scopes","traverseScope","cteSelections","outerScope","sourceEntry","table","innerSource","Scope","scopeList","singularCteSelections","selections","innerScope","fromOrJoin","FromExpr","JoinExpr","mergeable","alias","renameInnerSources","mergeFrom","mergeExpressions","mergeOrder","mergeJoins","mergeWhere","mergeHints","popCte","subquery","innerSelect","isWindowExpressionInUnmergableOperation","windowAliases","SelectExpr","innerSelectExpr","s","Expression","WindowExpr","innerSelectName","unmergableWindowColumns","column","WhereExpr","GroupExpr","OrderExpr","HavingExpr","AggFuncExpr","outerSelectJoinsOnInnerSelectJoin","on","c","innerFrom","innerFromTable","innerProjections","selection","projection","col","isRecursive","cte","node","outerSelectExpr","arg","Dialect","e","ExplodeExpr","joinSide","outerJoins","j","isInstanceOf","seqGet","QueryTransformExpr","innerTaken","outerTaken","conflicts","x","taken","conflict","newName","findNewName","source","newAlias","toIdentifier","TableExpr","SubqueryExpr","TableAliasExpr","nodeToReplace","newSubquery","joinHint","tables","newSubquerySource","newJoins","joins","join","joinSource","position","outerColumns","name","columnList","expr","projectionName","columnsToReplace","unaliasedExpr","mustWrapExpression","cls","isNumber","parent","replacementExpr","UnaryExpr","BinaryExpr","paren","where","whereThis","outerExpression","from","sources","whereTables","columnTableNames","t","innerScopeHint","outerScopeHint","innerHintExpressions","hintExpression","with_","pushdownPredicates","expression","options","dialectArg","root","buildScope","dialect","Dialect","unnestRequiresCrossJoin","scopeRefCount","scope","select","whereClause","selectedSources","joins","joinIndex","join","i","name","pushdownAllowed","k","source","node","parent","JoinExpr","FromExpr","UnnestExpr","whereThis","Expression","pushdown","onClause","condition","sources","simplified","simplify","cnfLike","normalized","predicates","AndExpr","OrExpr","pushdownCnf","pushdownDnf","joinIndexMap","predicate","nodes","nodesForPredicate","predicateTables","columnTableNames","thisIndex","table","true_","SelectExpr","innerPredicate","replaceAliases","findInScope","AggFuncExpr","pushdownTables","a","aTables","b","bTables","t","conditions","existing","or","tables","whereCondition","WhereExpr","sourceEntry","TableExpr","with_","narrowInstanceOf","Scope","WithExpr","side","hasWindowExpression","sel","WindowExpr","hasGroup","refCount","aliases","AliasExpr","aliasThis","replaceAlias","column","ColumnExpr","replacement","Resolver","_Resolver","scope","schema","options","inferSchema","Dialect","MapBinaryTuple","column","columnName","tableName","joinContext","availableSources","e","OptimizeError","allSourceColumns","sourcesWithoutSchema","source","columns","selectedSource","toIdentifier","node","currentNode","QueryExpr","nodeAlias","Expression","IdentifierExpr","expression","SelectExpr","SubqueryExpr","subqueryThis","SetOperationExpr","setOp","onColumnList","col","side","kind","leftExpr","rightExpr","left","right","combined","leftSet","rightSet","name","onlyVisible","TableExpr","Scope","sourceExpr","ValuesExpr","UnnestExpr","unnest","isType","unnestExpressions","unnestExpr","seqGet","ColumnExpr","colType","elementTypes","field","isInstanceOf","select","QueryTransformExpr","c","columnAliases","newColumns","i","alias","colName","allSources","sourceName","sourceColumns","unambiguousColumns","joinAncestor","JoinExpr","from","joins","fromName","join","joinName","sourceColumnsPairs","firstTable","firstColumns","SingleValuedMapping","unnestOriginalAliases","aliasArg","TableAliasExpr","allColumns","table","unique","ambiguous","unnestAlias","tableIdentifier","nestedSource","SELECT_ALL","defaultSelection","options","isAgg","alias","MaxExpr","LiteralExpr","pushdownProjections","expression","schemaArg","removeUnusedSelections","dialect","schema","ensureSchema","sourceColumnAliasCount","referencedColumns","scopes","traverseScope","i","scope","parentSelections","aliasCount","scopeExpr","SetOperationExpr","kind","side","left","right","select","Expression","rightSelections","j","leftSelect","rightSelect","SelectExpr","removeUnusedSelections_","selects","col","tableName","colName","selectsForTable","name","source","node","sourceScope","Scope","firstSelect","seqGet","columns","QueryTransformExpr","referencedCols","columnAliases","aliasCountParam","order","orderRefs","ColumnExpr","newSelections","removed","star","selectAll","selection","selectionExpr","AggFuncExpr","resolver","Resolver","names","s","sortedSelections","table","column","isolateTableSelects","expression","options","schemaArg","dialect","schema","ensureSchema","scope","traverseScope","sourceEntry","node","actualSource","TableExpr","source","columnNames","SubqueryExpr","OptimizeError","aliasName","subquery","select","alias","qualifyColumns","expression","options","schemaArg","expandAliasRefs","expandStars","inferSchemaArg","allowPartialQualification","dialectArg","schema","ensureSchema","annotator","TypeAnnotator","inferSchema","dialect","Dialect","dialectClass","pseudocolumns","scope","traverseScope","pushdownCteAliasColumns","isSelect","SelectExpr","separatePseudocolumns","resolver","Resolver","popTableColumnAliases","usingColumnTables","expandUsing","expandAliasRefs_","convertColumnsToDots","qualifyColumnsInScope","expandStars_","qualifyOutputs","expandGroupBy","expandOrderByAndDistinctOn","validateQualifyColumns","sql","allUnqualifiedColumns","unqualifiedColumns","column","forTable","line","col","start","end","errorMsg","formattedSql","highlightSql","OptimizeError","unpivotColumnSet","unpivotColumns","firstColumn","firstColumnThis","isInstanceOf","Expression","hasPseudocolumns","scopeExpression","name","PseudocolumnExpr","unpivot","nameColumns","field","InExpr","ColumnExpr","valueColumns","e","derivedTables","table","WithExpr","tableAlias","TableAliasExpr","joins","names","j","ordered","k","columns","updateSourceColumns","sourceName","colName","columnTables","i","join","assertIsInstanceOf","JoinExpr","sourceTable","joinTable","using","joinColumns","conditions","usingIdentifierCount","isSemiOrAntiJoin","identifierNode","identifier","lhs","coalesceColumns","t","CoalesceExpr","tables_","and","coalesceArgs","replacement","alias","StructExpr","PropertyEqExpr","toIdentifier","expandOnlyGroupby","aliasToExpression","projections","s","replaced","replaceColumns","node","resolveTable","literalIndex","isGroupBy","GroupExpr","isHaving","HavingExpr","walkInScope","n","skipReplace","aliasEntry","aliasExpr_","aliasIdx","AggFuncExpr","WindowExpr","columnTable","LiteralExpr","parenNode","paren","simplified","simplifyParens","projection","AliasExpr","parentScope","onRightSubTree","cteExpr","aliasArg","aliasColumns","columnsSource","converted","allCols","DotExpr","dotParts","parts","firstPart","remainingParts","newRoot","fieldParts","newTable","wasQualified","newColumn","columnName","sourceColumns","PivotExpr","source","Scope","colThis","TableColumnExpr","pivot","addExceptColumns","tables","exceptColumns","except_","exceptList","addRenameColumns","renameColumns","rename","thisExpr","addReplaceColumns","replace","expandStructStarsNoParens","dotColumn","dotColumnCopy","dotColumnType","startingStruct","DataTypeExpr","outer","part","fieldExprs","IdentifierExpr","ColumnDefExpr","fieldKindRaw","fieldKind","takenNames","newSelections","fieldThis","thisIdent","allParts","p","root","expandStructStarsWithParens","ParenExpr","parent","dotColumnType2","rhs","StarExpr","matched","expressions","filterInstanceOf","structFieldDef","outerParen","newIdentifier","newDot","newAlias","replaceColumnsMap","renameColumnsMap","coalesedColumns","pivotOutputColumns","pivotExcludeColumns","seqGet","c","structFields","tableName","exprThis","columnsToExclude","renamedColumns","replacedColumns","pivotColumns","tablesForCol","alias_","selectionExpr","scopeOrExpression","scopeInstance","built","buildScope","selects","outerColumns","maxLen","selection","aliasedColumn","QueryTransformExpr","SubqueryExpr","AliasesExpr","selectByPos","index","select","expandPositionalReferences","newNodes","ambiguousProjections","selectAlias","selectThis","ambiguous","CONSTANTS","C","ExplodeExpr","UnnestExpr","group","groupExpressions","modifierKey","modifier","DistinctExpr","modifierExpressions","expanded","original","expandedNode","agg","selectsMap","expr","match","quoteIdentifiers","identify","cte","aliasColumnNames","selectExpr","newExpressions","newProjection","qualifyTables","expression","options","dbArg","catalogArg","onQualify","dialectArg","canonicalizeTableAliases","dialect","Dialect","nextAliasName","nameSequence","db","parseIdentifier","normalizeIdentifiers","catalog","qualify","table","IdentifierExpr","QueryExpr","with_","WithExpr","cteNames","cte","node","n","TableExpr","setAlias","expr","canonicalAliases","targetAlias","scope","normalize","columns","alias","TableAliasExpr","newAliasName","toIdentifier","c","traverseScope","localColumns","query","subquery","SubqueryExpr","derivedTable","unnested","joins","derivedThis","Expression","newSelect","select","pivot","seqGet","tableAliases","name","source","isRealTableSource","pivots","sourceName","tableThis","tableAlias","functionColumns","FuncExpr","funcTypeName","ensureList","defaultCols","sourceFqn","p","sourceAliasThis","Scope","udtf","ValuesExpr","i","parent","FromExpr","JoinExpr","column","columnParts","canonicalTable","qualify","expression","options","dialectArg","db","catalog","schemaArg","expandAliasRefs","expandStars","inferSchema","isolateTables","qualifyColumnsFlag","allowPartialQualification","validateQualifyColumnsFlag","quoteIdentifiersFlag","identify","canonicalizeTableAliases","onQualify","sql","schema","ensureSchema","dialect","Dialect","normalizeIdentifiers","qualifyTables","isolateTableSelects","qualifyColumns","quoteIdentifiers","validateQualifyColumns","unnestSubqueries","expression","nextAliasName","nameSequence","scope","traverseScope","select","parent","isInstanceOf","SelectExpr","selectExpr","decorrelate","unnest","parentSelect","predicate","ConditionExpr","FuncExpr","TableExpr","FromExpr","JoinExpr","selectToUse","SetOperationExpr","aliasExpr","clause","HavingExpr","WhereExpr","InExpr","AnyExpr","columnExpr","column","clauseParentSelect","sel","findInScope","AggFuncExpr","MaxExpr","SubqueryExpr","joinType","onClause","ExistsExpr","null_","true_","replace","LimitExpr","OffsetExpr","predicateToUse","eqPredicate","EqExpr","otherOperand","value","valueThis","Expression","joinKey","joinKeyNotNull","group","groupExprSqls","e","alias","externalColumns","where","OrExpr","tableAlias","keys","PredicateExpr","key","BinaryExpr","node","isSubqueryProjection","s","keyAliasesBySql","keyByAliasSql","groupBySqls","groupBy","exprInGroupBy","expr","keySql","parentPredicate","aggFunc","ArrayAggExpr","keyAlias","other","opType","AllExpr","predicateExpr","CountExpr","removeAggs","LiteralExpr","CoalesceExpr","nested","toIdentifier","conditionExpr","condition","RULES","qualify","pushdownProjections","normalize","unnestSubqueries","pushdownPredicates","optimizeJoins","eliminateSubqueries","mergeSubqueries","eliminateJoins","eliminateCtes","quoteIdentifiers","annotateTypes","canonicalize","simplify","optimize","expression","options","schemaArg","db","catalog","dialect","rules","sql","isolateTables","quoteIdentifiersFlag","extraOptions","schema","ensureSchema","possibleOptions","optimized","maybeParse","rule"]}
|