@sixb/pg 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +73 -0
  3. package/dist/agents/agent-storage.d.ts +20 -0
  4. package/dist/agents/agent-storage.d.ts.map +1 -0
  5. package/dist/agents/index.d.ts +6 -0
  6. package/dist/agents/index.d.ts.map +1 -0
  7. package/dist/agents/messages.d.ts +13 -0
  8. package/dist/agents/messages.d.ts.map +1 -0
  9. package/dist/agents/rows.d.ts +77 -0
  10. package/dist/agents/rows.d.ts.map +1 -0
  11. package/dist/agents/runs.d.ts +25 -0
  12. package/dist/agents/runs.d.ts.map +1 -0
  13. package/dist/agents/threads.d.ts +13 -0
  14. package/dist/agents/threads.d.ts.map +1 -0
  15. package/dist/auth-storage/access-tokens.d.ts +33 -0
  16. package/dist/auth-storage/access-tokens.d.ts.map +1 -0
  17. package/dist/auth-storage/auth-storage.d.ts +41 -0
  18. package/dist/auth-storage/auth-storage.d.ts.map +1 -0
  19. package/dist/auth-storage/group-memberships.d.ts +21 -0
  20. package/dist/auth-storage/group-memberships.d.ts.map +1 -0
  21. package/dist/auth-storage/identities.d.ts +17 -0
  22. package/dist/auth-storage/identities.d.ts.map +1 -0
  23. package/dist/auth-storage/index.d.ts +3 -0
  24. package/dist/auth-storage/index.d.ts.map +1 -0
  25. package/dist/auth-storage/invitations.d.ts +29 -0
  26. package/dist/auth-storage/invitations.d.ts.map +1 -0
  27. package/dist/auth-storage/magic-links.d.ts +28 -0
  28. package/dist/auth-storage/magic-links.d.ts.map +1 -0
  29. package/dist/auth-storage/oidc-attempts.d.ts +18 -0
  30. package/dist/auth-storage/oidc-attempts.d.ts.map +1 -0
  31. package/dist/auth-storage/rows.d.ts +138 -0
  32. package/dist/auth-storage/rows.d.ts.map +1 -0
  33. package/dist/auth-storage/service-account-group-memberships.d.ts +17 -0
  34. package/dist/auth-storage/service-account-group-memberships.d.ts.map +1 -0
  35. package/dist/auth-storage/service-accounts.d.ts +14 -0
  36. package/dist/auth-storage/service-accounts.d.ts.map +1 -0
  37. package/dist/auth-storage/sessions.d.ts +55 -0
  38. package/dist/auth-storage/sessions.d.ts.map +1 -0
  39. package/dist/auth-storage/shared.d.ts +159 -0
  40. package/dist/auth-storage/shared.d.ts.map +1 -0
  41. package/dist/auth-storage/users.d.ts +19 -0
  42. package/dist/auth-storage/users.d.ts.map +1 -0
  43. package/dist/index.d.ts +127 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +11957 -0
  46. package/dist/index.js.map +55 -0
  47. package/dist/latest-run-query.d.ts +24 -0
  48. package/dist/latest-run-query.d.ts.map +1 -0
  49. package/dist/migrations.d.ts +20 -0
  50. package/dist/migrations.d.ts.map +1 -0
  51. package/dist/ontology-storage/commits.d.ts +11 -0
  52. package/dist/ontology-storage/commits.d.ts.map +1 -0
  53. package/dist/ontology-storage/index.d.ts +22 -0
  54. package/dist/ontology-storage/index.d.ts.map +1 -0
  55. package/dist/ontology-storage/materialization-session.d.ts +63 -0
  56. package/dist/ontology-storage/materialization-session.d.ts.map +1 -0
  57. package/dist/ontology-storage/materialization-state.d.ts +69 -0
  58. package/dist/ontology-storage/materialization-state.d.ts.map +1 -0
  59. package/dist/ontology-storage/materialization-writer.d.ts +15 -0
  60. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -0
  61. package/dist/ontology-storage/materializations.d.ts +33 -0
  62. package/dist/ontology-storage/materializations.d.ts.map +1 -0
  63. package/dist/ontology-storage/outbox.d.ts +12 -0
  64. package/dist/ontology-storage/outbox.d.ts.map +1 -0
  65. package/dist/ontology-storage/shared.d.ts +95 -0
  66. package/dist/ontology-storage/shared.d.ts.map +1 -0
  67. package/dist/ontology-storage/sources.d.ts +25 -0
  68. package/dist/ontology-storage/sources.d.ts.map +1 -0
  69. package/dist/pg-action-run-storage.d.ts +21 -0
  70. package/dist/pg-action-run-storage.d.ts.map +1 -0
  71. package/dist/pg-client.d.ts +58 -0
  72. package/dist/pg-client.d.ts.map +1 -0
  73. package/dist/pg-object-query-compiler.d.ts +55 -0
  74. package/dist/pg-object-query-compiler.d.ts.map +1 -0
  75. package/dist/pg-object-storage.d.ts +90 -0
  76. package/dist/pg-object-storage.d.ts.map +1 -0
  77. package/dist/pg-pipeline-run-storage.d.ts +18 -0
  78. package/dist/pg-pipeline-run-storage.d.ts.map +1 -0
  79. package/dist/pg-projection-run-storage.d.ts +19 -0
  80. package/dist/pg-projection-run-storage.d.ts.map +1 -0
  81. package/dist/pg-rules-storage.d.ts +25 -0
  82. package/dist/pg-rules-storage.d.ts.map +1 -0
  83. package/dist/pg-sync-run-storage.d.ts +15 -0
  84. package/dist/pg-sync-run-storage.d.ts.map +1 -0
  85. package/dist/pg-timeseries-storage.d.ts +32 -0
  86. package/dist/pg-timeseries-storage.d.ts.map +1 -0
  87. package/dist/pg-webhook-delivery-storage.d.ts +17 -0
  88. package/dist/pg-webhook-delivery-storage.d.ts.map +1 -0
  89. package/dist/pg-webhook-run-storage.d.ts +14 -0
  90. package/dist/pg-webhook-run-storage.d.ts.map +1 -0
  91. package/dist/pg-workflow-intervention-storage.d.ts +16 -0
  92. package/dist/pg-workflow-intervention-storage.d.ts.map +1 -0
  93. package/dist/pg-workflow-run-storage.d.ts +49 -0
  94. package/dist/pg-workflow-run-storage.d.ts.map +1 -0
  95. package/dist/run-list-query.d.ts +30 -0
  96. package/dist/run-list-query.d.ts.map +1 -0
  97. package/dist/storage-errors.d.ts +16 -0
  98. package/dist/storage-errors.d.ts.map +1 -0
  99. package/dist/transactions.d.ts +10 -0
  100. package/dist/transactions.d.ts.map +1 -0
  101. package/dist/tsconfig.json +5 -0
  102. package/package.json +60 -0
  103. package/src/agents/agent-storage.ts +26 -0
  104. package/src/agents/index.ts +5 -0
  105. package/src/agents/messages.ts +144 -0
  106. package/src/agents/rows.ts +227 -0
  107. package/src/agents/runs.ts +330 -0
  108. package/src/agents/threads.ts +116 -0
  109. package/src/auth-storage/access-tokens.ts +254 -0
  110. package/src/auth-storage/auth-storage.ts +798 -0
  111. package/src/auth-storage/group-memberships.ts +47 -0
  112. package/src/auth-storage/identities.ts +85 -0
  113. package/src/auth-storage/index.ts +2 -0
  114. package/src/auth-storage/invitations.ts +280 -0
  115. package/src/auth-storage/magic-links.ts +140 -0
  116. package/src/auth-storage/oidc-attempts.ts +93 -0
  117. package/src/auth-storage/rows.ts +352 -0
  118. package/src/auth-storage/service-account-group-memberships.ts +150 -0
  119. package/src/auth-storage/service-accounts.ts +154 -0
  120. package/src/auth-storage/sessions.ts +193 -0
  121. package/src/auth-storage/shared.ts +799 -0
  122. package/src/auth-storage/users.ts +196 -0
  123. package/src/index.ts +367 -0
  124. package/src/latest-run-query.ts +42 -0
  125. package/src/migrations/001-initial-schema.sql +1195 -0
  126. package/src/migrations.ts +280 -0
  127. package/src/ontology-storage/commits.ts +115 -0
  128. package/src/ontology-storage/index.ts +35 -0
  129. package/src/ontology-storage/materialization-session.ts +426 -0
  130. package/src/ontology-storage/materialization-state.ts +1109 -0
  131. package/src/ontology-storage/materialization-writer.ts +509 -0
  132. package/src/ontology-storage/materializations.ts +939 -0
  133. package/src/ontology-storage/outbox.ts +216 -0
  134. package/src/ontology-storage/shared.ts +293 -0
  135. package/src/ontology-storage/sources.ts +658 -0
  136. package/src/pg-action-run-storage.ts +657 -0
  137. package/src/pg-client.ts +124 -0
  138. package/src/pg-object-query-compiler.ts +1545 -0
  139. package/src/pg-object-storage.ts +638 -0
  140. package/src/pg-pipeline-run-storage.ts +457 -0
  141. package/src/pg-projection-run-storage.ts +526 -0
  142. package/src/pg-rules-storage.ts +308 -0
  143. package/src/pg-sync-run-storage.ts +263 -0
  144. package/src/pg-timeseries-storage.ts +180 -0
  145. package/src/pg-webhook-delivery-storage.ts +180 -0
  146. package/src/pg-webhook-run-storage.ts +185 -0
  147. package/src/pg-workflow-intervention-storage.ts +339 -0
  148. package/src/pg-workflow-run-storage.ts +1065 -0
  149. package/src/run-list-query.ts +108 -0
  150. package/src/sql.d.ts +4 -0
  151. package/src/storage-errors.ts +72 -0
  152. package/src/transactions.ts +58 -0
@@ -0,0 +1,55 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/agents/messages.ts", "../src/storage-errors.ts", "../src/transactions.ts", "../src/agents/rows.ts", "../src/agents/runs.ts", "../src/run-list-query.ts", "../src/agents/threads.ts", "../src/agents/agent-storage.ts", "../src/auth-storage/auth-storage.ts", "../src/auth-storage/access-tokens.ts", "../src/auth-storage/rows.ts", "../src/auth-storage/shared.ts", "../src/auth-storage/group-memberships.ts", "../src/auth-storage/identities.ts", "../src/auth-storage/invitations.ts", "../src/auth-storage/magic-links.ts", "../src/auth-storage/oidc-attempts.ts", "../src/auth-storage/service-account-group-memberships.ts", "../src/auth-storage/service-accounts.ts", "../src/auth-storage/sessions.ts", "../src/auth-storage/users.ts", "../src/migrations.ts", "../src/ontology-storage/shared.ts", "../src/ontology-storage/commits.ts", "../src/ontology-storage/materializations.ts", "../src/ontology-storage/materialization-session.ts", "../src/ontology-storage/materialization-state.ts", "../src/ontology-storage/materialization-writer.ts", "../src/ontology-storage/outbox.ts", "../src/ontology-storage/sources.ts", "../src/ontology-storage/index.ts", "../src/pg-action-run-storage.ts", "../src/pg-client.ts", "../src/pg-object-query-compiler.ts", "../src/pg-object-storage.ts", "../src/pg-pipeline-run-storage.ts", "../src/latest-run-query.ts", "../src/pg-projection-run-storage.ts", "../src/pg-rules-storage.ts", "../src/pg-sync-run-storage.ts", "../src/pg-timeseries-storage.ts", "../src/pg-webhook-delivery-storage.ts", "../src/pg-webhook-run-storage.ts", "../src/pg-workflow-intervention-storage.ts", "../src/pg-workflow-run-storage.ts"],
4
+ "sourcesContent": [
5
+ "// Keep SQL module declarations visible to downstream workspaces that typecheck this package from\n// source.\n/// <reference path=\"./sql.d.ts\" />\n\nimport { AsyncLocalStorage } from \"node:async_hooks\"\nimport type {\n MigrationCapableStorage,\n Storage,\n StorageMigrator,\n StorageTransactionOptions,\n} from \"@sixb/core\"\nimport { ProviderMaterializationTransactionLifecycle } from \"@sixb/core/internal/ontology-storage-provider\"\nimport {\n createAgentOperationScope,\n createAuthOperationScope,\n createOntologyOperationScope,\n createOperationScopedFacade,\n createStorageOperationScope,\n createWorkflowRunOperationScope,\n} from \"@sixb/core/internal/storage-operation-scope\"\nimport {\n createTransactionStorageProxy,\n type ObjectStorage,\n StorageTransactionError,\n throwNestedStorageTransaction,\n} from \"@sixb/core/storage\"\nimport { PgAgentStorage } from \"./agents\"\nimport { PgAuthStorage } from \"./auth-storage\"\nimport { createPostgresStorageMigrators, dropSchema } from \"./migrations\"\nimport { PgOntologyStorage, type PgOntologyTransactionContext } from \"./ontology-storage\"\nimport { PgActionRunStorage } from \"./pg-action-run-storage\"\nimport { createPgClient, type SQL, type SQLClient } from \"./pg-client\"\nimport { PgObjectStorage } from \"./pg-object-storage\"\nimport { PgPipelineRunStorage } from \"./pg-pipeline-run-storage\"\nimport { PgProjectionRunStorage } from \"./pg-projection-run-storage\"\nimport { PgRulesStorage } from \"./pg-rules-storage\"\nimport { PgSyncRunStorage } from \"./pg-sync-run-storage\"\nimport { PgTimeseriesStorage } from \"./pg-timeseries-storage\"\nimport { PgWebhookDeliveryStorage } from \"./pg-webhook-delivery-storage\"\nimport { PgWebhookRunStorage } from \"./pg-webhook-run-storage\"\nimport { PgWorkflowInterventionStorage } from \"./pg-workflow-intervention-storage\"\nimport { PgWorkflowRunStorage } from \"./pg-workflow-run-storage\"\nimport { isRetryableTransactionConflict } from \"./storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport interface PostgresStorageOptions {\n /** Full connection string (e.g. DATABASE_URL). Takes precedence over individual fields. */\n connectionString?: string\n\n /** PostgreSQL host. Defaults to 'localhost'. */\n host?: string\n /** PostgreSQL port. Defaults to 5432. */\n port?: number\n /** Database name. */\n database?: string\n /** Database user. */\n user?: string\n /** Database password. */\n password?: string\n\n /** Maximum number of connections in the pool. Defaults to 10. */\n max?: number\n /** Idle connection timeout in milliseconds. Defaults to 30000. */\n idleTimeoutMillis?: number\n\n /**\n * Server-side `statement_timeout` (ms) applied to every connection in the pool. A query\n * exceeding it is cancelled by PostgreSQL, which frees its pooled connection instead of\n * pinning it indefinitely. Without this, a single stalled query can starve a small pool\n * until the process is restarted. Unset by default (no timeout). Set per role — keep it\n * generous or unset for workers that run long migrations/bulk writes.\n */\n statementTimeoutMillis?: number\n /**\n * Server-side `idle_in_transaction_session_timeout` (ms) applied to every connection. A\n * transaction left open and idle beyond it is aborted by PostgreSQL, releasing the\n * connection. Unset by default (no timeout).\n */\n idleInTransactionSessionTimeoutMillis?: number\n\n /**\n * Grace period (ms) for {@link PostgresStorage.close}. On shutdown the pool stops\n * accepting new queries and waits up to this long for in-flight queries to finish before\n * destroying the connections, so a restart drains cleanly instead of severing live work.\n * Defaults to 5000.\n */\n shutdownTimeoutMillis?: number\n\n /** Seconds to wait when establishing a connection. Defaults to 10000. */\n connectTimeoutMillis?: number\n /**\n * Whether to use server-side prepared statements (porsager's default, faster against a\n * direct Postgres connection). Behind PgBouncer transaction mode they require PgBouncer\n * >= 1.21 with `max_prepared_statements > 0`; set `false` for an older PgBouncer or when\n * that setting is 0. Defaults to `true`.\n */\n prepare?: boolean\n\n /** PostgreSQL schema name for all Sixb tables. Defaults to 'sixb'. */\n schemaName?: string\n\n /** SSL configuration. */\n ssl?: boolean | \"require\" | \"prefer\"\n}\n\n/**\n * PostgreSQL storage provider for Sixb.\n *\n * Bundles Sixb storage adapters backed by a shared PostgreSQL connection pool (porsager\n * `postgres`), which reliably reclaims connections under load.\n *\n * The storage exposes a core `StorageMigrator`. Sixb CLI startup and\n * `sixb db migrate` run it automatically through `migrateStorage(storage)`.\n *\n * Usage:\n * ```ts\n * const pg = new PostgresStorage({\n * connectionString: process.env.DATABASE_URL!,\n * })\n *\n * export const sixb = createSixb({\n * broker: myBroker,\n * storage: pg,\n * })\n * ```\n */\nexport class PostgresStorage implements MigrationCapableStorage {\n readonly objects: ObjectStorage\n readonly ontology: PgOntologyStorage\n readonly auth: PgAuthStorage\n readonly agents: PgAgentStorage\n readonly actionRuns: PgActionRunStorage\n readonly pipelineRuns: PgPipelineRunStorage\n readonly workflowRuns: PgWorkflowRunStorage\n readonly workflowInterventions: PgWorkflowInterventionStorage\n readonly syncRuns: PgSyncRunStorage\n readonly projectionRuns: PgProjectionRunStorage\n readonly timeseries: Storage[\"timeseries\"]\n readonly webhookDeliveries: PgWebhookDeliveryStorage\n readonly webhookRuns: PgWebhookRunStorage\n readonly rules: PgRulesStorage\n readonly migrators: readonly StorageMigrator[]\n\n private readonly sql: SQL\n private readonly schemaName: string\n private readonly shutdownTimeoutSeconds: number\n private readonly transactionScope = new AsyncLocalStorage<boolean>()\n\n constructor(options: PostgresStorageOptions) {\n this.schemaName = options.schemaName ?? \"sixb\"\n this.shutdownTimeoutSeconds = Math.max(\n 1,\n Math.round((options.shutdownTimeoutMillis ?? 5000) / 1000)\n )\n\n this.sql = createPgClient({\n ...(options.connectionString !== undefined\n ? { connectionString: options.connectionString }\n : {}),\n ...(options.host !== undefined ? { host: options.host } : {}),\n ...(options.port !== undefined ? { port: options.port } : {}),\n ...(options.database !== undefined ? { database: options.database } : {}),\n ...(options.user !== undefined ? { user: options.user } : {}),\n ...(options.password !== undefined ? { password: options.password } : {}),\n max: options.max ?? 10,\n schemaName: this.schemaName,\n ...(options.idleTimeoutMillis !== undefined\n ? { idleTimeoutMillis: options.idleTimeoutMillis }\n : {}),\n ...(resolveTimeoutMillis(options.statementTimeoutMillis, \"statementTimeoutMillis\") !==\n undefined\n ? { statementTimeoutMillis: options.statementTimeoutMillis }\n : {}),\n ...(resolveTimeoutMillis(\n options.idleInTransactionSessionTimeoutMillis,\n \"idleInTransactionSessionTimeoutMillis\"\n ) !== undefined\n ? { idleInTransactionSessionTimeoutMillis: options.idleInTransactionSessionTimeoutMillis }\n : {}),\n ...(resolveTimeoutMillis(options.connectTimeoutMillis, \"connectTimeoutMillis\") !== undefined\n ? { connectTimeoutMillis: options.connectTimeoutMillis }\n : {}),\n ...(options.prepare !== undefined ? { prepare: options.prepare } : {}),\n ...(options.ssl !== undefined ? { ssl: options.ssl } : {}),\n })\n\n this.migrators = createPostgresStorageMigrators(this.sql, this.schemaName)\n const stores = createPostgresStores(this.sql, {\n runOntologyOperation: (run) => runPgTransaction(this.sql, run),\n transactionContext: null,\n })\n const scope = createStorageOperationScope(\n async (run) => {\n this.assertRootOperationAvailable()\n return run()\n },\n () => this.assertRootOperationAvailable()\n )\n this.objects = createOperationScopedFacade(stores.objects, scope)\n this.ontology = createOntologyOperationScope(stores.ontology, scope)\n this.auth = createAuthOperationScope(stores.auth, scope)\n this.agents = createAgentOperationScope(stores.agents, scope)\n this.actionRuns = createOperationScopedFacade(stores.actionRuns, scope)\n this.pipelineRuns = createOperationScopedFacade(stores.pipelineRuns, scope)\n this.workflowRuns = createWorkflowRunOperationScope(stores.workflowRuns, scope)\n this.workflowInterventions = createOperationScopedFacade(stores.workflowInterventions, scope)\n this.syncRuns = createOperationScopedFacade(stores.syncRuns, scope)\n this.projectionRuns = createOperationScopedFacade(stores.projectionRuns, scope)\n this.timeseries = createOperationScopedFacade(stores.timeseries, scope)\n this.webhookDeliveries = createOperationScopedFacade(stores.webhookDeliveries, scope)\n this.webhookRuns = createOperationScopedFacade(stores.webhookRuns, scope)\n this.rules = createOperationScopedFacade(stores.rules, scope)\n }\n\n async ping(): Promise<void> {\n this.assertRootOperationAvailable()\n await this.sql`SELECT 1`\n }\n\n async transaction<T>(\n run: (tx: Storage) => Promise<T> | T,\n options: StorageTransactionOptions = {}\n ): Promise<T> {\n if (this.transactionScope.getStore()) {\n throwNestedStorageTransaction()\n }\n\n try {\n return await runPgTransaction(\n this.sql,\n async (client) => {\n let active = true\n const transactionContext: PgOntologyTransactionContext = {\n id: {},\n materializations: new ProviderMaterializationTransactionLifecycle(),\n active: true,\n }\n const txStorage = this.createTransactionStorage(client, transactionContext)\n const tx = createTransactionStorageProxy(txStorage, () => active)\n\n try {\n const result = await this.transactionScope.run(true, () => run(tx))\n transactionContext.materializations.assertCommittable()\n return result\n } finally {\n transactionContext.active = false\n txStorage.ontology.deactivateSessions()\n transactionContext.materializations.deactivate()\n active = false\n }\n },\n { isolation: options.isolation === \"serializable\" ? \"serializable\" : undefined }\n )\n } catch (error) {\n if (isRetryableTransactionConflict(error)) {\n throw new StorageTransactionError(\n \"[SixbPg] Storage transaction failed due to a serialization conflict or deadlock and may be retried.\",\n { cause: error, code: \"serialization_failure\" }\n )\n }\n throw error\n }\n }\n\n private assertRootOperationAvailable(): void {\n if (!this.transactionScope.getStore()) return\n throw new StorageTransactionError(\n \"[SixbPg] Root storage cannot be used inside a transaction callback; use the provided tx storage.\"\n )\n }\n\n /**\n * Close the connection pool. Should be called on shutdown.\n *\n * Stops accepting new queries and waits up to `shutdownTimeoutMillis` for in-flight\n * queries to finish before destroying connections.\n */\n async close(): Promise<void> {\n await this.sql.end({ timeout: this.shutdownTimeoutSeconds })\n }\n\n /**\n * Drop all Sixb tables and schema. Useful for test cleanup.\n * WARNING: This permanently deletes all data.\n */\n async dropSchema(): Promise<void> {\n await dropSchema(this.sql, this.schemaName)\n }\n\n private createTransactionStorage(\n client: PgStoreClient,\n transactionContext: PgOntologyTransactionContext\n ): Storage & { readonly ontology: PgOntologyStorage } {\n return {\n ...createPostgresStores(client, {\n runOntologyOperation: async (run) => run(client),\n transactionContext,\n }),\n ping: async () => {\n await client`SELECT 1`\n },\n transaction: async <T>(): Promise<T> => {\n throwNestedStorageTransaction()\n },\n }\n }\n}\n\nfunction createPostgresStores(\n sql: PgStoreClient,\n options: {\n readonly runOntologyOperation: <T>(run: (sql: SQLClient) => Promise<T>) => Promise<T>\n readonly transactionContext: PgOntologyTransactionContext | null\n }\n): PostgresStoreSet {\n return {\n objects: new PgObjectStorage(sql),\n ontology: new PgOntologyStorage({\n sql,\n runRootOperation: options.runOntologyOperation,\n transactionContext: options.transactionContext,\n }),\n auth: new PgAuthStorage({ sql }),\n agents: new PgAgentStorage({ sql }),\n actionRuns: new PgActionRunStorage(sql),\n pipelineRuns: new PgPipelineRunStorage(sql),\n workflowRuns: new PgWorkflowRunStorage(sql),\n workflowInterventions: new PgWorkflowInterventionStorage(sql),\n syncRuns: new PgSyncRunStorage(sql),\n projectionRuns: new PgProjectionRunStorage(sql),\n timeseries: new PgTimeseriesStorage(sql),\n webhookDeliveries: new PgWebhookDeliveryStorage(sql),\n webhookRuns: new PgWebhookRunStorage(sql),\n rules: new PgRulesStorage(sql),\n }\n}\n\ninterface PostgresStoreSet {\n readonly objects: PgObjectStorage\n readonly ontology: PgOntologyStorage\n readonly auth: PgAuthStorage\n readonly agents: PgAgentStorage\n readonly actionRuns: PgActionRunStorage\n readonly pipelineRuns: PgPipelineRunStorage\n readonly workflowRuns: PgWorkflowRunStorage\n readonly workflowInterventions: PgWorkflowInterventionStorage\n readonly syncRuns: PgSyncRunStorage\n readonly projectionRuns: PgProjectionRunStorage\n readonly timeseries: PgTimeseriesStorage\n readonly webhookDeliveries: PgWebhookDeliveryStorage\n readonly webhookRuns: PgWebhookRunStorage\n readonly rules: PgRulesStorage\n}\n\nfunction resolveTimeoutMillis(value: number | undefined, label: string): number | undefined {\n if (value === undefined) {\n return undefined\n }\n\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`[Sixb] PostgresStorage ${label} must be a non-negative finite number.`)\n }\n\n return Math.trunc(value)\n}\n\nexport { migratePostgresStorage } from \"./migrations\"\n",
6
+ "import { AGENT_MESSAGE_CONTENT_VERSION } from \"@sixb/core/internal/agents\"\nimport {\n type AgentMessageRecord,\n type AgentMessageStore,\n AgentStorageError,\n type AppendAgentMessageInput,\n type ListAgentMessagesInput,\n type ListAgentMessagesResult,\n} from \"@sixb/core/storage\"\nimport type { SqlParameter } from \"../pg-client\"\nimport { isUniqueViolation } from \"../storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"../transactions\"\nimport { type AgentMessageRow, queryAgentList, rowToMessageRecord } from \"./rows\"\n\nexport class PgAgentMessageStore implements AgentMessageStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async append(input: AppendAgentMessageInput): Promise<AgentMessageRecord> {\n const createdAt = input.createdAt ?? new Date()\n\n try {\n return await runPgTransaction(this.sql, async (tx) => {\n const [thread] = await tx<{ id: string }[]>`\n SELECT id FROM agent_threads\n WHERE project_id = ${input.projectId} AND id = ${input.threadId}\n FOR UPDATE\n `\n\n if (!thread) {\n throw new AgentStorageError(\n \"thread_not_found\",\n `[SixbPg] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (input.runId !== null) {\n const [run] = await tx<{ id: string }[]>`\n SELECT id FROM agent_runs WHERE project_id = ${input.projectId} AND id = ${input.runId}\n `\n\n if (!run) {\n throw new AgentStorageError(\n \"run_not_found\",\n `[SixbPg] Agent run '${input.runId}' not found for project '${input.projectId}'.`\n )\n }\n }\n\n const [seqRow] = await tx<{ next: number | string }[]>`\n SELECT COALESCE(MAX(seq), 0) + 1 AS next FROM agent_messages\n WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}\n `\n\n const [row] = await tx<AgentMessageRow[]>`\n INSERT INTO agent_messages (\n project_id,\n id,\n thread_id,\n run_id,\n role,\n author_principal_type,\n author_principal_id,\n seq,\n parts,\n metadata,\n content_version,\n created_at,\n completed_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.threadId},\n ${input.runId},\n ${input.role},\n ${input.authorPrincipal?.type ?? null},\n ${input.authorPrincipal?.id ?? null},\n ${Number(seqRow.next)},\n ${JSON.stringify(input.parts)}::text::jsonb,\n ${input.metadata === undefined ? null : JSON.stringify(input.metadata)}::text::jsonb,\n ${AGENT_MESSAGE_CONTENT_VERSION},\n ${createdAt},\n ${input.completedAt ?? null}\n )\n RETURNING *\n `\n\n await tx`\n UPDATE agent_threads\n SET message_count = message_count + 1, last_message_at = ${createdAt}, updated_at = ${createdAt}\n WHERE project_id = ${input.projectId} AND id = ${input.threadId}\n `\n\n return rowToMessageRecord(row)\n })\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new AgentStorageError(\n \"duplicate_id\",\n `[SixbPg] Agent message '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async getById(params: { projectId: string; id: string }): Promise<AgentMessageRecord | null> {\n const [row] = await this.sql<AgentMessageRow[]>`\n SELECT * FROM agent_messages WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToMessageRecord(row) : null\n }\n\n async list(input: ListAgentMessagesInput): Promise<ListAgentMessagesResult> {\n if (input.roles !== undefined && input.roles.length === 0) {\n return { messages: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\", \"thread_id = $2\"]\n const params: SqlParameter[] = [input.projectId, input.threadId]\n let index = 3\n\n if (input.roles) {\n const placeholders = input.roles.map(() => `$${index++}`)\n whereClauses.push(`role IN (${placeholders.join(\", \")})`)\n params.push(...input.roles)\n }\n\n const dir = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const { rows, total, hasMore } = await queryAgentList<AgentMessageRow>({\n sql: this.sql,\n table: \"agent_messages\",\n whereClauses,\n params,\n nextIndex: index,\n orderBy: `seq ${dir}`,\n limit: input.limit,\n offset: input.offset,\n })\n\n return { messages: rows.map(rowToMessageRecord), hasMore, total }\n }\n}\n",
7
+ "// Map thrown errors to their PostgreSQL/porsager meaning by code rather than by matching\n// message text. Database errors arrive in the native Postgres format with a SQLSTATE on\n// `.code`; connection-layer failures arrive with porsager's own codes or, for Node socket\n// errors, as an `AggregateError` of `ECONNREFUSED`/`ETIMEDOUT`/… entries.\n\n/** PostgreSQL SQLSTATE for a unique-constraint violation. */\nconst UNIQUE_VIOLATION = \"23505\"\n\n/**\n * PostgreSQL SQLSTATEs in class 40 (transaction rollback) that are transient and safe to retry by\n * replaying the whole transaction: `40001` (serialization_failure) and `40P01` (deadlock_detected).\n * Under `SERIALIZABLE` the server raises *either* — a serialization anomaly surfaces as `40001`,\n * while two transactions taking row locks in crossing order surface as `40P01` — and both clear on\n * a fresh attempt. The other class-40 codes (`40002` integrity-constraint violation, `40003`\n * statement-completion unknown) are deliberately excluded: they are not safe to blindly replay.\n */\nconst RETRYABLE_TRANSACTION_CONFLICT_CODES = new Set([\"40001\", \"40P01\"])\n\nconst CONNECTION_ERROR_CODES = new Set([\n // porsager-specific\n \"CONNECT_TIMEOUT\",\n \"CONNECTION_CLOSED\",\n \"CONNECTION_DESTROYED\",\n \"CONNECTION_ENDED\",\n // Node socket errors\n \"ECONNREFUSED\",\n \"ECONNRESET\",\n \"ETIMEDOUT\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n])\n\n/** The SQLSTATE / system error code carried by a thrown database or connection error. */\nexport function pgErrorCode(error: unknown): string | undefined {\n if (error instanceof Error) {\n const code = (error as { readonly code?: unknown }).code\n if (typeof code === \"string\") {\n return code\n }\n }\n return undefined\n}\n\n/** True when the error is a PostgreSQL unique-constraint violation (SQLSTATE 23505). */\nexport function isUniqueViolation(error: unknown): boolean {\n return pgErrorCode(error) === UNIQUE_VIOLATION\n}\n\n/**\n * True when the error is a transient transaction-rollback conflict that is safe to retry by\n * replaying the transaction — a serialization failure (SQLSTATE 40001) or a deadlock (40P01).\n * See {@link RETRYABLE_TRANSACTION_CONFLICT_CODES}.\n */\nexport function isRetryableTransactionConflict(error: unknown): boolean {\n const code = pgErrorCode(error)\n return code !== undefined && RETRYABLE_TRANSACTION_CONFLICT_CODES.has(code)\n}\n\n/**\n * True when the error originates from the connection layer (porsager connection codes, or a\n * Node socket failure surfaced as an `AggregateError`) rather than from a SQL statement.\n */\nexport function isConnectionError(error: unknown): boolean {\n const code = pgErrorCode(error)\n if (code !== undefined && CONNECTION_ERROR_CODES.has(code)) {\n return true\n }\n if (error instanceof AggregateError) {\n return error.errors.some(isConnectionError)\n }\n return false\n}\n",
8
+ "import { createHash } from \"node:crypto\"\nimport type { SQL, SQLClient } from \"./pg-client\"\n\nexport type PgStoreClient = SQL | SQLClient\n\nexport interface RunPgTransactionOptions {\n /** Open the transaction at `SERIALIZABLE`; omit for the server default (`READ COMMITTED`). */\n readonly isolation?: \"serializable\"\n}\n\nexport async function runPgTransaction<T>(\n sql: PgStoreClient,\n run: (tx: SQLClient) => Promise<T>,\n options: RunPgTransactionOptions = {}\n): Promise<T> {\n if (!canStartPgTransaction(sql)) {\n return run(sql)\n }\n\n // porsager passes the callback a transaction-scoped client (a TransactionSql, which is an\n // ISql == SQLClient). The `as Promise<T>` only unwraps porsager's UnwrapPromiseArray return\n // type (our callbacks never return the pipelined-array form), not a structural cast.\n //\n // The isolation level is folded into `BEGIN` (`BEGIN ISOLATION LEVEL SERIALIZABLE`) rather than\n // a separate `SET TRANSACTION` statement: one round-trip instead of two, and the level is\n // guaranteed to take effect before any data statement of the transaction runs.\n if (options.isolation === \"serializable\") {\n return sql.begin(\"isolation level serializable\", run) as Promise<T>\n }\n return sql.begin(run) as Promise<T>\n}\n\nexport function authLockKey(kind: string, ...parts: readonly string[]): string {\n return [\"auth\", kind, ...parts].join(\":\")\n}\n\nexport async function lockAdvisoryKeys(sql: SQLClient, keys: readonly string[]): Promise<void> {\n const locks = [...new Set(keys)].sort().map(advisoryLockParts)\n if (locks.length === 0) return\n\n await sql`\n SELECT pg_advisory_xact_lock(locks.first_key, locks.second_key)\n FROM unnest(\n ${sql.array(locks.map(([first]) => first))}::integer[],\n ${sql.array(locks.map(([, second]) => second))}::integer[]\n ) WITH ORDINALITY AS locks(first_key, second_key, lock_order)\n ORDER BY locks.lock_order\n `\n}\n\nfunction advisoryLockParts(key: string): readonly [number, number] {\n const hash = createHash(\"sha256\").update(key).digest()\n return [hash.readInt32BE(0), hash.readInt32BE(4)]\n}\n\nfunction canStartPgTransaction(sql: PgStoreClient): sql is SQL {\n return typeof (sql as { readonly begin?: unknown }).begin === \"function\"\n}\n",
9
+ "import { type AgentMessagePart, type Principal, SYSTEM_PRINCIPAL } from \"@sixb/core\"\nimport {\n type AgentMessageRecord,\n type AgentRunDiagnostic,\n type AgentRunRecord,\n type AgentRunUsage,\n type AgentThreadRecord,\n coerceAgentRunFinishReason,\n} from \"@sixb/core/storage\"\nimport type { SQLClient, SqlParameter } from \"../pg-client\"\n\n// ── row shapes (porsager returns timestamptz as Date, jsonb parsed, int as number — typed loosely\n// to tolerate the string forms some drivers/poolers surface) ──────────────────────────────────\n\nexport interface AgentThreadRow {\n project_id: string\n id: string\n agent_id: string\n owner_principal_type: Principal[\"type\"]\n owner_principal_id: string\n title: string | null\n status: AgentThreadRecord[\"status\"]\n active_run_id: string | null\n last_message_at: Date | string | null\n message_count: number | string\n created_at: Date | string\n updated_at: Date | string\n}\n\nexport interface AgentRunRow {\n project_id: string\n id: string\n thread_id: string\n agent_id: string\n trigger_message_id: string\n requested_by_principal_type: Principal[\"type\"] | null\n requested_by_principal_id: string | null\n execution_principal_type: \"serviceAccount\" | null\n execution_principal_id: string | null\n status: AgentRunRecord[\"status\"]\n model_id: string | null\n finish_reason: string | null\n usage_input_tokens: number | string | null\n usage_output_tokens: number | string | null\n usage_total_tokens: number | string | null\n usage_reasoning_tokens: number | string | null\n usage_cached_input_tokens: number | string | null\n error: string | null\n diagnostics: AgentRunDiagnostic[] | string | null\n attempt: number | string\n execution_token: string | null\n execution_queue_lease_expires_at: Date | string | null\n created_at: Date | string\n started_at: Date | string | null\n completed_at: Date | string | null\n}\n\nexport interface AgentMessageRow {\n project_id: string\n id: string\n thread_id: string\n run_id: string | null\n role: AgentMessageRecord[\"role\"]\n author_principal_type: Principal[\"type\"] | null\n author_principal_id: string | null\n seq: number | string\n parts: AgentMessagePart[] | string\n metadata: unknown\n content_version: number | string\n created_at: Date | string\n completed_at: Date | string | null\n}\n\n// ── row → record mappers ────────────────────────────────────────────────────────────────────────\n\nexport function rowToThreadRecord(row: AgentThreadRow): AgentThreadRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n agentId: row.agent_id,\n ownerPrincipal: { type: row.owner_principal_type, id: row.owner_principal_id },\n title: row.title ?? undefined,\n status: row.status,\n activeRunId: row.active_run_id,\n lastMessageAt: row.last_message_at ? new Date(row.last_message_at) : undefined,\n messageCount: Number(row.message_count),\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n }\n}\n\nexport function rowToRunRecord(row: AgentRunRow): AgentRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n threadId: row.thread_id,\n agentId: row.agent_id,\n triggerMessageId: row.trigger_message_id,\n requestedByPrincipal:\n principalFromColumns(row.requested_by_principal_type, row.requested_by_principal_id) ??\n SYSTEM_PRINCIPAL,\n executionPrincipal: serviceAccountPrincipalFromColumns(\n row.execution_principal_type,\n row.execution_principal_id\n ),\n status: row.status,\n modelId: row.model_id ?? undefined,\n finishReason: coerceAgentRunFinishReason(row.finish_reason),\n usage: rowToUsage(row),\n error: row.error ?? undefined,\n diagnostics: normalizeDiagnostics(row.diagnostics),\n attempt: Number(row.attempt),\n execution:\n row.execution_token && row.execution_queue_lease_expires_at\n ? {\n token: row.execution_token,\n queueLeaseExpiresAt: new Date(row.execution_queue_lease_expires_at),\n }\n : undefined,\n createdAt: new Date(row.created_at),\n startedAt: row.started_at ? new Date(row.started_at) : undefined,\n completedAt: row.completed_at ? new Date(row.completed_at) : undefined,\n }\n}\n\nexport function rowToMessageRecord(row: AgentMessageRow): AgentMessageRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n threadId: row.thread_id,\n runId: row.run_id,\n role: row.role,\n authorPrincipal: principalFromColumns(row.author_principal_type, row.author_principal_id),\n seq: Number(row.seq),\n parts:\n typeof row.parts === \"string\" ? (JSON.parse(row.parts) as AgentMessagePart[]) : row.parts,\n // A null/absent column and an explicit JSON `null` both mean \"no metadata\" — jsonb cannot tell\n // SQL NULL from a json null on read, so both backends normalise to `undefined` for parity.\n metadata: normalizeMetadata(row.metadata),\n contentVersion: Number(row.content_version),\n createdAt: new Date(row.created_at),\n completedAt: row.completed_at ? new Date(row.completed_at) : undefined,\n }\n}\n\nfunction principalFromColumns(\n type: Principal[\"type\"] | null | undefined,\n id: string | null | undefined\n): Principal | undefined {\n return type && id ? { type, id } : undefined\n}\n\nfunction serviceAccountPrincipalFromColumns(\n type: \"serviceAccount\" | null | undefined,\n id: string | null | undefined\n): Extract<Principal, { readonly type: \"serviceAccount\" }> | undefined {\n return type === \"serviceAccount\" && id ? { type, id } : undefined\n}\n\nfunction rowToUsage(row: AgentRunRow): AgentRunUsage | undefined {\n const usage: AgentRunUsage = {\n ...(row.usage_input_tokens === null ? {} : { inputTokens: Number(row.usage_input_tokens) }),\n ...(row.usage_output_tokens === null ? {} : { outputTokens: Number(row.usage_output_tokens) }),\n ...(row.usage_total_tokens === null ? {} : { totalTokens: Number(row.usage_total_tokens) }),\n ...(row.usage_reasoning_tokens === null\n ? {}\n : { reasoningTokens: Number(row.usage_reasoning_tokens) }),\n ...(row.usage_cached_input_tokens === null\n ? {}\n : { cachedInputTokens: Number(row.usage_cached_input_tokens) }),\n }\n return Object.keys(usage).length === 0 ? undefined : usage\n}\n\nfunction normalizeMetadata(value: unknown): AgentMessageRecord[\"metadata\"] {\n if (value === null || value === undefined) {\n return undefined\n }\n const parsed = typeof value === \"string\" ? JSON.parse(value) : value\n return parsed === null ? undefined : (parsed as AgentMessageRecord[\"metadata\"])\n}\n\nfunction normalizeDiagnostics(\n value: AgentRunRow[\"diagnostics\"]\n): readonly AgentRunDiagnostic[] | undefined {\n if (value === null) {\n return undefined\n }\n return typeof value === \"string\" ? (JSON.parse(value) as AgentRunDiagnostic[]) : value\n}\n\n// ── offset pagination (threads / messages order by their own column, not started_at) ─────────────\n\nexport async function queryAgentList<TRow>(input: {\n readonly sql: SQLClient\n readonly table: \"agent_threads\" | \"agent_messages\"\n readonly whereClauses: readonly string[]\n readonly params: readonly SqlParameter[]\n readonly nextIndex: number\n readonly orderBy: string\n readonly limit?: number\n readonly offset?: number\n}): Promise<{ readonly rows: readonly TRow[]; readonly total: number; readonly hasMore: boolean }> {\n const where = `WHERE ${input.whereClauses.join(\" AND \")}`\n const offset = input.offset ?? 0\n\n const [totalRow] = await input.sql.unsafe<{ count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM ${input.table} ${where}`,\n [...input.params] as SqlParameter[]\n )\n\n const queryParams = [...input.params] as SqlParameter[]\n let query = `SELECT * FROM ${input.table} ${where} ORDER BY ${input.orderBy}`\n let nextIndex = input.nextIndex\n\n if (input.limit !== undefined) {\n query += ` LIMIT $${nextIndex++} OFFSET $${nextIndex++}`\n queryParams.push(input.limit, offset)\n } else if (offset > 0) {\n query += ` OFFSET $${nextIndex++}`\n queryParams.push(offset)\n }\n\n const rows = await input.sql.unsafe<TRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n return { rows, total, hasMore: offset + rows.length < total }\n}\n",
10
+ "import {\n type AgentRunRecord,\n type AgentRunStore,\n AgentStorageError,\n type ConfirmAgentRunExecutionOwnershipInput,\n type CreateAgentRunInput,\n type FinishAgentRunInput,\n type FinishQueuedAgentRunInput,\n type ListAgentRunsInput,\n type ListAgentRunsResult,\n type ReclaimAgentRunInput,\n type StartAgentRunInput,\n} from \"@sixb/core/storage\"\nimport type { SQLClient, SqlParameter } from \"../pg-client\"\nimport { appendRunListFilters, hasEmptyStatuses, queryRunList } from \"../run-list-query\"\nimport { isUniqueViolation } from \"../storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"../transactions\"\nimport { type AgentRunRow, rowToRunRecord } from \"./rows\"\n\nconst PG_RUN_ID_BATCH_SIZE = 10_000\n\nexport class PgAgentRunStore implements AgentRunStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateAgentRunInput): Promise<AgentRunRecord> {\n const createdAt = input.createdAt ?? new Date()\n\n try {\n return await runPgTransaction(this.sql, async (tx) => {\n const [thread] = await tx<{ active_run_id: string | null }[]>`\n SELECT active_run_id FROM agent_threads\n WHERE project_id = ${input.projectId} AND id = ${input.threadId}\n FOR UPDATE\n `\n\n if (!thread) {\n throw new AgentStorageError(\n \"thread_not_found\",\n `[SixbPg] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (thread.active_run_id !== null) {\n throw new AgentStorageError(\n \"active_run_exists\",\n `[SixbPg] Agent thread '${input.threadId}' already has an active run '${thread.active_run_id}'.`\n )\n }\n\n const [row] = await tx<AgentRunRow[]>`\n INSERT INTO agent_runs (\n project_id,\n id,\n thread_id,\n agent_id,\n trigger_message_id,\n requested_by_principal_type,\n requested_by_principal_id,\n status,\n attempt,\n created_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.threadId},\n ${input.agentId},\n ${input.triggerMessageId},\n ${input.requestedByPrincipal.type},\n ${input.requestedByPrincipal.id},\n ${\"queued\"},\n ${0},\n ${createdAt}\n )\n RETURNING *\n `\n\n await tx`\n UPDATE agent_threads SET active_run_id = ${input.id}, updated_at = ${createdAt}\n WHERE project_id = ${input.projectId} AND id = ${input.threadId}\n `\n\n return rowToRunRecord(row)\n })\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new AgentStorageError(\n \"duplicate_id\",\n `[SixbPg] Agent run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async start(input: StartAgentRunInput): Promise<AgentRunRecord> {\n const startedAt = input.startedAt ?? new Date()\n return runPgTransaction(this.sql, async (tx) => {\n await this.lockStatus(tx, input.projectId, input.id, \"queued\")\n const [row] = await tx<AgentRunRow[]>`\n UPDATE agent_runs\n SET\n status = ${\"running\"},\n execution_principal_type = ${input.executionPrincipal?.type ?? null},\n execution_principal_id = ${input.executionPrincipal?.id ?? null},\n model_id = ${input.modelId ?? null},\n attempt = ${1},\n execution_token = ${input.execution.token},\n execution_queue_lease_expires_at = ${input.execution.queueLeaseExpiresAt},\n started_at = ${startedAt}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n return rowToRunRecord(row)\n })\n }\n\n async finishQueued(input: FinishQueuedAgentRunInput): Promise<AgentRunRecord> {\n const completedAt = input.completedAt ?? new Date()\n return runPgTransaction(this.sql, async (tx) => {\n const run = await this.lockStatus(tx, input.projectId, input.id, \"queued\")\n const [row] = await tx<AgentRunRow[]>`\n UPDATE agent_runs\n SET status = ${input.status}, error = ${input.error ?? null}, completed_at = ${completedAt}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n await this.releaseThread(tx, run, completedAt)\n return rowToRunRecord(row)\n })\n }\n\n async reclaim(input: ReclaimAgentRunInput): Promise<AgentRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await this.lockRunning(tx, input.projectId, input.id)\n const [row] = await tx<AgentRunRow[]>`\n UPDATE agent_runs\n SET\n attempt = attempt + 1,\n execution_token = ${input.execution.token},\n execution_queue_lease_expires_at = ${input.execution.queueLeaseExpiresAt}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToRunRecord(row)\n })\n }\n\n async confirmExecutionOwnership(\n input: ConfirmAgentRunExecutionOwnershipInput\n ): Promise<AgentRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const run = await this.lockRunning(tx, input.projectId, input.id)\n if (run.execution_token !== input.executionToken) {\n throw new AgentStorageError(\n \"execution_lost\",\n `[SixbPg] Execution token is no longer current on agent run '${input.id}'.`\n )\n }\n\n const [row] = await tx<AgentRunRow[]>`\n UPDATE agent_runs\n SET execution_queue_lease_expires_at = GREATEST(\n execution_queue_lease_expires_at,\n ${input.queueLeaseExpiresAt}\n )\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n return rowToRunRecord(row)\n })\n }\n\n async finish(input: FinishAgentRunInput): Promise<AgentRunRecord> {\n const completedAt = input.completedAt ?? new Date()\n const errorValue = input.status === \"succeeded\" ? null : (input.error ?? null)\n\n return runPgTransaction(this.sql, async (tx) => {\n const run = await this.lockRunning(tx, input.projectId, input.id)\n\n if (run.execution_token !== input.executionToken) {\n throw new AgentStorageError(\n \"execution_lost\",\n `[SixbPg] Execution token is no longer current on agent run '${input.id}'.`\n )\n }\n\n const [row] = await tx<AgentRunRow[]>`\n UPDATE agent_runs\n SET\n status = ${input.status},\n model_id = COALESCE(${input.modelId ?? null}, model_id),\n finish_reason = ${input.finishReason ?? null},\n usage_input_tokens = ${input.usage?.inputTokens ?? null},\n usage_output_tokens = ${input.usage?.outputTokens ?? null},\n usage_total_tokens = ${input.usage?.totalTokens ?? null},\n usage_reasoning_tokens = ${input.usage?.reasoningTokens ?? null},\n usage_cached_input_tokens = ${input.usage?.cachedInputTokens ?? null},\n error = ${errorValue},\n diagnostics = ${input.diagnostics === undefined ? null : JSON.stringify(input.diagnostics)}::text::jsonb,\n execution_token = ${null},\n execution_queue_lease_expires_at = ${null},\n completed_at = ${completedAt}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n await this.releaseThread(tx, run, completedAt)\n\n return rowToRunRecord(row)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<AgentRunRecord | null> {\n const [row] = await this.sql<AgentRunRow[]>`\n SELECT * FROM agent_runs WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToRunRecord(row) : null\n }\n\n async getByIds(params: {\n projectId: string\n ids: readonly string[]\n }): Promise<readonly AgentRunRecord[]> {\n const ids = [...new Set(params.ids)]\n if (ids.length === 0) {\n return []\n }\n\n const rows: AgentRunRow[] = []\n for (let offset = 0; offset < ids.length; offset += PG_RUN_ID_BATCH_SIZE) {\n const batch = ids.slice(offset, offset + PG_RUN_ID_BATCH_SIZE)\n const placeholders = batch.map((_, index) => `$${index + 2}`).join(\", \")\n rows.push(\n ...(await this.sql.unsafe<AgentRunRow[]>(\n `SELECT * FROM agent_runs WHERE project_id = $1 AND id IN (${placeholders})`,\n [params.projectId, ...batch] as SqlParameter[]\n ))\n )\n }\n const byId = new Map(rows.map((row) => [row.id, rowToRunRecord(row)]))\n return ids.flatMap((id) => {\n const run = byId.get(id)\n return run ? [run] : []\n })\n }\n\n async list(input: ListAgentRunsInput): Promise<ListAgentRunsResult> {\n if (hasEmptyStatuses(input)) {\n return { runs: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.threadId) {\n whereClauses.push(`thread_id = $${index++}`)\n params.push(input.threadId)\n }\n\n if (input.agentId) {\n whereClauses.push(`agent_id = $${index++}`)\n params.push(input.agentId)\n }\n\n index = appendRunListFilters(\n whereClauses,\n params,\n index,\n input,\n \"COALESCE(started_at, created_at)\"\n )\n\n const { rows, total, hasMore } = await queryRunList<AgentRunRow>({\n sql: this.sql,\n tableName: \"agent_runs\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return { runs: rows.map(rowToRunRecord), hasMore, total }\n }\n\n private lockRunning(sql: SQLClient, projectId: string, id: string): Promise<AgentRunRow> {\n return this.lockStatus(sql, projectId, id, \"running\")\n }\n\n private async lockStatus(\n sql: SQLClient,\n projectId: string,\n id: string,\n status: AgentRunRecord[\"status\"]\n ): Promise<AgentRunRow> {\n const [row] = await sql<AgentRunRow[]>`\n SELECT * FROM agent_runs\n WHERE project_id = ${projectId} AND id = ${id}\n FOR UPDATE\n `\n\n if (!row) {\n throw new AgentStorageError(\n \"run_not_found\",\n `[SixbPg] Agent run '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.status !== status) {\n throw new AgentStorageError(\n \"invalid_state\",\n `[SixbPg] Agent run '${id}' is not ${status} (status '${row.status}').`\n )\n }\n\n return row\n }\n\n private async releaseThread(sql: SQLClient, run: AgentRunRow, completedAt: Date): Promise<void> {\n await sql`\n UPDATE agent_threads SET active_run_id = ${null}, updated_at = ${completedAt}\n WHERE project_id = ${run.project_id} AND id = ${run.thread_id} AND active_run_id = ${run.id}\n `\n }\n}\n",
11
+ "import type { SQLClient, SqlParameter } from \"./pg-client\"\n\ntype PgRunListTable =\n | \"agent_runs\"\n | \"pipeline_runs\"\n | \"pipeline_step_runs\"\n | \"sync_runs\"\n | \"webhook_runs\"\n | \"workflow_runs\"\n | \"workflow_node_runs\"\n | \"workflow_agent_node_runs\"\n\n/** Column projection — `sync_runs` needs the derived `checkpoint_present` flag. */\ntype PgRunListSelectList = \"*\" | \"*, checkpoint IS NOT NULL AS checkpoint_present\"\ntype StartedAtExpression = \"started_at\" | \"COALESCE(started_at, created_at)\"\n\nexport function hasEmptyStatuses(input: { readonly statuses?: readonly unknown[] }): boolean {\n return input.statuses !== undefined && input.statuses.length === 0\n}\n\nexport function appendRunListFilters(\n whereClauses: string[],\n params: unknown[],\n index: number,\n input: {\n readonly statuses?: readonly string[]\n readonly startedAfter?: Date\n readonly startedBefore?: Date\n },\n startedAtExpression: StartedAtExpression = \"started_at\"\n): number {\n let nextIndex = index\n\n if (input.statuses) {\n if (input.statuses.length === 0) {\n whereClauses.push(\"1 = 0\")\n } else {\n const placeholders = input.statuses.map(() => `$${nextIndex++}`)\n whereClauses.push(`status IN (${placeholders.join(\", \")})`)\n params.push(...input.statuses)\n }\n }\n\n if (input.startedAfter) {\n whereClauses.push(`${startedAtExpression} >= $${nextIndex++}`)\n params.push(input.startedAfter)\n }\n\n if (input.startedBefore) {\n whereClauses.push(`${startedAtExpression} <= $${nextIndex++}`)\n params.push(input.startedBefore)\n }\n\n return nextIndex\n}\n\nexport async function queryRunList<TRow>(input: {\n readonly sql: SQLClient\n readonly tableName: PgRunListTable\n readonly whereClauses: readonly string[]\n readonly params: readonly unknown[]\n readonly nextIndex: number\n readonly order?: \"asc\" | \"desc\"\n readonly limit?: number\n readonly offset?: number\n readonly selectList?: PgRunListSelectList\n}): Promise<{ readonly rows: readonly TRow[]; readonly total: number; readonly hasMore: boolean }> {\n const where = `WHERE ${input.whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n\n const [totalRow] = await input.sql.unsafe<{ count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM ${input.tableName} ${where}`,\n [...input.params] as SqlParameter[]\n )\n\n const queryParams = [...input.params] as SqlParameter[]\n const orderColumn =\n input.tableName === \"agent_runs\"\n ? \"COALESCE(started_at, created_at)\"\n : input.tableName === \"workflow_agent_node_runs\"\n ? \"created_at\"\n : \"started_at\"\n const idColumn = input.tableName === \"workflow_agent_node_runs\" ? \"node_run_id\" : \"id\"\n let query = `\n SELECT ${input.selectList ?? \"*\"} FROM ${input.tableName}\n ${where}\n ORDER BY ${orderColumn} ${order}, ${idColumn} ${order}\n `\n let nextIndex = input.nextIndex\n\n if (input.limit !== undefined) {\n query += ` LIMIT $${nextIndex++} OFFSET $${nextIndex++}`\n queryParams.push(input.limit, offset)\n } else if (offset > 0) {\n query += ` OFFSET $${nextIndex++}`\n queryParams.push(offset)\n }\n\n const rows = await input.sql.unsafe<TRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n\n return {\n rows,\n total,\n hasMore: offset + rows.length < total,\n }\n}\n",
12
+ "import {\n AgentStorageError,\n type AgentThreadRecord,\n type AgentThreadStore,\n type CreateAgentThreadInput,\n type ListAgentThreadsInput,\n type ListAgentThreadsResult,\n} from \"@sixb/core/storage\"\nimport type { SqlParameter } from \"../pg-client\"\nimport { isUniqueViolation } from \"../storage-errors\"\nimport type { PgStoreClient } from \"../transactions\"\nimport { type AgentThreadRow, queryAgentList, rowToThreadRecord } from \"./rows\"\n\nexport class PgAgentThreadStore implements AgentThreadStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateAgentThreadInput): Promise<AgentThreadRecord> {\n const createdAt = input.createdAt ?? new Date()\n const updatedAt = input.updatedAt ?? createdAt\n\n try {\n const [row] = await this.sql<AgentThreadRow[]>`\n INSERT INTO agent_threads (\n project_id,\n id,\n agent_id,\n owner_principal_type,\n owner_principal_id,\n title,\n status,\n created_at,\n updated_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.agentId},\n ${input.ownerPrincipal.type},\n ${input.ownerPrincipal.id},\n ${input.title ?? null},\n ${input.status ?? \"active\"},\n ${createdAt},\n ${updatedAt}\n )\n RETURNING *\n `\n\n return rowToThreadRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new AgentStorageError(\n \"duplicate_id\",\n `[SixbPg] Agent thread '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async getById(params: { projectId: string; id: string }): Promise<AgentThreadRecord | null> {\n const [row] = await this.sql<AgentThreadRow[]>`\n SELECT * FROM agent_threads WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToThreadRecord(row) : null\n }\n\n async list(input: ListAgentThreadsInput): Promise<ListAgentThreadsResult> {\n if (\n (input.statuses !== undefined && input.statuses.length === 0) ||\n (input.agentIds !== undefined && input.agentIds.length === 0)\n ) {\n return { threads: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.agentId) {\n whereClauses.push(`agent_id = $${index++}`)\n params.push(input.agentId)\n }\n\n if (input.agentIds) {\n const placeholders = input.agentIds.map(() => `$${index++}`)\n whereClauses.push(`agent_id IN (${placeholders.join(\", \")})`)\n params.push(...input.agentIds)\n }\n\n if (input.statuses) {\n const placeholders = input.statuses.map(() => `$${index++}`)\n whereClauses.push(`status IN (${placeholders.join(\", \")})`)\n params.push(...input.statuses)\n }\n\n if (input.ownerPrincipal) {\n whereClauses.push(`owner_principal_type = $${index++} AND owner_principal_id = $${index++}`)\n params.push(input.ownerPrincipal.type, input.ownerPrincipal.id)\n }\n\n const dir = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const { rows, total, hasMore } = await queryAgentList<AgentThreadRow>({\n sql: this.sql,\n table: \"agent_threads\",\n whereClauses,\n params,\n nextIndex: index,\n orderBy: `COALESCE(last_message_at, created_at) ${dir}, id ${dir}`,\n limit: input.limit,\n offset: input.offset,\n })\n\n return { threads: rows.map(rowToThreadRecord), hasMore, total }\n }\n}\n",
13
+ "import type { AgentStorage } from \"@sixb/core/storage\"\nimport type { PgStoreClient } from \"../transactions\"\nimport { PgAgentMessageStore } from \"./messages\"\nimport { PgAgentRunStore } from \"./runs\"\nimport { PgAgentThreadStore } from \"./threads\"\n\nexport interface PgAgentStorageOptions {\n readonly sql: PgStoreClient\n}\n\n/**\n * PostgreSQL-backed agent persistence: thread / run / message sub-stores sharing one connection.\n * Cross-table writes (reserve + finish touch the thread anchor, append bumps thread stats) run\n * inside `runPgTransaction` with `SELECT ... FOR UPDATE` row locks for single-flight safety.\n */\nexport class PgAgentStorage implements AgentStorage {\n readonly threads: PgAgentThreadStore\n readonly runs: PgAgentRunStore\n readonly messages: PgAgentMessageStore\n\n constructor(options: PgAgentStorageOptions) {\n this.threads = new PgAgentThreadStore(options.sql)\n this.runs = new PgAgentRunStore(options.sql)\n this.messages = new PgAgentMessageStore(options.sql)\n }\n}\n",
14
+ "import type {\n AuthStorage,\n CompleteMagicLinkSignInInput,\n CompleteOidcSignInInput,\n CompleteSignInResult,\n GroupMembershipRecord,\n InvitationRecord,\n SessionRecord,\n SuspendUserAndRevokeSessionsInput,\n UserIdentityRecord,\n UserRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport {\n authLockKey,\n lockAdvisoryKeys,\n type PgStoreClient,\n runPgTransaction,\n} from \"../transactions\"\nimport { PgAuthAccessTokenStore } from \"./access-tokens\"\nimport { PgAuthGroupMembershipStore } from \"./group-memberships\"\nimport { PgAuthUserIdentityStore } from \"./identities\"\nimport { PgAuthInvitationStore } from \"./invitations\"\nimport { PgAuthMagicLinkStore } from \"./magic-links\"\nimport { PgAuthOidcAuthorizationAttemptStore } from \"./oidc-attempts\"\nimport type {\n PgAuthMagicLinkRow,\n PgAuthOidcAttemptRow,\n PgAuthUserIdentityRow,\n PgAuthUserRow,\n} from \"./rows\"\nimport { rowToIdentityRecord, rowToUserRecord, serializeOptionalRecord } from \"./rows\"\nimport { PgAuthServiceAccountGroupMembershipStore } from \"./service-account-group-memberships\"\nimport { PgAuthServiceAccountStore } from \"./service-accounts\"\nimport { PgAuthSessionStore } from \"./sessions\"\nimport {\n assertMagicLinkUsable,\n assertNonEmpty,\n assertOidcAttemptUsable,\n consumeMagicLink,\n consumeOidcAttempt,\n createSession,\n getActiveInvitationByEmail,\n getIdentityRowBySubject,\n getMagicLinkRowById,\n getOidcAttemptRowById,\n getUserRowByEmail,\n getUserRowById,\n mapUniqueConstraintError,\n normalizeEmail,\n normalizeGroupIds,\n revokeActiveSessionsForUser,\n upsertGroupMembership,\n validateCompleteSessionInput,\n} from \"./shared\"\nimport { PgAuthUserStore } from \"./users\"\n\ninterface AuthTransactionError {\n readonly error: AuthStorageError\n}\n\nexport interface PgAuthStorageOptions {\n readonly sql: PgStoreClient\n}\n\nexport class PgAuthStorage implements AuthStorage {\n private readonly sql: PgStoreClient\n\n readonly users: PgAuthUserStore\n readonly identities: PgAuthUserIdentityStore\n readonly serviceAccounts: PgAuthServiceAccountStore\n readonly serviceAccountGroupMemberships: PgAuthServiceAccountGroupMembershipStore\n readonly sessions: PgAuthSessionStore\n readonly accessTokens: PgAuthAccessTokenStore\n readonly invitations: PgAuthInvitationStore\n readonly groupMemberships: PgAuthGroupMembershipStore\n readonly magicLinks: PgAuthMagicLinkStore\n readonly oidcAuthorizationAttempts: PgAuthOidcAuthorizationAttemptStore\n\n constructor(options: PgAuthStorageOptions) {\n this.sql = options.sql\n this.users = new PgAuthUserStore(this.sql)\n this.identities = new PgAuthUserIdentityStore(this.sql)\n this.serviceAccounts = new PgAuthServiceAccountStore(this.sql)\n this.serviceAccountGroupMemberships = new PgAuthServiceAccountGroupMembershipStore(this.sql)\n this.sessions = new PgAuthSessionStore(this.sql)\n this.accessTokens = new PgAuthAccessTokenStore(this.sql)\n this.invitations = new PgAuthInvitationStore(this.sql)\n this.groupMemberships = new PgAuthGroupMembershipStore(this.sql)\n this.magicLinks = new PgAuthMagicLinkStore(this.sql)\n this.oidcAuthorizationAttempts = new PgAuthOidcAuthorizationAttemptStore(this.sql)\n }\n\n async completeMagicLinkSignIn(\n input: CompleteMagicLinkSignInInput\n ): Promise<CompleteSignInResult> {\n const result = await runPgTransaction(\n this.sql,\n async (tx): Promise<CompleteSignInResult | AuthTransactionError> => {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const completedAt = new Date(input.completedAt)\n const initialMagicLink = await getMagicLinkRowById(tx, {\n projectId,\n id: input.magicLinkId,\n })\n\n if (!initialMagicLink) {\n throw new AuthStorageError(\n \"missing_magic_link\",\n `[Sixb] Magic link '${input.magicLinkId}' not found for project '${projectId}'.`\n )\n }\n\n const email = normalizeEmail(initialMagicLink.email)\n await lockAdvisoryKeys(tx, [\n authLockKey(\"bootstrap\", projectId),\n authLockKey(\"invitations\", projectId, email),\n authLockKey(\"magic-links\", projectId, email),\n authLockKey(\"users\", projectId, email),\n ])\n\n const magicLink = await getMagicLinkRowById(\n tx,\n {\n projectId,\n id: input.magicLinkId,\n },\n { forUpdate: true }\n )\n\n this.assertMagicLinkUsable(\n projectId,\n input.magicLinkId,\n input.tokenHash,\n completedAt,\n magicLink\n )\n\n const existingUserRow = await getUserRowByEmail(\n tx,\n {\n projectId,\n email,\n },\n { forUpdate: true }\n )\n const activeInvitation = await getActiveInvitationByEmail(\n tx,\n {\n projectId,\n email,\n now: completedAt,\n },\n { forUpdate: true }\n )\n const shouldCreateUser = !existingUserRow\n const manualGroupIds = normalizeGroupIds(input.manualGroupIds)\n\n if (existingUserRow?.status === \"suspended\") {\n await consumeMagicLink(tx, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n return {\n error: new AuthStorageError(\n \"suspended_user\",\n `[Sixb] User '${existingUserRow.id}' is suspended for project '${projectId}'.`\n ),\n }\n }\n\n if (shouldCreateUser && !activeInvitation && !input.allowUserCreationWithoutInvitation) {\n await consumeMagicLink(tx, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] Magic link '${input.magicLinkId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n if (\n shouldCreateUser &&\n !activeInvitation &&\n input.allowUserCreationWithoutInvitation &&\n input.requireNoActiveUsersForUserCreation &&\n (await hasActiveUsers(tx, projectId))\n ) {\n await consumeMagicLink(tx, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] Magic link '${input.magicLinkId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n await validateCompleteSessionInput(tx, projectId, input.session)\n assertSignInSessionAudience(projectId, input.session.audience, magicLink.audience)\n\n let newUserId: string | undefined\n if (shouldCreateUser) {\n newUserId = assertNonEmpty(input.newUserId, \"User id\")\n if (await getUserRowById(tx, { projectId, id: newUserId })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User '${newUserId}' already exists for project '${projectId}'.`\n )\n }\n }\n\n const sessionUserId = existingUserRow?.id ?? newUserId ?? input.newUserId\n await lockAdvisoryKeys(tx, [authLockKey(\"sessions\", projectId, sessionUserId)])\n\n await consumeMagicLink(tx, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n\n const user = existingUserRow\n ? rowToUserRecord(existingUserRow)\n : await this.insertUser(tx, {\n id: newUserId ?? assertNonEmpty(input.newUserId, \"User id\"),\n projectId,\n email,\n displayName: input.newUserDisplayName,\n avatarUrl: input.newUserAvatarUrl,\n createdAt: completedAt,\n })\n\n const invitation = await this.acceptInvitationAndApplyGroups(tx, {\n activeInvitation,\n completedAt,\n projectId,\n user,\n })\n const groupMemberships = await this.applyManualGroups(tx, {\n completedAt,\n existing: invitation.groupMemberships,\n groupIds: manualGroupIds,\n projectId,\n userId: user.id,\n })\n const session = await this.createSignInSession(tx, {\n projectId,\n strategyId: magicLink.strategy_id,\n session: input.session,\n userId: user.id,\n })\n\n return {\n user,\n session,\n invitation: invitation.invitation,\n groupMemberships,\n }\n }\n )\n\n if (\"error\" in result) {\n throw result.error\n }\n\n return result\n }\n\n async completeOidcSignIn(input: CompleteOidcSignInInput): Promise<CompleteSignInResult> {\n const result = await runPgTransaction(\n this.sql,\n async (tx): Promise<CompleteSignInResult | AuthTransactionError> => {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const completedAt = new Date(input.completedAt)\n const attempt = await getOidcAttemptRowById(\n tx,\n {\n projectId,\n id: input.oidcAuthorizationAttemptId,\n },\n { forUpdate: true }\n )\n\n this.assertOidcAttemptUsable(\n projectId,\n input.oidcAuthorizationAttemptId,\n input.stateHash,\n completedAt,\n attempt\n )\n\n const subject = assertNonEmpty(input.subject, \"Subject\")\n const email = normalizeEmail(input.email)\n await lockAdvisoryKeys(tx, [\n authLockKey(\"bootstrap\", projectId),\n authLockKey(\"invitations\", projectId, email),\n authLockKey(\"identities\", projectId, attempt.strategy_id, subject),\n authLockKey(\"users\", projectId, email),\n ])\n\n const identity = await getIdentityRowBySubject(\n tx,\n {\n projectId,\n strategyId: attempt.strategy_id,\n subject,\n },\n { forUpdate: true }\n )\n const activeInvitation = identity\n ? null\n : await getActiveInvitationByEmail(\n tx,\n {\n projectId,\n email,\n now: completedAt,\n },\n { forUpdate: true }\n )\n let userRow = identity\n ? await getUserRowById(tx, { projectId, id: identity.user_id }, { forUpdate: true })\n : await getUserRowByEmail(tx, { projectId, email }, { forUpdate: true })\n const shouldCreateUser = !identity && !userRow\n const manualGroupIds = normalizeGroupIds(input.manualGroupIds)\n\n if (identity && !userRow) {\n await this.consumeOidcAttempt(input, completedAt, projectId, tx)\n return {\n error: new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${identity.user_id}' not found for linked OIDC identity.`\n ),\n }\n }\n\n if (!identity && userRow && (!input.autoLinkByVerifiedEmail || !input.emailVerified)) {\n await this.consumeOidcAttempt(input, completedAt, projectId, tx)\n return {\n error: new AuthStorageError(\n \"email_link_not_allowed\",\n `[Sixb] OIDC identity cannot auto-link to user '${userRow.id}' for project '${projectId}'.`\n ),\n }\n }\n\n if (userRow?.status === \"suspended\") {\n await this.consumeOidcAttempt(input, completedAt, projectId, tx)\n return {\n error: new AuthStorageError(\n \"suspended_user\",\n `[Sixb] User '${userRow.id}' is suspended for project '${projectId}'.`\n ),\n }\n }\n\n if (shouldCreateUser && !input.emailVerified) {\n await this.consumeOidcAttempt(input, completedAt, projectId, tx)\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n if (shouldCreateUser && !activeInvitation && !input.allowUserCreationWithoutInvitation) {\n await this.consumeOidcAttempt(input, completedAt, projectId, tx)\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n if (\n shouldCreateUser &&\n !activeInvitation &&\n input.allowUserCreationWithoutInvitation &&\n input.requireNoActiveUsersForUserCreation &&\n (await hasActiveUsers(tx, projectId))\n ) {\n await this.consumeOidcAttempt(input, completedAt, projectId, tx)\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n await validateCompleteSessionInput(tx, projectId, input.session)\n assertSignInSessionAudience(projectId, input.session.audience, attempt.audience)\n\n let newUserId: string | undefined\n if (shouldCreateUser) {\n newUserId = assertNonEmpty(input.newUserId, \"User id\")\n if (await getUserRowById(tx, { projectId, id: newUserId })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User '${newUserId}' already exists for project '${projectId}'.`\n )\n }\n }\n\n await lockAdvisoryKeys(tx, [\n authLockKey(\"sessions\", projectId, userRow?.id ?? newUserId ?? input.newUserId),\n ])\n await this.consumeOidcAttempt(input, completedAt, projectId, tx)\n\n let user: UserRecord\n if (!userRow) {\n user = await this.insertUser(tx, {\n id: newUserId ?? assertNonEmpty(input.newUserId, \"User id\"),\n projectId,\n email,\n displayName: input.displayName,\n avatarUrl: input.avatarUrl,\n createdAt: completedAt,\n })\n userRow = {\n project_id: user.projectId,\n id: user.id,\n email: user.email,\n display_name: user.displayName ?? null,\n avatar_url: user.avatarUrl ?? null,\n status: user.status,\n created_at: user.createdAt,\n updated_at: user.updatedAt,\n }\n } else {\n user = rowToUserRecord(userRow)\n }\n\n const invitation = await this.acceptInvitationAndApplyGroups(tx, {\n activeInvitation,\n completedAt,\n projectId,\n user,\n })\n const groupMemberships = await this.applyManualGroups(tx, {\n completedAt,\n existing: invitation.groupMemberships,\n groupIds: manualGroupIds,\n projectId,\n userId: user.id,\n })\n const nextIdentity = await this.upsertIdentity(tx, {\n projectId,\n strategyId: attempt.strategy_id,\n subject,\n userId: user.id,\n claims: input.claims,\n createdAt: identity ? new Date(identity.created_at) : completedAt,\n updatedAt: completedAt,\n })\n const session = await this.createSignInSession(tx, {\n projectId,\n strategyId: attempt.strategy_id,\n session: input.session,\n userId: user.id,\n })\n\n return {\n user,\n session,\n identity: nextIdentity,\n invitation: invitation.invitation,\n groupMemberships,\n }\n }\n )\n\n if (\"error\" in result) {\n throw result.error\n }\n\n return result\n }\n\n async suspendUserAndRevokeSessions(\n input: SuspendUserAndRevokeSessionsInput\n ): Promise<UserRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await lockAdvisoryKeys(tx, [authLockKey(\"sessions\", input.projectId, input.userId)])\n const existing = await getUserRowById(\n tx,\n {\n projectId: input.projectId,\n id: input.userId,\n },\n { forUpdate: true }\n )\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${input.userId}' not found for project '${input.projectId}'.`\n )\n }\n\n const [updated] = await tx<PgAuthUserRow[]>`\n UPDATE auth_users\n SET status = 'suspended',\n updated_at = ${input.suspendedAt}\n WHERE project_id = ${input.projectId}\n AND id = ${input.userId}\n RETURNING *\n `\n\n await revokeActiveSessionsForUser(tx, {\n projectId: input.projectId,\n userId: input.userId,\n revokedAt: input.suspendedAt,\n })\n\n return rowToUserRecord(updated)\n })\n }\n\n private assertMagicLinkUsable(\n projectId: string,\n id: string,\n tokenHash: string,\n completedAt: Date,\n row: PgAuthMagicLinkRow | null\n ): asserts row is PgAuthMagicLinkRow {\n if (!row) {\n throw new AuthStorageError(\n \"missing_magic_link\",\n `[Sixb] Magic link '${id}' not found for project '${projectId}'.`\n )\n }\n\n assertMagicLinkUsable(projectId, id, tokenHash, completedAt, row)\n }\n\n private assertOidcAttemptUsable(\n projectId: string,\n id: string,\n stateHash: string,\n completedAt: Date,\n row: PgAuthOidcAttemptRow | null\n ): asserts row is PgAuthOidcAttemptRow {\n if (!row) {\n throw new AuthStorageError(\n \"missing_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' not found for project '${projectId}'.`\n )\n }\n\n assertOidcAttemptUsable(projectId, id, stateHash, completedAt, row)\n }\n\n private async insertUser(\n sql: SQLClient,\n input: {\n readonly id: string\n readonly projectId: string\n readonly email: string\n readonly displayName?: string\n readonly avatarUrl?: string\n readonly createdAt: Date\n }\n ): Promise<UserRecord> {\n try {\n const [row] = await sql<PgAuthUserRow[]>`\n INSERT INTO auth_users (\n project_id,\n id,\n email,\n display_name,\n avatar_url,\n status,\n created_at,\n updated_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.email},\n ${input.displayName ?? null},\n ${input.avatarUrl ?? null},\n ${\"active\"},\n ${input.createdAt},\n ${input.createdAt}\n )\n RETURNING *\n `\n\n return rowToUserRecord(row)\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_user\",\n `[Sixb] User '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n }\n\n private async acceptInvitationAndApplyGroups(\n sql: SQLClient,\n input: {\n readonly activeInvitation: InvitationRecord | null\n readonly completedAt: Date\n readonly projectId: string\n readonly user: UserRecord\n }\n ): Promise<{\n readonly invitation?: InvitationRecord\n readonly groupMemberships: readonly GroupMembershipRecord[]\n }> {\n if (!input.activeInvitation) {\n return { groupMemberships: [] }\n }\n\n await sql`\n UPDATE auth_invitations\n SET status = 'accepted',\n accepted_at = ${input.completedAt},\n updated_at = ${input.completedAt}\n WHERE project_id = ${input.projectId}\n AND id = ${input.activeInvitation.id}\n `\n\n const invitation: InvitationRecord = {\n ...input.activeInvitation,\n status: \"accepted\",\n acceptedAt: new Date(input.completedAt),\n updatedAt: new Date(input.completedAt),\n }\n const groupMemberships: GroupMembershipRecord[] = []\n for (const groupId of input.activeInvitation.groupIds) {\n groupMemberships.push(\n await upsertGroupMembership(sql, {\n projectId: input.projectId,\n userId: input.user.id,\n groupId,\n source: \"invitation\",\n createdAt: input.completedAt,\n })\n )\n }\n\n return { invitation, groupMemberships }\n }\n\n private async applyManualGroups(\n sql: SQLClient,\n input: {\n readonly completedAt: Date\n readonly existing: readonly GroupMembershipRecord[]\n readonly groupIds: readonly string[]\n readonly projectId: string\n readonly userId: string\n }\n ): Promise<readonly GroupMembershipRecord[]> {\n const groupMemberships = [...input.existing]\n\n for (const groupId of input.groupIds) {\n groupMemberships.push(\n await upsertGroupMembership(sql, {\n projectId: input.projectId,\n userId: input.userId,\n groupId,\n source: \"manual\",\n createdAt: input.completedAt,\n })\n )\n }\n\n return groupMemberships\n }\n\n private async createSignInSession(\n sql: SQLClient,\n input: {\n readonly projectId: string\n readonly strategyId: string\n readonly session: CompleteMagicLinkSignInInput[\"session\"]\n readonly userId: string\n }\n ): Promise<SessionRecord> {\n await lockAdvisoryKeys(sql, [\n authLockKey(\"sessions\", input.projectId, input.userId),\n authLockKey(\"sessions\", input.projectId, input.userId, input.session.audience),\n ])\n\n return createSession(sql, {\n id: input.session.id,\n projectId: input.projectId,\n userId: input.userId,\n strategyId: input.strategyId,\n audience: input.session.audience,\n tokenHash: input.session.tokenHash,\n createdAt: input.session.createdAt,\n expiresAt: input.session.expiresAt,\n absoluteExpiresAt: input.session.absoluteExpiresAt,\n userAgent: input.session.userAgent,\n ipAddress: input.session.ipAddress,\n })\n }\n\n private async consumeOidcAttempt(\n input: CompleteOidcSignInInput,\n completedAt: Date,\n projectId: string,\n sql: SQLClient\n ): Promise<void> {\n await consumeOidcAttempt(sql, {\n projectId,\n id: input.oidcAuthorizationAttemptId,\n stateHash: input.stateHash,\n consumedAt: completedAt,\n })\n }\n\n private async upsertIdentity(\n sql: SQLClient,\n input: {\n readonly projectId: string\n readonly strategyId: string\n readonly subject: string\n readonly userId: string\n readonly claims?: Readonly<Record<string, unknown>>\n readonly createdAt: Date\n readonly updatedAt: Date\n }\n ): Promise<UserIdentityRecord> {\n const [row] = await sql<PgAuthUserIdentityRow[]>`\n INSERT INTO auth_user_identities (\n project_id,\n strategy_id,\n subject,\n user_id,\n claims,\n created_at,\n updated_at\n ) VALUES (\n ${input.projectId},\n ${input.strategyId},\n ${input.subject},\n ${input.userId},\n ${serializeOptionalRecord(input.claims)}::text::jsonb,\n ${input.createdAt},\n ${input.updatedAt}\n )\n ON CONFLICT (project_id, strategy_id, subject)\n DO UPDATE SET\n user_id = excluded.user_id,\n claims = excluded.claims,\n updated_at = excluded.updated_at\n RETURNING *\n `\n\n return rowToIdentityRecord(row)\n }\n}\n\nasync function hasActiveUsers(sql: SQLClient, projectId: string): Promise<boolean> {\n const rows = (await sql`\n SELECT 1 AS active\n FROM auth_users\n WHERE project_id = ${projectId}\n AND status = 'active'\n LIMIT 1\n `) as Array<{ readonly active: number }>\n\n return rows.length > 0\n}\n\nfunction assertSignInSessionAudience(\n projectId: string,\n sessionAudience: string,\n storedAudience: string\n): void {\n if (sessionAudience === storedAudience) {\n return\n }\n\n throw new AuthStorageError(\n \"invalid_input\",\n `[Sixb] Sign-in session audience '${sessionAudience}' does not match stored auth audience '${storedAudience}' for project '${projectId}'.`\n )\n}\n",
15
+ "import type {\n AccessTokenRecord,\n AuthAccessTokenStore,\n CreateAuthAccessTokenInput,\n ListAuthAccessTokensInput,\n ListAuthAccessTokensResult,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { PgStoreClient } from \"../transactions\"\nimport type { PgAuthAccessTokenRow, PgAuthServiceAccountRow, PgAuthUserRow } from \"./rows\"\nimport { rowToAccessTokenRecord, serializeOptionalStringArray } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n mapUniqueConstraintError,\n normalizeGroupIds,\n type PgValue,\n} from \"./shared\"\n\nexport class PgAuthAccessTokenStore implements AuthAccessTokenStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateAuthAccessTokenInput): Promise<AccessTokenRecord> {\n const id = assertNonEmpty(input.id, \"Access token id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const name = assertNonEmpty(input.name, \"Access token name\")\n const subjectId = assertNonEmpty(input.subjectId, \"Access token subject id\")\n const tokenHash = assertNonEmpty(input.tokenHash, \"Access token hash\")\n assertKindMatchesSubject(input)\n await this.assertSubjectExists(projectId, input.subjectType, subjectId)\n const groupIds = input.groupIds === undefined ? undefined : normalizeGroupIds(input.groupIds)\n\n try {\n const [row] = await this.sql<PgAuthAccessTokenRow[]>`\n INSERT INTO auth_access_tokens (\n project_id,\n id,\n name,\n kind,\n subject_type,\n subject_id,\n token_hash,\n group_ids,\n created_by_user_id,\n created_by_service_account_id,\n created_by_system_id,\n created_by_session_id,\n created_at,\n expires_at\n ) VALUES (\n ${projectId},\n ${id},\n ${name},\n ${input.kind},\n ${input.subjectType},\n ${subjectId},\n ${tokenHash},\n ${serializeOptionalStringArray(groupIds)},\n ${input.createdByPrincipal?.type === \"user\" ? input.createdByPrincipal.id : null},\n ${\n input.createdByPrincipal?.type === \"serviceAccount\" ? input.createdByPrincipal.id : null\n },\n ${input.createdByPrincipal?.type === \"system\" ? input.createdByPrincipal.id : null},\n ${input.createdBySessionId ?? null},\n ${input.createdAt},\n ${input.expiresAt}\n )\n RETURNING *\n `\n\n return rowToAccessTokenRecord(row)\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_access_token\",\n `[Sixb] Access token '${id}' already exists for project '${projectId}'.`\n )\n }\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<AccessTokenRecord | null> {\n const [row] = await this.sql<PgAuthAccessTokenRow[]>`\n SELECT *\n FROM auth_access_tokens\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n `\n return row ? rowToAccessTokenRecord(row) : null\n }\n\n async list(input: ListAuthAccessTokensInput): Promise<ListAuthAccessTokensResult> {\n const whereClauses = [\"project_id = $1\"]\n const params: PgValue[] = [input.projectId]\n let nextIndex = 2\n if (input.kind) {\n whereClauses.push(`kind = $${nextIndex++}`)\n params.push(input.kind)\n }\n if (input.subjectType) {\n whereClauses.push(`subject_type = $${nextIndex++}`)\n params.push(input.subjectType)\n }\n if (input.subjectId) {\n whereClauses.push(`subject_id = $${nextIndex++}`)\n params.push(input.subjectId)\n }\n if (!input.includeRevoked) {\n whereClauses.push(\"revoked_at IS NULL\")\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const [totalRow] = await this.sql.unsafe<{ readonly count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM auth_access_tokens ${where}`,\n [...params]\n )\n const queryParams = [...params]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_access_tokens\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryParams,\n nextIndex,\n input\n )\n const rows = await this.sql.unsafe<PgAuthAccessTokenRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n\n return {\n accessTokens: rows.map(rowToAccessTokenRecord),\n hasMore: input.limit === undefined ? false : (input.offset ?? 0) + input.limit < total,\n total,\n }\n }\n\n async findValidByTokenHash(params: {\n readonly projectId: string\n readonly id: string\n readonly kind: AccessTokenRecord[\"kind\"]\n readonly tokenHash: string\n readonly now: Date\n }): Promise<AccessTokenRecord | null> {\n const [row] = await this.sql<PgAuthAccessTokenRow[]>`\n SELECT *\n FROM auth_access_tokens\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n AND kind = ${params.kind}\n AND token_hash = ${params.tokenHash}\n AND revoked_at IS NULL\n AND expires_at > ${params.now}\n `\n\n return row ? rowToAccessTokenRecord(row) : null\n }\n\n async revoke(params: {\n readonly projectId: string\n readonly id: string\n readonly revokedAt: Date\n }): Promise<AccessTokenRecord> {\n const [row] = await this.sql<PgAuthAccessTokenRow[]>`\n UPDATE auth_access_tokens\n SET revoked_at = ${params.revokedAt}\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n RETURNING *\n `\n if (!row) {\n throw new AuthStorageError(\n \"missing_access_token\",\n `[Sixb] Access token '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return rowToAccessTokenRecord(row)\n }\n\n async touch(params: {\n readonly projectId: string\n readonly id: string\n readonly lastUsedAt: Date\n readonly userAgent?: string\n readonly ipAddress?: string\n }): Promise<AccessTokenRecord> {\n const [row] = await this.sql<PgAuthAccessTokenRow[]>`\n UPDATE auth_access_tokens\n SET last_used_at = ${params.lastUsedAt},\n last_used_user_agent = COALESCE(${params.userAgent ?? null}, last_used_user_agent),\n last_used_ip_address = COALESCE(${params.ipAddress ?? null}, last_used_ip_address)\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n RETURNING *\n `\n if (!row) {\n throw new AuthStorageError(\n \"missing_access_token\",\n `[Sixb] Access token '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return rowToAccessTokenRecord(row)\n }\n\n private async assertSubjectExists(\n projectId: string,\n subjectType: CreateAuthAccessTokenInput[\"subjectType\"],\n subjectId: string\n ): Promise<void> {\n if (subjectType === \"user\") {\n const [row] = await this.sql<PgAuthUserRow[]>`\n SELECT *\n FROM auth_users\n WHERE project_id = ${projectId}\n AND id = ${subjectId}\n `\n if (row) return\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${subjectId}' not found for project '${projectId}'.`\n )\n }\n\n const [row] = await this.sql<PgAuthServiceAccountRow[]>`\n SELECT *\n FROM auth_service_accounts\n WHERE project_id = ${projectId}\n AND id = ${subjectId}\n `\n if (row) return\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${subjectId}' not found for project '${projectId}'.`\n )\n }\n}\n\nfunction assertKindMatchesSubject(input: CreateAuthAccessTokenInput): void {\n if (\n (input.kind === \"personal\" && input.subjectType === \"user\") ||\n (input.kind === \"serviceAccount\" && input.subjectType === \"serviceAccount\")\n ) {\n return\n }\n\n throw new AuthStorageError(\n \"invalid_input\",\n `[Sixb] Access token kind '${input.kind}' cannot target subject type '${input.subjectType}'.`\n )\n}\n",
16
+ "import type { Principal } from \"@sixb/core\"\nimport type {\n AccessTokenRecord,\n GroupMembershipRecord,\n GroupMembershipSource,\n InvitationRecord,\n InvitationStatus,\n MagicLinkRecord,\n OidcAuthorizationAttemptRecord,\n ServiceAccountGroupMembershipRecord,\n ServiceAccountRecord,\n ServiceAccountStatus,\n SessionRecord,\n UserIdentityRecord,\n UserRecord,\n UserStatus,\n} from \"@sixb/core/storage\"\n\ntype PgDate = Date | string\n\nexport interface PgAuthUserRow {\n readonly project_id: string\n readonly id: string\n readonly email: string\n readonly display_name: string | null\n readonly avatar_url: string | null\n readonly status: UserStatus\n readonly created_at: PgDate\n readonly updated_at: PgDate\n}\n\nexport interface PgAuthUserIdentityRow {\n readonly project_id: string\n readonly strategy_id: string\n readonly subject: string\n readonly user_id: string\n readonly claims: Readonly<Record<string, unknown>> | string | null\n readonly created_at: PgDate\n readonly updated_at: PgDate\n}\n\nexport interface PgAuthServiceAccountRow {\n readonly project_id: string\n readonly id: string\n readonly name: string\n readonly description: string | null\n readonly status: ServiceAccountStatus\n readonly created_by_user_id: string | null\n readonly created_by_service_account_id: string | null\n readonly created_by_system_id: string | null\n readonly created_by_session_id: string | null\n readonly created_at: PgDate\n readonly updated_at: PgDate\n}\n\nexport interface PgAuthServiceAccountGroupMembershipRow {\n readonly project_id: string\n readonly service_account_id: string\n readonly group_id: string\n readonly source: GroupMembershipSource\n readonly created_at: PgDate\n}\n\nexport interface PgAuthSessionRow {\n readonly project_id: string\n readonly id: string\n readonly user_id: string\n readonly strategy_id: string\n readonly audience: SessionRecord[\"audience\"]\n readonly token_hash: string\n readonly created_at: PgDate\n readonly expires_at: PgDate\n readonly absolute_expires_at: PgDate | null\n readonly revoked_at: PgDate | null\n readonly last_seen_at: PgDate | null\n readonly user_agent: string | null\n readonly ip_address: string | null\n}\n\nexport interface PgAuthAccessTokenRow {\n readonly project_id: string\n readonly id: string\n readonly name: string\n readonly kind: AccessTokenRecord[\"kind\"]\n readonly subject_type: AccessTokenRecord[\"subjectType\"]\n readonly subject_id: string\n readonly token_hash: string\n readonly group_ids: readonly string[] | string | null\n readonly created_by_user_id: string | null\n readonly created_by_service_account_id: string | null\n readonly created_by_system_id: string | null\n readonly created_by_session_id: string | null\n readonly created_at: PgDate\n readonly expires_at: PgDate\n readonly revoked_at: PgDate | null\n readonly last_used_at: PgDate | null\n readonly last_used_user_agent: string | null\n readonly last_used_ip_address: string | null\n}\n\nexport interface PgAuthInvitationRow {\n readonly project_id: string\n readonly id: string\n readonly email: string\n readonly status: InvitationStatus\n readonly created_by_user_id: string | null\n readonly created_by_service_account_id: string | null\n readonly created_by_system_id: string | null\n readonly created_by_session_id: string | null\n readonly created_at: PgDate\n readonly updated_at: PgDate\n readonly expires_at: PgDate\n readonly accepted_at: PgDate | null\n readonly revoked_at: PgDate | null\n}\n\nexport interface PgAuthGroupMembershipRow {\n readonly project_id: string\n readonly user_id: string\n readonly group_id: string\n readonly source: GroupMembershipSource\n readonly created_at: PgDate\n}\n\nexport interface PgAuthMagicLinkRow {\n readonly project_id: string\n readonly id: string\n readonly strategy_id: string\n readonly audience: MagicLinkRecord[\"audience\"]\n readonly email: string\n readonly token_hash: string\n readonly return_to: string | null\n readonly created_at: PgDate\n readonly expires_at: PgDate\n readonly consumed_at: PgDate | null\n readonly revoked_at: PgDate | null\n}\n\nexport interface PgAuthOidcAttemptRow {\n readonly project_id: string\n readonly id: string\n readonly strategy_id: string\n readonly audience: OidcAuthorizationAttemptRecord[\"audience\"]\n readonly state_hash: string\n readonly nonce_hash: string\n readonly code_verifier: string\n readonly return_to: string | null\n readonly created_at: PgDate\n readonly expires_at: PgDate\n readonly consumed_at: PgDate | null\n}\n\nexport function rowToUserRecord(row: PgAuthUserRow): UserRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n email: row.email,\n displayName: row.display_name ?? undefined,\n avatarUrl: row.avatar_url ?? undefined,\n status: row.status,\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at),\n }\n}\n\nexport function rowToIdentityRecord(row: PgAuthUserIdentityRow): UserIdentityRecord {\n return {\n projectId: row.project_id,\n strategyId: row.strategy_id,\n subject: row.subject,\n userId: row.user_id,\n claims: parseOptionalRecord(row.claims),\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at),\n }\n}\n\nexport function rowToServiceAccountRecord(row: PgAuthServiceAccountRow): ServiceAccountRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n name: row.name,\n description: row.description ?? undefined,\n status: row.status,\n createdByPrincipal: principalFromColumns(row),\n createdBySessionId: row.created_by_session_id ?? undefined,\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at),\n }\n}\n\nexport function rowToServiceAccountGroupMembershipRecord(\n row: PgAuthServiceAccountGroupMembershipRow\n): ServiceAccountGroupMembershipRecord {\n return {\n projectId: row.project_id,\n serviceAccountId: row.service_account_id,\n groupId: row.group_id,\n source: row.source,\n createdAt: toDate(row.created_at),\n }\n}\n\nexport function rowToSessionRecord(row: PgAuthSessionRow): SessionRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n userId: row.user_id,\n strategyId: row.strategy_id,\n audience: row.audience,\n tokenHash: row.token_hash,\n createdAt: toDate(row.created_at),\n expiresAt: toDate(row.expires_at),\n absoluteExpiresAt: row.absolute_expires_at ? toDate(row.absolute_expires_at) : undefined,\n revokedAt: row.revoked_at ? toDate(row.revoked_at) : undefined,\n lastSeenAt: row.last_seen_at ? toDate(row.last_seen_at) : undefined,\n userAgent: row.user_agent ?? undefined,\n ipAddress: row.ip_address ?? undefined,\n }\n}\n\nexport function rowToAccessTokenRecord(row: PgAuthAccessTokenRow): AccessTokenRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n name: row.name,\n kind: row.kind,\n subjectType: row.subject_type,\n subjectId: row.subject_id,\n tokenHash: row.token_hash,\n groupIds: parseOptionalStringArray(row.group_ids),\n createdByPrincipal: principalFromColumns(row),\n createdBySessionId: row.created_by_session_id ?? undefined,\n createdAt: toDate(row.created_at),\n expiresAt: toDate(row.expires_at),\n revokedAt: row.revoked_at ? toDate(row.revoked_at) : undefined,\n lastUsedAt: row.last_used_at ? toDate(row.last_used_at) : undefined,\n lastUsedUserAgent: row.last_used_user_agent ?? undefined,\n lastUsedIpAddress: row.last_used_ip_address ?? undefined,\n }\n}\n\nexport function rowToInvitationRecord(\n row: PgAuthInvitationRow,\n groupIds: readonly string[]\n): InvitationRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n email: row.email,\n groupIds,\n status: row.status,\n createdByPrincipal: invitationCreatorFromRow(row),\n createdBySessionId: row.created_by_session_id ?? undefined,\n createdAt: toDate(row.created_at),\n updatedAt: toDate(row.updated_at),\n expiresAt: toDate(row.expires_at),\n acceptedAt: row.accepted_at ? toDate(row.accepted_at) : undefined,\n revokedAt: row.revoked_at ? toDate(row.revoked_at) : undefined,\n }\n}\n\nexport function rowToGroupMembershipRecord(row: PgAuthGroupMembershipRow): GroupMembershipRecord {\n return {\n projectId: row.project_id,\n userId: row.user_id,\n groupId: row.group_id,\n source: row.source,\n createdAt: toDate(row.created_at),\n }\n}\n\nexport function rowToMagicLinkRecord(row: PgAuthMagicLinkRow): MagicLinkRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n strategyId: row.strategy_id,\n audience: row.audience,\n email: row.email,\n tokenHash: row.token_hash,\n returnTo: row.return_to ?? undefined,\n createdAt: toDate(row.created_at),\n expiresAt: toDate(row.expires_at),\n consumedAt: row.consumed_at ? toDate(row.consumed_at) : undefined,\n revokedAt: row.revoked_at ? toDate(row.revoked_at) : undefined,\n }\n}\n\nexport function rowToOidcAuthorizationAttemptRecord(\n row: PgAuthOidcAttemptRow\n): OidcAuthorizationAttemptRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n strategyId: row.strategy_id,\n audience: row.audience,\n stateHash: row.state_hash,\n nonceHash: row.nonce_hash,\n codeVerifier: row.code_verifier,\n returnTo: row.return_to ?? undefined,\n createdAt: toDate(row.created_at),\n expiresAt: toDate(row.expires_at),\n consumedAt: row.consumed_at ? toDate(row.consumed_at) : undefined,\n }\n}\n\nexport function serializeOptionalRecord(\n value: Readonly<Record<string, unknown>> | undefined\n): string | null {\n return value ? JSON.stringify(value) : null\n}\n\nexport function serializeOptionalStringArray(value: readonly string[] | undefined): string | null {\n return value === undefined ? null : JSON.stringify(value)\n}\n\nfunction principalFromColumns(row: {\n readonly created_by_user_id: string | null\n readonly created_by_service_account_id: string | null\n readonly created_by_system_id: string | null\n}): Principal | undefined {\n if (row.created_by_user_id) return { type: \"user\", id: row.created_by_user_id }\n if (row.created_by_service_account_id) {\n return { type: \"serviceAccount\", id: row.created_by_service_account_id }\n }\n if (row.created_by_system_id) return { type: \"system\", id: row.created_by_system_id }\n return undefined\n}\n\nfunction invitationCreatorFromRow(row: PgAuthInvitationRow): Principal | undefined {\n return principalFromColumns(row)\n}\n\nfunction parseOptionalRecord(\n value: Readonly<Record<string, unknown>> | string | null\n): Readonly<Record<string, unknown>> | undefined {\n if (!value) return undefined\n if (typeof value === \"string\") return JSON.parse(value) as Readonly<Record<string, unknown>>\n return structuredClone(value)\n}\n\nfunction parseOptionalStringArray(\n value: readonly string[] | string | null\n): readonly string[] | undefined {\n if (value === null) return undefined\n if (typeof value === \"string\") return JSON.parse(value) as readonly string[]\n return [...value]\n}\n\nfunction toDate(value: PgDate): Date {\n return value instanceof Date ? new Date(value) : new Date(value)\n}\n",
17
+ "import type { AuthSessionAudience, Principal } from \"@sixb/core\"\nimport type {\n CompleteAuthSessionInput,\n CreateAuthSessionInput,\n GroupMembershipRecord,\n InvitationRecord,\n MagicLinkRecord,\n OidcAuthorizationAttemptRecord,\n SessionRecord,\n UpsertAuthGroupMembershipInput,\n UserRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport { isUniqueViolation } from \"../storage-errors\"\nimport type {\n PgAuthGroupMembershipRow,\n PgAuthInvitationRow,\n PgAuthMagicLinkRow,\n PgAuthOidcAttemptRow,\n PgAuthSessionRow,\n PgAuthUserIdentityRow,\n PgAuthUserRow,\n} from \"./rows\"\nimport {\n rowToGroupMembershipRecord,\n rowToInvitationRecord,\n rowToMagicLinkRecord,\n rowToOidcAuthorizationAttemptRecord,\n rowToSessionRecord,\n rowToUserRecord,\n} from \"./rows\"\n\nexport type PgValue = string | number | Date | null\n\nexport function assertNonEmpty(value: string, label: string): string {\n const normalized = value.trim()\n if (!normalized) {\n throw new AuthStorageError(\"invalid_input\", `[Sixb] ${label} must be a non-empty string.`)\n }\n return normalized\n}\n\nexport function normalizeEmail(email: string): string {\n return assertNonEmpty(email, \"Email\").toLowerCase()\n}\n\nexport function normalizeGroupIds(groupIds: readonly string[] | undefined): readonly string[] {\n return [...new Set((groupIds ?? []).map((groupId) => assertNonEmpty(groupId, \"Group id\")))]\n}\n\nexport function dateOrNow(value: Date | undefined): Date {\n return value ? new Date(value) : new Date()\n}\n\nexport function hasEmptyFilter(values: readonly unknown[] | undefined): boolean {\n return values !== undefined && values.length === 0\n}\n\nexport function appendPagination(\n query: string,\n params: PgValue[],\n nextIndex: number,\n input: { readonly limit?: number; readonly offset?: number }\n): string {\n const offset = input.offset ?? 0\n\n if (input.limit !== undefined) {\n params.push(input.limit, offset)\n return `${query} LIMIT $${nextIndex++} OFFSET $${nextIndex++}`\n }\n\n if (offset > 0) {\n params.push(offset)\n return `${query} OFFSET $${nextIndex++}`\n }\n\n return query\n}\n\nexport function placeholders(startIndex: number, count: number): readonly string[] {\n return Array.from({ length: count }, (_, index) => `$${startIndex + index}`)\n}\n\nexport async function getUserRowById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<PgAuthUserRow | null> {\n const [row] = await sql.unsafe<PgAuthUserRow[]>(\n `\n SELECT *\n FROM auth_users\n WHERE project_id = $1\n AND id = $2\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, params.id]\n )\n\n return row ?? null\n}\n\nexport async function getUserById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string }\n): Promise<UserRecord | null> {\n const row = await getUserRowById(sql, params)\n return row ? rowToUserRecord(row) : null\n}\n\nexport async function getUserRowByEmail(\n sql: SQLClient,\n params: { readonly projectId: string; readonly email: string },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<PgAuthUserRow | null> {\n const [row] = await sql.unsafe<PgAuthUserRow[]>(\n `\n SELECT *\n FROM auth_users\n WHERE project_id = $1\n AND email = $2\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, normalizeEmail(params.email)]\n )\n\n return row ?? null\n}\n\nexport async function getUserByEmail(\n sql: SQLClient,\n params: { readonly projectId: string; readonly email: string }\n): Promise<UserRecord | null> {\n const row = await getUserRowByEmail(sql, params)\n return row ? rowToUserRecord(row) : null\n}\n\nexport async function requireUserById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string }\n): Promise<UserRecord> {\n const user = await getUserById(sql, params)\n if (!user) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return user\n}\n\nexport async function getIdentityRowBySubject(\n sql: SQLClient,\n params: {\n readonly projectId: string\n readonly strategyId: string\n readonly subject: string\n },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<PgAuthUserIdentityRow | null> {\n const [row] = await sql.unsafe<PgAuthUserIdentityRow[]>(\n `\n SELECT *\n FROM auth_user_identities\n WHERE project_id = $1\n AND strategy_id = $2\n AND subject = $3\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, params.strategyId, params.subject]\n )\n\n return row ?? null\n}\n\nexport async function getSessionRowById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<PgAuthSessionRow | null> {\n const [row] = await sql.unsafe<PgAuthSessionRow[]>(\n `\n SELECT *\n FROM auth_sessions\n WHERE project_id = $1\n AND id = $2\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, params.id]\n )\n\n return row ?? null\n}\n\nexport async function getSessionById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string }\n): Promise<ReturnType<typeof rowToSessionRecord> | null> {\n const row = await getSessionRowById(sql, params)\n return row ? rowToSessionRecord(row) : null\n}\n\nexport async function requireSessionById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string }\n): Promise<ReturnType<typeof rowToSessionRecord>> {\n const session = await getSessionById(sql, params)\n if (!session) {\n throw new AuthStorageError(\n \"missing_session\",\n `[Sixb] Session '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return session\n}\n\nexport async function getInvitationGroupIds(\n sql: SQLClient,\n params: { readonly projectId: string; readonly invitationId: string }\n): Promise<readonly string[]> {\n const rows = (await sql`\n SELECT group_id\n FROM auth_invitation_groups\n WHERE project_id = ${params.projectId}\n AND invitation_id = ${params.invitationId}\n ORDER BY position ASC, group_id ASC\n `) as Array<{ readonly group_id: string }>\n\n return rows.map((row) => row.group_id)\n}\n\nexport async function getInvitationById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<InvitationRecord | null> {\n const [row] = await sql.unsafe<PgAuthInvitationRow[]>(\n `\n SELECT *\n FROM auth_invitations\n WHERE project_id = $1\n AND id = $2\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, params.id]\n )\n\n return row ? invitationRowToRecord(sql, row) : null\n}\n\nexport async function requireInvitationById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<InvitationRecord> {\n const invitation = await getInvitationById(sql, params, options)\n if (!invitation) {\n throw new AuthStorageError(\n \"missing_invitation\",\n `[Sixb] Invitation '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return invitation\n}\n\nexport async function getActiveInvitationByEmail(\n sql: SQLClient,\n params: { readonly projectId: string; readonly email: string; readonly now: Date },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<InvitationRecord | null> {\n const [row] = await sql.unsafe<PgAuthInvitationRow[]>(\n `\n SELECT *\n FROM auth_invitations\n WHERE project_id = $1\n AND email = $2\n AND status = 'pending'\n AND expires_at > $3\n ORDER BY created_at DESC, id DESC\n LIMIT 1\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, normalizeEmail(params.email), params.now]\n )\n\n return row ? invitationRowToRecord(sql, row) : null\n}\n\nexport async function replaceInvitationGroups(\n sql: SQLClient,\n params: {\n readonly projectId: string\n readonly invitationId: string\n readonly groupIds: readonly string[]\n }\n): Promise<void> {\n await sql`\n DELETE FROM auth_invitation_groups\n WHERE project_id = ${params.projectId}\n AND invitation_id = ${params.invitationId}\n `\n\n for (const [index, groupId] of params.groupIds.entries()) {\n await sql`\n INSERT INTO auth_invitation_groups (\n project_id,\n invitation_id,\n group_id,\n position\n ) VALUES (\n ${params.projectId},\n ${params.invitationId},\n ${groupId},\n ${index}\n )\n `\n }\n}\n\nexport async function getMagicLinkRowById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<PgAuthMagicLinkRow | null> {\n const [row] = await sql.unsafe<PgAuthMagicLinkRow[]>(\n `\n SELECT *\n FROM auth_magic_links\n WHERE project_id = $1\n AND id = $2\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, params.id]\n )\n\n return row ?? null\n}\n\nexport async function getMagicLinkById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string }\n): Promise<MagicLinkRecord | null> {\n const row = await getMagicLinkRowById(sql, params)\n return row ? rowToMagicLinkRecord(row) : null\n}\n\nexport async function consumeMagicLink(\n sql: SQLClient,\n params: {\n readonly projectId: string\n readonly id: string\n readonly tokenHash: string\n readonly consumedAt: Date\n }\n): Promise<MagicLinkRecord> {\n const projectId = assertNonEmpty(params.projectId, \"Project id\")\n const id = assertNonEmpty(params.id, \"Magic link id\")\n const tokenHash = assertNonEmpty(params.tokenHash, \"Magic link token hash\")\n const row = await getMagicLinkRowById(sql, { projectId, id }, { forUpdate: true })\n\n if (!row) {\n throw new AuthStorageError(\n \"missing_magic_link\",\n `[Sixb] Magic link '${id}' not found for project '${projectId}'.`\n )\n }\n\n assertMagicLinkUsable(projectId, id, tokenHash, params.consumedAt, row)\n\n await sql`\n UPDATE auth_magic_links\n SET consumed_at = ${params.consumedAt}\n WHERE project_id = ${projectId}\n AND id = ${id}\n `\n\n return rowToMagicLinkRecord({\n ...row,\n consumed_at: params.consumedAt,\n })\n}\n\nexport async function getOidcAttemptRowById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string },\n options: { readonly forUpdate?: boolean } = {}\n): Promise<PgAuthOidcAttemptRow | null> {\n const [row] = await sql.unsafe<PgAuthOidcAttemptRow[]>(\n `\n SELECT *\n FROM auth_oidc_authorization_attempts\n WHERE project_id = $1\n AND id = $2\n ${options.forUpdate ? \"FOR UPDATE\" : \"\"}\n `,\n [params.projectId, params.id]\n )\n\n return row ?? null\n}\n\nexport async function getOidcAttemptById(\n sql: SQLClient,\n params: { readonly projectId: string; readonly id: string }\n): Promise<OidcAuthorizationAttemptRecord | null> {\n const row = await getOidcAttemptRowById(sql, params)\n return row ? rowToOidcAuthorizationAttemptRecord(row) : null\n}\n\nexport async function consumeOidcAttempt(\n sql: SQLClient,\n params: {\n readonly projectId: string\n readonly id: string\n readonly stateHash: string\n readonly consumedAt: Date\n }\n): Promise<OidcAuthorizationAttemptRecord> {\n const projectId = assertNonEmpty(params.projectId, \"Project id\")\n const id = assertNonEmpty(params.id, \"OIDC authorization attempt id\")\n const stateHash = assertNonEmpty(params.stateHash, \"OIDC state hash\")\n const row = await getOidcAttemptRowById(sql, { projectId, id }, { forUpdate: true })\n\n if (!row) {\n throw new AuthStorageError(\n \"missing_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' not found for project '${projectId}'.`\n )\n }\n\n assertOidcAttemptUsable(projectId, id, stateHash, params.consumedAt, row)\n\n await sql`\n UPDATE auth_oidc_authorization_attempts\n SET consumed_at = ${params.consumedAt}\n WHERE project_id = ${projectId}\n AND id = ${id}\n `\n\n return rowToOidcAuthorizationAttemptRecord({\n ...row,\n consumed_at: params.consumedAt,\n })\n}\n\nexport async function validateCompleteSessionInput(\n sql: SQLClient,\n projectId: string,\n session: CompleteAuthSessionInput\n): Promise<void> {\n const sessionId = assertNonEmpty(session.id, \"Session id\")\n assertNonEmpty(session.audience, \"Session audience\")\n assertNonEmpty(session.tokenHash, \"Session token hash\")\n await assertSessionIdAvailable(sql, projectId, sessionId)\n}\n\nexport async function assertSessionIdAvailable(\n sql: SQLClient,\n projectId: string,\n sessionId: string\n): Promise<void> {\n if (await getSessionRowById(sql, { projectId, id: sessionId })) {\n throw new AuthStorageError(\n \"duplicate_session\",\n `[Sixb] Session '${sessionId}' already exists for project '${projectId}'.`\n )\n }\n}\n\nexport async function createSession(\n sql: SQLClient,\n input: CreateAuthSessionInput\n): Promise<SessionRecord> {\n const id = assertNonEmpty(input.id, \"Session id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const userId = assertNonEmpty(input.userId, \"User id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const audience = assertNonEmpty(input.audience, \"Session audience\")\n const tokenHash = assertNonEmpty(input.tokenHash, \"Session token hash\")\n\n await requireUserById(sql, { projectId, id: userId })\n await assertSessionIdAvailable(sql, projectId, id)\n\n try {\n const [row] = await sql<PgAuthSessionRow[]>`\n INSERT INTO auth_sessions (\n project_id,\n id,\n user_id,\n strategy_id,\n audience,\n token_hash,\n created_at,\n expires_at,\n absolute_expires_at,\n user_agent,\n ip_address\n ) VALUES (\n ${projectId},\n ${id},\n ${userId},\n ${strategyId},\n ${audience},\n ${tokenHash},\n ${input.createdAt},\n ${input.expiresAt},\n ${input.absoluteExpiresAt ?? null},\n ${input.userAgent ?? null},\n ${input.ipAddress ?? null}\n )\n RETURNING *\n `\n\n return rowToSessionRecord(row)\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_session\",\n `[Sixb] Session '${id}' already exists for project '${projectId}'.`\n )\n }\n}\n\nexport async function revokeActiveSessionsForUser(\n sql: SQLClient,\n params: {\n readonly projectId: string\n readonly userId: string\n readonly audience?: AuthSessionAudience\n readonly revokedAt: Date\n }\n): Promise<readonly SessionRecord[]> {\n const rows =\n params.audience === undefined\n ? await sql<PgAuthSessionRow[]>`\n SELECT *\n FROM auth_sessions\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n AND revoked_at IS NULL\n AND expires_at > ${params.revokedAt}\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.revokedAt})\n ORDER BY created_at ASC, id ASC\n FOR UPDATE\n `\n : await sql<PgAuthSessionRow[]>`\n SELECT *\n FROM auth_sessions\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n AND audience = ${params.audience}\n AND revoked_at IS NULL\n AND expires_at > ${params.revokedAt}\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.revokedAt})\n ORDER BY created_at ASC, id ASC\n FOR UPDATE\n `\n\n if (params.audience === undefined) {\n await sql`\n UPDATE auth_sessions\n SET revoked_at = ${params.revokedAt}\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n AND revoked_at IS NULL\n AND expires_at > ${params.revokedAt}\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.revokedAt})\n `\n } else {\n await sql`\n UPDATE auth_sessions\n SET revoked_at = ${params.revokedAt}\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n AND audience = ${params.audience}\n AND revoked_at IS NULL\n AND expires_at > ${params.revokedAt}\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.revokedAt})\n `\n }\n\n return rows.map((row) =>\n rowToSessionRecord({\n ...row,\n revoked_at: params.revokedAt,\n })\n )\n}\n\nexport async function upsertGroupMembership(\n sql: SQLClient,\n input: UpsertAuthGroupMembershipInput\n): Promise<GroupMembershipRecord> {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const userId = assertNonEmpty(input.userId, \"User id\")\n const groupId = assertNonEmpty(input.groupId, \"Group id\")\n\n await requireUserById(sql, { projectId, id: userId })\n\n await sql`\n INSERT INTO auth_group_memberships (\n project_id,\n user_id,\n group_id,\n source,\n created_at\n ) VALUES (\n ${projectId},\n ${userId},\n ${groupId},\n ${input.source},\n ${dateOrNow(input.createdAt)}\n )\n ON CONFLICT (project_id, user_id, group_id) DO NOTHING\n `\n\n const membership = await getGroupMembership(sql, { projectId, userId, groupId })\n if (!membership) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] Failed to load group membership '${groupId}' for user '${userId}'.`\n )\n }\n return membership\n}\n\nexport async function removeGroupMembership(\n sql: SQLClient,\n params: { readonly projectId: string; readonly userId: string; readonly groupId: string }\n): Promise<GroupMembershipRecord | null> {\n const projectId = assertNonEmpty(params.projectId, \"Project id\")\n const userId = assertNonEmpty(params.userId, \"User id\")\n const groupId = assertNonEmpty(params.groupId, \"Group id\")\n\n const [row] = await sql<PgAuthGroupMembershipRow[]>`\n DELETE FROM auth_group_memberships\n WHERE project_id = ${projectId}\n AND user_id = ${userId}\n AND group_id = ${groupId}\n RETURNING *\n `\n\n return row ? rowToGroupMembershipRecord(row) : null\n}\n\nexport async function getGroupMembership(\n sql: SQLClient,\n params: { readonly projectId: string; readonly userId: string; readonly groupId: string }\n): Promise<GroupMembershipRecord | null> {\n const [row] = await sql<PgAuthGroupMembershipRow[]>`\n SELECT *\n FROM auth_group_memberships\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n AND group_id = ${params.groupId}\n `\n\n return row ? rowToGroupMembershipRecord(row) : null\n}\n\nexport async function listMembershipsForUser(\n sql: SQLClient,\n params: { readonly projectId: string; readonly userId: string }\n): Promise<readonly GroupMembershipRecord[]> {\n const rows = await sql<PgAuthGroupMembershipRow[]>`\n SELECT *\n FROM auth_group_memberships\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n ORDER BY group_id ASC\n `\n\n return rows.map(rowToGroupMembershipRecord)\n}\n\nexport async function revokeActiveMagicLinksForEmail(\n sql: SQLClient,\n params: { readonly projectId: string; readonly email: string; readonly revokedAt: Date }\n): Promise<readonly MagicLinkRecord[]> {\n const email = normalizeEmail(params.email)\n const rows = await sql<PgAuthMagicLinkRow[]>`\n SELECT *\n FROM auth_magic_links\n WHERE project_id = ${params.projectId}\n AND email = ${email}\n AND consumed_at IS NULL\n AND revoked_at IS NULL\n AND expires_at > ${params.revokedAt}\n ORDER BY created_at ASC, id ASC\n FOR UPDATE\n `\n\n await sql`\n UPDATE auth_magic_links\n SET revoked_at = ${params.revokedAt}\n WHERE project_id = ${params.projectId}\n AND email = ${email}\n AND consumed_at IS NULL\n AND revoked_at IS NULL\n AND expires_at > ${params.revokedAt}\n `\n\n return rows.map((row) =>\n rowToMagicLinkRecord({\n ...row,\n revoked_at: params.revokedAt,\n })\n )\n}\n\nexport function invitationCreatorColumns(principal: Principal | undefined): {\n readonly createdByUserId: string | null\n readonly createdByServiceAccountId: string | null\n readonly createdBySystemId: string | null\n} {\n return {\n createdByUserId: principal?.type === \"user\" ? principal.id : null,\n createdByServiceAccountId: principal?.type === \"serviceAccount\" ? principal.id : null,\n createdBySystemId: principal?.type === \"system\" ? principal.id : null,\n }\n}\n\nexport function assertMagicLinkUsable(\n projectId: string,\n id: string,\n tokenHash: string,\n at: Date,\n row: PgAuthMagicLinkRow\n): void {\n if (row.token_hash !== tokenHash || row.consumed_at || row.revoked_at) {\n throw new AuthStorageError(\n \"invalid_magic_link\",\n `[Sixb] Magic link '${id}' is not valid for project '${projectId}'.`\n )\n }\n\n if (new Date(row.expires_at) <= at) {\n throw new AuthStorageError(\n \"expired_magic_link\",\n `[Sixb] Magic link '${id}' is expired for project '${projectId}'.`\n )\n }\n}\n\nexport function assertOidcAttemptUsable(\n projectId: string,\n id: string,\n stateHash: string,\n at: Date,\n row: PgAuthOidcAttemptRow\n): void {\n if (row.state_hash !== stateHash || row.consumed_at) {\n throw new AuthStorageError(\n \"invalid_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' is not valid for project '${projectId}'.`\n )\n }\n\n if (new Date(row.expires_at) <= at) {\n throw new AuthStorageError(\n \"expired_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' is expired for project '${projectId}'.`\n )\n }\n}\n\nexport function mapUniqueConstraintError(\n error: unknown,\n code:\n | \"duplicate_access_token\"\n | \"duplicate_identity\"\n | \"duplicate_invitation\"\n | \"duplicate_magic_link\"\n | \"duplicate_oidc_attempt\"\n | \"duplicate_service_account\"\n | \"duplicate_session\"\n | \"duplicate_user\",\n message: string\n): never {\n if (isUniqueViolation(error)) {\n throw new AuthStorageError(code, message)\n }\n\n throw error\n}\n\nasync function invitationRowToRecord(\n sql: SQLClient,\n row: PgAuthInvitationRow\n): Promise<InvitationRecord> {\n return rowToInvitationRecord(\n row,\n await getInvitationGroupIds(sql, {\n projectId: row.project_id,\n invitationId: row.id,\n })\n )\n}\n",
18
+ "import type {\n AuthGroupMembershipStore,\n GroupMembershipRecord,\n UpsertAuthGroupMembershipInput,\n} from \"@sixb/core/storage\"\nimport type { PgStoreClient } from \"../transactions\"\nimport type { PgAuthGroupMembershipRow } from \"./rows\"\nimport { rowToGroupMembershipRecord } from \"./rows\"\nimport { listMembershipsForUser, removeGroupMembership, upsertGroupMembership } from \"./shared\"\n\nexport class PgAuthGroupMembershipStore implements AuthGroupMembershipStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async upsert(input: UpsertAuthGroupMembershipInput): Promise<GroupMembershipRecord> {\n return upsertGroupMembership(this.sql, input)\n }\n\n async remove(params: {\n readonly projectId: string\n readonly userId: string\n readonly groupId: string\n }): Promise<GroupMembershipRecord | null> {\n return removeGroupMembership(this.sql, params)\n }\n\n async listForUser(params: {\n readonly projectId: string\n readonly userId: string\n }): Promise<readonly GroupMembershipRecord[]> {\n return listMembershipsForUser(this.sql, params)\n }\n\n async listForGroup(params: {\n readonly projectId: string\n readonly groupId: string\n }): Promise<readonly GroupMembershipRecord[]> {\n const rows = await this.sql<PgAuthGroupMembershipRow[]>`\n SELECT *\n FROM auth_group_memberships\n WHERE project_id = ${params.projectId}\n AND group_id = ${params.groupId}\n ORDER BY user_id ASC\n `\n\n return rows.map(rowToGroupMembershipRecord)\n }\n}\n",
19
+ "import type {\n AuthUserIdentityStore,\n UpsertAuthUserIdentityInput,\n UserIdentityRecord,\n} from \"@sixb/core/storage\"\nimport type { PgStoreClient } from \"../transactions\"\nimport type { PgAuthUserIdentityRow } from \"./rows\"\nimport { rowToIdentityRecord, serializeOptionalRecord } from \"./rows\"\nimport { assertNonEmpty, dateOrNow, getIdentityRowBySubject, requireUserById } from \"./shared\"\n\nexport class PgAuthUserIdentityStore implements AuthUserIdentityStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async upsert(input: UpsertAuthUserIdentityInput): Promise<UserIdentityRecord> {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const subject = assertNonEmpty(input.subject, \"Subject\")\n const userId = assertNonEmpty(input.userId, \"User id\")\n const existing = await getIdentityRowBySubject(this.sql, {\n projectId,\n strategyId,\n subject,\n })\n const createdAt = existing ? new Date(existing.created_at) : dateOrNow(input.createdAt)\n const updatedAt = input.updatedAt\n ? new Date(input.updatedAt)\n : existing\n ? new Date()\n : createdAt\n\n await requireUserById(this.sql, { projectId, id: userId })\n\n const [row] = await this.sql<PgAuthUserIdentityRow[]>`\n INSERT INTO auth_user_identities (\n project_id,\n strategy_id,\n subject,\n user_id,\n claims,\n created_at,\n updated_at\n ) VALUES (\n ${projectId},\n ${strategyId},\n ${subject},\n ${userId},\n ${serializeOptionalRecord(input.claims)}::text::jsonb,\n ${createdAt},\n ${updatedAt}\n )\n ON CONFLICT (project_id, strategy_id, subject)\n DO UPDATE SET\n user_id = excluded.user_id,\n claims = excluded.claims,\n updated_at = excluded.updated_at\n RETURNING *\n `\n\n return rowToIdentityRecord(row)\n }\n\n async getBySubject(params: {\n readonly projectId: string\n readonly strategyId: string\n readonly subject: string\n }): Promise<UserIdentityRecord | null> {\n const row = await getIdentityRowBySubject(this.sql, params)\n return row ? rowToIdentityRecord(row) : null\n }\n\n async listForUser(params: {\n readonly projectId: string\n readonly userId: string\n }): Promise<readonly UserIdentityRecord[]> {\n const rows = await this.sql<PgAuthUserIdentityRow[]>`\n SELECT *\n FROM auth_user_identities\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n ORDER BY created_at ASC, strategy_id ASC, subject ASC\n `\n\n return rows.map(rowToIdentityRecord)\n }\n}\n",
20
+ "import type {\n AuthInvitationStore,\n CreateOrUpdateAuthInvitationInput,\n InvitationRecord,\n ListAuthInvitationsInput,\n ListAuthInvitationsResult,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport {\n authLockKey,\n lockAdvisoryKeys,\n type PgStoreClient,\n runPgTransaction,\n} from \"../transactions\"\nimport type { PgAuthInvitationRow } from \"./rows\"\nimport { rowToInvitationRecord } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n dateOrNow,\n getActiveInvitationByEmail,\n getInvitationById,\n getInvitationGroupIds,\n hasEmptyFilter,\n invitationCreatorColumns,\n mapUniqueConstraintError,\n normalizeEmail,\n normalizeGroupIds,\n type PgValue,\n placeholders,\n replaceInvitationGroups,\n requireInvitationById,\n requireSessionById,\n requireUserById,\n} from \"./shared\"\n\nexport class PgAuthInvitationStore implements AuthInvitationStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async createOrUpdateActive(input: CreateOrUpdateAuthInvitationInput): Promise<InvitationRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const id = assertNonEmpty(input.id, \"Invitation id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const email = normalizeEmail(input.email)\n const groupIds = normalizeGroupIds(input.groupIds)\n const now = dateOrNow(input.updatedAt ?? input.createdAt)\n const creator = invitationCreatorColumns(input.createdByPrincipal)\n\n await lockAdvisoryKeys(tx, [authLockKey(\"invitations\", projectId, email)])\n await this.validateCreator(tx, projectId, input)\n\n const existingActive = await getActiveInvitationByEmail(\n tx,\n {\n projectId,\n email,\n now,\n },\n { forUpdate: true }\n )\n\n if (existingActive) {\n await tx`\n UPDATE auth_invitations\n SET created_by_user_id = ${creator.createdByUserId},\n created_by_service_account_id = ${creator.createdByServiceAccountId},\n created_by_system_id = ${creator.createdBySystemId},\n created_by_session_id = ${input.createdBySessionId ?? null},\n expires_at = ${input.expiresAt},\n updated_at = ${now}\n WHERE project_id = ${projectId}\n AND id = ${existingActive.id}\n `\n await replaceInvitationGroups(tx, {\n projectId,\n invitationId: existingActive.id,\n groupIds,\n })\n\n return requireInvitationById(tx, { projectId, id: existingActive.id })\n }\n\n if (await getInvitationById(tx, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_invitation\",\n `[Sixb] Invitation '${id}' already exists but is not active for project '${projectId}'.`\n )\n }\n\n const createdAt = dateOrNow(input.createdAt)\n try {\n await tx`\n INSERT INTO auth_invitations (\n project_id,\n id,\n email,\n status,\n created_by_user_id,\n created_by_service_account_id,\n created_by_system_id,\n created_by_session_id,\n created_at,\n updated_at,\n expires_at\n ) VALUES (\n ${projectId},\n ${id},\n ${email},\n ${\"pending\"},\n ${creator.createdByUserId},\n ${creator.createdByServiceAccountId},\n ${creator.createdBySystemId},\n ${input.createdBySessionId ?? null},\n ${createdAt},\n ${now},\n ${input.expiresAt}\n )\n `\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_invitation\",\n `[Sixb] Invitation '${id}' already exists for project '${projectId}'.`\n )\n }\n\n await replaceInvitationGroups(tx, { projectId, invitationId: id, groupIds })\n return requireInvitationById(tx, { projectId, id })\n })\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<InvitationRecord | null> {\n return getInvitationById(this.sql, params)\n }\n\n async getActiveByEmail(params: {\n readonly projectId: string\n readonly email: string\n readonly now: Date\n }): Promise<InvitationRecord | null> {\n return getActiveInvitationByEmail(this.sql, params)\n }\n\n async list(input: ListAuthInvitationsInput): Promise<ListAuthInvitationsResult> {\n if (hasEmptyFilter(input.statuses) || hasEmptyFilter(input.groupIds)) {\n return { invitations: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: PgValue[] = [input.projectId]\n let nextIndex = 2\n\n if (input.email) {\n whereClauses.push(`email = $${nextIndex++}`)\n params.push(normalizeEmail(input.email))\n }\n\n if (input.statuses) {\n const statusPlaceholders = placeholders(nextIndex, input.statuses.length)\n nextIndex += input.statuses.length\n whereClauses.push(`status IN (${statusPlaceholders.join(\", \")})`)\n params.push(...input.statuses)\n }\n\n const groupIds = input.groupIds ? normalizeGroupIds(input.groupIds) : null\n if (groupIds) {\n const groupPlaceholders = placeholders(nextIndex, groupIds.length)\n nextIndex += groupIds.length\n whereClauses.push(`\n EXISTS (\n SELECT 1\n FROM auth_invitation_groups invitation_groups\n WHERE invitation_groups.project_id = auth_invitations.project_id\n AND invitation_groups.invitation_id = auth_invitations.id\n AND invitation_groups.group_id IN (${groupPlaceholders.join(\", \")})\n )\n `)\n params.push(...groupIds)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const [totalRow] = await this.sql.unsafe<{ readonly count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM auth_invitations ${where}`,\n [...params]\n )\n\n const queryParams = [...params]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_invitations\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryParams,\n nextIndex,\n input\n )\n const rows = await this.sql.unsafe<PgAuthInvitationRow[]>(query, queryParams)\n const invitations = await Promise.all(\n rows.map(async (row) =>\n rowToInvitationRecord(\n row,\n await getInvitationGroupIds(this.sql, {\n projectId: row.project_id,\n invitationId: row.id,\n })\n )\n )\n )\n const total = Number(totalRow?.count ?? 0)\n\n return {\n invitations,\n hasMore: (input.offset ?? 0) + rows.length < total,\n total,\n }\n }\n\n async accept(params: {\n readonly projectId: string\n readonly id: string\n readonly acceptedAt: Date\n }): Promise<InvitationRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await requireInvitationById(tx, params, { forUpdate: true })\n\n await tx`\n UPDATE auth_invitations\n SET status = 'accepted',\n accepted_at = ${params.acceptedAt},\n updated_at = ${params.acceptedAt}\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n `\n\n return requireInvitationById(tx, params)\n })\n }\n\n async revoke(params: {\n readonly projectId: string\n readonly id: string\n readonly revokedAt: Date\n }): Promise<InvitationRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await requireInvitationById(tx, params, { forUpdate: true })\n\n await tx`\n UPDATE auth_invitations\n SET status = 'revoked',\n revoked_at = ${params.revokedAt},\n updated_at = ${params.revokedAt}\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n `\n\n return requireInvitationById(tx, params)\n })\n }\n\n private async validateCreator(\n sql: SQLClient,\n projectId: string,\n input: CreateOrUpdateAuthInvitationInput\n ): Promise<void> {\n if (input.createdByPrincipal?.type === \"user\") {\n await requireUserById(sql, { projectId, id: input.createdByPrincipal.id })\n }\n\n if (input.createdBySessionId) {\n await requireSessionById(sql, { projectId, id: input.createdBySessionId })\n }\n }\n}\n",
21
+ "import { resolveAuthSessionAudience } from \"@sixb/core\"\nimport type {\n AuthMagicLinkStore,\n CreateAuthMagicLinkInput,\n MagicLinkRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport {\n authLockKey,\n lockAdvisoryKeys,\n type PgStoreClient,\n runPgTransaction,\n} from \"../transactions\"\nimport type { PgAuthMagicLinkRow } from \"./rows\"\nimport { rowToMagicLinkRecord } from \"./rows\"\nimport {\n assertNonEmpty,\n consumeMagicLink,\n getMagicLinkById,\n getMagicLinkRowById,\n mapUniqueConstraintError,\n normalizeEmail,\n revokeActiveMagicLinksForEmail,\n} from \"./shared\"\n\nexport class PgAuthMagicLinkStore implements AuthMagicLinkStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateAuthMagicLinkInput): Promise<MagicLinkRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const id = assertNonEmpty(input.id, \"Magic link id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const audience = resolveAuthSessionAudience(input.audience)\n const email = normalizeEmail(input.email)\n const tokenHash = assertNonEmpty(input.tokenHash, \"Magic link token hash\")\n\n await lockAdvisoryKeys(tx, [authLockKey(\"magic-links\", projectId, email)])\n\n if (await getMagicLinkRowById(tx, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_magic_link\",\n `[Sixb] Magic link '${id}' already exists for project '${projectId}'.`\n )\n }\n\n await revokeActiveMagicLinksForEmail(tx, {\n projectId,\n email,\n revokedAt: input.createdAt,\n })\n\n try {\n const [row] = await tx<PgAuthMagicLinkRow[]>`\n INSERT INTO auth_magic_links (\n project_id,\n id,\n strategy_id,\n audience,\n email,\n token_hash,\n return_to,\n created_at,\n expires_at\n ) VALUES (\n ${projectId},\n ${id},\n ${strategyId},\n ${audience},\n ${email},\n ${tokenHash},\n ${input.returnTo ?? null},\n ${input.createdAt},\n ${input.expiresAt}\n )\n RETURNING *\n `\n\n return rowToMagicLinkRecord(row)\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_magic_link\",\n `[Sixb] Magic link '${id}' already exists for project '${projectId}'.`\n )\n }\n })\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<MagicLinkRecord | null> {\n return getMagicLinkById(this.sql, params)\n }\n\n async getActiveByEmail(params: {\n readonly projectId: string\n readonly email: string\n readonly now: Date\n }): Promise<MagicLinkRecord | null> {\n const [row] = await this.sql<PgAuthMagicLinkRow[]>`\n SELECT *\n FROM auth_magic_links\n WHERE project_id = ${params.projectId}\n AND email = ${normalizeEmail(params.email)}\n AND consumed_at IS NULL\n AND revoked_at IS NULL\n AND expires_at > ${params.now}\n ORDER BY created_at DESC, id DESC\n LIMIT 1\n `\n\n return row ? rowToMagicLinkRecord(row) : null\n }\n\n async consume(params: {\n readonly projectId: string\n readonly id: string\n readonly tokenHash: string\n readonly consumedAt: Date\n }): Promise<MagicLinkRecord> {\n return runPgTransaction(this.sql, (tx) => consumeMagicLink(tx, params))\n }\n\n async revokeActiveForEmail(params: {\n readonly projectId: string\n readonly email: string\n readonly revokedAt: Date\n }): Promise<readonly MagicLinkRecord[]> {\n return runPgTransaction(this.sql, async (tx) => {\n const email = normalizeEmail(params.email)\n await lockAdvisoryKeys(tx, [authLockKey(\"magic-links\", params.projectId, email)])\n return revokeActiveMagicLinksForEmail(tx, {\n ...params,\n email,\n })\n })\n }\n}\n",
22
+ "import { resolveAuthSessionAudience } from \"@sixb/core\"\nimport type {\n AuthOidcAuthorizationAttemptStore,\n CreateOidcAuthorizationAttemptInput,\n OidcAuthorizationAttemptRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport { type PgStoreClient, runPgTransaction } from \"../transactions\"\nimport type { PgAuthOidcAttemptRow } from \"./rows\"\nimport { rowToOidcAuthorizationAttemptRecord } from \"./rows\"\nimport {\n assertNonEmpty,\n consumeOidcAttempt,\n getOidcAttemptById,\n getOidcAttemptRowById,\n mapUniqueConstraintError,\n} from \"./shared\"\n\nexport class PgAuthOidcAuthorizationAttemptStore implements AuthOidcAuthorizationAttemptStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(\n input: CreateOidcAuthorizationAttemptInput\n ): Promise<OidcAuthorizationAttemptRecord> {\n const id = assertNonEmpty(input.id, \"OIDC authorization attempt id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const audience = resolveAuthSessionAudience(input.audience)\n const stateHash = assertNonEmpty(input.stateHash, \"OIDC state hash\")\n const nonceHash = assertNonEmpty(input.nonceHash, \"OIDC nonce hash\")\n const codeVerifier = assertNonEmpty(input.codeVerifier, \"OIDC code verifier\")\n\n if (await getOidcAttemptRowById(this.sql, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' already exists for project '${projectId}'.`\n )\n }\n\n try {\n const [row] = await this.sql<PgAuthOidcAttemptRow[]>`\n INSERT INTO auth_oidc_authorization_attempts (\n project_id,\n id,\n strategy_id,\n audience,\n state_hash,\n nonce_hash,\n code_verifier,\n return_to,\n created_at,\n expires_at\n ) VALUES (\n ${projectId},\n ${id},\n ${strategyId},\n ${audience},\n ${stateHash},\n ${nonceHash},\n ${codeVerifier},\n ${input.returnTo ?? null},\n ${input.createdAt},\n ${input.expiresAt}\n )\n RETURNING *\n `\n\n return rowToOidcAuthorizationAttemptRecord(row)\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' already exists for project '${projectId}'.`\n )\n }\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<OidcAuthorizationAttemptRecord | null> {\n return getOidcAttemptById(this.sql, params)\n }\n\n async consume(params: {\n readonly projectId: string\n readonly id: string\n readonly stateHash: string\n readonly consumedAt: Date\n }): Promise<OidcAuthorizationAttemptRecord> {\n return runPgTransaction(this.sql, (tx) => consumeOidcAttempt(tx, params))\n }\n}\n",
23
+ "import type {\n AuthServiceAccountGroupMembershipStore,\n ReconcileAuthServiceAccountGroupMembershipsInput,\n ServiceAccountGroupMembershipRecord,\n UpsertAuthServiceAccountGroupMembershipInput,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { PgStoreClient } from \"../transactions\"\nimport type { PgAuthServiceAccountGroupMembershipRow, PgAuthServiceAccountRow } from \"./rows\"\nimport { rowToServiceAccountGroupMembershipRecord } from \"./rows\"\nimport { assertNonEmpty, dateOrNow } from \"./shared\"\n\nexport class PgAuthServiceAccountGroupMembershipStore\n implements AuthServiceAccountGroupMembershipStore\n{\n constructor(private readonly sql: PgStoreClient) {}\n\n async upsert(\n input: UpsertAuthServiceAccountGroupMembershipInput\n ): Promise<ServiceAccountGroupMembershipRecord> {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const serviceAccountId = assertNonEmpty(input.serviceAccountId, \"Service account id\")\n const groupId = assertNonEmpty(input.groupId, \"Group id\")\n const [serviceAccount] = await this.sql<PgAuthServiceAccountRow[]>`\n SELECT *\n FROM auth_service_accounts\n WHERE project_id = ${projectId}\n AND id = ${serviceAccountId}\n `\n if (!serviceAccount) {\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${serviceAccountId}' not found for project '${projectId}'.`\n )\n }\n\n const [row] = await this.sql<PgAuthServiceAccountGroupMembershipRow[]>`\n INSERT INTO auth_service_account_group_memberships (\n project_id,\n service_account_id,\n group_id,\n source,\n created_at\n ) VALUES (\n ${projectId},\n ${serviceAccountId},\n ${groupId},\n ${input.source},\n ${dateOrNow(input.createdAt)}\n )\n ON CONFLICT (project_id, service_account_id, group_id) DO UPDATE\n SET source = auth_service_account_group_memberships.source\n RETURNING *\n `\n\n return rowToServiceAccountGroupMembershipRecord(row)\n }\n\n async reconcileForServiceAccount(\n input: ReconcileAuthServiceAccountGroupMembershipsInput\n ): Promise<readonly ServiceAccountGroupMembershipRecord[]> {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const serviceAccountId = assertNonEmpty(input.serviceAccountId, \"Service account id\")\n const groupIds = [\n ...new Set(input.groupIds.map((groupId) => assertNonEmpty(groupId, \"Group id\"))),\n ]\n const [serviceAccount] = await this.sql<PgAuthServiceAccountRow[]>`\n SELECT *\n FROM auth_service_accounts\n WHERE project_id = ${projectId}\n AND id = ${serviceAccountId}\n `\n if (!serviceAccount) {\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${serviceAccountId}' not found for project '${projectId}'.`\n )\n }\n\n if (groupIds.length === 0) {\n await this.sql`\n DELETE FROM auth_service_account_group_memberships\n WHERE project_id = ${projectId}\n AND service_account_id = ${serviceAccountId}\n AND source = ${input.source}\n `\n } else {\n await this.sql`\n DELETE FROM auth_service_account_group_memberships\n WHERE project_id = ${projectId}\n AND service_account_id = ${serviceAccountId}\n AND source = ${input.source}\n AND group_id NOT IN ${this.sql(groupIds)}\n `\n }\n\n const updatedAt = dateOrNow(input.updatedAt)\n for (const groupId of groupIds) {\n await this.sql<PgAuthServiceAccountGroupMembershipRow[]>`\n INSERT INTO auth_service_account_group_memberships (\n project_id,\n service_account_id,\n group_id,\n source,\n created_at\n ) VALUES (\n ${projectId},\n ${serviceAccountId},\n ${groupId},\n ${input.source},\n ${updatedAt}\n )\n ON CONFLICT (project_id, service_account_id, group_id) DO UPDATE\n SET source = EXCLUDED.source\n `\n }\n\n return this.listForServiceAccount({ projectId, serviceAccountId })\n }\n\n async listForServiceAccount(params: {\n readonly projectId: string\n readonly serviceAccountId: string\n }): Promise<readonly ServiceAccountGroupMembershipRecord[]> {\n const rows = await this.sql<PgAuthServiceAccountGroupMembershipRow[]>`\n SELECT *\n FROM auth_service_account_group_memberships\n WHERE project_id = ${params.projectId}\n AND service_account_id = ${params.serviceAccountId}\n ORDER BY group_id ASC\n `\n\n return rows.map(rowToServiceAccountGroupMembershipRecord)\n }\n\n async listForGroup(params: {\n readonly projectId: string\n readonly groupId: string\n }): Promise<readonly ServiceAccountGroupMembershipRecord[]> {\n const rows = await this.sql<PgAuthServiceAccountGroupMembershipRow[]>`\n SELECT *\n FROM auth_service_account_group_memberships\n WHERE project_id = ${params.projectId}\n AND group_id = ${params.groupId}\n ORDER BY service_account_id ASC\n `\n\n return rows.map(rowToServiceAccountGroupMembershipRecord)\n }\n}\n",
24
+ "import type {\n AuthServiceAccountStore,\n CreateAuthServiceAccountInput,\n ListAuthServiceAccountsInput,\n ListAuthServiceAccountsResult,\n ServiceAccountRecord,\n UpdateAuthServiceAccountInput,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { PgStoreClient } from \"../transactions\"\nimport type { PgAuthServiceAccountRow } from \"./rows\"\nimport { rowToServiceAccountRecord } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n dateOrNow,\n hasEmptyFilter,\n mapUniqueConstraintError,\n type PgValue,\n} from \"./shared\"\n\nexport class PgAuthServiceAccountStore implements AuthServiceAccountStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateAuthServiceAccountInput): Promise<ServiceAccountRecord> {\n const id = assertNonEmpty(input.id, \"Service account id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const name = assertNonEmpty(input.name, \"Service account name\")\n const createdAt = dateOrNow(input.createdAt)\n const updatedAt = input.updatedAt ? new Date(input.updatedAt) : createdAt\n\n try {\n const [row] = await this.sql<PgAuthServiceAccountRow[]>`\n INSERT INTO auth_service_accounts (\n project_id,\n id,\n name,\n description,\n status,\n created_by_user_id,\n created_by_service_account_id,\n created_by_system_id,\n created_by_session_id,\n created_at,\n updated_at\n ) VALUES (\n ${projectId},\n ${id},\n ${name},\n ${input.description ?? null},\n ${input.status ?? \"active\"},\n ${input.createdByPrincipal?.type === \"user\" ? input.createdByPrincipal.id : null},\n ${\n input.createdByPrincipal?.type === \"serviceAccount\" ? input.createdByPrincipal.id : null\n },\n ${input.createdByPrincipal?.type === \"system\" ? input.createdByPrincipal.id : null},\n ${input.createdBySessionId ?? null},\n ${createdAt},\n ${updatedAt}\n )\n RETURNING *\n `\n\n return rowToServiceAccountRecord(row)\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_service_account\",\n `[Sixb] Service account '${id}' already exists for project '${projectId}'.`\n )\n }\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<ServiceAccountRecord | null> {\n const [row] = await this.sql<PgAuthServiceAccountRow[]>`\n SELECT *\n FROM auth_service_accounts\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n `\n return row ? rowToServiceAccountRecord(row) : null\n }\n\n async update(input: UpdateAuthServiceAccountInput): Promise<ServiceAccountRecord> {\n const existing = await this.getById(input)\n if (!existing) {\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n const updatedAt = dateOrNow(input.updatedAt)\n const name =\n input.name === undefined ? existing.name : assertNonEmpty(input.name, \"Service account name\")\n const description = input.description === undefined ? existing.description : input.description\n const [row] = await this.sql<PgAuthServiceAccountRow[]>`\n UPDATE auth_service_accounts\n SET name = ${name},\n description = ${description ?? null},\n status = ${input.status ?? existing.status},\n updated_at = ${updatedAt}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n RETURNING *\n `\n\n return rowToServiceAccountRecord(row)\n }\n\n async list(input: ListAuthServiceAccountsInput): Promise<ListAuthServiceAccountsResult> {\n if (hasEmptyFilter(input.statuses)) {\n return { serviceAccounts: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: PgValue[] = [input.projectId]\n let nextIndex = 2\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => `$${nextIndex++}`).join(\", \")})`)\n params.push(...input.statuses)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const [totalRow] = await this.sql.unsafe<{ readonly count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM auth_service_accounts ${where}`,\n [...params]\n )\n const queryParams = [...params]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_service_accounts\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryParams,\n nextIndex,\n input\n )\n const rows = await this.sql.unsafe<PgAuthServiceAccountRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n\n return {\n serviceAccounts: rows.map(rowToServiceAccountRecord),\n hasMore: input.limit === undefined ? false : (input.offset ?? 0) + input.limit < total,\n total,\n }\n }\n}\n",
25
+ "import type { AuthSessionAudience } from \"@sixb/core\"\nimport type { AuthSessionStore, CreateAuthSessionInput, SessionRecord } from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport {\n authLockKey,\n lockAdvisoryKeys,\n type PgStoreClient,\n runPgTransaction,\n} from \"../transactions\"\nimport type { PgAuthSessionRow } from \"./rows\"\nimport { rowToSessionRecord } from \"./rows\"\nimport {\n createSession,\n getSessionById,\n getSessionRowById,\n requireSessionById,\n revokeActiveSessionsForUser,\n} from \"./shared\"\n\nexport class PgAuthSessionStore implements AuthSessionStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateAuthSessionInput): Promise<SessionRecord> {\n // Session ids are random UUIDs and the table has a primary-key guard, so\n // concurrent inserts cannot collide; no advisory lock is needed here.\n return runPgTransaction(this.sql, (tx) => createSession(tx, input))\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<SessionRecord | null> {\n return getSessionById(this.sql, params)\n }\n\n async getActiveByUserId(params: {\n readonly projectId: string\n readonly userId: string\n readonly audience: AuthSessionAudience\n readonly now: Date\n }): Promise<SessionRecord | null> {\n const [row] = await this.sql<PgAuthSessionRow[]>`\n SELECT *\n FROM auth_sessions\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n AND audience = ${params.audience}\n AND revoked_at IS NULL\n AND expires_at > ${params.now}\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.now})\n ORDER BY created_at DESC, id DESC\n LIMIT 1\n `\n\n return row ? rowToSessionRecord(row) : null\n }\n\n async listActiveByUserId(params: {\n readonly projectId: string\n readonly userId: string\n readonly now: Date\n }): Promise<readonly SessionRecord[]> {\n const rows = (await this.sql`\n SELECT *\n FROM auth_sessions\n WHERE project_id = ${params.projectId}\n AND user_id = ${params.userId}\n AND revoked_at IS NULL\n AND expires_at > ${params.now}\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.now})\n ORDER BY COALESCE(last_seen_at, created_at) DESC, created_at DESC, id DESC\n `) as PgAuthSessionRow[]\n\n return rows.map(rowToSessionRecord)\n }\n\n async findValidByTokenHash(params: {\n readonly projectId: string\n readonly id: string\n readonly audience: AuthSessionAudience\n readonly tokenHash: string\n readonly now: Date\n }): Promise<SessionRecord | null> {\n const row = await getSessionRowById(this.sql, params)\n\n if (\n !row ||\n row.audience !== params.audience ||\n row.token_hash !== params.tokenHash ||\n row.revoked_at ||\n new Date(row.expires_at) <= params.now ||\n (row.absolute_expires_at !== null && new Date(row.absolute_expires_at) <= params.now)\n ) {\n return null\n }\n\n return rowToSessionRecord(row)\n }\n\n async renewIfValid(params: {\n readonly projectId: string\n readonly id: string\n readonly audience: AuthSessionAudience\n readonly tokenHash: string\n readonly now: Date\n readonly expiresAt: Date\n }): Promise<SessionRecord | null> {\n const [row] = await this.sql<PgAuthSessionRow[]>`\n UPDATE auth_sessions\n SET expires_at = GREATEST(\n expires_at,\n LEAST(\n ${params.expiresAt},\n COALESCE(absolute_expires_at, ${params.expiresAt})\n )\n ),\n last_seen_at = ${params.now}\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n AND audience = ${params.audience}\n AND token_hash = ${params.tokenHash}\n AND revoked_at IS NULL\n AND expires_at > ${params.now}\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ${params.now})\n RETURNING *\n `\n\n return row ? rowToSessionRecord(row) : null\n }\n\n async revoke(params: {\n readonly projectId: string\n readonly id: string\n readonly revokedAt: Date\n }): Promise<SessionRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existing = await getSessionRowById(tx, params, { forUpdate: true })\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_session\",\n `[Sixb] Session '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n\n const [row] = await tx<PgAuthSessionRow[]>`\n UPDATE auth_sessions\n SET revoked_at = ${params.revokedAt}\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n RETURNING *\n `\n\n return rowToSessionRecord(row)\n })\n }\n\n async revokeActiveForUser(params: {\n readonly projectId: string\n readonly userId: string\n readonly audience?: AuthSessionAudience\n readonly revokedAt: Date\n }): Promise<readonly SessionRecord[]> {\n return runPgTransaction(this.sql, async (tx) => {\n const locks = [authLockKey(\"sessions\", params.projectId, params.userId)]\n if (params.audience) {\n locks.push(authLockKey(\"sessions\", params.projectId, params.userId, params.audience))\n }\n await lockAdvisoryKeys(tx, locks)\n return revokeActiveSessionsForUser(tx, params)\n })\n }\n\n async touch(params: {\n readonly projectId: string\n readonly id: string\n readonly lastSeenAt: Date\n }): Promise<SessionRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await requireSessionById(tx, params)\n\n const [row] = await tx<PgAuthSessionRow[]>`\n UPDATE auth_sessions\n SET last_seen_at = ${params.lastSeenAt}\n WHERE project_id = ${params.projectId}\n AND id = ${params.id}\n RETURNING *\n `\n\n return rowToSessionRecord(row)\n })\n }\n}\n",
26
+ "import type {\n AuthUserStore,\n CreateAuthUserInput,\n ListAuthUsersInput,\n ListAuthUsersResult,\n UpdateAuthUserProfileInput,\n UpdateAuthUserStatusInput,\n UserRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { PgStoreClient } from \"../transactions\"\nimport type { PgAuthUserRow } from \"./rows\"\nimport { rowToUserRecord } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n dateOrNow,\n getUserRowByEmail,\n getUserRowById,\n hasEmptyFilter,\n mapUniqueConstraintError,\n normalizeEmail,\n type PgValue,\n} from \"./shared\"\n\nexport class PgAuthUserStore implements AuthUserStore {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateAuthUserInput): Promise<UserRecord> {\n const id = assertNonEmpty(input.id, \"User id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const email = normalizeEmail(input.email)\n\n if (await getUserRowById(this.sql, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User '${id}' already exists for project '${projectId}'.`\n )\n }\n\n if (await getUserRowByEmail(this.sql, { projectId, email })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User email '${email}' already exists for project '${projectId}'.`\n )\n }\n\n const createdAt = dateOrNow(input.createdAt)\n const updatedAt = input.updatedAt ? new Date(input.updatedAt) : createdAt\n\n try {\n const [row] = await this.sql<PgAuthUserRow[]>`\n INSERT INTO auth_users (\n project_id,\n id,\n email,\n display_name,\n avatar_url,\n status,\n created_at,\n updated_at\n ) VALUES (\n ${projectId},\n ${id},\n ${email},\n ${input.displayName ?? null},\n ${input.avatarUrl ?? null},\n ${input.status ?? \"active\"},\n ${createdAt},\n ${updatedAt}\n )\n RETURNING *\n `\n\n return rowToUserRecord(row)\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_user\",\n `[Sixb] User '${id}' already exists for project '${projectId}'.`\n )\n }\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<UserRecord | null> {\n const row = await getUserRowById(this.sql, params)\n return row ? rowToUserRecord(row) : null\n }\n\n async getByEmail(params: {\n readonly projectId: string\n readonly email: string\n }): Promise<UserRecord | null> {\n const row = await getUserRowByEmail(this.sql, params)\n return row ? rowToUserRecord(row) : null\n }\n\n async updateProfile(input: UpdateAuthUserProfileInput): Promise<UserRecord> {\n const existing = await getUserRowById(this.sql, {\n projectId: input.projectId,\n id: input.id,\n })\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n const updatedAt = dateOrNow(input.updatedAt)\n const [row] = await this.sql<PgAuthUserRow[]>`\n UPDATE auth_users\n SET display_name = ${input.displayName ?? null},\n avatar_url = ${input.avatarUrl ?? null},\n updated_at = ${updatedAt}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n RETURNING *\n `\n\n return rowToUserRecord(row)\n }\n\n async updateStatus(input: UpdateAuthUserStatusInput): Promise<UserRecord> {\n const existing = await getUserRowById(this.sql, {\n projectId: input.projectId,\n id: input.id,\n })\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n const updatedAt = dateOrNow(input.updatedAt)\n const [row] = await this.sql<PgAuthUserRow[]>`\n UPDATE auth_users\n SET status = ${input.status},\n updated_at = ${updatedAt}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n RETURNING *\n `\n\n return rowToUserRecord(row)\n }\n\n async list(input: ListAuthUsersInput): Promise<ListAuthUsersResult> {\n if (hasEmptyFilter(input.statuses)) {\n return { users: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: PgValue[] = [input.projectId]\n let nextIndex = 2\n\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => `$${nextIndex++}`).join(\", \")})`)\n params.push(...input.statuses)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const [totalRow] = await this.sql.unsafe<{ readonly count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM auth_users ${where}`,\n [...params]\n )\n\n const queryParams = [...params]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_users\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryParams,\n nextIndex,\n input\n )\n const rows = await this.sql.unsafe<PgAuthUserRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n\n return {\n users: rows.map(rowToUserRecord),\n hasMore: (input.offset ?? 0) + rows.length < total,\n total,\n }\n }\n}\n",
27
+ "import { createHash } from \"node:crypto\"\nimport type { StorageMigrator } from \"@sixb/core\"\nimport type {\n MigrationHistoryStore,\n MigrationRecord,\n MigrationSet,\n MigrationStep,\n MigrationStepOptions,\n} from \"@sixb/core/storage\"\nimport {\n defineMigrations,\n describeMigrationHistory,\n runMigrationSet,\n step,\n} from \"@sixb/core/storage\"\nimport initialSchemaSql from \"./migrations/001-initial-schema.sql\" with { type: \"text\" }\nimport type { SQL, SQLClient } from \"./pg-client\"\n\nexport interface PostgresMigrationContext {\n exec(sqlText: string): Promise<void>\n}\n\nexport const POSTGRES_STORAGE_ADAPTER_ID = \"SixbPostgresStorage\"\n\nexport function pgSql(id: string, sqlText: string): MigrationStep<PostgresMigrationContext> {\n return pgStep(id, (context) => context.exec(sqlText), { checksum: checksum(sqlText) })\n}\n\nexport function pgStep(\n id: string,\n up: (context: PostgresMigrationContext) => void | Promise<void>,\n options: MigrationStepOptions = {}\n): MigrationStep<PostgresMigrationContext> {\n return step<PostgresMigrationContext>(id, up, options)\n}\n\nexport function createPostgresStorageMigrators(\n sql: SQL,\n schemaName: string\n): readonly StorageMigrator[] {\n return [\n createPostgresMigrator({\n sql,\n schemaName,\n migrations: postgresStorageMigrations,\n }),\n ]\n}\n\nexport function createPostgresMigrator(params: {\n readonly sql: SQL\n readonly schemaName: string\n readonly migrations: MigrationSet<PostgresMigrationContext>\n}): StorageMigrator {\n return {\n adapterId: params.migrations.adapterId,\n latestVersion: params.migrations.latestVersion,\n async status() {\n return describeMigrationHistory({\n migrations: params.migrations,\n rows: await readPostgresHistory(params.sql, params.schemaName, params.migrations.adapterId),\n })\n },\n migrate() {\n return withPostgresMigrationLock(params, async (sql) => {\n const session = postgresMigrationSession(sql, params.schemaName)\n return runMigrationSet({\n context: session.context,\n migrations: params.migrations,\n state: session.state,\n })\n })\n },\n }\n}\n\nexport async function migratePostgresStorage(sql: SQL, schemaName: string): Promise<void> {\n await createPostgresMigrator({\n sql,\n schemaName,\n migrations: postgresStorageMigrations,\n }).migrate()\n}\n\nexport async function dropSchema(sql: SQL, schemaName: string): Promise<void> {\n await sql.unsafe(`DROP SCHEMA IF EXISTS ${quoteIdent(schemaName)} CASCADE`)\n}\n\nexport function quoteIdent(identifier: string): string {\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier)) {\n throw new Error(`[SixbPg] Invalid identifier: ${identifier}`)\n }\n return `\"${identifier}\"`\n}\n\nfunction postgresMigrationSession(\n sql: SQL,\n schemaName: string\n): { context: PostgresMigrationContext; state: MigrationHistoryStore } {\n const schema = quoteIdent(schemaName)\n const migrationsTable = `${schema}.sixb_migrations`\n // Migration steps receive a stable context; route exec() through the active transaction.\n let active: SQLClient | null = null\n const connection = (): SQLClient => active ?? sql\n\n return {\n context: {\n async exec(sqlText) {\n await connection().unsafe(sqlText)\n },\n },\n state: {\n async ensure() {\n await sql.unsafe(`\n CREATE SCHEMA IF NOT EXISTS ${schema};\n\n CREATE TABLE IF NOT EXISTS ${migrationsTable} (\n adapter_id TEXT NOT NULL,\n version INTEGER NOT NULL,\n id TEXT NOT NULL,\n checksum TEXT,\n status TEXT NOT NULL CHECK (status IN ('started', 'applied')),\n started_at TIMESTAMPTZ NOT NULL,\n finished_at TIMESTAMPTZ,\n PRIMARY KEY (adapter_id, version)\n );\n `)\n },\n async readHistory(adapterId) {\n const rows = await sql.unsafe<PostgresMigrationRow[]>(\n `SELECT * FROM ${migrationsTable} WHERE adapter_id = $1 ORDER BY version`,\n [adapterId]\n )\n return rows.map(rowToMigrationRecord)\n },\n async markStarted(adapterId, migration, at) {\n await connection().unsafe(\n `\n INSERT INTO ${migrationsTable} (\n adapter_id, version, id, checksum, status, started_at, finished_at\n ) VALUES ($1, $2, $3, $4, 'started', $5, NULL)\n ON CONFLICT(adapter_id, version) DO UPDATE SET\n id = excluded.id,\n checksum = excluded.checksum,\n status = excluded.status,\n started_at = excluded.started_at,\n finished_at = NULL\n `,\n [adapterId, migration.version, migration.id, migration.checksum ?? null, at]\n )\n },\n async markApplied(adapterId, migration, at) {\n await connection().unsafe(\n `\n UPDATE ${migrationsTable}\n SET status = 'applied', finished_at = $1\n WHERE adapter_id = $2 AND version = $3\n `,\n [at, adapterId, migration.version]\n )\n },\n async transaction(run) {\n // `sql` is the reserved connection holding the migration advisory lock. porsager's\n // reserved connection has no `.begin`, so drive the transaction manually on it and\n // route exec()/markStarted()/markApplied() through the same connection via `active`.\n const previous = active\n active = sql\n await sql.unsafe(\"BEGIN\")\n try {\n await sql.unsafe(`SET LOCAL search_path TO ${schema}`)\n const result = await run()\n await sql.unsafe(\"COMMIT\")\n return result\n } catch (error) {\n await sql.unsafe(\"ROLLBACK\")\n throw error\n } finally {\n active = previous\n }\n },\n },\n }\n}\n\n/**\n * Reads migration history without DDL and without the advisory lock. `null` means the\n * history table does not exist, which is a state and not a failure.\n *\n * `migrate()` cannot be used for this: it calls `ensure()` first, so it runs\n * `CREATE SCHEMA`/`CREATE TABLE` and reserves a connection to hold\n * `pg_advisory_lock`. A probe must need no DDL grant — `/ready` is public and\n * unauthenticated — and must not serialize N replicas behind one lock.\n *\n * `to_regclass` returns NULL for a missing relation (including a missing schema)\n * instead of raising, and needs no catalog privileges.\n */\nasync function readPostgresHistory(\n sql: SQL,\n schemaName: string,\n adapterId: string\n): Promise<readonly MigrationRecord[] | null> {\n const schema = quoteIdent(schemaName)\n const probe = await sql.unsafe<{ oid: string | null }[]>(`SELECT to_regclass($1) AS oid`, [\n `${schema}.sixb_migrations`,\n ])\n if (!probe[0]?.oid) {\n return null\n }\n\n const rows = await sql.unsafe<PostgresMigrationRow[]>(\n `SELECT * FROM ${schema}.sixb_migrations WHERE adapter_id = $1 ORDER BY version`,\n [adapterId]\n )\n return rows.map(rowToMigrationRecord)\n}\n\nasync function withPostgresMigrationLock<T>(\n params: {\n readonly sql: SQL\n readonly schemaName: string\n readonly migrations: MigrationSet<PostgresMigrationContext>\n },\n run: (sql: SQL) => Promise<T>\n): Promise<T> {\n const sql = await params.sql.reserve()\n const [first, second] = advisoryLockParts(\n `storage:migration:${params.schemaName}:${params.migrations.adapterId}`\n )\n\n try {\n await sql`SELECT pg_advisory_lock(${first}, ${second})`\n try {\n return await run(sql)\n } finally {\n await sql`SELECT pg_advisory_unlock(${first}, ${second})`\n }\n } finally {\n sql.release()\n }\n}\n\nfunction advisoryLockParts(key: string): readonly [number, number] {\n const hash = createHash(\"sha256\").update(key).digest()\n return [hash.readInt32BE(0), hash.readInt32BE(4)]\n}\n\nfunction rowToMigrationRecord(row: PostgresMigrationRow): MigrationRecord {\n return {\n adapterId: row.adapter_id,\n version: row.version,\n id: row.id,\n checksum: row.checksum ?? undefined,\n status: row.status,\n startedAt: toIsoString(row.started_at),\n finishedAt: row.finished_at ? toIsoString(row.finished_at) : undefined,\n }\n}\n\nfunction toIsoString(value: Date | string): string {\n return value instanceof Date ? value.toISOString() : new Date(value).toISOString()\n}\n\nfunction checksum(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\")\n}\n\nexport const postgresStorageMigrations = defineMigrations<PostgresMigrationContext>({\n adapterId: POSTGRES_STORAGE_ADAPTER_ID,\n steps: [pgSql(\"001-initial-schema\", initialSchemaSql)],\n})\n\ninterface PostgresMigrationRow {\n readonly adapter_id: string\n readonly version: number\n readonly id: string\n readonly checksum: string | null\n readonly status: MigrationRecord[\"status\"]\n readonly started_at: Date | string\n readonly finished_at: Date | string | null\n}\n",
28
+ "import type { ProjectionEntityRef } from \"@sixb/core/internal/materialization\"\nimport { MaterializationConflictError } from \"@sixb/core/internal/materialization\"\nimport type {\n AssertSourceMaterializationExecutionInput,\n OntologyCommitRecord,\n OntologyCommitWrite,\n OntologyOutboxRecord,\n OntologySourceRecord,\n StageSourceAssertion,\n} from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\n\nexport {\n assertNonblank,\n assertNonnegativeInteger,\n assertPositiveInteger,\n assertTimestamp,\n canonicalJson,\n linkRefFromColumns,\n objectRefFromColumns,\n originColumns,\n originWhere,\n sourceEntityKey,\n} from \"@sixb/core/internal/ontology-storage-provider\"\n\nexport type PgRootOperation = <T>(run: (sql: SQLClient) => Promise<T>) => Promise<T>\n\ntype PgJsonValue = Parameters<SQLClient[\"json\"]>[0]\n\nexport interface PgOntologyCommitRow {\n readonly project_id: string\n readonly id: string\n readonly idempotency_key: string\n readonly request_hash: string\n readonly origin_kind: string\n readonly origin_run_id: string | null\n readonly origin_batch_ordinal: number | string | null\n readonly origin: unknown\n readonly actor: unknown | null\n readonly ontology_revision: string\n readonly projection_revision: string | null\n readonly ownership_hash: string | null\n readonly intent: unknown\n readonly result: unknown\n readonly committed_at: Date | string\n}\n\nexport interface PgOntologySourceRow {\n readonly project_id: string\n readonly source_id: string\n readonly materialization_id: string\n readonly projection_run_id: string\n readonly projection_kind: \"object\" | \"link\"\n readonly protocol: \"replacement\"\n readonly status: OntologySourceRecord[\"status\"]\n readonly execution_token: string | null\n readonly dataset_id: string\n readonly dataset_version_id: string\n readonly dataset_version_created_at: Date | string\n readonly projection_revision: string\n readonly ownership_hash: string\n readonly ontology_revision: string\n readonly root_count: number | string | null\n readonly assertion_count: number | string | null\n readonly created_at: Date | string\n readonly ready_at: Date | string | null\n readonly activated_at: Date | string | null\n readonly terminal_at: Date | string | null\n readonly last_commit_id: string | null\n readonly updated_at: Date | string\n}\n\nexport interface PgOntologySourceAssertionRow {\n readonly project_id: string\n readonly source_id: string\n readonly materialization_id: string\n readonly entity_kind: \"object\" | \"link\"\n readonly entity_key: unknown\n readonly entity_sort_key: string\n readonly root_kind: \"object\" | \"link\"\n readonly root_key: unknown\n readonly root_sort_key: string\n readonly staging_ordinal: number | string\n readonly root: unknown\n readonly assertion: unknown\n}\n\nexport interface PgOntologyOverrideRow {\n readonly entity_kind: \"object\" | \"link\"\n readonly value: unknown\n readonly last_commit_id: string\n readonly updated_at: Date | string\n}\n\nexport interface PgOntologyOutboxRow {\n readonly envelope: unknown\n readonly available_at: Date | string\n readonly attempts: number | string\n readonly lease_id: string | null\n readonly lease_expires_at: Date | string | null\n readonly published_at: Date | string | null\n readonly last_error: string | null\n readonly created_at: Date | string\n}\n\nexport function jsonParameter(sql: SQLClient, value: unknown): ReturnType<SQLClient[\"json\"]> {\n return sql.json(value as PgJsonValue)\n}\n\nexport function jsonKeyParameter(\n sql: SQLClient,\n canonicalKey: string\n): ReturnType<SQLClient[\"json\"]> {\n return jsonParameter(sql, JSON.parse(canonicalKey))\n}\n\nexport function toIsoString(value: Date | string): string {\n return value instanceof Date ? value.toISOString() : new Date(value).toISOString()\n}\n\nexport function optionalIsoString(value: Date | string | null): string | null {\n return value === null ? null : toIsoString(value)\n}\n\nexport function databaseSafeInteger(value: number | string, label: string): number {\n const result = Number(value)\n if (!Number.isSafeInteger(result) || result < 0) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `${label} is outside the nonnegative safe-integer range.`\n )\n }\n return result\n}\n\nexport function sourceRecord(row: PgOntologySourceRow): OntologySourceRecord {\n return {\n projectId: row.project_id,\n source: { projectionId: row.source_id },\n materializationId: row.materialization_id,\n projectionRunId: row.projection_run_id,\n projectionKind: row.projection_kind,\n protocol: row.protocol,\n status: row.status,\n executionToken: row.execution_token,\n datasetVersion: {\n datasetId: row.dataset_id,\n versionId: row.dataset_version_id,\n createdAt: toIsoString(row.dataset_version_created_at),\n },\n projectionRevision: row.projection_revision,\n ownershipHash: row.ownership_hash,\n ontologyRevision: row.ontology_revision,\n rootCount:\n row.root_count === null ? null : databaseSafeInteger(row.root_count, \"Source root count\"),\n assertionCount:\n row.assertion_count === null\n ? null\n : databaseSafeInteger(row.assertion_count, \"Source assertion count\"),\n createdAt: toIsoString(row.created_at),\n readyAt: optionalIsoString(row.ready_at),\n activatedAt: optionalIsoString(row.activated_at),\n terminalAt: optionalIsoString(row.terminal_at),\n lastCommitId: row.last_commit_id,\n updatedAt: toIsoString(row.updated_at),\n }\n}\n\nexport function sourceAssertion(row: PgOntologySourceAssertionRow): StageSourceAssertion {\n return {\n root: structuredClone(row.root) as ProjectionEntityRef,\n assertion: structuredClone(row.assertion) as StageSourceAssertion[\"assertion\"],\n stagingOrdinal: databaseSafeInteger(row.staging_ordinal, \"Source staging ordinal\"),\n }\n}\n\nexport function commitRecord(row: PgOntologyCommitRow): OntologyCommitRecord {\n const base = {\n projectId: row.project_id,\n id: row.id,\n idempotencyKey: row.idempotency_key,\n requestHash: row.request_hash,\n origin: structuredClone(row.origin) as OntologyCommitWrite[\"origin\"],\n ...(row.actor === null\n ? {}\n : {\n actor: structuredClone(row.actor) as NonNullable<OntologyCommitWrite[\"actor\"]>,\n }),\n ontologyRevision: row.ontology_revision,\n ...(row.projection_revision === null ? {} : { projectionRevision: row.projection_revision }),\n ...(row.ownership_hash === null ? {} : { ownershipHash: row.ownership_hash }),\n committedAt: toIsoString(row.committed_at),\n }\n const intent = structuredClone(row.intent) as OntologyCommitWrite[\"intent\"]\n const result = structuredClone(row.result) as OntologyCommitRecord[\"result\"]\n return { ...base, intent, result } as OntologyCommitRecord\n}\n\nexport function outboxRecord(row: PgOntologyOutboxRow): OntologyOutboxRecord {\n return {\n envelope: structuredClone(row.envelope) as OntologyOutboxRecord[\"envelope\"],\n availableAt: toIsoString(row.available_at),\n attempts: databaseSafeInteger(row.attempts, \"Ontology outbox attempts\"),\n leaseId: row.lease_id,\n leaseExpiresAt: optionalIsoString(row.lease_expires_at),\n publishedAt: optionalIsoString(row.published_at),\n lastError: row.last_error,\n createdAt: toIsoString(row.created_at),\n }\n}\n\nexport async function assertProjectionExecution(\n sql: SQLClient,\n input: {\n readonly projectId: string\n readonly sourceId: string\n readonly projectionRunId: string\n readonly executionToken: string\n readonly identity?: AssertSourceMaterializationExecutionInput[\"identity\"]\n }\n): Promise<void> {\n const [run] = await sql<\n {\n readonly projection_id: string\n readonly projection_kind: string\n readonly status: string\n readonly materialization_protocol: string | null\n readonly execution_token: string | null\n readonly dataset_id: string\n readonly dataset_version_id: string\n readonly dataset_version_created_at: Date | string | null\n readonly ontology_revision: string | null\n readonly projection_revision: string | null\n readonly ownership_hash: string | null\n }[]\n >`\n SELECT projection_id, projection_kind, status, materialization_protocol, execution_token,\n dataset_id, dataset_version_id, dataset_version_created_at,\n ontology_revision, projection_revision, ownership_hash\n FROM projection_runs\n WHERE project_id = ${input.projectId} AND id = ${input.projectionRunId}\n FOR UPDATE\n `\n if (!run || run.status !== \"running\") {\n throw new MaterializationConflictError(\n \"run-correlation\",\n `Projection run '${input.projectionRunId}' is missing or is not running.`\n )\n }\n if (run.projection_id !== input.sourceId || run.materialization_protocol !== \"replacement\") {\n throw new MaterializationConflictError(\n \"run-correlation\",\n `Projection run '${input.projectionRunId}' does not own replacement source '${input.sourceId}'.`\n )\n }\n if (run.execution_token !== input.executionToken) {\n throw new MaterializationConflictError(\n \"execution-lost\",\n `Projection run '${input.projectionRunId}' execution token is stale.`\n )\n }\n const identity = input.identity\n if (\n identity &&\n (run.projection_kind !== identity.projectionKind ||\n run.materialization_protocol !== identity.protocol ||\n run.dataset_id !== identity.datasetVersion.datasetId ||\n run.dataset_version_id !== identity.datasetVersion.versionId ||\n run.dataset_version_created_at === null ||\n toIsoString(run.dataset_version_created_at) !== identity.datasetVersion.createdAt ||\n run.ontology_revision !== identity.ontologyRevision ||\n run.projection_revision !== identity.projectionRevision ||\n run.ownership_hash !== identity.ownershipHash)\n ) {\n throw new MaterializationConflictError(\n \"run-correlation\",\n `Projection run '${input.projectionRunId}' immutable source identity does not match.`\n )\n }\n}\n\nexport function requireRow<T>(\n row: T | undefined,\n kind: ConstructorParameters<typeof MaterializationConflictError>[0],\n message: string\n): T {\n if (!row) throw new MaterializationConflictError(kind, message)\n return row\n}\n\nexport function ontologyLockKey(kind: string, ...parts: readonly string[]): string {\n return `ontology:${kind}:${JSON.stringify(parts)}`\n}\n",
29
+ "import type {\n GetOntologyCommitByIdempotencyKeyInput,\n GetOntologyCommitByIdInput,\n GetOntologyCommitByOriginInput,\n ListOntologyCommitsInput,\n ListOntologyCommitsResult,\n OntologyCommitRecord,\n OntologyCommitStorage,\n} from \"@sixb/core/storage\"\nimport {\n assertNonblank,\n assertNonnegativeInteger,\n commitRecord,\n originWhere,\n type PgOntologyCommitRow,\n type PgRootOperation,\n} from \"./shared\"\n\nexport class PgOntologyCommitStorage implements OntologyCommitStorage {\n constructor(private readonly runRootOperation: PgRootOperation) {}\n\n async getByIdempotencyKey(\n input: GetOntologyCommitByIdempotencyKeyInput\n ): Promise<OntologyCommitRecord | null> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n assertNonblank(input.idempotencyKey, \"Ontology commit idempotency key\")\n const [row] = await sql<PgOntologyCommitRow[]>`\n SELECT * FROM ontology_commits\n WHERE project_id = ${input.projectId} AND idempotency_key = ${input.idempotencyKey}\n `\n return row ? commitRecord(row) : null\n })\n }\n\n async getById(input: GetOntologyCommitByIdInput): Promise<OntologyCommitRecord | null> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n assertNonblank(input.id, \"Ontology commit id\")\n const [row] = await sql<PgOntologyCommitRow[]>`\n SELECT * FROM ontology_commits\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n `\n return row ? commitRecord(row) : null\n })\n }\n\n async getByOrigin(input: GetOntologyCommitByOriginInput): Promise<OntologyCommitRecord | null> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n const origin = originWhere(input.origin)\n assertNonblank(origin.runId, \"Ontology commit origin run id\")\n if (origin.batchOrdinal !== null) {\n assertNonnegativeInteger(origin.batchOrdinal, \"Ontology telemetry commit batch ordinal\")\n }\n const [row] =\n origin.batchOrdinal === null\n ? await sql<PgOntologyCommitRow[]>`\n SELECT * FROM ontology_commits\n WHERE project_id = ${input.projectId}\n AND origin_kind = ${origin.kind}\n AND origin_run_id = ${origin.runId}\n AND origin_batch_ordinal IS NULL\n `\n : await sql<PgOntologyCommitRow[]>`\n SELECT * FROM ontology_commits\n WHERE project_id = ${input.projectId}\n AND origin_kind = ${origin.kind}\n AND origin_run_id = ${origin.runId}\n AND origin_batch_ordinal = ${origin.batchOrdinal}\n `\n return row ? commitRecord(row) : null\n })\n }\n\n async list(input: ListOntologyCommitsInput): Promise<ListOntologyCommitsResult> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n if (input.run) assertNonblank(input.run.id, \"Ontology commit run id\")\n const offset = input.offset ?? 0\n const limit = input.limit\n assertNonnegativeInteger(offset, \"Ontology commit list offset\")\n if (limit !== undefined) assertNonnegativeInteger(limit, \"Ontology commit list limit\")\n\n const runFilter =\n input.run?.kind === \"action\"\n ? sql`AND origin_kind = 'action' AND origin_run_id = ${input.run.id}`\n : input.run?.kind === \"projection\"\n ? sql`AND origin_run_id = ${input.run.id}\n AND origin_kind IN ('projection', 'telemetry')`\n : sql``\n const [{ total }] = await sql<{ readonly total: number | string }[]>`\n SELECT COUNT(*) AS total\n FROM ontology_commits\n WHERE project_id = ${input.projectId} ${runFilter}\n `\n const direction = input.order === \"desc\" ? sql`DESC` : sql`ASC`\n const order =\n input.run?.kind === \"projection\"\n ? sql`CASE WHEN origin_kind = 'telemetry' THEN origin_batch_ordinal ELSE -1 END\n ${direction}, committed_at ${direction}, id ${direction}`\n : sql`committed_at ${direction}, id ${direction}`\n const limitFragment = limit === undefined ? sql`` : sql`LIMIT ${limit}`\n const rows = await sql<PgOntologyCommitRow[]>`\n SELECT * FROM ontology_commits\n WHERE project_id = ${input.projectId} ${runFilter}\n ORDER BY ${order}\n ${limitFragment} OFFSET ${offset}\n `\n const count = Number(total)\n const commits = rows.map(commitRecord)\n return { commits, total: count, hasMore: offset + commits.length < count }\n })\n }\n}\n",
30
+ "import type {\n EffectiveChangeCounts,\n ExpectedLinkRevision,\n ExpectedObjectRevision,\n} from \"@sixb/core/internal/materialization\"\nimport {\n assertPinnedDatasetWatermark,\n linkRefKey,\n linkRefSortKey,\n linkScopeSortKey,\n MaterializationConflictError,\n objectRefKey,\n objectRefSortKey,\n telemetryPointKey,\n telemetryPointSortKey,\n} from \"@sixb/core/internal/materialization\"\nimport {\n assertMaterializationFinalizationCorrelation,\n assertMaterializationHeader,\n assertMaterializationLaneCompletion,\n assertPageRows,\n assertPlanChunkCorrelations,\n assertSourceActivationCorrelation,\n invalidCorrelation,\n sameNonnegativeCounts as sameCounts,\n uniqueSorted,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n ApplyMaterializationChunkInput,\n ApplyMaterializationResult,\n FinalizeMaterializationInput,\n MaterializationObjectExistence,\n MaterializationPlanHeader,\n MaterializationSession,\n MaterializationStatePage,\n MaterializationWorkPage,\n OntologyCommitRecord,\n OntologyMaterializationStorage,\n ReadMaterializationObjectExistenceInput,\n SourceActivationWrite,\n SourceReplacementStatePage,\n StageMaterializationWorkInput,\n StreamMaterializationStateInput,\n StreamMaterializationWorkInput,\n StreamSourceReplacementStateInput,\n} from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport { isUniqueViolation } from \"../storage-errors\"\nimport { lockAdvisoryKeys } from \"../transactions\"\nimport {\n type PgMaterializationSessionState,\n PgMaterializationSessions,\n type PgOntologyTransactionContext,\n} from \"./materialization-session\"\nimport {\n linkSortExpression,\n PG_MATERIALIZATION_WORK_TABLE,\n PgMaterializationStateReader,\n} from \"./materialization-state\"\nimport { PgMaterializationWriter } from \"./materialization-writer\"\nimport {\n assertProjectionExecution,\n commitRecord,\n jsonParameter,\n ontologyLockKey,\n originColumns,\n type PgOntologyCommitRow,\n type PgOntologySourceRow,\n toIsoString,\n} from \"./shared\"\n\ninterface ProjectionCountsRow {\n readonly object_classifications: number | string\n readonly link_classifications: number | string\n readonly objects_created: number | string\n readonly objects_updated: number | string\n readonly objects_deleted: number | string\n readonly links_created: number | string\n readonly links_updated: number | string\n readonly links_deleted: number | string\n}\n\ninterface TelemetrySummaryRow {\n readonly classified_points: number | string\n readonly points_created: number | string\n readonly points_updated: number | string\n readonly latest_objects_changed: number | string\n}\n\nexport class PgOntologyMaterializationStorage implements OntologyMaterializationStorage {\n private readonly sessions: PgMaterializationSessions\n private readonly writer: PgMaterializationWriter\n\n constructor(\n private readonly sql: SQLClient,\n context: PgOntologyTransactionContext | null\n ) {\n this.sessions = new PgMaterializationSessions(sql, context)\n this.writer = new PgMaterializationWriter(sql)\n }\n\n async begin(input: MaterializationPlanHeader): Promise<MaterializationSession> {\n assertMaterializationHeader(input)\n const session = await this.sessions.create(input)\n try {\n await lockAdvisoryKeys(this.sql, materializationLockKeys(input))\n await this.assertCommitAbsent(input)\n const reader = new PgMaterializationStateReader(this.sql, input.commit.projectId)\n await this.assertSources(input.expected.sources, input.commit.projectId)\n const objectRevisions = await reader.effectiveObjectRevisions(\n input.expected.objects.map((expected) => expected.ref),\n true\n )\n for (const expected of input.expected.objects) {\n this.assertObject(objectRevisions.get(objectRefKey(expected.ref)) ?? null, expected)\n }\n const linkRevisions = await reader.effectiveLinkLastCommits(\n input.expected.links.map((expected) => expected.ref),\n true\n )\n for (const expected of input.expected.links) {\n this.assertLink(linkRevisions.get(linkRefKey(expected.ref)), expected)\n }\n const linkScopes = await reader.linkScopes(input.expected.linkScopes)\n for (const [index, expected] of input.expected.linkScopes.entries()) {\n if (linkScopes[index]?.fingerprint !== expected.fingerprint) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected link scope changed for ${expected.source.objectTypeId}:${expected.source.primaryId}.${expected.linkId}.`\n )\n }\n }\n const points = await reader.exactPoints(input.expected.points, true)\n const pointRevisions = new Map(\n points.map(\n (point) => [telemetryPointKey(point.series, point.at), point.lastCommitId] as const\n )\n )\n for (const expected of input.expected.points) {\n if (\n (pointRevisions.get(telemetryPointKey(expected.series, expected.at)) ?? null) !==\n expected.lastCommitId\n ) {\n throw new MaterializationConflictError(\n \"timeseries-point\",\n `Telemetry point ${telemetryPointKey(expected.series, expected.at)} changed.`\n )\n }\n }\n return session.publicSession()\n } catch (error) {\n await this.sessions.release(session)\n throw error\n }\n }\n\n async *streamState(\n input: StreamMaterializationStateInput\n ): AsyncIterable<MaterializationStatePage> {\n const session = this.sessions.require(input.session)\n assertPageRows(input.pageRows)\n const reader = new PgMaterializationStateReader(this.sql, session.header.commit.projectId)\n for await (const request of input.requests) {\n this.sessions.require(input.session)\n const objects = uniqueSorted(request.objects, objectRefKey, objectRefSortKey)\n for (let offset = 0; offset < objects.length; offset += input.pageRows) {\n const states = await reader.objectStates(objects.slice(offset, offset + input.pageRows))\n yield { objects: states, links: [], linkScopes: [], points: [] }\n }\n const links = uniqueSorted(request.links, linkRefKey, linkRefSortKey)\n for (let offset = 0; offset < links.length; offset += input.pageRows) {\n const states = await reader.linkStates(links.slice(offset, offset + input.pageRows))\n yield { objects: [], links: states, linkScopes: [], points: [] }\n }\n for await (const refs of reader.incidentLinks(request.incidentObjects, input.pageRows)) {\n this.sessions.require(input.session)\n yield {\n objects: [],\n links: await reader.linkStates(refs),\n linkScopes: [],\n points: [],\n }\n }\n const scopes = uniqueSorted(\n request.linkScopes,\n (scope) =>\n JSON.stringify([scope.source.objectTypeId, scope.source.primaryId, scope.linkId]),\n (scope) => linkScopeSortKey(scope.source, scope.linkId)\n )\n for (let offset = 0; offset < scopes.length; offset += input.pageRows) {\n yield {\n objects: [],\n links: [],\n linkScopes: await reader.linkScopes(scopes.slice(offset, offset + input.pageRows)),\n points: [],\n }\n }\n const points = uniqueSorted(\n request.points,\n (point) => telemetryPointKey(point.series, point.at),\n (point) => telemetryPointSortKey(point.series, point.at)\n )\n for (let offset = 0; offset < points.length; offset += input.pageRows) {\n const stored = await reader.exactPoints(points.slice(offset, offset + input.pageRows))\n if (stored.length > 0) {\n yield { objects: [], links: [], linkScopes: [], points: stored }\n }\n }\n }\n }\n\n async *streamSourceReplacementState(\n input: StreamSourceReplacementStateInput\n ): AsyncIterable<SourceReplacementStatePage> {\n const session = this.sessions.require(input.session)\n assertPageRows(input.pageRows)\n const replacement = await this.requireReplacement(session, input)\n const reader = new PgMaterializationStateReader(this.sql, session.header.commit.projectId)\n if (input.entityKind === \"object\") {\n if (replacement.projectionKind !== \"object\") {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Link projection replacement cannot stream object state.\"\n )\n }\n if (replacement.objectStreamStarted) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Replacement object state may only be streamed once per session.\"\n )\n }\n replacement.objectStreamStarted = true\n for await (const identities of reader.replacementIdentities({\n sessionId: session.id,\n sourceId: replacement.sourceId,\n candidateMaterializationId: replacement.candidateMaterializationId,\n previousMaterializationId: replacement.previousMaterializationId,\n kind: \"object\",\n pageRows: input.pageRows,\n })) {\n this.sessions.require(input.session)\n const refs = identities.map((identity) => {\n if (identity.kind !== \"object\") {\n invalidCorrelation(\"Object replacement returned a link identity.\")\n }\n return identity.ref\n })\n const objects = await reader.replacementObjectStates(\n replacement.sourceId,\n replacement.candidateMaterializationId,\n refs\n )\n yield { objects, links: [] }\n }\n this.sessions.require(input.session)\n replacement.objectStreamCompleted = true\n return\n }\n\n if (replacement.projectionKind === \"object\" && !replacement.objectStreamCompleted) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Object projection replacement must fully stream object state before link state.\"\n )\n }\n if (replacement.linkStreamStarted) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Replacement link state may only be streamed once per session.\"\n )\n }\n replacement.linkStreamStarted = true\n const materializationIds = [\n replacement.candidateMaterializationId,\n ...(replacement.previousMaterializationId ? [replacement.previousMaterializationId] : []),\n ]\n for await (const identities of reader.replacementIdentities({\n sessionId: session.id,\n sourceId: replacement.sourceId,\n candidateMaterializationId: replacement.candidateMaterializationId,\n previousMaterializationId: replacement.previousMaterializationId,\n kind: \"link\",\n pageRows: input.pageRows,\n })) {\n this.sessions.require(input.session)\n const linkIdentities = identities.map((identity) => {\n if (identity.kind !== \"link\") {\n invalidCorrelation(\"Link replacement returned an object identity.\")\n }\n return identity\n })\n const links = await reader.replacementLinkStates(\n replacement.sourceId,\n replacement.candidateMaterializationId,\n materializationIds,\n linkIdentities\n )\n yield { objects: [], links }\n }\n this.sessions.require(input.session)\n replacement.linkStreamCompleted = true\n }\n\n async stageWork(input: StageMaterializationWorkInput): Promise<void> {\n await this.sessions.stage(input)\n }\n\n streamWork(input: StreamMaterializationWorkInput): AsyncIterable<MaterializationWorkPage> {\n assertPageRows(input.pageRows)\n return this.sessions.stream(input)\n }\n\n async readObjectExistence(\n input: ReadMaterializationObjectExistenceInput\n ): Promise<readonly MaterializationObjectExistence[]> {\n const session = this.sessions.require(input.session)\n return this.sessions.readObjectExistence(session, input.refs)\n }\n\n async applyChunk(input: ApplyMaterializationChunkInput): Promise<void> {\n const session = this.sessions.require(input.session)\n const { commit } = session.header\n assertPlanChunkCorrelations(input.chunk, commit)\n const progress = await this.sessions.prepareChunkSequence(session, input.chunk)\n await this.writer.apply(commit.projectId, commit.id, input.chunk)\n this.sessions.commitChunkSequence(session, progress)\n }\n\n async finalize(input: FinalizeMaterializationInput): Promise<ApplyMaterializationResult> {\n const session = this.sessions.require(input.session)\n await this.assertCommitAbsent(session.header)\n await this.assertFinalization(session, input)\n for (const activation of input.finalization.sourceActivations) {\n await this.activateSource(session, activation)\n }\n const record = await this.insertCommit(session.header, input)\n await this.sessions.release(session)\n return { commit: record }\n }\n\n deactivateSessions(): void {\n this.sessions.deactivateAll()\n }\n\n private async requireReplacement(\n session: PgMaterializationSessionState,\n input: StreamSourceReplacementStateInput\n ): Promise<NonNullable<PgMaterializationSessionState[\"replacement\"]>> {\n if (session.replacement) {\n if (\n session.replacement.sourceId !== input.source.projectionId ||\n session.replacement.candidateMaterializationId !== input.candidateMaterializationId\n ) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Materialization session already owns another replacement union.\"\n )\n }\n return session.replacement\n }\n const projectId = session.header.commit.projectId\n const candidate = await this.getSource(\n projectId,\n input.source.projectionId,\n input.candidateMaterializationId,\n true\n )\n if (!candidate || candidate.status !== \"ready\" || candidate.execution_token === null) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n `Candidate source materialization '${input.candidateMaterializationId}' is missing or is not ready.`\n )\n }\n await assertProjectionExecution(this.sql, {\n projectId,\n sourceId: input.source.projectionId,\n projectionRunId: candidate.projection_run_id,\n executionToken: candidate.execution_token,\n })\n const previous = await this.getActiveSource(projectId, input.source.projectionId, true)\n if (\n candidate.protocol !== \"replacement\" ||\n (previous &&\n (previous.protocol !== candidate.protocol ||\n previous.projection_kind !== candidate.projection_kind))\n ) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Source replacement kind or protocol does not match its active materialization.\"\n )\n }\n session.replacement = {\n sourceId: input.source.projectionId,\n candidateMaterializationId: input.candidateMaterializationId,\n previousMaterializationId: previous?.materialization_id ?? null,\n projectionKind: candidate.projection_kind,\n objectStreamStarted: false,\n objectStreamCompleted: false,\n linkStreamStarted: false,\n linkStreamCompleted: false,\n }\n return session.replacement\n }\n\n private async assertCommitAbsent(header: MaterializationPlanHeader): Promise<void> {\n const [duplicateIdentity] = await this.sql<\n { readonly id: string; readonly idempotency_key: string }[]\n >`\n SELECT id, idempotency_key\n FROM ontology_commits\n WHERE project_id = ${header.commit.projectId}\n AND (id = ${header.commit.id} OR idempotency_key = ${header.commit.idempotencyKey})\n ORDER BY CASE WHEN id = ${header.commit.id} THEN 0 ELSE 1 END\n LIMIT 1\n FOR UPDATE\n `\n if (duplicateIdentity) {\n throw new MaterializationConflictError(\n \"idempotency\",\n duplicateIdentity.id === header.commit.id\n ? `Ontology commit '${header.commit.id}' already exists.`\n : \"Ontology idempotency key already exists.\"\n )\n }\n\n const origin = originColumns(header.commit.origin)\n if (origin.runId === null) return\n const [duplicateOrigin] =\n origin.batchOrdinal === null\n ? await this.sql<{ readonly id: string }[]>`\n SELECT id FROM ontology_commits\n WHERE project_id = ${header.commit.projectId}\n AND origin_kind = ${origin.kind}\n AND origin_run_id = ${origin.runId}\n AND origin_batch_ordinal IS NULL\n LIMIT 1\n FOR UPDATE\n `\n : await this.sql<{ readonly id: string }[]>`\n SELECT id FROM ontology_commits\n WHERE project_id = ${header.commit.projectId}\n AND origin_kind = ${origin.kind}\n AND origin_run_id = ${origin.runId}\n AND origin_batch_ordinal = ${origin.batchOrdinal}\n LIMIT 1\n FOR UPDATE\n `\n if (duplicateOrigin) {\n throw new MaterializationConflictError(\n \"run-correlation\",\n \"Ontology commit origin already has an authoritative commit.\"\n )\n }\n }\n\n private async assertSources(\n expectedSources: MaterializationPlanHeader[\"expected\"][\"sources\"],\n projectId: string\n ): Promise<void> {\n if (expectedSources.length === 0) return\n const rows = await this.sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${projectId}\n AND source_id = ANY(\n ${this.sql.array(expectedSources.map((expected) => expected.source.projectionId))}::text[]\n )\n AND status = 'active'\n FOR UPDATE\n `\n const active = new Map(rows.map((row) => [row.source_id, row] as const))\n for (const expected of expectedSources) {\n this.assertSourceRow(expected, active.get(expected.source.projectionId) ?? null)\n }\n }\n\n private assertSourceRow(\n expected: MaterializationPlanHeader[\"expected\"][\"sources\"][number],\n active: PgOntologySourceRow | null\n ): void {\n if (\n (active?.materialization_id ?? null) !== expected.activeMaterializationId ||\n (active?.last_commit_id ?? null) !== expected.lastCommitId\n ) {\n throw new MaterializationConflictError(\n \"projection-fence\",\n `Source '${expected.source.projectionId}' changed.`\n )\n }\n }\n\n private assertObject(\n row: { readonly version: number; readonly lastCommitId: string | null } | null,\n expected: ExpectedObjectRevision\n ): void {\n if (!expected.exists) {\n if (row) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected object ${objectRefKey(expected.ref)} to be absent.`\n )\n }\n return\n }\n if (!row || row.version !== expected.version || row.lastCommitId !== expected.lastCommitId) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected object ${objectRefKey(expected.ref)} changed.`\n )\n }\n }\n\n private assertLink(\n lastCommitId: string | null | undefined,\n expected: ExpectedLinkRevision\n ): void {\n if (!expected.exists) {\n if (lastCommitId !== undefined) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected link ${linkRefKey(expected.ref)} to be absent.`\n )\n }\n return\n }\n if (lastCommitId === undefined || lastCommitId !== expected.lastCommitId) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected link ${linkRefKey(expected.ref)} changed.`\n )\n }\n }\n\n private async assertFinalization(\n session: PgMaterializationSessionState,\n input: FinalizeMaterializationInput\n ): Promise<void> {\n const { commit } = session.header\n const { result } = input.finalization\n assertMaterializationFinalizationCorrelation(session, input)\n const laneCounts = await this.sessions.laneCounts(session)\n assertMaterializationLaneCompletion(session, laneCounts)\n await this.assertFinalCardinality(session)\n const eventCount = laneCounts.event\n const [outbox] = await this.sql<\n {\n readonly count: number | string\n readonly minimum: number | string | null\n readonly maximum: number | string | null\n }[]\n >`\n SELECT COUNT(*) AS count, MIN(commit_ordinal) AS minimum,\n MAX(commit_ordinal) AS maximum\n FROM ontology_outbox\n WHERE project_id = ${commit.projectId} AND commit_id = ${commit.id}\n `\n const outboxCount = Number(outbox?.count ?? 0)\n const minimum = outbox?.minimum === null ? null : Number(outbox?.minimum)\n const maximum = outbox?.maximum === null ? null : Number(outbox?.maximum)\n if (\n outboxCount !== eventCount ||\n (eventCount > 0 && (minimum !== 0 || maximum !== eventCount - 1))\n ) {\n invalidCorrelation(\"Outbox event ordinals must be contiguous from zero.\")\n }\n\n if (commit.intent.kind === \"telemetry\") {\n const summary = await this.telemetrySummary(session, commit.intent.pointCount)\n if (summary.classifiedPoints !== commit.intent.pointCount) {\n invalidCorrelation(\n \"Telemetry point classification coverage does not match the commit intent.\"\n )\n }\n if (result.kind !== \"telemetry\" || !sameCounts(result, summary.counts)) {\n invalidCorrelation(\"Telemetry result counts do not correlate with finalized work.\")\n }\n }\n if (commit.intent.kind === \"projection\") {\n if (result.kind !== \"projection\") return\n await this.sessions.assertClassificationCoverage(session)\n if (!sameCounts(result.counts, await this.projectionCounts(session))) {\n invalidCorrelation(\"Projection result counts do not correlate with finalized work.\")\n }\n }\n }\n\n private async assertFinalCardinality(session: PgMaterializationSessionState): Promise<void> {\n const [violation] = await this.sql<{ readonly reason: \"duplicate\" | \"mismatch\" }[]>`\n WITH work AS (\n SELECT payload->>'scopeSortKey' AS scope_sort_key,\n payload->>'linkSortKey' AS link_sort_key,\n (payload->>'occupied')::boolean AS occupied,\n payload->'ref'->'source'->>'objectTypeId' AS source_type_id,\n payload->'ref'->'source'->>'primaryId' AS source_id,\n payload->'ref'->>'linkId' AS link_id\n FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id} AND kind = 'cardinality'\n ), duplicate AS (\n SELECT scope_sort_key FROM work WHERE occupied\n GROUP BY scope_sort_key HAVING COUNT(*) > 1\n ), scopes AS (\n SELECT DISTINCT scope_sort_key, source_type_id, source_id, link_id FROM work\n ), expected AS (\n SELECT scope_sort_key, link_sort_key FROM work WHERE occupied\n ), actual AS (\n SELECT scopes.scope_sort_key,\n ${this.sql.unsafe(linkSortExpression(\"links\"))} AS link_sort_key\n FROM scopes\n JOIN links USING (source_type_id, source_id, link_id)\n WHERE links.project_id = ${session.header.commit.projectId}\n ), differences AS (\n (SELECT * FROM expected EXCEPT SELECT * FROM actual)\n UNION ALL\n (SELECT * FROM actual EXCEPT SELECT * FROM expected)\n )\n SELECT 'duplicate'::text AS reason FROM duplicate\n UNION ALL\n SELECT 'mismatch'::text AS reason FROM differences\n LIMIT 1\n `\n if (violation?.reason === \"duplicate\") {\n invalidCorrelation(\"Materialization cardinality work violates cardinality-one.\")\n }\n if (violation) {\n invalidCorrelation(\n \"Materialization cardinality work does not match the final effective link scope.\"\n )\n }\n }\n\n private async projectionCounts(\n session: PgMaterializationSessionState\n ): Promise<EffectiveChangeCounts> {\n const [row] = await this.sql<ProjectionCountsRow[]>`\n SELECT\n COUNT(*) FILTER (\n WHERE kind = 'classification' AND payload->>'entityKind' = 'object'\n ) AS object_classifications,\n COUNT(*) FILTER (\n WHERE kind = 'classification' AND payload->>'entityKind' = 'link'\n ) AS link_classifications,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'object-upsert'\n AND NOT (payload->'item'->'value'->'expected'->>'exists')::boolean\n ) AS objects_created,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'object-upsert'\n AND (payload->'item'->'value'->'expected'->>'exists')::boolean\n ) AS objects_updated,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'object-delete'\n ) AS objects_deleted,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'link-upsert'\n AND NOT (payload->'item'->'value'->'expected'->>'exists')::boolean\n ) AS links_created,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'link-upsert'\n AND (payload->'item'->'value'->'expected'->>'exists')::boolean\n ) AS links_updated,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'link-delete'\n ) AS links_deleted\n FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id}\n `\n const objectsCreated = databaseCount(row?.objects_created)\n const objectsUpdated = databaseCount(row?.objects_updated)\n const objectsDeleted = databaseCount(row?.objects_deleted)\n const linksCreated = databaseCount(row?.links_created)\n const linksUpdated = databaseCount(row?.links_updated)\n const linksDeleted = databaseCount(row?.links_deleted)\n return {\n objectsCreated,\n objectsUpdated,\n objectsDeleted,\n objectsUnchanged:\n databaseCount(row?.object_classifications) -\n objectsCreated -\n objectsUpdated -\n objectsDeleted,\n linksCreated,\n linksUpdated,\n linksDeleted,\n linksUnchanged:\n databaseCount(row?.link_classifications) - linksCreated - linksUpdated - linksDeleted,\n }\n }\n\n private async telemetrySummary(session: PgMaterializationSessionState, pointCount: number) {\n const [row] = await this.sql<TelemetrySummaryRow[]>`\n SELECT\n COUNT(*) FILTER (\n WHERE kind = 'classification' AND payload->>'entityKind' = 'point'\n ) AS classified_points,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'point-upsert'\n AND payload->'item'->'value'->'expected'->>'lastCommitId' IS NULL\n ) AS points_created,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'point-upsert'\n AND payload->'item'->'value'->'expected'->>'lastCommitId' IS NOT NULL\n ) AS points_updated,\n COUNT(*) FILTER (\n WHERE kind = 'plan' AND payload->'item'->>'kind' = 'object-upsert'\n ) AS latest_objects_changed\n FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id}\n `\n const pointsCreated = databaseCount(row?.points_created)\n const pointsUpdated = databaseCount(row?.points_updated)\n return {\n classifiedPoints: databaseCount(row?.classified_points),\n counts: {\n pointsCreated,\n pointsUpdated,\n pointsUnchanged: pointCount - pointsCreated - pointsUpdated,\n latestObjectsChanged: databaseCount(row?.latest_objects_changed),\n },\n }\n }\n\n private async activateSource(\n session: PgMaterializationSessionState,\n activation: SourceActivationWrite\n ): Promise<void> {\n const { commit } = session.header\n assertSourceActivationCorrelation(session, activation)\n const candidate = await this.getSource(\n commit.projectId,\n activation.source.projectionId,\n activation.materializationId,\n true\n )\n if (!candidate || candidate.status !== \"ready\" || candidate.execution_token === null) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Source activation candidate is missing or is not ready.\"\n )\n }\n await assertProjectionExecution(this.sql, {\n projectId: commit.projectId,\n sourceId: activation.source.projectionId,\n projectionRunId: activation.execution.projectionRunId,\n executionToken: activation.execution.executionToken,\n })\n if (\n candidate.projection_run_id !== activation.execution.projectionRunId ||\n candidate.execution_token !== activation.execution.executionToken ||\n candidate.projection_kind !== activation.projectionKind ||\n candidate.protocol !== activation.protocol ||\n candidate.dataset_id !== activation.datasetVersion.datasetId ||\n candidate.dataset_version_id !== activation.datasetVersion.versionId ||\n toIsoString(candidate.dataset_version_created_at) !== activation.datasetVersion.createdAt ||\n candidate.projection_revision !== activation.projectionRevision ||\n candidate.ownership_hash !== activation.ownershipHash ||\n candidate.ontology_revision !== activation.ontologyRevision ||\n candidate.ready_at === null ||\n activation.updatedAt < toIsoString(candidate.ready_at)\n ) {\n invalidCorrelation(\"Source activation does not match its ready candidate identity.\")\n }\n const previous = await this.getActiveSource(\n commit.projectId,\n activation.source.projectionId,\n true\n )\n this.assertSourceRow(activation.expected, previous)\n if (previous) {\n assertPinnedDatasetWatermark(\n {\n datasetId: previous.dataset_id,\n versionId: previous.dataset_version_id,\n createdAt: toIsoString(previous.dataset_version_created_at),\n },\n activation.datasetVersion,\n \"Source activation\"\n )\n if (activation.updatedAt < toIsoString(previous.updated_at)) {\n invalidCorrelation(\"Source activation cannot precede the active materialization update.\")\n }\n const superseded = await this.sql<{ readonly materialization_id: string }[]>`\n UPDATE ontology_sources\n SET status = 'superseded', execution_token = NULL,\n terminal_at = ${activation.updatedAt}, updated_at = ${activation.updatedAt}\n WHERE project_id = ${commit.projectId}\n AND source_id = ${activation.source.projectionId}\n AND materialization_id = ${previous.materialization_id}\n AND status = 'active'\n AND last_commit_id IS NOT DISTINCT FROM ${activation.expected.lastCommitId}\n RETURNING materialization_id\n `\n if (superseded.length !== 1) {\n throw new MaterializationConflictError(\n \"projection-fence\",\n `Source '${activation.source.projectionId}' changed.`\n )\n }\n }\n let activated: readonly { readonly materialization_id: string }[]\n try {\n activated = await this.sql<{ readonly materialization_id: string }[]>`\n UPDATE ontology_sources\n SET status = 'active', execution_token = NULL,\n activated_at = ${activation.updatedAt}, last_commit_id = ${activation.lastCommitId},\n updated_at = ${activation.updatedAt}\n WHERE project_id = ${commit.projectId}\n AND source_id = ${activation.source.projectionId}\n AND materialization_id = ${activation.materializationId}\n AND status = 'ready'\n AND execution_token = ${activation.execution.executionToken}\n RETURNING materialization_id\n `\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new MaterializationConflictError(\n \"projection-fence\",\n `Source '${activation.source.projectionId}' changed.`\n )\n }\n throw error\n }\n if (activated.length !== 1) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Source activation candidate changed.\"\n )\n }\n }\n\n private async insertCommit(\n header: MaterializationPlanHeader,\n input: FinalizeMaterializationInput\n ): Promise<OntologyCommitRecord> {\n const { commit } = header\n const origin = originColumns(commit.origin)\n const actor = commit.actor === undefined ? null : jsonParameter(this.sql, commit.actor)\n const rows = await this.sql<PgOntologyCommitRow[]>`\n INSERT INTO ontology_commits (\n project_id, id, idempotency_key, request_hash,\n origin_kind, origin_run_id, origin_batch_ordinal, origin, actor,\n ontology_revision, projection_revision, ownership_hash,\n intent, result, committed_at\n ) VALUES (\n ${commit.projectId}, ${commit.id}, ${commit.idempotencyKey}, ${commit.requestHash},\n ${origin.kind}, ${origin.runId}, ${origin.batchOrdinal},\n ${jsonParameter(this.sql, commit.origin)}, ${actor}, ${commit.ontologyRevision},\n ${commit.projectionRevision ?? null}, ${commit.ownershipHash ?? null},\n ${jsonParameter(this.sql, commit.intent)},\n ${jsonParameter(this.sql, input.finalization.result)}, ${commit.committedAt}\n )\n ON CONFLICT DO NOTHING\n RETURNING *\n `\n if (!rows[0]) {\n await this.assertCommitAbsent(header)\n throw new MaterializationConflictError(\n \"idempotency\",\n \"Ontology commit identity already exists.\"\n )\n }\n return commitRecord(rows[0])\n }\n\n private async getActiveSource(\n projectId: string,\n sourceId: string,\n lock = false\n ): Promise<PgOntologySourceRow | null> {\n const lockFragment = lock ? this.sql`FOR UPDATE` : this.sql``\n const [row] = await this.sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${projectId} AND source_id = ${sourceId} AND status = 'active'\n ${lockFragment}\n `\n return row ?? null\n }\n\n private async getSource(\n projectId: string,\n sourceId: string,\n materializationId: string,\n lock = false\n ): Promise<PgOntologySourceRow | null> {\n const lockFragment = lock ? this.sql`FOR UPDATE` : this.sql``\n const [row] = await this.sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${projectId}\n AND source_id = ${sourceId}\n AND materialization_id = ${materializationId}\n ${lockFragment}\n `\n return row ?? null\n }\n}\n\nfunction materializationLockKeys(header: MaterializationPlanHeader): string[] {\n const { commit, expected } = header\n const origin = originColumns(commit.origin)\n return [\n ontologyLockKey(\"commit-id\", commit.projectId, commit.id),\n ontologyLockKey(\"commit-idempotency\", commit.projectId, commit.idempotencyKey),\n ...(origin.runId === null\n ? []\n : [\n ontologyLockKey(\n \"commit-origin\",\n commit.projectId,\n origin.kind,\n origin.runId,\n origin.batchOrdinal === null ? \"\" : String(origin.batchOrdinal)\n ),\n ]),\n ...expected.sources.map((value) =>\n ontologyLockKey(\"source\", commit.projectId, value.source.projectionId)\n ),\n ...expected.objects.map((value) =>\n ontologyLockKey(\"object\", commit.projectId, objectRefKey(value.ref))\n ),\n ...expected.links.map((value) =>\n ontologyLockKey(\"link\", commit.projectId, linkRefKey(value.ref))\n ),\n ...expected.linkScopes.map((value) =>\n ontologyLockKey(\n \"link-scope\",\n commit.projectId,\n value.source.objectTypeId,\n value.source.primaryId,\n value.linkId\n )\n ),\n ...expected.points.map((value) =>\n ontologyLockKey(\"point\", commit.projectId, telemetryPointKey(value.series, value.at))\n ),\n ]\n}\n\nfunction databaseCount(value: number | string | undefined): number {\n return Number(value ?? 0)\n}\n",
31
+ "import { MaterializationConflictError } from \"@sixb/core/internal/materialization\"\nimport {\n correlateMaterializationChunk,\n duplicateMaterializationWork as duplicateWork,\n invalidCorrelation,\n materializationPlanItems,\n ProviderMaterializationSessionState,\n type ProviderMaterializationTransactionLifecycle,\n prepareMaterializationWork,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n MaterializationEventWorkRecord,\n MaterializationPlanChunk,\n MaterializationPlanHeader,\n MaterializationSession,\n MaterializationWorkPage,\n MaterializationWorkRecord,\n StageMaterializationWorkInput,\n StreamMaterializationWorkInput,\n} from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport { PG_MATERIALIZATION_WORK_TABLE, PG_REPLACEMENT_WORK_TABLE } from \"./materialization-state\"\nimport { jsonParameter } from \"./shared\"\n\nexport interface PgOntologyTransactionContext {\n readonly id: object\n readonly materializations: ProviderMaterializationTransactionLifecycle\n active: boolean\n}\n\ninterface WorkCursor {\n readonly majorOrder: number\n readonly minorOrder: number\n readonly sortOne: string\n readonly sortTwo: string\n readonly recordKey: string\n}\n\nexport interface PgChunkSequenceProgress {\n readonly appliedPlanCount: number\n readonly appliedOutboxCount: number\n readonly appliedPlanCursor: WorkCursor | null\n readonly appliedEventCursor: WorkCursor | null\n}\n\nexport class PgMaterializationSessionState extends ProviderMaterializationSessionState {\n appliedPlanCursor: WorkCursor | null = null\n appliedEventCursor: WorkCursor | null = null\n}\n\ninterface WorkDatabaseRow {\n readonly record_key: string\n readonly major_order: number\n readonly minor_order: number\n readonly sort_one: string\n readonly sort_two: string\n readonly payload: unknown\n}\n\nexport class PgMaterializationSessions {\n private readonly sessions = new WeakMap<object, PgMaterializationSessionState>()\n private readonly live = new Set<PgMaterializationSessionState>()\n private tablesReady = false\n\n constructor(\n private readonly sql: SQLClient,\n private readonly context: PgOntologyTransactionContext | null\n ) {}\n\n async create(header: MaterializationPlanHeader): Promise<PgMaterializationSessionState> {\n if (!this.context?.active) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Materialization sessions require an active storage transaction.\"\n )\n }\n await this.ensureTables()\n const session = new PgMaterializationSessionState(structuredClone(header), this.context.id)\n this.sessions.set(session.providerToken, session)\n this.live.add(session)\n this.context.materializations.register(session.providerToken)\n return session\n }\n\n require(session: MaterializationSession): PgMaterializationSessionState {\n const value = this.sessions.get(session.providerToken)\n if (\n !value ||\n !value.active ||\n !this.context?.active ||\n value.transactionId !== this.context.id\n ) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Materialization session is inactive.\"\n )\n }\n return value\n }\n\n async release(session: PgMaterializationSessionState): Promise<void> {\n if (!session.active) return\n await this.deleteWork(session.id)\n session.active = false\n session.replacement = null\n this.live.delete(session)\n this.context?.materializations.complete(session.providerToken)\n }\n\n deactivateAll(): void {\n for (const session of this.live) {\n session.active = false\n session.replacement = null\n }\n this.live.clear()\n }\n\n async stage(input: StageMaterializationWorkInput): Promise<void> {\n const session = this.require(input.session)\n const records = prepareMaterializationWork(session, input)\n if (records.length === 0) return\n const keys = records.map(({ record }) => record.recordKey)\n const uniqueKeys = records.map(({ uniqueKey }) => uniqueKey)\n\n const [duplicate] = await this.sql<{ readonly record_key: string }[]>`\n SELECT record_key\n FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id}\n AND (\n record_key = ANY(${this.sql.array(keys)}::text[])\n OR unique_key = ANY(${this.sql.array(uniqueKeys)}::text[])\n )\n LIMIT 1\n `\n if (duplicate) throw duplicateWork(duplicate.record_key)\n\n const payload = records.map(({ record, uniqueKey, columns }) => {\n return {\n recordKey: record.recordKey,\n uniqueKey,\n kind: record.kind,\n lane: columns.lane,\n majorOrder: columns.majorOrder,\n minorOrder: columns.minorOrder,\n sortOne: columns.sortOne,\n sortTwo: columns.sortTwo,\n record,\n }\n })\n await this.sql`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, payload)}::jsonb)\n )\n INSERT INTO ${this.sql(PG_MATERIALIZATION_WORK_TABLE)} (\n session_id, record_key, unique_key, kind, lane,\n major_order, minor_order, sort_one, sort_two, payload\n )\n SELECT ${session.id}, value->>'recordKey', value->>'uniqueKey', value->>'kind',\n value->>'lane', (value->>'majorOrder')::integer, (value->>'minorOrder')::integer,\n value->>'sortOne', value->>'sortTwo', value->'record'\n FROM staged\n `\n }\n\n async *stream(input: StreamMaterializationWorkInput): AsyncIterable<MaterializationWorkPage> {\n const session = this.require(input.session)\n const stream = session.workStreams[input.order]\n if (stream.started) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Materialization ${input.order} work may only be streamed once per session.`\n )\n }\n stream.started = true\n session.workSealed = true\n let cursor: WorkCursor | null = null\n while (true) {\n this.require(input.session)\n const rows = await this.readLane(input.order, session.id, cursor, input.pageRows)\n if (rows.length === 0) break\n const records = rows.map((row) =>\n structuredClone(row.payload)\n ) as MaterializationWorkPage[\"records\"]\n cursor = workCursor(rows[rows.length - 1]!)\n stream.emittedCount += records.length\n yield { records }\n }\n this.require(input.session)\n stream.completed = true\n }\n\n async readObjectExistence(\n session: PgMaterializationSessionState,\n refs: readonly { readonly objectTypeId: string; readonly primaryId: string }[]\n ): Promise<\n readonly {\n readonly ref: { readonly objectTypeId: string; readonly primaryId: string }\n readonly exists: boolean\n }[]\n > {\n if (refs.length === 0) return []\n const keys = refs.map(\n (ref) => `object-existence:${JSON.stringify([ref.objectTypeId, ref.primaryId])}`\n )\n const rows = await this.sql<{ readonly unique_key: string; readonly payload: unknown }[]>`\n SELECT unique_key, payload FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id}\n AND unique_key = ANY(${this.sql.array(keys)}::text[])\n AND kind = 'object-existence'\n `\n const found = new Map(rows.map((row) => [row.unique_key, row.payload] as const))\n return keys.flatMap((key) => {\n const payload = found.get(key)\n if (!payload) return []\n const record = structuredClone(payload) as Extract<\n MaterializationWorkRecord,\n { readonly kind: \"object-existence\" }\n >\n return [{ ref: record.ref, exists: record.exists }]\n })\n }\n\n async prepareChunkSequence(\n session: PgMaterializationSessionState,\n chunk: MaterializationPlanChunk\n ): Promise<PgChunkSequenceProgress> {\n const items = materializationPlanItems(chunk)\n const planRows = await this.readLane(\n \"apply\",\n session.id,\n session.appliedPlanCursor,\n items.length\n )\n const expectedItems = planRows.map(\n (row) =>\n (\n structuredClone(row.payload) as Extract<\n MaterializationWorkRecord,\n { readonly kind: \"plan\" }\n >\n ).item\n )\n const eventRows = await this.readLane(\n \"event\",\n session.id,\n session.appliedEventCursor,\n chunk.outbox.length\n )\n const expectedEvents = eventRows.map(\n (row) => structuredClone(row.payload) as MaterializationEventWorkRecord\n )\n const progress = correlateMaterializationChunk(\n session,\n chunk,\n items,\n expectedItems,\n expectedEvents\n )\n\n return {\n ...progress,\n appliedPlanCursor:\n planRows.length === 0\n ? session.appliedPlanCursor\n : workCursor(planRows[planRows.length - 1]!),\n appliedEventCursor:\n eventRows.length === 0\n ? session.appliedEventCursor\n : workCursor(eventRows[eventRows.length - 1]!),\n }\n }\n\n commitChunkSequence(\n session: PgMaterializationSessionState,\n progress: PgChunkSequenceProgress\n ): void {\n session.appliedPlanCount = progress.appliedPlanCount\n session.appliedOutboxCount = progress.appliedOutboxCount\n session.appliedPlanCursor = progress.appliedPlanCursor\n session.appliedEventCursor = progress.appliedEventCursor\n }\n\n async count(session: PgMaterializationSessionState, kind: string): Promise<number> {\n const [row] = await this.sql<{ readonly count: number | string }[]>`\n SELECT COUNT(*) AS count FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id} AND kind = ${kind}\n `\n return Number(row?.count ?? 0)\n }\n\n async laneCounts(session: PgMaterializationSessionState): Promise<{\n readonly apply: number\n readonly cardinality: number\n readonly event: number\n }> {\n const rows = await this.sql<\n { readonly lane: \"apply\" | \"cardinality\" | \"event\"; readonly count: number | string }[]\n >`\n SELECT lane, COUNT(*) AS count FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id} AND lane <> 'none'\n GROUP BY lane\n `\n const counts = { apply: 0, cardinality: 0, event: 0 }\n for (const row of rows) counts[row.lane] = Number(row.count)\n return counts\n }\n\n async assertClassificationCoverage(session: PgMaterializationSessionState): Promise<void> {\n if (!session.replacement) return\n const includeObjects = session.replacement.projectionKind === \"object\"\n const [mismatch] = await this.sql<{ readonly marker: number }[]>`\n WITH expected AS (\n SELECT entity_kind, identity_key\n FROM ${this.sql(PG_REPLACEMENT_WORK_TABLE)}\n WHERE session_id = ${session.id} AND diff_required\n AND (entity_kind = 'link' OR ${includeObjects})\n ), actual AS (\n SELECT payload->>'entityKind' AS entity_kind,\n payload->>'identityKey' AS identity_key\n FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id} AND kind = 'classification'\n AND payload->>'entityKind' IN ('object', 'link')\n ), differences AS (\n (SELECT * FROM expected EXCEPT SELECT * FROM actual)\n UNION ALL\n (SELECT * FROM actual EXCEPT SELECT * FROM expected)\n ), invalid AS (\n SELECT 1 AS marker FROM differences\n UNION ALL\n SELECT 1 AS marker FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${session.id} AND kind = 'classification'\n AND payload->>'entityKind' = 'point'\n )\n SELECT marker FROM invalid LIMIT 1\n `\n if (mismatch) {\n invalidCorrelation(\n \"Projection replacement classification coverage does not match its streamed state.\"\n )\n }\n }\n\n private async readLane(\n lane: StreamMaterializationWorkInput[\"order\"],\n sessionId: string,\n cursor: WorkCursor | null,\n limit: number\n ): Promise<WorkDatabaseRow[]> {\n if (limit === 0) return []\n const after = cursor\n ? this.sql`AND (major_order, minor_order, sort_one, sort_two, record_key) >\n (${cursor.majorOrder}, ${cursor.minorOrder}, ${cursor.sortOne}, ${cursor.sortTwo},\n ${cursor.recordKey})`\n : this.sql``\n return this.sql<WorkDatabaseRow[]>`\n SELECT record_key, major_order, minor_order, sort_one, sort_two, payload\n FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${sessionId} AND lane = ${lane} ${after}\n ORDER BY major_order, minor_order, sort_one, sort_two, record_key\n LIMIT ${limit}\n `\n }\n\n private async ensureTables(): Promise<void> {\n if (this.tablesReady) return\n await this.sql`\n CREATE TEMP TABLE ${this.sql(PG_MATERIALIZATION_WORK_TABLE)} (\n session_id TEXT NOT NULL,\n record_key TEXT COLLATE \"C\" NOT NULL,\n unique_key TEXT NOT NULL,\n kind TEXT NOT NULL,\n lane TEXT NOT NULL,\n major_order INTEGER NOT NULL,\n minor_order INTEGER NOT NULL,\n sort_one TEXT COLLATE \"C\" NOT NULL,\n sort_two TEXT COLLATE \"C\" NOT NULL,\n payload JSONB NOT NULL,\n PRIMARY KEY (session_id, record_key),\n UNIQUE (session_id, unique_key)\n ) ON COMMIT DROP\n `\n await this.sql`\n CREATE INDEX ontology_materialization_work_lane\n ON ${this.sql(PG_MATERIALIZATION_WORK_TABLE)} (\n session_id, lane, major_order, minor_order, sort_one, sort_two, record_key\n )\n `\n await this.sql`\n CREATE TEMP TABLE ${this.sql(PG_REPLACEMENT_WORK_TABLE)} (\n session_id TEXT NOT NULL,\n entity_kind TEXT NOT NULL,\n identity_key TEXT COLLATE \"C\" NOT NULL,\n sort_key TEXT COLLATE \"C\" NOT NULL,\n diff_required BOOLEAN NOT NULL,\n PRIMARY KEY (session_id, entity_kind, identity_key)\n ) ON COMMIT DROP\n `\n await this.sql`\n CREATE INDEX ontology_replacement_work_order\n ON ${this.sql(PG_REPLACEMENT_WORK_TABLE)} (\n session_id, entity_kind, sort_key, identity_key\n )\n `\n this.tablesReady = true\n }\n\n private async deleteWork(sessionId: string): Promise<void> {\n if (!this.tablesReady) return\n await this.sql`\n DELETE FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)} WHERE session_id = ${sessionId}\n `\n await this.sql`\n DELETE FROM ${this.sql(PG_REPLACEMENT_WORK_TABLE)} WHERE session_id = ${sessionId}\n `\n }\n}\n\nfunction workCursor(row: WorkDatabaseRow): WorkCursor {\n return {\n majorOrder: row.major_order,\n minorOrder: row.minor_order,\n sortOne: row.sort_one,\n sortTwo: row.sort_two,\n recordKey: row.record_key,\n }\n}\n",
32
+ "import type {\n EffectiveLinkSnapshot,\n EffectiveObjectSnapshot,\n OntologyLinkRef,\n OntologyObjectRef,\n ProjectionEntityRef,\n TelemetrySeriesRef,\n} from \"@sixb/core/internal/materialization\"\nimport {\n linkRefKey,\n linkScopeSortKey,\n MaterializationConflictError,\n objectRefKey,\n projectionEntityKey,\n telemetryPointKey,\n telemetryPointSortKey,\n} from \"@sixb/core/internal/materialization\"\nimport {\n appendScopeSnapshot,\n finishScopeAccumulator,\n startScopeAccumulator,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n MaterializationLinkScopeState,\n MaterializationLinkState,\n MaterializationObjectState,\n SourceReplacementLinkState,\n SourceReplacementObjectState,\n StoredLinkOverride,\n StoredObjectOverride,\n StoredSourceAssertion,\n StoredSourceLinkAssertion,\n StoredSourceObjectAssertion,\n StoredTelemetryPoint,\n} from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport {\n databaseSafeInteger,\n jsonKeyParameter,\n jsonParameter,\n linkRefFromColumns,\n objectRefFromColumns,\n type PgOntologyOverrideRow,\n type PgOntologySourceAssertionRow,\n toIsoString,\n} from \"./shared\"\n\nexport const PG_MATERIALIZATION_WORK_TABLE = \"ontology_materialization_work\"\nexport const PG_REPLACEMENT_WORK_TABLE = \"ontology_replacement_work\"\n\ninterface EffectiveObjectRow {\n readonly object_type_id: string\n readonly primary_id: string\n readonly properties: unknown\n readonly created_at: Date | string\n readonly updated_at: Date | string\n readonly version: number\n readonly last_commit_id: string | null\n}\n\ninterface EffectiveLinkRow {\n readonly source_type_id: string\n readonly source_id: string\n readonly link_id: string\n readonly target_type_id: string\n readonly target_id: string\n readonly properties: unknown | null\n readonly created_at: Date | string\n readonly updated_at: Date | string\n readonly last_commit_id: string | null\n}\n\ninterface TelemetryRow {\n readonly object_type_id: string\n readonly object_id: string\n readonly property_id: string\n readonly value: unknown\n readonly unit: string | null\n readonly at: Date | string\n readonly last_commit_id: string | null\n}\n\ninterface LinkIdentityRow {\n readonly source_type_id: string\n readonly source_id: string\n readonly link_id: string\n readonly target_type_id: string\n readonly target_id: string\n readonly sort_key: string\n}\n\ninterface LinkScopeRow extends EffectiveLinkRow {\n readonly scope_sort_key: string\n readonly link_sort_key: string\n}\n\ninterface ObjectOverrideRow extends PgOntologyOverrideRow {\n readonly object_type_id: string\n readonly primary_id: string\n}\n\ninterface LinkOverrideRow extends PgOntologyOverrideRow {\n readonly source_type_id: string\n readonly source_primary_id: string\n readonly link_id: string\n readonly target_type_id: string\n readonly target_primary_id: string\n}\n\nexport type ReplacementIdentity =\n | {\n readonly kind: \"object\"\n readonly ref: OntologyObjectRef\n readonly sortKey: string\n readonly diffRequired: true\n }\n | {\n readonly kind: \"link\"\n readonly ref: OntologyLinkRef\n readonly sortKey: string\n readonly diffRequired: boolean\n }\n\ninterface ReplacementSources {\n readonly owned: ReadonlySet<string>\n readonly byMaterialization: ReadonlyMap<string, ReadonlyMap<string, StoredSourceAssertion>>\n}\n\ninterface ReplacementIdentityInput {\n readonly sessionId: string\n readonly sourceId: string\n readonly candidateMaterializationId: string\n readonly previousMaterializationId: string | null\n readonly kind: \"object\" | \"link\"\n readonly pageRows: number\n}\n\ninterface ReplacementWorkRow {\n readonly entity_kind: \"object\" | \"link\"\n readonly identity_key: string\n readonly sort_key: string\n readonly diff_required: boolean\n}\n\nexport class PgMaterializationStateReader {\n constructor(\n private readonly sql: SQLClient,\n readonly projectId: string\n ) {}\n\n async objectState(ref: OntologyObjectRef): Promise<MaterializationObjectState> {\n const [state] = await this.objectStates([ref])\n return state!\n }\n\n async objectStates(\n refs: readonly OntologyObjectRef[]\n ): Promise<readonly MaterializationObjectState[]> {\n if (refs.length === 0) return []\n const requested = refs.map((ref) => ({\n object_type_id: ref.objectTypeId,\n primary_id: ref.primaryId,\n }))\n const requestedParameter = jsonParameter(this.sql, requested)\n const [effectiveRows, sourceRows, overrideRows, telemetryRows] = await Promise.all([\n this.sql<EffectiveObjectRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${requestedParameter})\n AS requested_values(object_type_id TEXT, primary_id TEXT)\n )\n SELECT objects.* FROM objects\n JOIN requested USING (object_type_id, primary_id)\n WHERE objects.project_id = ${this.projectId}\n `,\n this.sql<PgOntologySourceAssertionRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${requestedParameter})\n AS requested_values(object_type_id TEXT, primary_id TEXT)\n )\n SELECT rows.*\n FROM ontology_source_rows AS rows\n JOIN requested USING (object_type_id, primary_id)\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n WHERE rows.project_id = ${this.projectId}\n AND rows.entity_kind = 'object'\n AND sources.status = 'active'\n `,\n this.sql<ObjectOverrideRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${requestedParameter})\n AS requested_values(object_type_id TEXT, primary_id TEXT)\n )\n SELECT overrides.* FROM ontology_overrides AS overrides\n JOIN requested USING (object_type_id, primary_id)\n WHERE overrides.project_id = ${this.projectId}\n AND overrides.entity_kind = 'object'\n `,\n this.sql<TelemetryRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${requestedParameter})\n AS requested_values(object_type_id TEXT, primary_id TEXT)\n )\n SELECT latest.*\n FROM timeseries_latest AS latest\n JOIN requested\n ON requested.object_type_id = latest.object_type_id\n AND requested.primary_id = latest.object_id\n WHERE latest.project_id = ${this.projectId}\n `,\n ])\n\n const effective = new Map(\n effectiveRows.map((row) => [objectRefKey(objectRefFromColumns(row)), row] as const)\n )\n const sources = activeSourceMap(sourceRows)\n const overrides = new Map(\n overrideRows.map(\n (row) => [objectRefKey(objectRefFromColumns(row)), storedObjectOverride(row)] as const\n )\n )\n const telemetry = new Map<string, StoredTelemetryPoint[]>()\n for (const row of telemetryRows) {\n const key = objectRefKey({ objectTypeId: row.object_type_id, primaryId: row.object_id })\n const points = telemetry.get(key) ?? []\n points.push(storedPoint(row))\n telemetry.set(key, points)\n }\n for (const points of telemetry.values()) {\n points.sort((left, right) =>\n telemetryPointSortKey(left.series, left.at).localeCompare(\n telemetryPointSortKey(right.series, right.at)\n )\n )\n }\n\n return refs.map((ref) => {\n const key = objectRefKey(ref)\n const effectiveRow = effective.get(key)\n return {\n ref: structuredClone(ref),\n source: sourceObject(sources.get(projectionEntityKey({ kind: \"object\", ref }))),\n override: overrides.get(key) ?? null,\n effective: effectiveRow ? effectiveObjectSnapshot(effectiveRow) : null,\n latestTelemetry: telemetry.get(key) ?? [],\n }\n })\n }\n\n async linkState(ref: OntologyLinkRef): Promise<MaterializationLinkState> {\n const [state] = await this.linkStates([ref])\n return state!\n }\n\n async linkStates(refs: readonly OntologyLinkRef[]): Promise<readonly MaterializationLinkState[]> {\n if (refs.length === 0) return []\n const requested = refs.map((ref) => ({\n source_type_id: ref.source.objectTypeId,\n source_id: ref.source.primaryId,\n source_primary_id: ref.source.primaryId,\n link_id: ref.linkId,\n target_type_id: ref.target.objectTypeId,\n target_id: ref.target.primaryId,\n target_primary_id: ref.target.primaryId,\n }))\n const requestedParameter = jsonParameter(this.sql, requested)\n const [effectiveRows, sourceRows, overrideRows] = await Promise.all([\n this.sql<EffectiveLinkRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${requestedParameter}) AS requested_values(\n source_type_id TEXT, source_id TEXT, link_id TEXT,\n target_type_id TEXT, target_id TEXT\n )\n )\n SELECT links.* FROM links\n JOIN requested USING (source_type_id, source_id, link_id, target_type_id, target_id)\n WHERE links.project_id = ${this.projectId}\n `,\n this.sql<PgOntologySourceAssertionRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${requestedParameter}) AS requested_values(\n source_type_id TEXT, source_primary_id TEXT, link_id TEXT,\n target_type_id TEXT, target_primary_id TEXT\n )\n )\n SELECT rows.*\n FROM ontology_source_rows AS rows\n JOIN requested USING (\n source_type_id, source_primary_id, link_id, target_type_id, target_primary_id\n )\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n WHERE rows.project_id = ${this.projectId}\n AND rows.entity_kind = 'link'\n AND sources.status = 'active'\n `,\n this.sql<LinkOverrideRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${requestedParameter}) AS requested_values(\n source_type_id TEXT, source_primary_id TEXT, link_id TEXT,\n target_type_id TEXT, target_primary_id TEXT\n )\n )\n SELECT overrides.* FROM ontology_overrides AS overrides\n JOIN requested USING (\n source_type_id, source_primary_id, link_id, target_type_id, target_primary_id\n )\n WHERE overrides.project_id = ${this.projectId}\n AND overrides.entity_kind = 'link'\n `,\n ])\n const effective = new Map(\n effectiveRows.map((row) => [linkRefKey(linkRefFromColumns(row)), row] as const)\n )\n const sources = activeSourceMap(sourceRows)\n const overrides = new Map(\n overrideRows.map(\n (row) => [linkRefKey(linkRefFromOverrideColumns(row)), storedLinkOverride(row)] as const\n )\n )\n return refs.map((ref) => {\n const key = linkRefKey(ref)\n const effectiveRow = effective.get(key)\n return {\n ref: structuredClone(ref),\n source: sourceLink(sources.get(projectionEntityKey({ kind: \"link\", ref }))),\n override: overrides.get(key) ?? null,\n effective: effectiveRow ? effectiveLinkSnapshot(effectiveRow) : null,\n }\n })\n }\n\n async exactPoint(\n series: TelemetrySeriesRef,\n at: string,\n lock = false\n ): Promise<StoredTelemetryPoint | null> {\n return (await this.exactPoints([{ series, at }], lock))[0] ?? null\n }\n\n async exactPoints(\n points: readonly { readonly series: TelemetrySeriesRef; readonly at: string }[],\n lock = false\n ): Promise<readonly StoredTelemetryPoint[]> {\n if (points.length === 0) return []\n const requested = points.map(({ series, at }) => ({\n object_type_id: series.object.objectTypeId,\n object_id: series.object.primaryId,\n property_id: series.propertyId,\n at,\n }))\n const lockFragment = lock ? this.sql`FOR UPDATE OF timeseries` : this.sql``\n const rows = await this.sql<TelemetryRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${jsonParameter(this.sql, requested)}) AS requested_values(\n object_type_id TEXT, object_id TEXT, property_id TEXT, at TIMESTAMPTZ\n )\n )\n SELECT timeseries.* FROM timeseries\n JOIN requested USING (object_type_id, object_id, property_id, at)\n WHERE timeseries.project_id = ${this.projectId}\n ${lockFragment}\n `\n const found = new Map(\n rows.map((row) => {\n const point = storedPoint(row)\n return [telemetryPointKey(point.series, point.at), point] as const\n })\n )\n return points.flatMap((point) => {\n const stored = found.get(telemetryPointKey(point.series, point.at))\n return stored ? [stored] : []\n })\n }\n\n async linkScopes(\n scopes: readonly { readonly source: OntologyObjectRef; readonly linkId: string }[]\n ): Promise<readonly MaterializationLinkScopeState[]> {\n if (scopes.length === 0) return []\n const requested = scopes.map(({ source, linkId }) => ({\n scope_sort_key: linkScopeSortKey(source, linkId),\n source_type_id: source.objectTypeId,\n source_id: source.primaryId,\n link_id: linkId,\n }))\n const accumulators = new Map(\n scopes.map(({ source, linkId }) => {\n const key = linkScopeSortKey(source, linkId)\n return [key, startScopeAccumulator(source, linkId, key)] as const\n })\n )\n let scopeCursor: string | null = null\n let linkCursor: string | null = null\n while (true) {\n const rows: LinkScopeRow[] = await this.sql`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${jsonParameter(this.sql, requested)})\n AS requested_values(\n scope_sort_key TEXT, source_type_id TEXT, source_id TEXT, link_id TEXT\n )\n ), selected AS (\n SELECT requested.scope_sort_key, links.*,\n ${this.sql.unsafe(linkSortExpression(\"links\"))} AS link_sort_key\n FROM links\n JOIN requested USING (source_type_id, source_id, link_id)\n WHERE links.project_id = ${this.projectId}\n )\n SELECT * FROM selected\n WHERE (${scopeCursor}::text IS NULL OR (scope_sort_key, link_sort_key) >\n (${scopeCursor}, ${linkCursor}))\n ORDER BY scope_sort_key, link_sort_key\n LIMIT 500\n `\n for (const row of rows) {\n const accumulator = accumulators.get(row.scope_sort_key)\n if (!accumulator) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Unexpected link scope '${row.scope_sort_key}' returned by storage.`\n )\n }\n appendScopeSnapshot(accumulator, effectiveLinkSnapshot(row))\n }\n if (rows.length < 500) break\n const last: LinkScopeRow = rows[rows.length - 1]!\n scopeCursor = last.scope_sort_key\n linkCursor = last.link_sort_key\n }\n return scopes.map(({ source, linkId }) =>\n finishScopeAccumulator(accumulators.get(linkScopeSortKey(source, linkId))!)\n )\n }\n\n async linkScope(\n source: OntologyObjectRef,\n linkId: string\n ): Promise<MaterializationLinkScopeState> {\n const [scope] = await this.linkScopes([{ source, linkId }])\n if (!scope) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Link scope lookup returned no row.\"\n )\n }\n return scope\n }\n\n async *incidentLinks(\n objects: readonly OntologyObjectRef[],\n pageRows: number\n ): AsyncIterable<OntologyLinkRef[]> {\n if (objects.length === 0) return\n const requested = objects.map((ref) => ({\n object_type_id: ref.objectTypeId,\n primary_id: ref.primaryId,\n }))\n let cursor: string | null = null\n while (true) {\n const rows: LinkIdentityRow[] = await this.sql`\n WITH requested AS (\n SELECT DISTINCT *\n FROM jsonb_to_recordset(${jsonParameter(this.sql, requested)})\n AS requested_values(object_type_id TEXT, primary_id TEXT)\n ), authority_links AS (\n SELECT links.source_type_id, links.source_id, links.link_id,\n links.target_type_id, links.target_id\n FROM links\n JOIN requested\n ON requested.object_type_id = links.source_type_id\n AND requested.primary_id = links.source_id\n WHERE links.project_id = ${this.projectId}\n UNION\n SELECT links.source_type_id, links.source_id, links.link_id,\n links.target_type_id, links.target_id\n FROM links\n JOIN requested\n ON requested.object_type_id = links.target_type_id\n AND requested.primary_id = links.target_id\n WHERE links.project_id = ${this.projectId}\n UNION\n SELECT overrides.source_type_id, overrides.source_primary_id AS source_id,\n overrides.link_id, overrides.target_type_id,\n overrides.target_primary_id AS target_id\n FROM ontology_overrides AS overrides\n JOIN requested\n ON requested.object_type_id = overrides.source_type_id\n AND requested.primary_id = overrides.source_primary_id\n WHERE overrides.project_id = ${this.projectId} AND overrides.entity_kind = 'link'\n UNION\n SELECT overrides.source_type_id, overrides.source_primary_id AS source_id,\n overrides.link_id, overrides.target_type_id,\n overrides.target_primary_id AS target_id\n FROM ontology_overrides AS overrides\n JOIN requested\n ON requested.object_type_id = overrides.target_type_id\n AND requested.primary_id = overrides.target_primary_id\n WHERE overrides.project_id = ${this.projectId} AND overrides.entity_kind = 'link'\n UNION\n SELECT rows.source_type_id, rows.source_primary_id AS source_id,\n rows.link_id, rows.target_type_id, rows.target_primary_id AS target_id\n FROM ontology_source_rows AS rows\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n JOIN requested\n ON requested.object_type_id = rows.source_type_id\n AND requested.primary_id = rows.source_primary_id\n WHERE rows.project_id = ${this.projectId}\n AND rows.entity_kind = 'link'\n AND sources.status = 'active'\n UNION\n SELECT rows.source_type_id, rows.source_primary_id AS source_id,\n rows.link_id, rows.target_type_id, rows.target_primary_id AS target_id\n FROM ontology_source_rows AS rows\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n JOIN requested\n ON requested.object_type_id = rows.target_type_id\n AND requested.primary_id = rows.target_primary_id\n WHERE rows.project_id = ${this.projectId}\n AND rows.entity_kind = 'link'\n AND sources.status = 'active'\n ), selected AS (\n SELECT DISTINCT links.*,\n ${this.sql.unsafe(linkSortExpression(\"links\"))} AS sort_key\n FROM authority_links AS links\n )\n SELECT * FROM selected\n WHERE (${cursor}::text IS NULL OR sort_key > ${cursor})\n ORDER BY sort_key\n LIMIT ${pageRows}\n `\n if (rows.length === 0) break\n yield rows.map(linkRefFromColumns)\n cursor = rows[rows.length - 1]?.sort_key ?? null\n }\n }\n\n async *replacementIdentities(\n input: ReplacementIdentityInput\n ): AsyncIterable<ReplacementIdentity[]> {\n await this.prepareReplacementIdentities(input)\n let cursor: string | null = null\n while (true) {\n const rows: ReplacementWorkRow[] = await this.sql<ReplacementWorkRow[]>`\n SELECT entity_kind, identity_key, sort_key, diff_required\n FROM ${this.sql(PG_REPLACEMENT_WORK_TABLE)}\n WHERE session_id = ${input.sessionId} AND entity_kind = ${input.kind}\n AND (${cursor}::text IS NULL OR sort_key > ${cursor})\n ORDER BY sort_key\n LIMIT ${input.pageRows}\n `\n if (rows.length === 0) break\n yield rows.map(replacementIdentity)\n cursor = rows[rows.length - 1]?.sort_key ?? null\n }\n }\n\n async replacementObjectStates(\n sourceId: string,\n candidateMaterializationId: string,\n refs: readonly OntologyObjectRef[]\n ): Promise<readonly SourceReplacementObjectState[]> {\n const base = await this.objectStates(refs)\n const candidates = await this.replacementSources(\n sourceId,\n [candidateMaterializationId],\n refs.map((ref) => ({ kind: \"object\" as const, ref }))\n )\n return base.map((state) => ({\n ref: state.ref,\n candidateSource: sourceObject(\n candidates.byMaterialization\n .get(candidateMaterializationId)\n ?.get(projectionEntityKey({ kind: \"object\", ref: state.ref }))\n ),\n override: state.override,\n effective: state.effective,\n latestTelemetry: state.latestTelemetry,\n }))\n }\n\n async replacementLinkStates(\n sourceId: string,\n candidateMaterializationId: string,\n materializationIds: readonly string[],\n identities: readonly Extract<ReplacementIdentity, { readonly kind: \"link\" }>[]\n ): Promise<readonly SourceReplacementLinkState[]> {\n const refs = identities.map((identity) => identity.ref)\n const base = await this.linkStates(refs)\n const replacements = await this.replacementSources(\n sourceId,\n materializationIds,\n refs.map((ref) => ({ kind: \"link\" as const, ref }))\n )\n const candidate = replacements.byMaterialization.get(candidateMaterializationId)\n return base.map((state, index) => {\n const key = projectionEntityKey({ kind: \"link\", ref: state.ref })\n return {\n ref: state.ref,\n candidateSource: replacements.owned.has(key)\n ? sourceLink(candidate?.get(key))\n : state.source,\n override: state.override,\n effective: state.effective,\n diffRequired: identities[index]!.diffRequired,\n }\n })\n }\n\n async effectiveObjectRevision(\n ref: OntologyObjectRef,\n lock = false\n ): Promise<{ readonly version: number; readonly lastCommitId: string | null } | null> {\n return (await this.effectiveObjectRevisions([ref], lock)).get(objectRefKey(ref)) ?? null\n }\n\n async effectiveObjectRevisions(\n refs: readonly OntologyObjectRef[],\n lock = false\n ): Promise<\n ReadonlyMap<string, { readonly version: number; readonly lastCommitId: string | null }>\n > {\n if (refs.length === 0) return new Map()\n const requested = refs.map((ref) => ({\n object_type_id: ref.objectTypeId,\n primary_id: ref.primaryId,\n }))\n const lockFragment = lock ? this.sql`FOR UPDATE OF objects` : this.sql``\n const rows = await this.sql<\n {\n readonly object_type_id: string\n readonly primary_id: string\n readonly version: number\n readonly last_commit_id: string | null\n }[]\n >`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${jsonParameter(this.sql, requested)})\n AS requested_values(object_type_id TEXT, primary_id TEXT)\n )\n SELECT objects.object_type_id, objects.primary_id, objects.version,\n objects.last_commit_id\n FROM objects JOIN requested USING (object_type_id, primary_id)\n WHERE objects.project_id = ${this.projectId}\n ${lockFragment}\n `\n return new Map(\n rows.map(\n (row) =>\n [\n objectRefKey(objectRefFromColumns(row)),\n { version: row.version, lastCommitId: row.last_commit_id },\n ] as const\n )\n )\n }\n\n async effectiveLinkLastCommit(\n ref: OntologyLinkRef,\n lock = false\n ): Promise<string | null | undefined> {\n return (await this.effectiveLinkLastCommits([ref], lock)).get(linkRefKey(ref))\n }\n\n async effectiveLinkLastCommits(\n refs: readonly OntologyLinkRef[],\n lock = false\n ): Promise<ReadonlyMap<string, string | null>> {\n if (refs.length === 0) return new Map()\n const requested = refs.map((ref) => ({\n source_type_id: ref.source.objectTypeId,\n source_id: ref.source.primaryId,\n link_id: ref.linkId,\n target_type_id: ref.target.objectTypeId,\n target_id: ref.target.primaryId,\n }))\n const lockFragment = lock ? this.sql`FOR UPDATE OF links` : this.sql``\n const rows = await this.sql<EffectiveLinkRow[]>`\n WITH requested AS (\n SELECT DISTINCT * FROM jsonb_to_recordset(${jsonParameter(this.sql, requested)})\n AS requested_values(\n source_type_id TEXT, source_id TEXT, link_id TEXT,\n target_type_id TEXT, target_id TEXT\n )\n )\n SELECT links.* FROM links\n JOIN requested USING (source_type_id, source_id, link_id, target_type_id, target_id)\n WHERE links.project_id = ${this.projectId}\n ${lockFragment}\n `\n return new Map(\n rows.map((row) => [linkRefKey(linkRefFromColumns(row)), row.last_commit_id] as const)\n )\n }\n\n async overrideLastCommit(kind: \"object\" | \"link\", entityKey: string): Promise<string | null> {\n const [row] = await this.sql<{ readonly last_commit_id: string }[]>`\n SELECT last_commit_id FROM ontology_overrides\n WHERE project_id = ${this.projectId}\n AND entity_kind = ${kind}\n AND entity_key = ${jsonKeyParameter(this.sql, entityKey)}\n `\n return row?.last_commit_id ?? null\n }\n\n private async replacementSources(\n sourceId: string,\n materializationIds: readonly string[],\n refs: readonly ProjectionEntityRef[]\n ): Promise<ReplacementSources> {\n if (materializationIds.length === 0 || refs.length === 0) {\n return { owned: new Set(), byMaterialization: new Map() }\n }\n const keys = refs.map((ref) => ({\n entity_kind: ref.kind,\n entity_key: JSON.parse(projectionEntityKey(ref)) as unknown,\n }))\n const rows = await this.sql<PgOntologySourceAssertionRow[]>`\n WITH requested AS (\n SELECT *\n FROM jsonb_to_recordset(${jsonParameter(this.sql, keys)})\n AS requested_values(entity_kind TEXT, entity_key JSONB)\n )\n SELECT rows.* FROM ontology_source_rows AS rows\n JOIN requested USING (entity_kind, entity_key)\n WHERE rows.project_id = ${this.projectId}\n AND rows.source_id = ${sourceId}\n AND rows.materialization_id = ANY(\n ${this.sql.array([...new Set(materializationIds)])}::text[]\n )\n `\n const owned = new Set<string>()\n const byMaterialization = new Map<string, Map<string, StoredSourceAssertion>>()\n for (const row of rows) {\n const source = storedSource(row)\n const key = projectionEntityKey(source.assertion)\n owned.add(key)\n const materialization = byMaterialization.get(row.materialization_id) ?? new Map()\n materialization.set(key, source)\n byMaterialization.set(row.materialization_id, materialization)\n }\n return { owned, byMaterialization }\n }\n\n private async prepareReplacementIdentities(input: ReplacementIdentityInput): Promise<void> {\n if (input.kind === \"object\") {\n await this.prepareReplacementObjects(input)\n return\n }\n await this.prepareReplacementLinks(input)\n }\n\n private async prepareReplacementObjects(input: ReplacementIdentityInput): Promise<void> {\n const materializationIds = [\n input.candidateMaterializationId,\n ...(input.previousMaterializationId ? [input.previousMaterializationId] : []),\n ]\n await this.sql`\n WITH selected AS (\n SELECT DISTINCT object_type_id, primary_id,\n ${this.sql.unsafe(objectKeyExpression(\"rows\"))} AS identity_key,\n ${this.sql.unsafe(objectSortExpression(\"rows\"))} AS sort_key\n FROM ontology_source_rows AS rows\n WHERE project_id = ${this.projectId}\n AND source_id = ${input.sourceId}\n AND entity_kind = 'object'\n AND materialization_id = ANY(${this.sql.array(materializationIds)}::text[])\n )\n INSERT INTO ${this.sql(PG_REPLACEMENT_WORK_TABLE)} (\n session_id, entity_kind, identity_key, sort_key, diff_required\n )\n SELECT ${input.sessionId}, 'object', identity_key, sort_key, TRUE\n FROM selected\n ON CONFLICT (session_id, entity_kind, identity_key) DO UPDATE SET\n diff_required = ${this.sql(PG_REPLACEMENT_WORK_TABLE)}.diff_required\n OR EXCLUDED.diff_required\n `\n }\n\n private async prepareReplacementLinks(input: ReplacementIdentityInput): Promise<void> {\n const materializationIds = [\n input.candidateMaterializationId,\n ...(input.previousMaterializationId ? [input.previousMaterializationId] : []),\n ]\n await this.sql`\n WITH incident_objects AS (\n SELECT DISTINCT payload->'ref'->>'objectTypeId' AS object_type_id,\n payload->'ref'->>'primaryId' AS primary_id\n FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}\n WHERE session_id = ${input.sessionId} AND kind = 'incident-object'\n ), replacement_links AS (\n SELECT source_type_id, source_primary_id AS source_id, link_id,\n target_type_id, target_primary_id AS target_id\n FROM ontology_source_rows\n WHERE project_id = ${this.projectId}\n AND source_id = ${input.sourceId}\n AND entity_kind = 'link'\n AND materialization_id = ANY(${this.sql.array(materializationIds)}::text[])\n ), incident_links AS (\n SELECT links.source_type_id, links.source_id, links.link_id,\n links.target_type_id, links.target_id\n FROM links\n JOIN incident_objects\n ON incident_objects.object_type_id = links.source_type_id\n AND incident_objects.primary_id = links.source_id\n WHERE links.project_id = ${this.projectId}\n UNION\n SELECT links.source_type_id, links.source_id, links.link_id,\n links.target_type_id, links.target_id\n FROM links\n JOIN incident_objects\n ON incident_objects.object_type_id = links.target_type_id\n AND incident_objects.primary_id = links.target_id\n WHERE links.project_id = ${this.projectId}\n UNION\n SELECT overrides.source_type_id, overrides.source_primary_id AS source_id,\n overrides.link_id, overrides.target_type_id,\n overrides.target_primary_id AS target_id\n FROM ontology_overrides AS overrides\n JOIN incident_objects\n ON incident_objects.object_type_id = overrides.source_type_id\n AND incident_objects.primary_id = overrides.source_primary_id\n WHERE overrides.project_id = ${this.projectId} AND overrides.entity_kind = 'link'\n UNION\n SELECT overrides.source_type_id, overrides.source_primary_id AS source_id,\n overrides.link_id, overrides.target_type_id,\n overrides.target_primary_id AS target_id\n FROM ontology_overrides AS overrides\n JOIN incident_objects\n ON incident_objects.object_type_id = overrides.target_type_id\n AND incident_objects.primary_id = overrides.target_primary_id\n WHERE overrides.project_id = ${this.projectId} AND overrides.entity_kind = 'link'\n UNION\n SELECT rows.source_type_id, rows.source_primary_id AS source_id,\n rows.link_id, rows.target_type_id, rows.target_primary_id AS target_id\n FROM ontology_source_rows AS rows\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n JOIN incident_objects\n ON incident_objects.object_type_id = rows.source_type_id\n AND incident_objects.primary_id = rows.source_primary_id\n WHERE rows.project_id = ${this.projectId}\n AND rows.entity_kind = 'link'\n AND sources.status = 'active'\n UNION\n SELECT rows.source_type_id, rows.source_primary_id AS source_id,\n rows.link_id, rows.target_type_id, rows.target_primary_id AS target_id\n FROM ontology_source_rows AS rows\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n JOIN incident_objects\n ON incident_objects.object_type_id = rows.target_type_id\n AND incident_objects.primary_id = rows.target_primary_id\n WHERE rows.project_id = ${this.projectId}\n AND rows.entity_kind = 'link'\n AND sources.status = 'active'\n ), diff_links AS (\n SELECT * FROM replacement_links\n UNION SELECT * FROM incident_links\n ), affected_scopes AS (\n SELECT DISTINCT source_type_id, source_id, link_id FROM diff_links\n ), all_links AS (\n SELECT diff_links.*, TRUE AS diff_required FROM diff_links\n UNION ALL\n SELECT links.source_type_id, links.source_id, links.link_id,\n links.target_type_id, links.target_id, FALSE AS diff_required\n FROM links\n JOIN affected_scopes USING (source_type_id, source_id, link_id)\n WHERE links.project_id = ${this.projectId}\n ), selected AS (\n SELECT source_type_id, source_id, link_id, target_type_id, target_id,\n ${this.sql.unsafe(linkKeyExpression(\"all_links\"))} AS identity_key,\n ${this.sql.unsafe(linkSortExpression(\"all_links\"))} AS sort_key,\n BOOL_OR(diff_required) AS diff_required\n FROM all_links\n GROUP BY source_type_id, source_id, link_id, target_type_id, target_id\n )\n INSERT INTO ${this.sql(PG_REPLACEMENT_WORK_TABLE)} (\n session_id, entity_kind, identity_key, sort_key, diff_required\n )\n SELECT ${input.sessionId}, 'link', identity_key, sort_key, diff_required\n FROM selected\n ON CONFLICT (session_id, entity_kind, identity_key) DO UPDATE SET\n diff_required = ${this.sql(PG_REPLACEMENT_WORK_TABLE)}.diff_required\n OR EXCLUDED.diff_required\n `\n }\n}\n\nfunction replacementIdentity(row: ReplacementWorkRow): ReplacementIdentity {\n const parts = JSON.parse(row.identity_key) as string[]\n if (row.entity_kind === \"object\") {\n return {\n kind: \"object\",\n ref: { objectTypeId: parts[0]!, primaryId: parts[1]! },\n sortKey: row.sort_key,\n diffRequired: true,\n }\n }\n return {\n kind: \"link\",\n ref: {\n source: { objectTypeId: parts[0]!, primaryId: parts[1]! },\n linkId: parts[2]!,\n target: { objectTypeId: parts[3]!, primaryId: parts[4]! },\n },\n sortKey: row.sort_key,\n diffRequired: row.diff_required,\n }\n}\n\nfunction activeSourceMap(\n rows: readonly PgOntologySourceAssertionRow[]\n): ReadonlyMap<string, StoredSourceAssertion> {\n const result = new Map<string, StoredSourceAssertion>()\n for (const row of rows) {\n const source = storedSource(row)\n const key = projectionEntityKey(source.assertion)\n if (result.has(key)) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n `Multiple active sources assert ${key}.`\n )\n }\n result.set(key, source)\n }\n return result\n}\n\nfunction sourceObject(\n source: StoredSourceAssertion | undefined\n): StoredSourceObjectAssertion | null {\n return source?.assertion.kind === \"object\" ? (source as StoredSourceObjectAssertion) : null\n}\n\nfunction sourceLink(source: StoredSourceAssertion | undefined): StoredSourceLinkAssertion | null {\n return source?.assertion.kind === \"link\" ? (source as StoredSourceLinkAssertion) : null\n}\n\nfunction storedObjectOverride(row: ObjectOverrideRow): StoredObjectOverride {\n const ref = objectRefFromColumns(row)\n return {\n ref,\n value: structuredClone(row.value) as StoredObjectOverride[\"value\"],\n lastCommitId: row.last_commit_id,\n updatedAt: toIsoString(row.updated_at),\n }\n}\n\nfunction storedLinkOverride(row: LinkOverrideRow): StoredLinkOverride {\n const ref = linkRefFromOverrideColumns(row)\n return {\n ref,\n value: structuredClone(row.value) as StoredLinkOverride[\"value\"],\n lastCommitId: row.last_commit_id,\n updatedAt: toIsoString(row.updated_at),\n }\n}\n\nfunction linkRefFromOverrideColumns(row: LinkOverrideRow): OntologyLinkRef {\n return {\n source: { objectTypeId: row.source_type_id, primaryId: row.source_primary_id },\n linkId: row.link_id,\n target: { objectTypeId: row.target_type_id, primaryId: row.target_primary_id },\n }\n}\n\nfunction storedSource(row: PgOntologySourceAssertionRow): StoredSourceAssertion {\n return {\n source: { projectionId: row.source_id },\n materializationId: row.materialization_id,\n root: structuredClone(row.root) as StoredSourceAssertion[\"root\"],\n assertion: structuredClone(row.assertion) as StoredSourceAssertion[\"assertion\"],\n stagingOrdinal: databaseSafeInteger(row.staging_ordinal, \"Source staging ordinal\"),\n } as StoredSourceAssertion\n}\n\nfunction effectiveObjectSnapshot(row: EffectiveObjectRow): EffectiveObjectSnapshot {\n if (!row.last_commit_id) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Effective object ${row.object_type_id}:${row.primary_id} lacks materializer provenance.`\n )\n }\n return {\n ref: objectRefFromColumns(row),\n properties: structuredClone(row.properties) as EffectiveObjectSnapshot[\"properties\"],\n version: row.version,\n createdAt: toIsoString(row.created_at),\n updatedAt: toIsoString(row.updated_at),\n lastCommitId: row.last_commit_id,\n }\n}\n\nfunction effectiveLinkSnapshot(row: EffectiveLinkRow): EffectiveLinkSnapshot {\n if (!row.last_commit_id) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Effective link ${linkRefKey(linkRefFromColumns(row))} lacks materializer provenance.`\n )\n }\n return {\n ref: linkRefFromColumns(row),\n ...(row.properties === null\n ? {}\n : {\n properties: structuredClone(row.properties) as NonNullable<\n EffectiveLinkSnapshot[\"properties\"]\n >,\n }),\n createdAt: toIsoString(row.created_at),\n updatedAt: toIsoString(row.updated_at),\n lastCommitId: row.last_commit_id,\n }\n}\n\nfunction storedPoint(row: TelemetryRow): StoredTelemetryPoint {\n const at = toIsoString(row.at)\n if (!row.last_commit_id) {\n throw new MaterializationConflictError(\n \"timeseries-point\",\n `Telemetry point ${telemetryPointSortKey(\n {\n object: { objectTypeId: row.object_type_id, primaryId: row.object_id },\n propertyId: row.property_id,\n },\n at\n )} lacks materializer provenance.`\n )\n }\n return {\n series: {\n object: { objectTypeId: row.object_type_id, primaryId: row.object_id },\n propertyId: row.property_id,\n },\n value: structuredClone(row.value) as StoredTelemetryPoint[\"value\"],\n ...(row.unit === null ? {} : { unit: row.unit }),\n at,\n lastCommitId: row.last_commit_id,\n }\n}\n\nexport function objectSortExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return utf8SortExpression([\n `to_jsonb(${prefix}object_type_id)::text`,\n `to_jsonb(${prefix}primary_id)::text`,\n ])\n}\n\nfunction objectKeyExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return jsonTupleExpression([\n `to_jsonb(${prefix}object_type_id)::text`,\n `to_jsonb(${prefix}primary_id)::text`,\n ])\n}\n\nexport function linkSortExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return utf8SortExpression([\n `to_jsonb(${prefix}source_type_id)::text`,\n `to_jsonb(${prefix}source_id)::text`,\n `to_jsonb(${prefix}link_id)::text`,\n `to_jsonb(${prefix}target_type_id)::text`,\n `to_jsonb(${prefix}target_id)::text`,\n ])\n}\n\nfunction linkKeyExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return jsonTupleExpression([\n `to_jsonb(${prefix}source_type_id)::text`,\n `to_jsonb(${prefix}source_id)::text`,\n `to_jsonb(${prefix}link_id)::text`,\n `to_jsonb(${prefix}target_type_id)::text`,\n `to_jsonb(${prefix}target_id)::text`,\n ])\n}\n\nexport function pointSortExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return utf8SortExpression([\n `to_jsonb(${prefix}object_type_id)::text`,\n `to_jsonb(${prefix}object_id)::text`,\n `to_jsonb(${prefix}property_id)::text`,\n `to_jsonb(to_char(${prefix}at AT TIME ZONE 'UTC', 'YYYY-MM-DD\"T\"HH24:MI:SS.MS\"Z\"'))::text`,\n ])\n}\n\nfunction utf8SortExpression(parts: readonly string[]): string {\n return `encode(convert_to(${jsonTupleExpression(parts)}, 'UTF8'), 'hex')`\n}\n\nfunction jsonTupleExpression(parts: readonly string[]): string {\n return `concat('[', ${parts.join(\", ',', \")}, ']')`\n}\n",
33
+ "import {\n linkRefKey,\n MaterializationConflictError,\n objectRefKey,\n telemetryPointKey,\n} from \"@sixb/core/internal/materialization\"\nimport {\n effectiveConflict,\n type OverrideEntity,\n overrideEntityColumns as overrideColumns,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type { MaterializationPlanChunk } from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport { assertTimestamp, jsonParameter } from \"./shared\"\n\n/** Applies one already-validated exact plan chunk in bounded PostgreSQL batches. */\nexport class PgMaterializationWriter {\n constructor(private readonly sql: SQLClient) {}\n\n async apply(projectId: string, commitId: string, chunk: MaterializationPlanChunk): Promise<void> {\n await this.applyOverrides(projectId, chunk)\n await this.applyEffective(projectId, chunk)\n await this.applyTimeseries(projectId, chunk)\n await this.applyOutbox(projectId, commitId, chunk)\n }\n\n private async applyOverrides(projectId: string, chunk: MaterializationPlanChunk): Promise<void> {\n const upserts = [\n ...chunk.overrides.objectUpserts.map((item) =>\n overrideWrite({ kind: \"object\", ref: item.ref }, item)\n ),\n ...chunk.overrides.linkUpserts.map((item) =>\n overrideWrite({ kind: \"link\", ref: item.ref }, item)\n ),\n ]\n const inserts = upserts.filter((item) => item.expectedLastCommitId === null)\n if (inserts.length > 0) {\n const rows = await this.sql<{ readonly entity_kind: \"object\" | \"link\" }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, inserts)}::jsonb)\n )\n INSERT INTO ontology_overrides (\n project_id, entity_kind, entity_key, entity_sort_key,\n object_type_id, primary_id, source_type_id, source_primary_id,\n link_id, target_type_id, target_primary_id,\n value, last_commit_id, updated_at\n )\n SELECT ${projectId}, value->>'kind', value->'entityKey', value->>'sortKey',\n value->>'objectTypeId', value->>'primaryId', value->>'sourceTypeId',\n value->>'sourcePrimaryId', value->>'linkId', value->>'targetTypeId',\n value->>'targetPrimaryId', value->'value', value->>'lastCommitId',\n (value->>'updatedAt')::timestamptz\n FROM staged\n ON CONFLICT DO NOTHING\n RETURNING entity_kind\n `\n if (rows.length !== inserts.length) throw overrideConflict(inserts[0]!.kind)\n }\n\n const updates = upserts.filter((item) => item.expectedLastCommitId !== null)\n if (updates.length > 0) {\n const rows = await this.sql<{ readonly entity_kind: \"object\" | \"link\" }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, updates)}::jsonb)\n )\n UPDATE ontology_overrides AS overrides\n SET value = staged.value->'value', last_commit_id = staged.value->>'lastCommitId',\n updated_at = (staged.value->>'updatedAt')::timestamptz\n FROM staged\n WHERE overrides.project_id = ${projectId}\n AND overrides.entity_kind = staged.value->>'kind'\n AND overrides.entity_key = staged.value->'entityKey'\n AND overrides.last_commit_id = staged.value->>'expectedLastCommitId'\n RETURNING overrides.entity_kind\n `\n if (rows.length !== updates.length) throw overrideConflict(updates[0]!.kind)\n }\n\n const deletes = [\n ...chunk.overrides.objectDeletes.map((item) => ({\n kind: \"object\" as const,\n entityKey: JSON.parse(objectRefKey(item.ref)) as unknown,\n expectedLastCommitId: item.expectedLastCommitId,\n })),\n ...chunk.overrides.linkDeletes.map((item) => ({\n kind: \"link\" as const,\n entityKey: JSON.parse(linkRefKey(item.ref)) as unknown,\n expectedLastCommitId: item.expectedLastCommitId,\n })),\n ]\n if (deletes.length > 0) {\n const rows = await this.sql<{ readonly entity_kind: \"object\" | \"link\" }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, deletes)}::jsonb)\n )\n DELETE FROM ontology_overrides AS overrides USING staged\n WHERE overrides.project_id = ${projectId}\n AND overrides.entity_kind = staged.value->>'kind'\n AND overrides.entity_key = staged.value->'entityKey'\n AND overrides.last_commit_id = staged.value->>'expectedLastCommitId'\n RETURNING overrides.entity_kind\n `\n if (rows.length !== deletes.length) throw overrideConflict(deletes[0]!.kind)\n }\n }\n\n private async applyEffective(projectId: string, chunk: MaterializationPlanChunk): Promise<void> {\n const linkDeletes = chunk.effective.linkDeletes.map((item) => ({\n sourceTypeId: item.ref.source.objectTypeId,\n sourceId: item.ref.source.primaryId,\n linkId: item.ref.linkId,\n targetTypeId: item.ref.target.objectTypeId,\n targetId: item.ref.target.primaryId,\n expectedLastCommitId: item.expected.lastCommitId,\n }))\n if (linkDeletes.length > 0) {\n const rows = await this.sql<{ readonly source_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, linkDeletes)}::jsonb)\n )\n DELETE FROM links AS effective USING staged\n WHERE effective.project_id = ${projectId}\n AND effective.source_type_id = staged.value->>'sourceTypeId'\n AND effective.source_id = staged.value->>'sourceId'\n AND effective.link_id = staged.value->>'linkId'\n AND effective.target_type_id = staged.value->>'targetTypeId'\n AND effective.target_id = staged.value->>'targetId'\n AND effective.last_commit_id = staged.value->>'expectedLastCommitId'\n RETURNING effective.source_type_id\n `\n if (rows.length !== linkDeletes.length) throw effectiveLinkConflict(linkDeletes[0]!)\n }\n\n const objectDeletes = chunk.effective.objectDeletes.map((item) => ({\n objectTypeId: item.ref.objectTypeId,\n primaryId: item.ref.primaryId,\n expectedVersion: item.expected.version,\n expectedLastCommitId: item.expected.lastCommitId,\n }))\n if (objectDeletes.length > 0) {\n const rows = await this.sql<{ readonly object_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, objectDeletes)}::jsonb)\n )\n DELETE FROM objects AS effective USING staged\n WHERE effective.project_id = ${projectId}\n AND effective.object_type_id = staged.value->>'objectTypeId'\n AND effective.primary_id = staged.value->>'primaryId'\n AND effective.version = (staged.value->>'expectedVersion')::integer\n AND effective.last_commit_id = staged.value->>'expectedLastCommitId'\n RETURNING effective.object_type_id\n `\n if (rows.length !== objectDeletes.length) throw effectiveObjectConflict(objectDeletes[0]!)\n }\n\n await this.applyObjects(projectId, chunk.effective.objectUpserts)\n await this.applyLinks(projectId, chunk.effective.linkUpserts)\n }\n\n private async applyObjects(\n projectId: string,\n items: MaterializationPlanChunk[\"effective\"][\"objectUpserts\"]\n ): Promise<void> {\n const payload = items.map(({ row, expected }) => ({\n objectTypeId: row.ref.objectTypeId,\n primaryId: row.ref.primaryId,\n properties: row.properties,\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n version: row.version,\n lastCommitId: row.lastCommitId,\n expectedExists: expected.exists,\n expectedVersion: expected.exists ? expected.version : null,\n expectedLastCommitId: expected.exists ? expected.lastCommitId : null,\n }))\n const inserts = payload.filter((item) => !item.expectedExists)\n if (inserts.length > 0) {\n const rows = await this.sql<{ readonly object_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, inserts)}::jsonb)\n )\n INSERT INTO objects (\n project_id, object_type_id, primary_id, properties, created_at,\n updated_at, version, last_commit_id\n )\n SELECT ${projectId}, value->>'objectTypeId', value->>'primaryId',\n value->'properties', (value->>'createdAt')::timestamptz,\n (value->>'updatedAt')::timestamptz, (value->>'version')::integer,\n value->>'lastCommitId'\n FROM staged\n ON CONFLICT DO NOTHING\n RETURNING object_type_id\n `\n if (rows.length !== inserts.length) {\n throw effectiveConflict(`Expected object ${objectIdentityKey(inserts[0]!)} to be absent.`)\n }\n }\n\n const updates = payload.filter((item) => item.expectedExists)\n if (updates.length > 0) {\n const rows = await this.sql<{ readonly object_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, updates)}::jsonb)\n )\n UPDATE objects AS effective\n SET properties = staged.value->'properties',\n created_at = (staged.value->>'createdAt')::timestamptz,\n updated_at = (staged.value->>'updatedAt')::timestamptz,\n version = (staged.value->>'version')::integer,\n last_commit_id = staged.value->>'lastCommitId'\n FROM staged\n WHERE effective.project_id = ${projectId}\n AND effective.object_type_id = staged.value->>'objectTypeId'\n AND effective.primary_id = staged.value->>'primaryId'\n AND effective.version = (staged.value->>'expectedVersion')::integer\n AND effective.last_commit_id = staged.value->>'expectedLastCommitId'\n RETURNING effective.object_type_id\n `\n if (rows.length !== updates.length) throw effectiveObjectConflict(updates[0]!)\n }\n }\n\n private async applyLinks(\n projectId: string,\n items: MaterializationPlanChunk[\"effective\"][\"linkUpserts\"]\n ): Promise<void> {\n const payload = items.map(({ row, expected }) => ({\n sourceTypeId: row.ref.source.objectTypeId,\n sourceId: row.ref.source.primaryId,\n linkId: row.ref.linkId,\n targetTypeId: row.ref.target.objectTypeId,\n targetId: row.ref.target.primaryId,\n ...(row.properties === undefined ? {} : { properties: row.properties }),\n createdAt: row.createdAt,\n updatedAt: row.updatedAt,\n lastCommitId: row.lastCommitId,\n expectedExists: expected.exists,\n expectedLastCommitId: expected.exists ? expected.lastCommitId : null,\n }))\n const inserts = payload.filter((item) => !item.expectedExists)\n if (inserts.length > 0) {\n const rows = await this.sql<{ readonly source_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, inserts)}::jsonb)\n )\n INSERT INTO links (\n project_id, source_type_id, source_id, link_id, target_type_id, target_id,\n properties, created_at, updated_at, last_commit_id\n )\n SELECT ${projectId}, value->>'sourceTypeId', value->>'sourceId', value->>'linkId',\n value->>'targetTypeId', value->>'targetId',\n CASE WHEN value ? 'properties' THEN value->'properties' ELSE NULL END,\n (value->>'createdAt')::timestamptz, (value->>'updatedAt')::timestamptz,\n value->>'lastCommitId'\n FROM staged\n ON CONFLICT DO NOTHING\n RETURNING source_type_id\n `\n if (rows.length !== inserts.length) {\n throw effectiveConflict(`Expected link ${linkIdentityKey(inserts[0]!)} to be absent.`)\n }\n }\n\n const updates = payload.filter((item) => item.expectedExists)\n if (updates.length > 0) {\n const rows = await this.sql<{ readonly source_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, updates)}::jsonb)\n )\n UPDATE links AS effective\n SET properties = CASE\n WHEN staged.value ? 'properties' THEN staged.value->'properties'\n ELSE NULL\n END,\n created_at = (staged.value->>'createdAt')::timestamptz,\n updated_at = (staged.value->>'updatedAt')::timestamptz,\n last_commit_id = staged.value->>'lastCommitId'\n FROM staged\n WHERE effective.project_id = ${projectId}\n AND effective.source_type_id = staged.value->>'sourceTypeId'\n AND effective.source_id = staged.value->>'sourceId'\n AND effective.link_id = staged.value->>'linkId'\n AND effective.target_type_id = staged.value->>'targetTypeId'\n AND effective.target_id = staged.value->>'targetId'\n AND effective.last_commit_id = staged.value->>'expectedLastCommitId'\n RETURNING effective.source_type_id\n `\n if (rows.length !== updates.length) throw effectiveLinkConflict(updates[0]!)\n }\n }\n\n private async applyTimeseries(projectId: string, chunk: MaterializationPlanChunk): Promise<void> {\n const payload = chunk.timeseries.pointUpserts.map(({ point, expected }) => ({\n objectTypeId: point.series.object.objectTypeId,\n objectId: point.series.object.primaryId,\n propertyId: point.series.propertyId,\n value: point.value,\n unit: point.unit ?? null,\n at: point.at,\n lastCommitId: point.lastCommitId,\n expectedLastCommitId: expected.lastCommitId,\n }))\n const inserts = payload.filter((item) => item.expectedLastCommitId === null)\n if (inserts.length > 0) {\n const rows = await this.sql<{ readonly object_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, inserts)}::jsonb)\n ), written AS (\n INSERT INTO timeseries (\n project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n )\n SELECT ${projectId}, value->>'objectTypeId', value->>'objectId',\n value->>'propertyId', value->'value', value->>'unit',\n (value->>'at')::timestamptz, value->>'lastCommitId'\n FROM staged\n ON CONFLICT DO NOTHING\n RETURNING *\n ), latest_candidates AS (\n SELECT DISTINCT ON (project_id, object_type_id, object_id, property_id)\n project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n FROM written\n ORDER BY project_id, object_type_id, object_id, property_id, at DESC\n ), latest AS (\n INSERT INTO timeseries_latest (\n project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n )\n SELECT project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n FROM latest_candidates\n ON CONFLICT (project_id, object_type_id, object_id, property_id)\n DO UPDATE SET value = EXCLUDED.value, unit = EXCLUDED.unit, at = EXCLUDED.at,\n last_commit_id = EXCLUDED.last_commit_id\n WHERE EXCLUDED.at >= timeseries_latest.at\n RETURNING object_type_id\n )\n SELECT object_type_id, (SELECT COUNT(*) FROM latest) AS latest_count FROM written\n `\n if (rows.length !== inserts.length) throw pointConflict(inserts[0]!)\n }\n\n const updates = payload.filter((item) => item.expectedLastCommitId !== null)\n if (updates.length > 0) {\n const rows = await this.sql<{ readonly object_type_id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, updates)}::jsonb)\n ), written AS (\n UPDATE timeseries AS points\n SET value = staged.value->'value', unit = staged.value->>'unit',\n last_commit_id = staged.value->>'lastCommitId'\n FROM staged\n WHERE points.project_id = ${projectId}\n AND points.object_type_id = staged.value->>'objectTypeId'\n AND points.object_id = staged.value->>'objectId'\n AND points.property_id = staged.value->>'propertyId'\n AND points.at = (staged.value->>'at')::timestamptz\n AND points.last_commit_id = staged.value->>'expectedLastCommitId'\n RETURNING points.*\n ), latest_candidates AS (\n SELECT DISTINCT ON (project_id, object_type_id, object_id, property_id)\n project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n FROM written\n ORDER BY project_id, object_type_id, object_id, property_id, at DESC\n ), latest AS (\n INSERT INTO timeseries_latest (\n project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n )\n SELECT project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n FROM latest_candidates\n ON CONFLICT (project_id, object_type_id, object_id, property_id)\n DO UPDATE SET value = EXCLUDED.value, unit = EXCLUDED.unit, at = EXCLUDED.at,\n last_commit_id = EXCLUDED.last_commit_id\n WHERE EXCLUDED.at >= timeseries_latest.at\n RETURNING object_type_id\n )\n SELECT object_type_id, (SELECT COUNT(*) FROM latest) AS latest_count FROM written\n `\n if (rows.length !== updates.length) throw pointConflict(updates[0]!)\n }\n }\n\n private async applyOutbox(\n projectId: string,\n commitId: string,\n chunk: MaterializationPlanChunk\n ): Promise<void> {\n if (chunk.outbox.length === 0) return\n const payload = chunk.outbox.map((item) => {\n assertTimestamp(item.availableAt, \"Outbox availableAt\")\n assertTimestamp(item.createdAt, \"Outbox createdAt\")\n return {\n id: item.envelope.id,\n commitOrdinal: item.envelope.commitOrdinal,\n envelope: item.envelope,\n availableAt: item.availableAt,\n createdAt: item.createdAt,\n }\n })\n const rows = await this.sql<{ readonly id: string }[]>`\n WITH staged AS (\n SELECT value FROM jsonb_array_elements(${jsonParameter(this.sql, payload)}::jsonb)\n )\n INSERT INTO ontology_outbox (\n project_id, id, commit_id, commit_ordinal, envelope,\n available_at, attempts, lease_id, lease_expires_at,\n published_at, last_error, created_at\n )\n SELECT ${projectId}, value->>'id', ${commitId},\n (value->>'commitOrdinal')::bigint, value->'envelope',\n (value->>'availableAt')::timestamptz, 0, NULL, NULL, NULL, NULL,\n (value->>'createdAt')::timestamptz\n FROM staged\n ON CONFLICT DO NOTHING\n RETURNING id\n `\n if (rows.length !== payload.length) {\n const inserted = new Set(rows.map((row) => row.id))\n const duplicate = payload.find((item) => !inserted.has(item.id)) ?? payload[0]!\n throw effectiveConflict(`Duplicate outbox event '${duplicate.id}'.`)\n }\n }\n}\n\nfunction overrideWrite(\n entity: OverrideEntity,\n item: {\n readonly value: unknown\n readonly lastCommitId: string\n readonly updatedAt: string\n readonly expectedLastCommitId: string | null\n }\n) {\n const key = entity.kind === \"object\" ? objectRefKey(entity.ref) : linkRefKey(entity.ref)\n const columns = overrideColumns(entity)\n return {\n kind: entity.kind,\n entityKey: JSON.parse(key) as unknown,\n ...columns,\n value: item.value,\n lastCommitId: item.lastCommitId,\n updatedAt: item.updatedAt,\n expectedLastCommitId: item.expectedLastCommitId,\n }\n}\n\nfunction overrideConflict(kind: \"object\" | \"link\"): MaterializationConflictError {\n return effectiveConflict(`Expected ${kind} override changed.`)\n}\n\nfunction objectIdentityKey(item: {\n readonly objectTypeId: string\n readonly primaryId: string\n}): string {\n return objectRefKey({ objectTypeId: item.objectTypeId, primaryId: item.primaryId })\n}\n\nfunction linkIdentityKey(item: {\n readonly sourceTypeId: string\n readonly sourceId: string\n readonly linkId: string\n readonly targetTypeId: string\n readonly targetId: string\n}): string {\n return linkRefKey({\n source: { objectTypeId: item.sourceTypeId, primaryId: item.sourceId },\n linkId: item.linkId,\n target: { objectTypeId: item.targetTypeId, primaryId: item.targetId },\n })\n}\n\nfunction effectiveObjectConflict(item: {\n readonly objectTypeId: string\n readonly primaryId: string\n}): MaterializationConflictError {\n return effectiveConflict(`Expected object ${objectIdentityKey(item)} changed.`)\n}\n\nfunction effectiveLinkConflict(item: {\n readonly sourceTypeId: string\n readonly sourceId: string\n readonly linkId: string\n readonly targetTypeId: string\n readonly targetId: string\n}): MaterializationConflictError {\n return effectiveConflict(`Expected link ${linkIdentityKey(item)} changed.`)\n}\n\nfunction pointConflict(item: {\n readonly objectTypeId: string\n readonly objectId: string\n readonly propertyId: string\n readonly at: string\n}): MaterializationConflictError {\n return new MaterializationConflictError(\n \"timeseries-point\",\n `Telemetry point ${telemetryPointKey(\n {\n object: { objectTypeId: item.objectTypeId, primaryId: item.objectId },\n propertyId: item.propertyId,\n },\n item.at\n )} changed.`\n )\n}\n",
34
+ "import {\n MaterializationConflictError,\n MaterializationValidationError,\n} from \"@sixb/core/internal/materialization\"\nimport type {\n ClaimedOntologyOutboxRow,\n ClaimOntologyOutboxInput,\n CompleteOntologyOutboxLeaseInput,\n OntologyOutboxStorage,\n OntologyOutboxSummary,\n PurgePublishedOntologyOutboxInput,\n RescheduleOntologyOutboxLeaseInput,\n SummarizeOntologyOutboxInput,\n} from \"@sixb/core/storage\"\nimport {\n assertNonblank,\n assertPositiveInteger,\n assertTimestamp,\n outboxRecord,\n type PgOntologyOutboxRow,\n type PgRootOperation,\n} from \"./shared\"\n\nexport class PgOntologyOutboxStorage implements OntologyOutboxStorage {\n constructor(private readonly runRootOperation: PgRootOperation) {}\n\n async claim(input: ClaimOntologyOutboxInput): Promise<readonly ClaimedOntologyOutboxRow[]> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n assertPositiveInteger(input.limit, \"Ontology outbox limit\")\n const now = assertTimestamp(input.now, \"Ontology outbox claim time\")\n const leaseExpiry = assertTimestamp(input.leaseExpiresAt, \"Ontology outbox lease expiry\")\n assertNonblank(input.leaseId, \"Ontology outbox lease id\")\n if (leaseExpiry <= now) {\n throw new MaterializationValidationError(\n \"Ontology outbox lease expiry must be later than the claim time.\"\n )\n }\n\n const rows = await sql<PgOntologyOutboxRow[]>`\n WITH candidates AS (\n SELECT project_id, id\n FROM ontology_outbox\n WHERE project_id = ${input.projectId}\n AND published_at IS NULL\n AND available_at <= ${input.now}\n AND (lease_expires_at IS NULL OR lease_expires_at <= ${input.now})\n ORDER BY created_at, commit_id, commit_ordinal\n LIMIT ${input.limit}\n FOR UPDATE SKIP LOCKED\n ), claimed AS (\n UPDATE ontology_outbox AS outbox\n SET attempts = outbox.attempts + 1,\n lease_id = ${input.leaseId},\n lease_expires_at = ${input.leaseExpiresAt}\n FROM candidates\n WHERE outbox.project_id = candidates.project_id AND outbox.id = candidates.id\n RETURNING outbox.id AS row_id, outbox.envelope, outbox.available_at,\n outbox.attempts, outbox.lease_id, outbox.lease_expires_at,\n outbox.published_at, outbox.last_error, outbox.created_at,\n outbox.commit_id, outbox.commit_ordinal\n )\n SELECT * FROM claimed ORDER BY created_at, commit_id, commit_ordinal\n `\n return rows.map((row) => {\n const record = outboxRecord(row)\n if (record.leaseId === null || record.leaseExpiresAt === null) {\n throw new MaterializationConflictError(\n \"outbox-lease\",\n \"Ontology outbox claim returned an unpaired lease.\"\n )\n }\n return { ...record, leaseId: record.leaseId, leaseExpiresAt: record.leaseExpiresAt }\n })\n })\n }\n\n async markPublished(input: CompleteOntologyOutboxLeaseInput): Promise<void> {\n await this.runRootOperation(async (sql) => {\n assertLeaseInput(input)\n assertTimestamp(input.publishedAt, \"Ontology outbox publishedAt\")\n const ids = validateLeaseIds(input.ids)\n if (ids.length === 0) return\n const rows = await sql<{ readonly id: string }[]>`\n WITH leased AS MATERIALIZED (\n SELECT id FROM ontology_outbox\n WHERE project_id = ${input.projectId}\n AND id = ANY(${sql.array(ids)}::text[])\n AND lease_id = ${input.leaseId}\n AND lease_expires_at IS NOT NULL\n FOR UPDATE\n ), eligible AS (\n SELECT id FROM leased\n WHERE (SELECT COUNT(*) FROM leased) = ${ids.length}\n )\n UPDATE ontology_outbox AS outbox\n SET published_at = ${input.publishedAt}, lease_id = NULL, lease_expires_at = NULL\n FROM eligible\n WHERE outbox.project_id = ${input.projectId} AND outbox.id = eligible.id\n RETURNING outbox.id\n `\n if (rows.length !== ids.length) throw leaseConflict()\n })\n }\n\n async reschedule(input: RescheduleOntologyOutboxLeaseInput): Promise<void> {\n await this.runRootOperation(async (sql) => {\n assertLeaseInput(input)\n assertTimestamp(input.availableAt, \"Ontology outbox availableAt\")\n const ids = validateLeaseIds(input.ids)\n if (ids.length === 0) return\n const rows = await sql<{ readonly id: string }[]>`\n WITH leased AS MATERIALIZED (\n SELECT id FROM ontology_outbox\n WHERE project_id = ${input.projectId}\n AND id = ANY(${sql.array(ids)}::text[])\n AND lease_id = ${input.leaseId}\n AND lease_expires_at IS NOT NULL\n FOR UPDATE\n ), eligible AS (\n SELECT id FROM leased\n WHERE (SELECT COUNT(*) FROM leased) = ${ids.length}\n )\n UPDATE ontology_outbox AS outbox\n SET available_at = ${input.availableAt}, last_error = ${input.error},\n lease_id = NULL, lease_expires_at = NULL\n FROM eligible\n WHERE outbox.project_id = ${input.projectId} AND outbox.id = eligible.id\n RETURNING outbox.id\n `\n if (rows.length !== ids.length) throw leaseConflict()\n })\n }\n\n async purgePublished(input: PurgePublishedOntologyOutboxInput): Promise<number> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n assertPositiveInteger(input.limit, \"Ontology outbox limit\")\n assertTimestamp(input.publishedBefore, \"Ontology outbox purge cutoff\")\n const rows = await sql<{ readonly id: string }[]>`\n WITH selected AS (\n SELECT project_id, id\n FROM ontology_outbox\n WHERE project_id = ${input.projectId}\n AND published_at IS NOT NULL\n AND published_at < ${input.publishedBefore}\n ORDER BY published_at, id\n LIMIT ${input.limit}\n FOR UPDATE SKIP LOCKED\n )\n DELETE FROM ontology_outbox AS outbox\n USING selected\n WHERE outbox.project_id = selected.project_id AND outbox.id = selected.id\n RETURNING outbox.id\n `\n return rows.length\n })\n }\n\n async summarize(input: SummarizeOntologyOutboxInput): Promise<OntologyOutboxSummary> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n const [summary] = await sql<\n {\n readonly pending_count: number\n readonly oldest_pending_at: Date | string | null\n readonly retrying_count: number\n readonly max_attempts: number\n }[]\n >`\n SELECT COUNT(*)::int AS pending_count,\n MIN(created_at) AS oldest_pending_at,\n COUNT(*) FILTER (WHERE attempts > 0)::int AS retrying_count,\n COALESCE(MAX(attempts), 0)::int AS max_attempts\n FROM ontology_outbox\n WHERE project_id = ${input.projectId} AND published_at IS NULL\n `\n return {\n pendingCount: summary?.pending_count ?? 0,\n oldestPendingAt: toOptionalIsoString(summary?.oldest_pending_at),\n retryingCount: summary?.retrying_count ?? 0,\n maxAttempts: summary?.max_attempts ?? 0,\n }\n })\n }\n}\n\nfunction toOptionalIsoString(value: Date | string | null | undefined): string | null {\n if (value === null || value === undefined) return null\n return value instanceof Date ? value.toISOString() : new Date(value).toISOString()\n}\n\nfunction validateLeaseIds(ids: readonly string[]): string[] {\n const seen = new Set<string>()\n for (const id of ids) {\n assertNonblank(id, \"Ontology outbox event id\")\n if (seen.has(id)) {\n throw new MaterializationValidationError(`Ontology outbox lease batch repeats event '${id}'.`)\n }\n seen.add(id)\n }\n return [...seen]\n}\n\nfunction assertLeaseInput(input: {\n readonly projectId: string\n readonly ids: readonly string[]\n readonly leaseId: string\n}): void {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n assertNonblank(input.leaseId, \"Ontology outbox lease id\")\n}\n\nfunction leaseConflict(): MaterializationConflictError {\n return new MaterializationConflictError(\"outbox-lease\", \"Ontology outbox lease does not match.\")\n}\n",
35
+ "import { MaterializationValidationError } from \"@sixb/core/internal/materialization\"\nimport {\n assertSourceBeginInput as assertBeginInput,\n assertSourceExecutionIdentity as assertExecutionIdentity,\n assertSourceProject as assertProjectAndSource,\n assertSourceCandidateOwner,\n assertSourceWriteIdentity as assertWriteIdentity,\n sourceEntityColumns as entityColumns,\n isExactStagingManifest,\n reconcileSourceStageRows,\n type SourceStageRow,\n sourceConflict,\n sourceMaterializationIdentity,\n sourceStageRow,\n sourceStageRows,\n utf8SortKey,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n AbandonSourceMaterializationCandidateInput,\n AbandonSourceMaterializationInput,\n AssertSourceMaterializationExecutionInput,\n BeginSourceMaterializationInput,\n CleanupTerminalSourceMaterializationsInput,\n CleanupTerminalSourceMaterializationsResult,\n GetActiveOntologySourceInput,\n MarkSourceMaterializationReadyInput,\n OntologySourceRecord,\n OntologySourceStorage,\n ReclaimSourceMaterializationInput,\n StageSourceRowsInput,\n StageSourceRowsResult,\n SummarizeTerminalSourceMaterializationsInput,\n TerminalSourceMaterializationSummary,\n} from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport { lockAdvisoryKeys } from \"../transactions\"\nimport {\n assertNonblank,\n assertNonnegativeInteger,\n assertPositiveInteger,\n assertProjectionExecution,\n assertTimestamp,\n jsonParameter,\n ontologyLockKey,\n type PgOntologySourceAssertionRow,\n type PgOntologySourceRow,\n type PgRootOperation,\n sourceAssertion,\n sourceRecord,\n toIsoString,\n} from \"./shared\"\n\nexport class PgOntologySourceStorage implements OntologySourceStorage {\n constructor(private readonly runRootOperation: PgRootOperation) {}\n\n async beginMaterialization(\n input: BeginSourceMaterializationInput\n ): Promise<OntologySourceRecord> {\n return this.runRootOperation(async (sql) => {\n assertBeginInput(input)\n await this.assertExecution(sql, input, sourceMaterializationIdentity(input))\n await lockAdvisoryKeys(sql, [\n ontologyLockKey(\"source-candidate\", input.projectId, input.execution.projectionRunId),\n ontologyLockKey(\n \"source-materialization\",\n input.projectId,\n input.source.projectionId,\n input.materializationId\n ),\n ])\n\n const existing = await this.getManifest(\n sql,\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n true\n )\n if (existing) {\n if (isExactStagingManifest(sourceRecord(existing), input)) return sourceRecord(existing)\n throw sourceConflict(\n `Source materialization '${input.materializationId}' already exists with different identity or state.`\n )\n }\n\n const candidate = await this.getRunCandidate(sql, input)\n if (candidate) {\n throw sourceConflict(\n `Projection run '${input.execution.projectionRunId}' already has a nonterminal source materialization; reclaim it before beginning another.`\n )\n }\n\n const rows = await sql<PgOntologySourceRow[]>`\n INSERT INTO ontology_sources (\n project_id, source_id, materialization_id, projection_run_id,\n projection_kind, protocol, status, execution_token,\n dataset_id, dataset_version_id, dataset_version_created_at,\n projection_revision, ownership_hash, ontology_revision,\n root_count, assertion_count, created_at, ready_at, activated_at,\n terminal_at, last_commit_id, updated_at\n ) VALUES (\n ${input.projectId}, ${input.source.projectionId}, ${input.materializationId},\n ${input.execution.projectionRunId}, ${input.projectionKind}, 'replacement',\n 'staging', ${input.execution.executionToken}, ${input.datasetVersion.datasetId},\n ${input.datasetVersion.versionId}, ${input.datasetVersion.createdAt},\n ${input.projectionRevision}, ${input.ownershipHash}, ${input.ontologyRevision},\n NULL, NULL, ${input.createdAt}, NULL, NULL, NULL, NULL, ${input.createdAt}\n )\n ON CONFLICT DO NOTHING\n RETURNING *\n `\n if (rows[0]) return sourceRecord(rows[0])\n\n const racedManifest = await this.getManifest(\n sql,\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n true\n )\n if (racedManifest && isExactStagingManifest(sourceRecord(racedManifest), input)) {\n return sourceRecord(racedManifest)\n }\n if (await this.getRunCandidate(sql, input)) {\n throw sourceConflict(\n `Projection run '${input.execution.projectionRunId}' already has a nonterminal source materialization; reclaim it before beginning another.`\n )\n }\n throw sourceConflict(\n `Source materialization '${input.materializationId}' already exists with different identity or state.`\n )\n })\n }\n\n async stageRows(input: StageSourceRowsInput): Promise<StageSourceRowsResult> {\n return this.runRootOperation(async (sql) => {\n assertWriteIdentity(input)\n await this.assertExecution(sql, input)\n const manifest = await this.requireManifest(\n sql,\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n true\n )\n assertSourceCandidateOwner(sourceRecord(manifest), input.execution)\n if (manifest.status !== \"staging\") {\n throw sourceConflict(\n `Source materialization '${input.materializationId}' is '${manifest.status}' and cannot accept rows.`\n )\n }\n\n const rows = sourceStageRows(manifest.projection_kind, input.rows)\n const existing = await this.findStageRows(sql, input, rows)\n const { pending, unchanged } = reconcileSourceStageRows(rows, existing)\n await this.insertStageRows(sql, input, pending)\n return { inserted: pending.length, unchanged }\n })\n }\n\n async markReady(input: MarkSourceMaterializationReadyInput): Promise<OntologySourceRecord> {\n return this.runRootOperation(async (sql) => {\n assertWriteIdentity(input)\n assertTimestamp(input.readyAt, \"Source readyAt\", true)\n assertNonnegativeInteger(input.rootCount, \"Source root count\")\n assertNonnegativeInteger(input.assertionCount, \"Source assertion count\")\n await this.assertExecution(sql, input)\n const manifest = await this.requireManifest(\n sql,\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n true\n )\n assertSourceCandidateOwner(sourceRecord(manifest), input.execution)\n if (manifest.status === \"ready\") {\n if (\n numberOrNull(manifest.root_count) === input.rootCount &&\n numberOrNull(manifest.assertion_count) === input.assertionCount &&\n toIsoString(manifest.ready_at!) === input.readyAt\n ) {\n return sourceRecord(manifest)\n }\n throw sourceConflict(\n `Source materialization '${input.materializationId}' was marked ready with different counts or time.`\n )\n }\n if (manifest.status !== \"staging\") {\n throw sourceConflict(\n `Source materialization '${input.materializationId}' cannot transition from '${manifest.status}' to 'ready'.`\n )\n }\n if (input.readyAt < toIsoString(manifest.created_at)) {\n throw new MaterializationValidationError(\"Source readyAt cannot precede source createdAt.\")\n }\n await this.assertReadyState(sql, manifest, input.rootCount, input.assertionCount)\n const rows = await sql<PgOntologySourceRow[]>`\n UPDATE ontology_sources\n SET status = 'ready', root_count = ${input.rootCount},\n assertion_count = ${input.assertionCount}, ready_at = ${input.readyAt},\n updated_at = ${input.readyAt}\n WHERE project_id = ${input.projectId}\n AND source_id = ${input.source.projectionId}\n AND materialization_id = ${input.materializationId}\n AND status = 'staging'\n AND execution_token = ${input.execution.executionToken}\n RETURNING *\n `\n if (!rows[0]) {\n throw sourceConflict(`Source materialization '${input.materializationId}' changed.`)\n }\n return sourceRecord(rows[0])\n })\n }\n\n async getActive(input: GetActiveOntologySourceInput): Promise<OntologySourceRecord | null> {\n return this.runRootOperation(async (sql) => {\n assertProjectAndSource(input)\n const [row] = await sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${input.projectId}\n AND source_id = ${input.source.projectionId}\n AND status = 'active'\n `\n return row ? sourceRecord(row) : null\n })\n }\n\n async abandon(input: AbandonSourceMaterializationCandidateInput): Promise<OntologySourceRecord>\n async abandon(input: ReclaimSourceMaterializationInput): Promise<OntologySourceRecord | null>\n async abandon(input: AbandonSourceMaterializationInput): Promise<OntologySourceRecord | null> {\n return this.runRootOperation(async (sql) => {\n assertProjectAndSource(input)\n assertExecutionIdentity(input.execution.projectionRunId, input.execution.executionToken)\n assertTimestamp(input.abandonedAt, \"Source abandonedAt\", true)\n await this.assertExecution(sql, input)\n return input.kind === \"candidate\"\n ? this.abandonCandidate(sql, input)\n : this.abandonForReclaim(sql, input)\n })\n }\n\n async cleanupTerminal(\n input: CleanupTerminalSourceMaterializationsInput\n ): Promise<CleanupTerminalSourceMaterializationsResult> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Terminal source cleanup project id\")\n assertTimestamp(input.terminalBefore, \"Terminal source cleanup cutoff\", true)\n assertPositiveInteger(input.limit, \"Terminal source cleanup limit\")\n const manifests = await sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${input.projectId}\n AND status IN ('superseded', 'abandoned')\n AND terminal_at < ${input.terminalBefore}\n ORDER BY terminal_at, source_id, materialization_id\n LIMIT ${input.limit}\n FOR UPDATE SKIP LOCKED\n `\n let remaining = input.limit\n let rowsDeleted = 0\n let materializationsDeleted = 0\n for (const manifest of manifests) {\n if (remaining === 0) break\n const deletedRows = await sql<{ readonly entity_sort_key: string }[]>`\n WITH selected AS (\n SELECT rows.ctid\n FROM ontology_source_rows AS rows\n WHERE rows.project_id = ${manifest.project_id}\n AND rows.source_id = ${manifest.source_id}\n AND rows.materialization_id = ${manifest.materialization_id}\n ORDER BY rows.entity_sort_key\n LIMIT ${remaining}\n FOR UPDATE SKIP LOCKED\n )\n DELETE FROM ontology_source_rows AS rows\n USING selected\n WHERE rows.ctid = selected.ctid\n RETURNING rows.entity_sort_key\n `\n rowsDeleted += deletedRows.length\n remaining -= deletedRows.length\n if (remaining === 0) break\n const removed = await sql<{ readonly materialization_id: string }[]>`\n DELETE FROM ontology_sources AS sources\n WHERE sources.project_id = ${manifest.project_id}\n AND sources.source_id = ${manifest.source_id}\n AND sources.materialization_id = ${manifest.materialization_id}\n AND sources.status IN ('superseded', 'abandoned')\n AND sources.terminal_at = ${manifest.terminal_at}\n AND sources.terminal_at < ${input.terminalBefore}\n AND NOT EXISTS (\n SELECT 1 FROM ontology_source_rows AS rows\n WHERE rows.project_id = sources.project_id\n AND rows.source_id = sources.source_id\n AND rows.materialization_id = sources.materialization_id\n )\n RETURNING sources.materialization_id\n `\n materializationsDeleted += removed.length\n remaining -= removed.length\n }\n return { rowsDeleted, materializationsDeleted }\n })\n }\n\n async summarizeTerminal(\n input: SummarizeTerminalSourceMaterializationsInput\n ): Promise<TerminalSourceMaterializationSummary> {\n return this.runRootOperation(async (sql) => {\n assertNonblank(input.projectId, \"Terminal source summary project id\")\n const [summary] = await sql<\n {\n readonly terminal_count: number\n readonly oldest_terminal_at: Date | string | null\n }[]\n >`\n SELECT COUNT(*)::int AS terminal_count, MIN(terminal_at) AS oldest_terminal_at\n FROM ontology_sources\n WHERE project_id = ${input.projectId}\n AND status IN ('superseded', 'abandoned')\n `\n return {\n count: summary?.terminal_count ?? 0,\n oldestTerminalAt: toOptionalIsoString(summary?.oldest_terminal_at),\n }\n })\n }\n\n private async abandonCandidate(\n sql: SQLClient,\n input: AbandonSourceMaterializationCandidateInput\n ): Promise<OntologySourceRecord> {\n const manifest = await this.requireManifest(\n sql,\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n true\n )\n if (manifest.status === \"abandoned\") {\n if (\n manifest.projection_run_id === input.execution.projectionRunId &&\n manifest.terminal_at !== null &&\n toIsoString(manifest.terminal_at) === input.abandonedAt\n ) {\n return sourceRecord(manifest)\n }\n throw sourceConflict(\n `Source materialization '${input.materializationId}' was abandoned by another execution or at another time.`\n )\n }\n assertSourceCandidateOwner(sourceRecord(manifest), input.execution)\n return this.transitionToAbandoned(sql, manifest, input.abandonedAt)\n }\n\n private async abandonForReclaim(\n sql: SQLClient,\n input: ReclaimSourceMaterializationInput\n ): Promise<OntologySourceRecord | null> {\n const candidates = await sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${input.projectId}\n AND source_id = ${input.source.projectionId}\n AND projection_run_id = ${input.execution.projectionRunId}\n AND status IN ('staging', 'ready')\n FOR UPDATE\n `\n if (\n candidates.some((candidate) => candidate.execution_token === input.execution.executionToken)\n ) {\n throw sourceConflict(\n `Projection run '${input.execution.projectionRunId}' already has a source materialization owned by the current execution.`\n )\n }\n if (candidates.length > 1) {\n throw sourceConflict(\n `Projection run '${input.execution.projectionRunId}' has multiple nonterminal source materializations.`\n )\n }\n return candidates[0] ? this.transitionToAbandoned(sql, candidates[0], input.abandonedAt) : null\n }\n\n private async transitionToAbandoned(\n sql: SQLClient,\n manifest: PgOntologySourceRow,\n abandonedAt: string\n ): Promise<OntologySourceRecord> {\n if (\n abandonedAt < toIsoString(manifest.created_at) ||\n (manifest.ready_at !== null && abandonedAt < toIsoString(manifest.ready_at))\n ) {\n throw new MaterializationValidationError(\n \"Source abandonedAt cannot precede source creation or readiness.\"\n )\n }\n const rows = await sql<PgOntologySourceRow[]>`\n UPDATE ontology_sources\n SET status = 'abandoned', execution_token = NULL,\n terminal_at = ${abandonedAt}, updated_at = ${abandonedAt}\n WHERE project_id = ${manifest.project_id}\n AND source_id = ${manifest.source_id}\n AND materialization_id = ${manifest.materialization_id}\n AND status IN ('staging', 'ready')\n RETURNING *\n `\n if (!rows[0]) {\n throw sourceConflict(\n `Source materialization '${manifest.materialization_id}' cannot transition to 'abandoned'.`\n )\n }\n return sourceRecord(rows[0])\n }\n\n private async assertReadyState(\n sql: SQLClient,\n manifest: PgOntologySourceRow,\n rootCount: number,\n assertionCount: number\n ): Promise<void> {\n const [counts] = await sql<\n {\n readonly assertions: number | string\n readonly roots: number | string\n readonly ordinals: number | string\n readonly min_ordinal: number | string | null\n readonly max_ordinal: number | string | null\n }[]\n >`\n SELECT COUNT(*) AS assertions, COUNT(DISTINCT root_key) AS roots,\n COUNT(DISTINCT staging_ordinal) AS ordinals,\n MIN(staging_ordinal) AS min_ordinal, MAX(staging_ordinal) AS max_ordinal\n FROM ontology_source_rows\n WHERE project_id = ${manifest.project_id}\n AND source_id = ${manifest.source_id}\n AND materialization_id = ${manifest.materialization_id}\n `\n const assertions = Number(counts?.assertions ?? 0)\n const roots = Number(counts?.roots ?? 0)\n const ordinals = Number(counts?.ordinals ?? 0)\n const minimum = counts?.min_ordinal === null ? null : Number(counts?.min_ordinal)\n const maximum = counts?.max_ordinal === null ? null : Number(counts?.max_ordinal)\n if (\n assertions !== assertionCount ||\n roots !== rootCount ||\n ordinals !== rootCount ||\n (rootCount > 0 && (minimum !== 0 || maximum !== rootCount - 1))\n ) {\n throw new MaterializationValidationError(\n \"Source ready counts do not match the staged roots and assertions.\"\n )\n }\n\n const [invalid] =\n manifest.projection_kind === \"link\"\n ? await sql<{ readonly root_key: unknown }[]>`\n SELECT root_key\n FROM ontology_source_rows\n WHERE project_id = ${manifest.project_id}\n AND source_id = ${manifest.source_id}\n AND materialization_id = ${manifest.materialization_id}\n GROUP BY root_key\n HAVING COUNT(*) <> 1\n OR BOOL_OR(root_kind <> 'link')\n OR BOOL_OR(entity_kind <> 'link')\n OR BOOL_OR(root_key <> entity_key)\n LIMIT 1\n `\n : await sql<{ readonly root_key: unknown }[]>`\n SELECT root_key\n FROM ontology_source_rows\n WHERE project_id = ${manifest.project_id}\n AND source_id = ${manifest.source_id}\n AND materialization_id = ${manifest.materialization_id}\n GROUP BY root_key\n HAVING BOOL_OR(root_kind <> 'object')\n OR COUNT(*) FILTER (\n WHERE entity_kind = 'object' AND entity_key = root_key\n ) <> 1\n OR COUNT(*) FILTER (\n WHERE (entity_kind = 'object' AND entity_key <> root_key)\n OR (entity_kind = 'link' AND (\n source_type_id <> root_object_type_id\n OR source_primary_id <> root_primary_id\n ))\n ) <> 0\n LIMIT 1\n `\n if (invalid) {\n throw new MaterializationValidationError(\n manifest.projection_kind === \"link\"\n ? \"Link projection roots must contain exactly their matching link assertion.\"\n : \"Object projection roots must contain exactly their matching object assertion plus links sourced from that root.\"\n )\n }\n }\n\n private async findStageRows(\n sql: SQLClient,\n input: StageSourceRowsInput,\n rows: readonly SourceStageRow[]\n ): Promise<readonly SourceStageRow[]> {\n if (rows.length === 0) return []\n const rootSortKeys = [...new Set(rows.map((row) => utf8SortKey(row.rootKey)))]\n const ordinals = [...new Set(rows.map((row) => row.row.stagingOrdinal))]\n const entitySortKeys = [...new Set(rows.map((row) => utf8SortKey(row.entityKey)))]\n const existing = await sql<PgOntologySourceAssertionRow[]>`\n SELECT * FROM ontology_source_rows\n WHERE project_id = ${input.projectId}\n AND source_id = ${input.source.projectionId}\n AND materialization_id = ${input.materializationId}\n AND (\n root_sort_key = ANY(${sql.array(rootSortKeys)}::text[])\n OR staging_ordinal = ANY(${sql.array(ordinals)}::bigint[])\n OR entity_sort_key = ANY(${sql.array(entitySortKeys)}::text[])\n )\n `\n return existing.map((row) => sourceStageRow(sourceAssertion(row)))\n }\n\n private async insertStageRows(\n sql: SQLClient,\n input: StageSourceRowsInput,\n rows: readonly SourceStageRow[]\n ): Promise<void> {\n if (rows.length === 0) return\n const payload = rows.map(({ entityKey, rootKey, row }) => {\n const entity = entityColumns(row.assertion)\n const root = entityColumns(row.root)\n return {\n entityKind: row.assertion.kind,\n entityKey: JSON.parse(entityKey) as unknown,\n entitySortKey: utf8SortKey(entityKey),\n rootKind: row.root.kind,\n rootKey: JSON.parse(rootKey) as unknown,\n rootSortKey: utf8SortKey(rootKey),\n stagingOrdinal: row.stagingOrdinal,\n root: row.root,\n assertion: row.assertion,\n objectTypeId: entity.objectTypeId,\n primaryId: entity.primaryId,\n sourceTypeId: entity.sourceTypeId,\n sourcePrimaryId: entity.sourcePrimaryId,\n linkId: entity.linkId,\n targetTypeId: entity.targetTypeId,\n targetPrimaryId: entity.targetPrimaryId,\n rootObjectTypeId: root.objectTypeId,\n rootPrimaryId: root.primaryId,\n rootSourceTypeId: root.sourceTypeId,\n rootSourcePrimaryId: root.sourcePrimaryId,\n rootLinkId: root.linkId,\n rootTargetTypeId: root.targetTypeId,\n rootTargetPrimaryId: root.targetPrimaryId,\n }\n })\n await sql`\n WITH staged AS (\n SELECT value\n FROM jsonb_array_elements(${jsonParameter(sql, payload)}::jsonb)\n )\n INSERT INTO ontology_source_rows (\n project_id, source_id, materialization_id,\n entity_kind, entity_key, entity_sort_key,\n root_kind, root_key, root_sort_key, staging_ordinal,\n root, assertion,\n object_type_id, primary_id,\n source_type_id, source_primary_id, link_id, target_type_id, target_primary_id,\n root_object_type_id, root_primary_id,\n root_source_type_id, root_source_primary_id, root_link_id,\n root_target_type_id, root_target_primary_id\n )\n SELECT\n ${input.projectId}, ${input.source.projectionId}, ${input.materializationId},\n value->>'entityKind', value->'entityKey', value->>'entitySortKey',\n value->>'rootKind', value->'rootKey', value->>'rootSortKey',\n (value->>'stagingOrdinal')::bigint,\n value->'root', value->'assertion',\n value->>'objectTypeId', value->>'primaryId',\n value->>'sourceTypeId', value->>'sourcePrimaryId', value->>'linkId',\n value->>'targetTypeId', value->>'targetPrimaryId',\n value->>'rootObjectTypeId', value->>'rootPrimaryId',\n value->>'rootSourceTypeId', value->>'rootSourcePrimaryId', value->>'rootLinkId',\n value->>'rootTargetTypeId', value->>'rootTargetPrimaryId'\n FROM staged\n `\n }\n\n private assertExecution(\n sql: SQLClient,\n input: {\n readonly projectId: string\n readonly source: { readonly projectionId: string }\n readonly execution: { readonly projectionRunId: string; readonly executionToken: string }\n },\n identity?: AssertSourceMaterializationExecutionInput[\"identity\"]\n ): Promise<void> {\n return assertProjectionExecution(sql, {\n projectId: input.projectId,\n sourceId: input.source.projectionId,\n projectionRunId: input.execution.projectionRunId,\n executionToken: input.execution.executionToken,\n ...(identity ? { identity } : {}),\n })\n }\n\n private async getRunCandidate(\n sql: SQLClient,\n input: BeginSourceMaterializationInput\n ): Promise<PgOntologySourceRow | null> {\n const [row] = await sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${input.projectId}\n AND projection_run_id = ${input.execution.projectionRunId}\n AND status IN ('staging', 'ready')\n LIMIT 1\n FOR UPDATE\n `\n return row ?? null\n }\n\n private async getManifest(\n sql: SQLClient,\n projectId: string,\n sourceId: string,\n materializationId: string,\n lock = false\n ): Promise<PgOntologySourceRow | null> {\n const lockFragment = lock ? sql`FOR UPDATE` : sql``\n const [row] = await sql<PgOntologySourceRow[]>`\n SELECT * FROM ontology_sources\n WHERE project_id = ${projectId}\n AND source_id = ${sourceId}\n AND materialization_id = ${materializationId}\n ${lockFragment}\n `\n return row ?? null\n }\n\n private async requireManifest(\n sql: SQLClient,\n projectId: string,\n sourceId: string,\n materializationId: string,\n lock = false\n ): Promise<PgOntologySourceRow> {\n const row = await this.getManifest(sql, projectId, sourceId, materializationId, lock)\n if (!row) throw sourceConflict(`Source materialization '${materializationId}' does not exist.`)\n return row\n }\n}\n\nfunction toOptionalIsoString(value: Date | string | null | undefined): string | null {\n if (value === null || value === undefined) return null\n return value instanceof Date ? value.toISOString() : new Date(value).toISOString()\n}\n\nfunction numberOrNull(value: number | string | null): number | null {\n return value === null ? null : Number(value)\n}\n",
36
+ "import type { OntologyStorage } from \"@sixb/core/storage\"\nimport type { SQLClient } from \"../pg-client\"\nimport { PgOntologyCommitStorage } from \"./commits\"\nimport type { PgOntologyTransactionContext } from \"./materialization-session\"\nimport { PgOntologyMaterializationStorage } from \"./materializations\"\nimport { PgOntologyOutboxStorage } from \"./outbox\"\nimport type { PgRootOperation } from \"./shared\"\nimport { PgOntologySourceStorage } from \"./sources\"\n\nexport class PgOntologyStorage implements OntologyStorage {\n readonly commits: PgOntologyCommitStorage\n readonly sources: PgOntologySourceStorage\n readonly materializations: PgOntologyMaterializationStorage\n readonly outbox: PgOntologyOutboxStorage\n\n constructor(input: {\n readonly sql: SQLClient\n readonly runRootOperation: PgRootOperation\n readonly transactionContext: PgOntologyTransactionContext | null\n }) {\n this.commits = new PgOntologyCommitStorage(input.runRootOperation)\n this.sources = new PgOntologySourceStorage(input.runRootOperation)\n this.materializations = new PgOntologyMaterializationStorage(\n input.sql,\n input.transactionContext\n )\n this.outbox = new PgOntologyOutboxStorage(input.runRootOperation)\n }\n\n deactivateSessions(): void {\n this.materializations.deactivateSessions()\n }\n}\n\nexport type { PgOntologyTransactionContext } from \"./materialization-session\"\n",
37
+ "import type { ActionSubject, JsonValue } from \"@sixb/core\"\nimport type {\n ActionRunEffectsRecord,\n ActionRunFailure,\n ActionRunParams,\n ActionRunPhase,\n ActionRunRecord,\n ActionRunStorage,\n ActionRunWritebackRecord,\n EnterActionRunPhaseInput,\n FinishActionRunInput,\n ListActionRunsInput,\n ListActionRunsResult,\n LockActionMaterializationRunInput,\n QueueActionRunInput,\n RecordActionEffectsInput,\n RecordActionWritebackInput,\n StartActionRunInput,\n} from \"@sixb/core/storage\"\nimport {\n ActionRunError,\n actionRunPhaseRecordsEqual,\n canRequeueActionRunAfterEnqueueFailure,\n finishActionRunPhase,\n isTerminalActionRun,\n} from \"@sixb/core/storage\"\nimport type { SQLClient, SqlParameter } from \"./pg-client\"\nimport { isUniqueViolation } from \"./storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgActionRunStorage implements ActionRunStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async lockForMaterialization(input: LockActionMaterializationRunInput): Promise<ActionRunRecord> {\n const [row] = await this.sql<DatabaseRow[]>`\n SELECT *\n FROM action_runs\n WHERE project_id = ${input.projectId} AND id = ${input.runId}\n FOR UPDATE\n `\n if (!row) {\n throw new ActionRunError(\n `[SixbPg] Action run '${input.runId}' not found for project '${input.projectId}'.`\n )\n }\n if (row.action_id !== input.actionId) {\n throw new ActionRunError(\n `[SixbPg] Action run '${input.runId}' does not belong to action '${input.actionId}'.`\n )\n }\n if (row.status !== \"running\") {\n throw new ActionRunError(\n `[SixbPg] Action run '${input.runId}' cannot materialize from status '${row.status}'.`\n )\n }\n return rowToActionRunRecord(row)\n }\n\n async queue(input: QueueActionRunInput): Promise<ActionRunRecord> {\n try {\n const [row] = await this.sql<DatabaseRow[]>`\n INSERT INTO action_runs (\n project_id,\n id,\n action_id,\n subject_kind,\n object_type_id,\n primary_id,\n status,\n phase,\n queued_at,\n started_at,\n finished_at,\n params,\n idempotency_key,\n writeback_status,\n writeback_completed_at,\n writeback_result,\n writeback_error_name,\n writeback_error_message,\n writeback_error_phase,\n effects_status,\n effects_completed_at,\n effects_error_name,\n effects_error_message,\n effects_error_phase,\n error_name,\n error_message,\n error_phase\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.actionId},\n ${input.subject.kind},\n ${input.subject.kind === \"object\" ? input.subject.objectTypeId : null},\n ${input.subject.kind === \"object\" ? input.subject.primaryId : null},\n ${\"queued\"},\n ${\"request\"},\n ${input.queuedAt ?? new Date()},\n ${null},\n ${null},\n ${JSON.stringify(input.params)}::text::jsonb,\n ${input.idempotencyKey},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null},\n ${null}\n )\n RETURNING *\n `\n\n return rowToActionRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n return this.requeueAfterEnqueueFailure(input)\n }\n\n throw error\n }\n }\n\n private async requeueAfterEnqueueFailure(input: QueueActionRunInput): Promise<ActionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<DatabaseRow[]>`\n SELECT * FROM action_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (\n !existing ||\n !canRequeueActionRunAfterEnqueueFailure(rowToActionRunRecord(existing), input)\n ) {\n throw new ActionRunError(\n `[SixbPg] Action run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE action_runs\n SET\n status = ${\"queued\"},\n phase = ${\"request\"},\n queued_at = ${input.queuedAt ?? new Date()},\n started_at = ${null},\n finished_at = ${null},\n writeback_status = ${null},\n writeback_completed_at = ${null},\n writeback_result = ${null},\n writeback_error_name = ${null},\n writeback_error_message = ${null},\n writeback_error_phase = ${null},\n effects_status = ${null},\n effects_completed_at = ${null},\n effects_error_name = ${null},\n effects_error_message = ${null},\n effects_error_phase = ${null},\n error_name = ${null},\n error_message = ${null},\n error_phase = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToActionRunRecord(updated)\n })\n }\n\n async start(input: StartActionRunInput): Promise<ActionRunRecord> {\n const [updated] = await this.sql<DatabaseRow[]>`\n UPDATE action_runs\n SET\n status = ${\"running\"},\n phase = ${input.phase ?? \"validation\"},\n started_at = ${input.startedAt ?? new Date()},\n error_name = ${null},\n error_message = ${null},\n error_phase = ${null}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n AND status = ${\"queued\"}\n RETURNING *\n `\n\n if (updated) {\n return rowToActionRunRecord(updated)\n }\n\n const existing = await this.getById({ projectId: input.projectId, id: input.id })\n if (!existing) {\n throw new ActionRunError(\n `[SixbPg] Action run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n throw new ActionRunError(\n `[SixbPg] Action run '${input.id}' cannot start from status '${existing.status}'.`\n )\n }\n\n async enterPhase(input: EnterActionRunPhaseInput): Promise<ActionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await this.requireRunningRun(tx, input.projectId, input.id, \"transition phase\")\n\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE action_runs\n SET phase = ${input.phase}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToActionRunRecord(updated)\n })\n }\n\n async recordWriteback(input: RecordActionWritebackInput): Promise<ActionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existing = await this.requireRunningRun(\n tx,\n input.projectId,\n input.id,\n \"record writeback\"\n )\n const nextWriteback = toWritebackRecord(input, new Date(input.completedAt ?? new Date()))\n const currentWriteback = toActionRunWritebackRecord(existing)\n\n if (currentWriteback) {\n if (actionRunPhaseRecordsEqual(currentWriteback, nextWriteback)) {\n return rowToActionRunRecord(existing)\n }\n\n throw new ActionRunError(\n `[SixbPg] Action run '${input.id}' already has a different writeback record.`\n )\n }\n\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE action_runs\n SET\n phase = ${\"writeback\"},\n writeback_status = ${input.status},\n writeback_completed_at = ${nextWriteback.completedAt},\n writeback_result = ${input.status === \"succeeded\" ? JSON.stringify(input.result) : null}::text::jsonb,\n writeback_error_name = ${input.status === \"failed\" ? (input.error.name ?? null) : null},\n writeback_error_message = ${input.status === \"failed\" ? input.error.message : null},\n writeback_error_phase = ${input.status === \"failed\" ? (input.error.phase ?? \"writeback\") : null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToActionRunRecord(updated)\n })\n }\n\n async recordEffects(input: RecordActionEffectsInput): Promise<ActionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existing = await this.requireRunningRun(tx, input.projectId, input.id, \"record effects\")\n const nextEffects = toEffectsRecord(input, new Date(input.completedAt ?? new Date()))\n const currentEffects = toActionRunEffectsRecord(existing)\n\n if (currentEffects) {\n if (actionRunPhaseRecordsEqual(currentEffects, nextEffects)) {\n return rowToActionRunRecord(existing)\n }\n\n throw new ActionRunError(\n `[SixbPg] Action run '${input.id}' already has a different effects record.`\n )\n }\n\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE action_runs\n SET\n phase = ${\"effects\"},\n effects_status = ${input.status},\n effects_completed_at = ${nextEffects.completedAt},\n effects_error_name = ${input.status === \"failed\" ? (input.error.name ?? null) : null},\n effects_error_message = ${input.status === \"failed\" ? input.error.message : null},\n effects_error_phase = ${input.status === \"failed\" ? (input.error.phase ?? \"effects\") : null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToActionRunRecord(updated)\n })\n }\n\n async finish(input: FinishActionRunInput): Promise<ActionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<DatabaseRow[]>`\n SELECT * FROM action_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new ActionRunError(\n `[SixbPg] Action run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (isTerminalActionRun({ status: existing.status })) {\n throw new ActionRunError(\n `[SixbPg] Action run '${input.id}' cannot finish from terminal status '${existing.status}'.`\n )\n }\n\n const phase = finishActionRunPhase(input, existing.phase)\n\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE action_runs\n SET\n status = ${input.status},\n phase = ${phase},\n finished_at = ${input.finishedAt ?? new Date()},\n error_name = ${input.status === \"succeeded\" ? null : (input.error?.name ?? null)},\n error_message = ${input.status === \"succeeded\" ? null : (input.error?.message ?? null)},\n error_phase = ${input.status === \"succeeded\" ? null : (input.error?.phase ?? phase)}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToActionRunRecord(updated)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<ActionRunRecord | null> {\n const [row] = await this.sql<DatabaseRow[]>`\n SELECT * FROM action_runs\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToActionRunRecord(row) : null\n }\n\n async list(input: ListActionRunsInput): Promise<ListActionRunsResult> {\n if ((input.statuses && input.statuses.length === 0) || input.actionIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.actionId) {\n whereClauses.push(`action_id = $${index++}`)\n params.push(input.actionId)\n }\n\n if (input.actionIds) {\n const placeholders = input.actionIds.map(() => `$${index++}`)\n whereClauses.push(`action_id IN (${placeholders.join(\", \")})`)\n params.push(...input.actionIds)\n }\n\n if (input.objectTypeIds) {\n if (input.objectTypeIds.length === 0) {\n whereClauses.push(`subject_kind <> $${index++}`)\n params.push(\"object\")\n } else {\n const subjectKindIndex = index++\n const placeholders = input.objectTypeIds.map(() => `$${index++}`)\n whereClauses.push(\n `(subject_kind <> $${subjectKindIndex} OR object_type_id IN (${placeholders.join(\", \")}))`\n )\n params.push(\"object\", ...input.objectTypeIds)\n }\n }\n\n if (input.objectTypeId) {\n whereClauses.push(`subject_kind = $${index++}`)\n params.push(\"object\")\n whereClauses.push(`object_type_id = $${index++}`)\n params.push(input.objectTypeId)\n }\n\n if (input.primaryId) {\n whereClauses.push(`subject_kind = $${index++}`)\n params.push(\"object\")\n whereClauses.push(`primary_id = $${index++}`)\n params.push(input.primaryId)\n }\n\n if (input.subject) {\n whereClauses.push(`subject_kind = $${index++}`)\n params.push(input.subject.kind)\n if (input.subject.kind === \"object\") {\n whereClauses.push(`object_type_id = $${index++}`)\n params.push(input.subject.objectTypeId)\n whereClauses.push(`primary_id = $${index++}`)\n params.push(input.subject.primaryId)\n }\n }\n\n if (input.statuses) {\n const placeholders = input.statuses.map(() => `$${index++}`)\n whereClauses.push(`status IN (${placeholders.join(\", \")})`)\n params.push(...input.statuses)\n }\n\n if (input.startedAfter) {\n whereClauses.push(`COALESCE(started_at, queued_at) >= $${index++}`)\n params.push(input.startedAfter)\n }\n\n if (input.startedBefore) {\n whereClauses.push(`COALESCE(started_at, queued_at) <= $${index++}`)\n params.push(input.startedBefore)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n\n const [totalRow] = await this.sql.unsafe<{ count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM action_runs ${where}`,\n params\n )\n\n const queryParams = [...params]\n let query = `\n SELECT * FROM action_runs\n ${where}\n ORDER BY COALESCE(started_at, queued_at) ${order}, id ${order}\n `\n\n if (input.limit !== undefined) {\n query += ` LIMIT $${index++} OFFSET $${index++}`\n queryParams.push(input.limit, offset)\n } else if (offset > 0) {\n query += ` OFFSET $${index++}`\n queryParams.push(offset)\n }\n\n const rows = await this.sql.unsafe<DatabaseRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n const runs = rows.map((row) => rowToActionRunRecord(row))\n\n return {\n runs,\n hasMore: offset + runs.length < total,\n total,\n }\n }\n\n private async requireRunningRun(\n runner: SQLClient,\n projectId: string,\n id: string,\n operation: string\n ): Promise<DatabaseRow> {\n const [existing] = await runner<DatabaseRow[]>`\n SELECT * FROM action_runs\n WHERE project_id = ${projectId} AND id = ${id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new ActionRunError(`[SixbPg] Action run '${id}' not found for project '${projectId}'.`)\n }\n\n if (existing.status !== \"running\") {\n throw new ActionRunError(\n `[SixbPg] Action run '${id}' cannot ${operation} from status '${existing.status}'.`\n )\n }\n\n return existing\n }\n}\n\nfunction toActionRunFailure(row: DatabaseRow): ActionRunFailure | undefined {\n return toFailure(row.error_name, row.error_message, row.error_phase)\n}\n\nfunction toFailure(\n name: string | null,\n message: string | null,\n phase: ActionRunPhase | null\n): ActionRunFailure | undefined {\n if (!message) {\n return undefined\n }\n\n return {\n name: name ?? undefined,\n message,\n phase: phase ?? undefined,\n }\n}\n\nfunction toActionRunWritebackRecord(row: DatabaseRow): ActionRunWritebackRecord | undefined {\n if (!row.writeback_status) {\n return undefined\n }\n\n const completedAt = row.writeback_completed_at\n ? new Date(row.writeback_completed_at)\n : new Date(row.queued_at)\n\n if (row.writeback_status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n result: (row.writeback_result ?? null) as JsonValue,\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: toFailure(\n row.writeback_error_name,\n row.writeback_error_message,\n row.writeback_error_phase\n ),\n }\n}\n\nfunction toActionRunEffectsRecord(row: DatabaseRow): ActionRunEffectsRecord | undefined {\n if (!row.effects_status) {\n return undefined\n }\n\n const completedAt = row.effects_completed_at\n ? new Date(row.effects_completed_at)\n : new Date(row.queued_at)\n\n if (row.effects_status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: toFailure(row.effects_error_name, row.effects_error_message, row.effects_error_phase),\n }\n}\n\nfunction toWritebackRecord(\n input: RecordActionWritebackInput,\n completedAt: Date\n): ActionRunWritebackRecord {\n if (input.status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n result: input.result,\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: input.error,\n }\n}\n\nfunction toEffectsRecord(\n input: RecordActionEffectsInput,\n completedAt: Date\n): ActionRunEffectsRecord {\n if (input.status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: input.error,\n }\n}\n\nfunction rowToActionRunRecord(row: DatabaseRow): ActionRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n actionId: row.action_id,\n subject: rowToActionSubject(row),\n status: row.status,\n phase: row.phase ?? undefined,\n queuedAt: new Date(row.queued_at),\n startedAt: row.started_at ? new Date(row.started_at) : undefined,\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n params: row.params,\n idempotencyKey: row.idempotency_key,\n writeback: toActionRunWritebackRecord(row),\n effects: toActionRunEffectsRecord(row),\n error: toActionRunFailure(row),\n }\n}\n\nfunction rowToActionSubject(row: DatabaseRow): ActionSubject {\n if (row.subject_kind === \"none\") {\n return { kind: \"none\" }\n }\n\n if (!row.object_type_id || !row.primary_id) {\n throw new ActionRunError(`[SixbPg] Action run '${row.id}' has an invalid object subject.`)\n }\n\n return {\n kind: \"object\",\n objectTypeId: row.object_type_id,\n primaryId: row.primary_id,\n }\n}\n\ninterface DatabaseRow {\n project_id: string\n id: string\n action_id: string\n subject_kind: ActionSubject[\"kind\"]\n object_type_id: string | null\n primary_id: string | null\n status: ActionRunRecord[\"status\"]\n phase: ActionRunPhase | null\n queued_at: Date | string\n started_at: Date | string | null\n finished_at: Date | string | null\n params: ActionRunParams\n idempotency_key: string\n writeback_status: ActionRunWritebackRecord[\"status\"] | null\n writeback_completed_at: Date | string | null\n writeback_result: JsonValue | null\n writeback_error_name: string | null\n writeback_error_message: string | null\n writeback_error_phase: ActionRunPhase | null\n effects_status: ActionRunEffectsRecord[\"status\"] | null\n effects_completed_at: Date | string | null\n effects_error_name: string | null\n effects_error_message: string | null\n effects_error_phase: ActionRunPhase | null\n error_name: string | null\n error_message: string | null\n error_phase: ActionRunPhase | null\n}\n",
38
+ "import postgres from \"postgres\"\n\n// Data-type policy (porsager defaults, deliberately not overridden):\n// - `timestamptz` -> JS `Date`. Row mappers normalize via `toIsoString(Date | string)`.\n// - `bigint` -> string (porsager avoids `Number` precision loss). The only bigint values\n// read here are `COUNT(*)` results, which fit safely in `Number`, so callers use\n// `Number(...)`. We do NOT register `postgres.BigInt` — it would break those `Number()`\n// conversions and JSON serialization.\n// - `numeric`/`decimal` -> string. The schema has no such columns; revisit if one is added.\n// - `jsonb` -> parsed JS value (objects/arrays/scalars), same as before.\n\n/**\n * Connection handle backing every Postgres storage adapter.\n *\n * This is the porsager `postgres` pool — not Bun's built-in SQL. bun:sql's pool orphaned\n * connections under request bursts (a query whose client disconnected mid-flight left its\n * connection checked out but never returned), so the pool drained to zero usable slots and\n * the whole API hung until a restart. porsager's pool reclaims connections reliably, which\n * is the actual fix for that wedge.\n *\n * Queries declare their row type per call (`` sql<RowType[]>`...` ``) rather than via an open\n * generic, so results are typed without `as` casts.\n */\nexport type SQL = postgres.Sql<Record<string, never>>\n\n/**\n * A query runner that may be the pool or an open transaction. Adapters that run the same\n * statement on either should accept this rather than {@link SQL} (only the pool exposes\n * `begin`/`reserve`/`end`).\n */\nexport type SQLClient = postgres.ISql<Record<string, never>>\n\n/**\n * A value accepted as a positional parameter by {@link SQLClient.unsafe}. Dynamically built\n * parameter arrays (from the query-IR compiler / run-list helpers) are cast to this since\n * their element types can't be inferred statically.\n */\nexport type SqlParameter = postgres.ParameterOrJSON<never>\n\nexport interface CreatePgClientOptions {\n readonly connectionString?: string\n readonly host?: string\n readonly port?: number\n readonly database?: string\n readonly user?: string\n readonly password?: string\n /** Maximum pooled connections. */\n readonly max: number\n /** Schema pinned via `search_path` on every connection. */\n readonly schemaName: string\n /** Close idle connections after this many ms (frees slots back to the server). Default 30s. */\n readonly idleTimeoutMillis?: number\n /** Per-connection `statement_timeout` (ms). Unset = no timeout. */\n readonly statementTimeoutMillis?: number\n /** Per-connection `idle_in_transaction_session_timeout` (ms). Unset = no timeout. */\n readonly idleInTransactionSessionTimeoutMillis?: number\n /** Seconds to wait when establishing a connection. Default 10. */\n readonly connectTimeoutMillis?: number\n /**\n * Whether porsager creates server-side prepared statements (its default; faster against a\n * direct Postgres connection). Keep `true` for a direct connection. Behind a transaction-mode\n * pooler, prepared statements are supported by PgBouncer >= 1.21 (Oct 2023) when\n * `max_prepared_statements > 0`; set `false` only for an older PgBouncer or when that setting\n * is 0. (The blanket incompatibility in porsager#93 predates PgBouncer 1.21.)\n */\n readonly prepare?: boolean\n readonly ssl?: boolean | \"require\" | \"prefer\"\n}\n\nconst DEFAULT_IDLE_TIMEOUT_SECONDS = 30\nconst DEFAULT_CONNECT_TIMEOUT_SECONDS = 10\n\n/** Build a configured porsager `postgres` pool. */\nexport function createPgClient(options: CreatePgClientOptions): SQL {\n // GUCs applied to every connection at startup.\n const connection: Record<string, string | number | boolean> = {\n search_path: options.schemaName,\n }\n if (options.statementTimeoutMillis !== undefined) {\n connection.statement_timeout = options.statementTimeoutMillis\n }\n if (options.idleInTransactionSessionTimeoutMillis !== undefined) {\n connection.idle_in_transaction_session_timeout = options.idleInTransactionSessionTimeoutMillis\n }\n\n const idleTimeout =\n options.idleTimeoutMillis !== undefined\n ? Math.max(1, Math.round(options.idleTimeoutMillis / 1000))\n : DEFAULT_IDLE_TIMEOUT_SECONDS\n\n const connectTimeout =\n options.connectTimeoutMillis !== undefined\n ? Math.max(1, Math.round(options.connectTimeoutMillis / 1000))\n : DEFAULT_CONNECT_TIMEOUT_SECONDS\n\n const base = {\n max: options.max,\n // `idle_timeout` is important on managed Postgres (e.g. DigitalOcean), which closes idle\n // server-side connections — without it porsager can hand out a dead socket (porsager#179).\n idle_timeout: idleTimeout,\n connect_timeout: connectTimeout,\n // `max_lifetime` is intentionally left at porsager's default (a random 45–90 min): it\n // cycles connections to avoid server-side memory bloat from long-lived prepared\n // statements and plays nicely with managed databases. Disabling it is discouraged.\n connection,\n // Match the previous (bun:sql) behavior of not surfacing routine PostgreSQL NOTICEs.\n onnotice: () => {},\n ...(options.prepare !== undefined ? { prepare: options.prepare } : {}),\n ...(options.ssl ? { ssl: options.ssl } : {}),\n }\n\n if (options.connectionString) {\n return postgres(options.connectionString, base)\n }\n\n return postgres({\n ...base,\n host: options.host ?? \"localhost\",\n port: options.port ?? 5432,\n ...(options.database !== undefined ? { database: options.database } : {}),\n ...(options.user !== undefined ? { username: options.user } : {}),\n ...(options.password !== undefined ? { password: options.password } : {}),\n })\n}\n",
39
+ "import {\n type ObjectExpansion,\n type ObjectQuery,\n ObjectQueryExecutionError,\n type ObjectQueryPredicate,\n type ObjectQuerySetOperation,\n type ObjectQuerySortField,\n type QueryScalarKind,\n} from \"@sixb/core\"\n\nexport interface PgObjectQueryPageRow {\n object_type_id: string\n primary_id: string\n properties: unknown\n _cursor_properties?: unknown\n}\n\nexport interface CompiledPgObjectQuery {\n sql: string\n args: unknown[]\n totalSql: string\n totalArgs: unknown[]\n order: CompiledOrder\n hasMoreProbe?: CompiledHasMoreProbe\n hasMore(rowCount: number, total?: number): boolean\n trimRows<T>(rows: readonly T[]): readonly T[]\n nextPageToken(rows: readonly PgObjectQueryPageRow[], rowCount: number): string | undefined\n}\n\nexport interface CompiledPgScalarQuery {\n sql: string\n args: unknown[]\n}\n\nexport interface CompiledPgFacetQuery {\n sql: string\n args: unknown[]\n}\n\ninterface CompiledHasMoreProbe {\n sql: string\n args: unknown[]\n hasMore(rowCount: number): boolean\n}\n\ninterface CompileContext {\n probeLimit: boolean\n}\n\ninterface CompiledPredicate {\n sql: string\n args: unknown[]\n}\n\ninterface CompiledAggregateSource {\n sql: string\n args: unknown[]\n}\n\ninterface CompiledOrder {\n sql: string\n args: unknown[]\n fields: readonly CompiledOrderField[]\n propertyColumn: string\n}\n\ntype CompiledOrderField =\n | {\n kind: \"property\"\n propertyId: string\n direction: \"asc\" | \"desc\"\n scalarKind?: QueryScalarKind\n }\n | {\n kind: \"column\"\n column: \"object_type_id\" | \"primary_id\"\n direction: \"asc\" | \"desc\"\n }\n\ninterface EncodedPageToken {\n version: 1\n order: readonly string[]\n values: readonly EncodedCursorValue[]\n}\n\ninterface EncodedCursorValue {\n nullish: boolean\n value?: unknown\n}\n\nconst PAGE_TOKEN_PREFIX = \"keyset:\"\nconst exactContext: CompileContext = { probeLimit: false }\n// Per-parent fanout the core executor bakes into every pushed-down expansion;\n// this default only guards a malformed (un-baked) IR and mirrors the core cap.\nconst DEFAULT_EXPANSION_FANOUT = 1_000\n\nexport function compilePgObjectQuery(\n projectId: string,\n query: ObjectQuery,\n options: { includeTotal?: boolean } = {}\n): CompiledPgObjectQuery {\n const compiled = compileObjectQueryInternal(projectId, query, {\n probeLimit: options.includeTotal === false,\n })\n return {\n ...compiled,\n sql: numberPlaceholders(compiled.sql),\n totalSql: numberPlaceholders(compiled.totalSql),\n hasMoreProbe: compiled.hasMoreProbe\n ? {\n ...compiled.hasMoreProbe,\n sql: numberPlaceholders(compiled.hasMoreProbe.sql),\n }\n : undefined,\n }\n}\n\nexport function compilePgObjectCountQuery(\n projectId: string,\n query: ObjectQuery\n): CompiledPgScalarQuery {\n const source = compileAggregateSource(projectId, query)\n return numberCompiledQuery({\n sql: `\n SELECT COUNT(*)::bigint AS count\n FROM (${source.sql}) AS input\n `,\n args: source.args,\n })\n}\n\nexport function compilePgObjectExistsQuery(\n projectId: string,\n query: ObjectQuery\n): CompiledPgScalarQuery {\n const source = compileAggregateSource(projectId, query)\n return numberCompiledQuery({\n sql: `\n SELECT 1\n FROM (${source.sql}) AS input\n LIMIT 1\n `,\n args: source.args,\n })\n}\n\nexport function compilePgObjectFacetQuery(\n projectId: string,\n query: ObjectQuery,\n propertyId: string,\n limit: number\n): CompiledPgFacetQuery {\n const source = compileAggregateSource(projectId, query)\n return numberCompiledQuery({\n sql: `\n SELECT facet.value_type, facet.value_text, COUNT(*)::bigint AS count\n FROM (\n SELECT\n jsonb_typeof(input.properties -> (?::text)) AS value_type,\n input.properties ->> (?::text) AS value_text\n FROM (${source.sql}) AS input\n WHERE jsonb_exists(input.properties, ?::text)\n ) AS facet\n GROUP BY facet.value_type, facet.value_text\n ORDER BY count DESC, facet.value_text ASC\n LIMIT ?\n `,\n args: [propertyId, propertyId, ...source.args, propertyId, limit],\n })\n}\n\nfunction compileObjectQueryInternal(\n projectId: string,\n query: ObjectQuery,\n ctx: CompileContext\n): CompiledPgObjectQuery {\n switch (query.kind) {\n case \"start\":\n return compileStart(projectId, query)\n case \"filter\":\n return compileFilter(projectId, query.input, query.predicate)\n case \"sort\":\n return compileSort(projectId, query.input, query.fields, ctx)\n case \"limit\":\n return compileLimit(projectId, query.input, query.limit, ctx)\n case \"page\":\n return compilePage(projectId, query.input, query.pageSize, query.pageToken)\n case \"traverse\":\n return compileTraversal(\n projectId,\n query.input,\n query.linkId,\n query.direction,\n query.sourceObjectTypeId\n )\n case \"set\":\n return compileSet(projectId, query.op, query.inputs)\n case \"project\":\n return compileProject(projectId, query.input, query.properties, ctx)\n case \"text\":\n return compileText(\n projectId,\n query.input,\n query.query,\n query.fields,\n query.fieldsByObjectType\n )\n case \"expand\":\n return compileExpand(projectId, query.input, query.expansions)\n case \"vector\":\n throw new Error(\n `[SixbPg] PostgreSQL object storage does not support query node '${query.kind}'`\n )\n }\n}\n\nfunction compileStart(\n projectId: string,\n query: Extract<ObjectQuery, { kind: \"start\" }>\n): CompiledPgObjectQuery {\n if (query.includeSubtypes === true) {\n throw new Error(\"[SixbPg] PostgreSQL object storage does not support start.includeSubtypes\")\n }\n\n const order = compileOrder(identityOrderFields())\n const sql = `\n SELECT *, properties AS _cursor_properties\n FROM objects\n WHERE project_id = ? AND object_type_id = ?\n ORDER BY ${order.sql}\n `\n\n return {\n sql,\n args: [projectId, query.objectTypeId, ...order.args],\n totalSql:\n \"SELECT COUNT(*)::bigint AS total FROM objects WHERE project_id = ? AND object_type_id = ?\",\n totalArgs: [projectId, query.objectTypeId],\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compileFilter(\n projectId: string,\n inputQuery: ObjectQuery,\n predicateNode: ObjectQueryPredicate\n): CompiledPgObjectQuery {\n return compileWhere(projectId, inputQuery, compilePredicate(predicateNode))\n}\n\nfunction compileWhere(\n projectId: string,\n inputQuery: ObjectQuery,\n predicate: CompiledPredicate\n): CompiledPgObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const sql = `\n SELECT *\n FROM (${input.sql}) AS input\n WHERE ${predicate.sql}\n ORDER BY ${input.order.sql}\n `\n\n return {\n sql,\n args: [...input.args, ...predicate.args, ...input.order.args],\n totalSql: `\n SELECT COUNT(*)::bigint AS total\n FROM (${input.sql}) AS input\n WHERE ${predicate.sql}\n `,\n totalArgs: [...input.args, ...predicate.args],\n order: input.order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compileText(\n projectId: string,\n inputQuery: ObjectQuery,\n query: string,\n fields: readonly string[] | undefined,\n fieldsByObjectType: Readonly<Record<string, readonly string[]>> | undefined\n): CompiledPgObjectQuery {\n return compileWhere(\n projectId,\n inputQuery,\n compileTextSearchPredicate(query, fields, fieldsByObjectType)\n )\n}\n\nfunction compileSort(\n projectId: string,\n inputQuery: ObjectQuery,\n fields: readonly ObjectQuerySortField[],\n ctx: CompileContext\n): CompiledPgObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const probeInput =\n ctx.probeLimit && needsLimitProbe(inputQuery)\n ? compileObjectQueryInternal(projectId, inputQuery, ctx)\n : undefined\n const order = compileOrder(sortOrderFields(fields))\n\n return {\n sql: `\n SELECT\n input.project_id,\n input.object_type_id,\n input.primary_id,\n input.properties,\n input.properties AS _cursor_properties,\n input.created_at,\n input.updated_at,\n input.version,\n input.last_commit_id\n FROM (${input.sql}) AS input\n ORDER BY ${order.sql}\n `,\n args: [...input.args, ...order.args],\n totalSql: input.totalSql,\n totalArgs: input.totalArgs,\n order,\n hasMoreProbe: probeInput ? hasMoreProbeFor(probeInput) : input.hasMoreProbe,\n hasMore: input.hasMore,\n trimRows: input.trimRows,\n nextPageToken: input.nextPageToken,\n }\n}\n\nfunction compileLimit(\n projectId: string,\n inputQuery: ObjectQuery,\n rawLimit: number,\n ctx: CompileContext\n): CompiledPgObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const limit = Math.max(0, rawLimit)\n const rowLimit = ctx.probeLimit ? limit + 1 : limit\n\n return {\n sql: `\n SELECT *\n FROM (${input.sql}) AS input\n ORDER BY ${input.order.sql}\n LIMIT ?\n `,\n args: [...input.args, ...input.order.args, rowLimit],\n totalSql: `\n SELECT COUNT(*)::bigint AS total\n FROM (${input.sql}) AS input\n `,\n totalArgs: input.args,\n order: input.order,\n hasMore: (rowCount, total) =>\n total === undefined ? ctx.probeLimit && rowCount > limit : limit < total,\n trimRows: ctx.probeLimit ? (rows) => rows.slice(0, limit) : identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compilePage(\n projectId: string,\n inputQuery: ObjectQuery,\n rawPageSize: number,\n pageToken: string | undefined\n): CompiledPgObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const pageSize = Math.max(0, rawPageSize)\n const cursor = pageToken ? decodePageToken(pageToken, input.order.fields) : undefined\n const cursorPredicate = cursor\n ? compileKeysetPredicate(input.order.fields, cursor, input.order.propertyColumn)\n : undefined\n const whereSql = cursorPredicate ? `WHERE ${cursorPredicate.sql}` : \"\"\n\n return {\n sql: `\n SELECT *\n FROM (${input.sql}) AS input\n ${whereSql}\n ORDER BY ${input.order.sql}\n LIMIT ?\n `,\n args: [...input.args, ...(cursorPredicate?.args ?? []), ...input.order.args, pageSize + 1],\n totalSql: `\n SELECT COUNT(*)::bigint AS total\n FROM (${input.sql}) AS input\n `,\n totalArgs: input.args,\n order: input.order,\n hasMore: (rowCount) => rowCount > pageSize,\n trimRows: (rows) => rows.slice(0, pageSize),\n nextPageToken: (rows, rowCount) => {\n if (rowCount <= pageSize || rows.length === 0) return undefined\n return encodePageToken(rows[rows.length - 1], input.order.fields)\n },\n }\n}\n\nfunction compileTraversal(\n projectId: string,\n inputQuery: ObjectQuery,\n linkId: string,\n direction: \"outgoing\" | \"incoming\",\n sourceObjectTypeId?: string\n): CompiledPgObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const outputAlias = direction === \"outgoing\" ? \"target_object\" : \"source_object\"\n const joinSql =\n direction === \"outgoing\"\n ? `\n JOIN links AS edge\n ON edge.project_id = input.project_id\n AND edge.source_type_id = input.object_type_id\n AND edge.source_id = input.primary_id\n AND edge.link_id = ?\n JOIN objects AS target_object\n ON target_object.project_id = edge.project_id\n AND target_object.object_type_id = edge.target_type_id\n AND target_object.primary_id = edge.target_id\n `\n : `\n JOIN links AS edge\n ON edge.project_id = input.project_id\n AND edge.target_type_id = input.object_type_id\n AND edge.target_id = input.primary_id\n AND edge.link_id = ?${sourceObjectTypeId === undefined ? \"\" : \"\\n AND edge.source_type_id = ?\"}\n JOIN objects AS source_object\n ON source_object.project_id = edge.project_id\n AND source_object.object_type_id = edge.source_type_id\n AND source_object.primary_id = edge.source_id\n `\n const order = compileOrder(identityOrderFields())\n const qualifiedOrder = compileOrder(identityOrderFields(), outputAlias)\n const sql = `\n SELECT DISTINCT ${outputAlias}.*, ${outputAlias}.properties AS _cursor_properties\n FROM (${input.sql}) AS input\n ${joinSql}\n ORDER BY ${qualifiedOrder.sql}\n `\n const args = [\n ...input.args,\n linkId,\n ...(sourceObjectTypeId === undefined ? [] : [sourceObjectTypeId]),\n ...qualifiedOrder.args,\n ]\n\n return {\n sql,\n args,\n totalSql: `SELECT COUNT(*)::bigint AS total FROM (${sql}) AS traversed`,\n totalArgs: args,\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\n/** Correlation handle for an expansion: the parent row's identity columns. */\ninterface ExpansionParent {\n project: string\n type: string\n id: string\n}\n\n// `expand` attaches linked objects to each result row without changing which\n// objects match (unlike `traverse`, which pivots to the targets). Each expansion\n// becomes a correlated subquery that hydrates its links into a JSONB value, and\n// all expansions are folded into one `_expand` object column the row mapper reads\n// back. The input set is otherwise untouched, so pagination/order pass through.\nfunction compileExpand(\n projectId: string,\n inputQuery: ObjectQuery,\n expansions: readonly ObjectExpansion[]\n): CompiledPgObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const expand = compileExpansionsObject(\n expansions,\n { project: \"input.project_id\", type: \"input.object_type_id\", id: \"input.primary_id\" },\n \"\"\n )\n const inputOrder = compileOrder(input.order.fields, \"input\", \"input._cursor_properties\")\n const sql = `\n SELECT input.*, ${expand.sql} AS _expand\n FROM (${input.sql}) AS input\n ORDER BY ${inputOrder.sql}\n `\n\n return {\n sql,\n args: [...expand.args, ...input.args, ...inputOrder.args],\n totalSql: input.totalSql,\n totalArgs: input.totalArgs,\n order: input.order,\n hasMoreProbe: input.hasMoreProbe,\n hasMore: input.hasMore,\n trimRows: input.trimRows,\n nextPageToken: input.nextPageToken,\n }\n}\n\n// `jsonb_build_object(linkId, value, ...)` over a set of expansions sharing one\n// parent. Link ids are user data, so they ride as parameters. Used both for the\n// outer `_expand` column and for each child's nested `links`.\nfunction compileExpansionsObject(\n expansions: readonly ObjectExpansion[],\n parent: ExpansionParent,\n pathPrefix: string\n): CompiledPredicate {\n const parts: string[] = []\n const args: unknown[] = []\n expansions.forEach((expansion, index) => {\n const path = pathPrefix === \"\" ? `${index}` : `${pathPrefix}_${index}`\n const value = compileExpansionValue(expansion, parent, path)\n parts.push(\"?::text\", value.sql)\n args.push(expansion.linkId, ...value.args)\n })\n return { sql: `jsonb_build_object(${parts.join(\", \")})`, args }\n}\n\n// One expansion's hydrated value. `row_number()` numbers a parent's links by the\n// order from `compileExpansionOrder` (the expansion's `orderBy` against the target\n// object's properties, then an identity tiebreak); `WHERE _ord <= N` keeps the\n// top-N per parent in-DB; each retained neighbour becomes a JSONB object; and the\n// value is an ordered array (\"many\") or the first element or null (\"one\"). The\n// cardinality is core-resolved before pushdown.\nfunction compileExpansionValue(\n expansion: ObjectExpansion,\n parent: ExpansionParent,\n path: string\n): CompiledPredicate {\n const edge = `edge_${path}`\n const target = `tgt_${path}`\n const ranked = `ranked_${path}`\n const incoming = expansion.direction === \"incoming\"\n // The hydrated neighbour is the link target (outgoing) or source (incoming);\n // the parent sits on the opposite end, mirroring `compileTraversal`.\n const neighborType = incoming ? `${edge}.source_type_id` : `${edge}.target_type_id`\n const neighborId = incoming ? `${edge}.source_id` : `${edge}.target_id`\n const parentType = incoming ? `${edge}.target_type_id` : `${edge}.source_type_id`\n const parentId = incoming ? `${edge}.target_id` : `${edge}.source_id`\n\n const child = compileExpansionChildJson(expansion, edge, target, path)\n const order = compileExpansionOrder(expansion, target, neighborType, neighborId)\n\n const whereParts = [\n `${edge}.project_id = ${parent.project}`,\n `${parentType} = ${parent.type}`,\n `${parentId} = ${parent.id}`,\n `${edge}.link_id = ?::text`,\n ]\n const whereArgs: unknown[] = [expansion.linkId]\n if (incoming && expansion.sourceObjectTypeId !== undefined) {\n whereParts.push(`${edge}.source_type_id = ?::text`)\n whereArgs.push(expansion.sourceObjectTypeId)\n }\n\n const inner = `\n SELECT ${child.sql} AS elem, row_number() OVER (ORDER BY ${order.sql}) AS _ord\n FROM links AS ${edge}\n JOIN objects AS ${target}\n ON ${target}.project_id = ${edge}.project_id\n AND ${target}.object_type_id = ${neighborType}\n AND ${target}.primary_id = ${neighborId}\n WHERE ${whereParts.join(\" AND \")}\n `\n const innerArgs = [...child.args, ...order.args, ...whereArgs]\n\n if (expansion.cardinality === \"one\") {\n return {\n sql: `(SELECT ${ranked}.elem FROM (${inner}) AS ${ranked} WHERE ${ranked}._ord = 1)`,\n args: innerArgs,\n }\n }\n\n // The fanout cap is baked into `limit` by the core executor before pushdown.\n const limit = expansion.limit ?? DEFAULT_EXPANSION_FANOUT\n return {\n sql: `COALESCE((SELECT jsonb_agg(${ranked}.elem ORDER BY ${ranked}._ord) FROM (${inner}) AS ${ranked} WHERE ${ranked}._ord <= ?), '[]'::jsonb)`,\n args: [...innerArgs, limit],\n }\n}\n\n// Build one hydrated neighbour as an `ExpandedObjectRow`-shaped JSONB object.\n// `linkProperties` always rides along (the mapper drops it when empty), and\n// nested expansions recurse under `links`, correlated on this neighbour.\nfunction compileExpansionChildJson(\n expansion: ObjectExpansion,\n edge: string,\n target: string,\n path: string\n): CompiledPredicate {\n const fields = [\n `'projectId', ${target}.project_id`,\n `'objectTypeId', ${target}.object_type_id`,\n `'primaryId', ${target}.primary_id`,\n `'properties', ${target}.properties`,\n `'createdAt', ${target}.created_at`,\n `'updatedAt', ${target}.updated_at`,\n `'version', ${target}.version`,\n `'lastCommitId', ${target}.last_commit_id`,\n `'linkProperties', ${edge}.properties`,\n ]\n const args: unknown[] = []\n\n if (expansion.expand && expansion.expand.length > 0) {\n const nested = compileExpansionsObject(\n expansion.expand,\n {\n project: `${target}.project_id`,\n type: `${target}.object_type_id`,\n id: `${target}.primary_id`,\n },\n path\n )\n fields.push(`'links', ${nested.sql}`)\n args.push(...nested.args)\n }\n\n return { sql: `jsonb_build_object(${fields.join(\", \")})`, args }\n}\n\n// Order a parent's links the way the fallback's per-parent trim does: each\n// property sorts nulls last with the requested direction (against the neighbour's\n// JSONB properties), then a deterministic identity tiebreak on the neighbour.\nfunction compileExpansionOrder(\n expansion: ObjectExpansion,\n target: string,\n neighborType: string,\n neighborId: string\n): CompiledPredicate {\n const propertyColumn = `${target}.properties`\n const clauses: string[] = []\n const args: unknown[] = []\n\n for (const field of expansion.orderBy ?? []) {\n // Relevance is a no-op in the fallback comparator; mirror that by skipping it.\n if (field.kind !== \"property\") continue\n const direction = field.direction === \"desc\" ? \"DESC\" : \"ASC\"\n clauses.push(\n `CASE WHEN ${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null' THEN 1 ELSE 0 END ASC`,\n `${\n field.scalarKind === \"decimal\"\n ? `(${jsonTextExpression(propertyColumn)})::numeric`\n : jsonValueExpression(propertyColumn)\n } ${direction}`\n )\n args.push(field.propertyId, field.propertyId, field.propertyId)\n }\n\n clauses.push(`${neighborType} ASC`, `${neighborId} ASC`)\n return { sql: clauses.join(\", \"), args }\n}\n\nfunction compileSet(\n projectId: string,\n op: ObjectQuerySetOperation,\n inputs: readonly ObjectQuery[]\n): CompiledPgObjectQuery {\n if (inputs.length === 0) {\n const order = compileOrder(identityOrderFields())\n return {\n sql: `\n SELECT *, properties AS _cursor_properties\n FROM objects\n WHERE 1 = 0\n ORDER BY ${order.sql}\n `,\n args: order.args,\n totalSql: \"SELECT 0::bigint AS total\",\n totalArgs: [],\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n }\n\n const compiledInputs = inputs.map((input) =>\n compileObjectQueryInternal(projectId, input, exactContext)\n )\n const identities = compileSetIdentities(op, compiledInputs)\n const order = compileOrder(identityOrderFields())\n const selectedOrder = compileOrder(identityOrderFields(), \"selected\")\n const sql = `\n SELECT selected.*, selected.properties AS _cursor_properties\n FROM (${identities.sql}) AS ids\n JOIN objects AS selected\n ON selected.project_id = ?\n AND selected.object_type_id = ids.object_type_id\n AND selected.primary_id = ids.primary_id\n ORDER BY ${selectedOrder.sql}\n `\n\n return {\n sql,\n args: [...identities.args, projectId, ...selectedOrder.args],\n totalSql: `SELECT COUNT(*)::bigint AS total FROM (${identities.sql}) AS ids`,\n totalArgs: identities.args,\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compileProject(\n projectId: string,\n inputQuery: ObjectQuery,\n properties: readonly string[] | undefined,\n ctx: CompileContext\n): CompiledPgObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, ctx)\n if (!properties) return input\n\n const projection = compileProjectionExpression(properties)\n const inputOrder = compileOrder(input.order.fields, \"input\", \"input._cursor_properties\")\n const outputOrder = compileOrder(input.order.fields, undefined, \"_cursor_properties\")\n\n return {\n sql: `\n SELECT\n input.project_id,\n input.object_type_id,\n input.primary_id,\n ${projection.sql} AS properties,\n input._cursor_properties AS _cursor_properties,\n input.created_at,\n input.updated_at,\n input.version,\n input.last_commit_id\n FROM (${input.sql}) AS input\n ORDER BY ${inputOrder.sql}\n `,\n args: [...projection.args, ...input.args, ...inputOrder.args],\n totalSql: input.totalSql,\n totalArgs: input.totalArgs,\n order: outputOrder,\n hasMoreProbe: input.hasMoreProbe,\n hasMore: input.hasMore,\n trimRows: input.trimRows,\n nextPageToken: input.nextPageToken,\n }\n}\n\nfunction compileAggregateSource(projectId: string, query: ObjectQuery): CompiledAggregateSource {\n switch (query.kind) {\n case \"start\":\n return compileAggregateStart(projectId, query)\n case \"filter\":\n return compileAggregateWhere(projectId, query.input, compilePredicate(query.predicate))\n case \"text\": {\n return compileAggregateWhere(\n projectId,\n query.input,\n compileTextSearchPredicate(query.query, query.fields, query.fieldsByObjectType)\n )\n }\n case \"traverse\":\n return compileAggregateTraversal(\n projectId,\n query.input,\n query.linkId,\n query.direction,\n query.sourceObjectTypeId\n )\n case \"set\":\n return compileAggregateSet(projectId, query.op, query.inputs)\n case \"sort\":\n case \"project\":\n // `expand` is output-shaping, like sort/project: aggregates ignore it.\n case \"expand\":\n return compileAggregateSource(projectId, query.input)\n case \"limit\":\n case \"page\":\n return compileRowQueryAggregateSource(projectId, query)\n case \"vector\":\n throw new Error(`[SixbPg] PostgreSQL object storage does not support query node 'vector'`)\n }\n}\n\nfunction compileAggregateStart(\n projectId: string,\n query: Extract<ObjectQuery, { kind: \"start\" }>\n): CompiledAggregateSource {\n if (query.includeSubtypes === true) {\n throw new Error(\"[SixbPg] PostgreSQL object storage does not support start.includeSubtypes\")\n }\n\n return {\n sql: `\n SELECT project_id, object_type_id, primary_id, properties\n FROM objects\n WHERE project_id = ? AND object_type_id = ?\n `,\n args: [projectId, query.objectTypeId],\n }\n}\n\nfunction compileAggregateWhere(\n projectId: string,\n inputQuery: ObjectQuery,\n predicate: CompiledPredicate\n): CompiledAggregateSource {\n const input = compileAggregateSource(projectId, inputQuery)\n return {\n sql: `\n SELECT input.project_id, input.object_type_id, input.primary_id, input.properties\n FROM (${input.sql}) AS input\n WHERE ${predicate.sql}\n `,\n args: [...input.args, ...predicate.args],\n }\n}\n\nfunction compileAggregateTraversal(\n projectId: string,\n inputQuery: ObjectQuery,\n linkId: string,\n direction: \"outgoing\" | \"incoming\",\n sourceObjectTypeId?: string\n): CompiledAggregateSource {\n const input = compileAggregateSource(projectId, inputQuery)\n const outputAlias = direction === \"outgoing\" ? \"target_object\" : \"source_object\"\n const joinSql =\n direction === \"outgoing\"\n ? `\n JOIN links AS edge\n ON edge.project_id = input.project_id\n AND edge.source_type_id = input.object_type_id\n AND edge.source_id = input.primary_id\n AND edge.link_id = ?\n JOIN objects AS target_object\n ON target_object.project_id = edge.project_id\n AND target_object.object_type_id = edge.target_type_id\n AND target_object.primary_id = edge.target_id\n `\n : `\n JOIN links AS edge\n ON edge.project_id = input.project_id\n AND edge.target_type_id = input.object_type_id\n AND edge.target_id = input.primary_id\n AND edge.link_id = ?${sourceObjectTypeId === undefined ? \"\" : \"\\n AND edge.source_type_id = ?\"}\n JOIN objects AS source_object\n ON source_object.project_id = edge.project_id\n AND source_object.object_type_id = edge.source_type_id\n AND source_object.primary_id = edge.source_id\n `\n\n return {\n sql: `\n SELECT DISTINCT\n ${outputAlias}.project_id,\n ${outputAlias}.object_type_id,\n ${outputAlias}.primary_id,\n ${outputAlias}.properties\n FROM (${input.sql}) AS input\n ${joinSql}\n `,\n args: [\n ...input.args,\n linkId,\n ...(sourceObjectTypeId === undefined ? [] : [sourceObjectTypeId]),\n ],\n }\n}\n\nfunction compileAggregateSet(\n projectId: string,\n op: ObjectQuerySetOperation,\n inputs: readonly ObjectQuery[]\n): CompiledAggregateSource {\n if (inputs.length === 0) {\n return {\n sql: `\n SELECT project_id, object_type_id, primary_id, properties\n FROM objects\n WHERE 1 = 0\n `,\n args: [],\n }\n }\n\n const compiledInputs = inputs.map((input) => compileAggregateSource(projectId, input))\n const identities = compileSetIdentities(op, compiledInputs)\n return {\n sql: `\n SELECT selected.project_id, selected.object_type_id, selected.primary_id, selected.properties\n FROM (${identities.sql}) AS ids\n JOIN objects AS selected\n ON selected.project_id = ?\n AND selected.object_type_id = ids.object_type_id\n AND selected.primary_id = ids.primary_id\n `,\n args: [...identities.args, projectId],\n }\n}\n\nfunction compileRowQueryAggregateSource(\n projectId: string,\n query: ObjectQuery\n): CompiledAggregateSource {\n const rowQuery = compileObjectQueryInternal(projectId, query, exactContext)\n return {\n sql: `\n SELECT input.project_id, input.object_type_id, input.primary_id, input.properties\n FROM (${rowQuery.sql}) AS input\n `,\n args: rowQuery.args,\n }\n}\n\nfunction needsLimitProbe(query: ObjectQuery): boolean {\n switch (query.kind) {\n case \"limit\":\n return true\n case \"project\":\n case \"sort\":\n return needsLimitProbe(query.input)\n default:\n return false\n }\n}\n\nfunction hasMoreProbeFor(compiled: CompiledPgObjectQuery): CompiledHasMoreProbe {\n return (\n compiled.hasMoreProbe ?? {\n sql: compiled.sql,\n args: compiled.args,\n hasMore: (rowCount) => compiled.hasMore(rowCount, undefined),\n }\n )\n}\n\nfunction compileSetIdentities(\n op: ObjectQuerySetOperation,\n inputs: readonly { sql: string; args: readonly unknown[] }[]\n): CompiledPredicate {\n const operator = op === \"union\" ? \"UNION\" : op === \"intersect\" ? \"INTERSECT\" : \"EXCEPT\"\n const identitySqls = inputs.map(\n (input) => `SELECT object_type_id, primary_id FROM (${input.sql}) AS input`\n )\n\n return {\n sql: identitySqls.join(` ${operator} `),\n args: inputs.flatMap((input) => input.args),\n }\n}\n\nfunction compileProjectionExpression(properties: readonly string[]): CompiledPredicate {\n if (properties.length === 0) return { sql: \"'{}'::jsonb\", args: [] }\n\n return {\n sql: `\n COALESCE(\n (\n SELECT jsonb_object_agg(projected.key, projected.value)\n FROM jsonb_each(input.properties) AS projected(key, value)\n WHERE projected.key IN (${properties.map(() => \"?::text\").join(\", \")})\n ),\n '{}'::jsonb\n )\n `,\n args: [...properties],\n }\n}\n\nfunction compilePredicate(predicate: ObjectQueryPredicate): CompiledPredicate {\n switch (predicate.op) {\n case \"and\":\n case \"or\": {\n const items = predicate.items.map(compilePredicate)\n const joiner = predicate.op === \"and\" ? \" AND \" : \" OR \"\n return {\n sql: `(${items.map((item) => item.sql).join(joiner)})`,\n args: items.flatMap((item) => item.args),\n }\n }\n case \"not\": {\n const item = compilePredicate(predicate.item)\n return negatePredicate(item)\n }\n case \"eq\":\n return predicate.scalarKind === \"decimal\"\n ? compileDecimalEqualityPredicate(predicate.propertyId, \"eq\", predicate.value)\n : compileEqualityPredicate(predicate.propertyId, \"eq\", predicate.value)\n case \"neq\":\n return predicate.scalarKind === \"decimal\"\n ? compileDecimalEqualityPredicate(predicate.propertyId, \"neq\", predicate.value)\n : compileEqualityPredicate(predicate.propertyId, \"neq\", predicate.value)\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\": {\n const op = sqlComparisonOperator(predicate.op)\n if (predicate.scalarKind === \"decimal\") {\n return {\n sql: `(${jsonTypeExpression()} = 'string' AND (${jsonTextExpression()})::numeric ${op} ?::numeric)`,\n args: [predicate.propertyId, predicate.propertyId, predicate.value],\n }\n }\n return {\n sql: `${jsonValueExpression()} ${op} ?::text::jsonb`,\n args: [predicate.propertyId, jsonbValue(predicate.value)],\n }\n }\n case \"in\":\n return predicate.scalarKind === \"decimal\"\n ? compileDecimalInPredicate(predicate.propertyId, predicate.values)\n : compileInPredicate(predicate.propertyId, predicate.values)\n case \"exists\": {\n const sql = `jsonb_exists(properties, ?::text)`\n const item: CompiledPredicate = { sql, args: [predicate.propertyId] }\n return predicate.value ? item : negatePredicate(item)\n }\n case \"contains\":\n return compileContainsPredicate(predicate.propertyId, predicate.value)\n }\n}\n\nfunction compileDecimalEqualityPredicate(\n propertyId: string,\n op: \"eq\" | \"neq\",\n value: unknown\n): CompiledPredicate {\n if (value === null) {\n const sql = `${jsonTypeExpression()} = 'null'`\n const item: CompiledPredicate = { sql, args: [propertyId] }\n return op === \"eq\" ? item : negatePredicate(item)\n }\n\n if (op === \"eq\") {\n return {\n sql: `(${jsonTypeExpression()} = 'string' AND (${jsonTextExpression()})::numeric = ?::numeric)`,\n args: [propertyId, propertyId, value],\n }\n }\n\n return {\n sql: `(${jsonTypeExpression()} IS NULL OR ${jsonTypeExpression()} = 'null' OR ${jsonTypeExpression()} <> 'string' OR (${jsonTextExpression()})::numeric <> ?::numeric)`,\n args: [propertyId, propertyId, propertyId, propertyId, value],\n }\n}\n\nfunction compileDecimalInPredicate(\n propertyId: string,\n values: readonly unknown[]\n): CompiledPredicate {\n if (values.length === 0) return { sql: \"0 = 1\", args: [] }\n const nonNullValues = values.filter((value) => value !== null)\n const clauses: string[] = []\n const args: unknown[] = []\n\n if (nonNullValues.length !== values.length) {\n clauses.push(`${jsonTypeExpression()} = 'null'`)\n args.push(propertyId)\n }\n\n if (nonNullValues.length > 0) {\n clauses.push(\n `(${jsonTypeExpression()} = 'string' AND (${jsonTextExpression()})::numeric IN (${nonNullValues\n .map(() => \"?::numeric\")\n .join(\", \")}))`\n )\n args.push(propertyId, propertyId, ...nonNullValues)\n }\n\n return {\n sql: `(${clauses.join(\" OR \")})`,\n args,\n }\n}\n\nfunction negatePredicate(predicate: CompiledPredicate): CompiledPredicate {\n return {\n sql: `(NOT COALESCE((${predicate.sql}), false))`,\n args: predicate.args,\n }\n}\n\nfunction compileEqualityPredicate(\n propertyId: string,\n op: \"eq\" | \"neq\",\n value: unknown\n): CompiledPredicate {\n if (value === null) {\n const sql = `${jsonTypeExpression()} = 'null'`\n const item: CompiledPredicate = { sql, args: [propertyId] }\n return op === \"eq\" ? item : negatePredicate(item)\n }\n\n if (typeof value === \"string\") {\n if (op === \"eq\") {\n return {\n sql: `(${jsonTypeExpression()} = 'string' AND ${jsonTextExpression()} = ?::text)`,\n args: [propertyId, propertyId, value],\n }\n }\n\n return {\n sql: `(${jsonTypeExpression()} IS NULL OR ${jsonTypeExpression()} = 'null' OR ${jsonTypeExpression()} <> 'string' OR ${jsonTextExpression()} <> ?::text)`,\n args: [propertyId, propertyId, propertyId, propertyId, value],\n }\n }\n\n if (op === \"eq\") {\n return {\n sql: `${jsonValueExpression()} = ?::text::jsonb`,\n args: [propertyId, jsonbValue(value)],\n }\n }\n\n return {\n sql: `(${jsonTypeExpression()} IS NULL OR ${jsonTypeExpression()} = 'null' OR ${jsonValueExpression()} <> ?::text::jsonb)`,\n args: [propertyId, propertyId, propertyId, jsonbValue(value)],\n }\n}\n\nfunction compileInPredicate(propertyId: string, values: readonly unknown[]): CompiledPredicate {\n if (values.length === 0) return { sql: \"0 = 1\", args: [] }\n\n const nonNullValues = values.filter((value) => value !== null)\n const stringValues = nonNullValues.filter((value): value is string => typeof value === \"string\")\n const jsonbValues = nonNullValues.filter((value) => typeof value !== \"string\")\n const clauses: string[] = []\n const args: unknown[] = []\n\n if (values.length !== nonNullValues.length) {\n clauses.push(`${jsonTypeExpression()} = 'null'`)\n args.push(propertyId)\n }\n\n if (stringValues.length > 0) {\n clauses.push(\n `(${jsonTypeExpression()} = 'string' AND ${jsonTextExpression()} IN (${stringValues\n .map(() => \"?::text\")\n .join(\", \")}))`\n )\n args.push(propertyId, propertyId, ...stringValues)\n }\n\n if (jsonbValues.length > 0) {\n clauses.push(\n `${jsonValueExpression()} IN (${jsonbValues.map(() => \"?::text::jsonb\").join(\", \")})`\n )\n args.push(propertyId, ...jsonbValues.map(jsonbValue))\n }\n\n return {\n sql: `(${clauses.join(\" OR \")})`,\n args,\n }\n}\n\nfunction compileContainsPredicate(propertyId: string, value: unknown): CompiledPredicate {\n const clauses: string[] = []\n const args: unknown[] = []\n\n if (typeof value === \"string\") {\n clauses.push(\n `(${jsonTypeExpression()} = 'string' AND position(?::text in ${jsonTextExpression()}) > 0)`\n )\n args.push(propertyId, value, propertyId)\n }\n\n clauses.push(\n `(${jsonTypeExpression()} = 'array' AND ${jsonValueExpression()} @> jsonb_build_array(?::text::jsonb))`\n )\n args.push(propertyId, propertyId, jsonbValue(value))\n\n if (typeof value === \"string\") {\n clauses.push(\n `(${jsonTypeExpression()} = 'object' AND jsonb_exists(${jsonValueExpression()}, ?::text))`\n )\n args.push(propertyId, propertyId, value)\n }\n\n return { sql: `(${clauses.join(\" OR \")})`, args }\n}\n\nfunction compileTextPredicate(query: string, fields: readonly string[]): CompiledPredicate {\n const terms = tokenize(query)\n if (terms.length === 0) return { sql: \"0 = 1\", args: [] }\n\n const clauses = terms.map(() => {\n const fieldClauses = fields.map(\n () => `position(?::text in lower(coalesce(${jsonTextExpression()}, ''))) > 0`\n )\n return `(${fieldClauses.join(\" OR \")})`\n })\n const args = terms.flatMap((term) => fields.flatMap((field) => [term, field]))\n\n return { sql: `(${clauses.join(\" AND \")})`, args }\n}\n\nfunction compileTextSearchPredicate(\n query: string,\n fields: readonly string[] | undefined,\n fieldsByObjectType: Readonly<Record<string, readonly string[]>> | undefined\n): CompiledPredicate {\n const predicate =\n fields && fields.length > 0\n ? compileTextPredicate(query, fields)\n : compileScopedTextPredicate(query, fieldsByObjectType)\n\n if (!predicate) {\n throw new Error(\n \"[SixbPg] PostgreSQL object text search requires fields or resolved text defaults\"\n )\n }\n\n return predicate\n}\n\nfunction compileScopedTextPredicate(\n query: string,\n fieldsByObjectType: Readonly<Record<string, readonly string[]>> | undefined\n): CompiledPredicate | null {\n const scopedPredicates: CompiledPredicate[] = []\n\n for (const [objectTypeId, fields] of Object.entries(fieldsByObjectType ?? {})) {\n if (fields.length === 0) continue\n const predicate = compileTextPredicate(query, fields)\n scopedPredicates.push({\n sql: `(object_type_id = ? AND ${predicate.sql})`,\n args: [objectTypeId, ...predicate.args],\n })\n }\n\n if (scopedPredicates.length === 0) return null\n\n return {\n sql: `(${scopedPredicates.map((predicate) => predicate.sql).join(\" OR \")})`,\n args: scopedPredicates.flatMap((predicate) => predicate.args),\n }\n}\n\nfunction compileOrder(\n fields: readonly CompiledOrderField[],\n qualifier?: string,\n propertyColumn = \"properties\"\n): CompiledOrder {\n const clauses: string[] = []\n const args: unknown[] = []\n\n for (const field of fields) {\n if (field.kind === \"column\") {\n clauses.push(`${columnExpression(field.column, qualifier)} ${field.direction.toUpperCase()}`)\n continue\n }\n\n const direction = field.direction === \"desc\" ? \"DESC\" : \"ASC\"\n clauses.push(\n `CASE WHEN ${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null' THEN 1 ELSE 0 END ASC`,\n `${compiledPropertyValueExpression(field, propertyColumn)} ${direction}`\n )\n args.push(field.propertyId, field.propertyId, field.propertyId)\n }\n\n return { sql: clauses.join(\", \"), args, fields, propertyColumn }\n}\n\nfunction sortOrderFields(fields: readonly ObjectQuerySortField[]): readonly CompiledOrderField[] {\n const orderFields: CompiledOrderField[] = []\n for (const field of fields) {\n if (field.kind !== \"property\") {\n throw new Error(\"[SixbPg] PostgreSQL object storage does not support relevance sorting\")\n }\n\n orderFields.push({\n kind: \"property\",\n propertyId: field.propertyId,\n direction: field.direction === \"desc\" ? \"desc\" : \"asc\",\n scalarKind: field.scalarKind,\n })\n }\n orderFields.push(...identityOrderFields())\n return orderFields\n}\n\nfunction identityOrderFields(): readonly CompiledOrderField[] {\n return [\n { kind: \"column\", column: \"object_type_id\", direction: \"asc\" },\n { kind: \"column\", column: \"primary_id\", direction: \"asc\" },\n ]\n}\n\nfunction compileKeysetPredicate(\n fields: readonly CompiledOrderField[],\n cursor: readonly EncodedCursorValue[],\n propertyColumn = \"properties\"\n): CompiledPredicate {\n const disjuncts: CompiledPredicate[] = []\n\n for (let index = 0; index < fields.length; index += 1) {\n const equalityPredicates = fields\n .slice(0, index)\n .map((field, equalityIndex) =>\n compileFieldEquality(field, cursor[equalityIndex], propertyColumn)\n )\n const advancePredicate = compileFieldAfter(fields[index], cursor[index], propertyColumn)\n if (!advancePredicate) continue\n\n const parts = [...equalityPredicates, advancePredicate]\n disjuncts.push({\n sql: `(${parts.map((part) => part.sql).join(\" AND \")})`,\n args: parts.flatMap((part) => part.args),\n })\n }\n\n if (disjuncts.length === 0) return { sql: \"0 = 1\", args: [] }\n\n return {\n sql: `(${disjuncts.map((part) => part.sql).join(\" OR \")})`,\n args: disjuncts.flatMap((part) => part.args),\n }\n}\n\nfunction compileFieldEquality(\n field: CompiledOrderField,\n cursor: EncodedCursorValue,\n propertyColumn = \"properties\"\n): CompiledPredicate {\n if (field.kind === \"column\") {\n return {\n sql: `${columnExpression(field.column)} = ?`,\n args: [cursor.value],\n }\n }\n\n if (cursor.nullish) {\n return {\n sql: `(${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null')`,\n args: [field.propertyId, field.propertyId],\n }\n }\n\n return {\n sql: `(${jsonTypeExpression(propertyColumn)} IS NOT NULL AND ${jsonTypeExpression(propertyColumn)} != 'null' AND ${compiledPropertyValueExpression(field, propertyColumn)} = ${field.scalarKind === \"decimal\" ? \"?::numeric\" : \"?::text::jsonb\"})`,\n args: [\n field.propertyId,\n field.propertyId,\n field.propertyId,\n field.scalarKind === \"decimal\" ? cursor.value : jsonbValue(cursor.value),\n ],\n }\n}\n\nfunction compileFieldAfter(\n field: CompiledOrderField,\n cursor: EncodedCursorValue,\n propertyColumn = \"properties\"\n): CompiledPredicate | null {\n if (field.kind === \"column\") {\n return {\n sql: `${columnExpression(field.column)} ${field.direction === \"desc\" ? \"<\" : \">\"} ?`,\n args: [cursor.value],\n }\n }\n\n if (cursor.nullish) return null\n\n const rankSql = `CASE WHEN ${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null' THEN 1 ELSE 0 END`\n const valueOperator = field.direction === \"desc\" ? \"<\" : \">\"\n\n return {\n sql: `(${rankSql} > 0 OR (${rankSql} = 0 AND ${compiledPropertyValueExpression(field, propertyColumn)} ${valueOperator} ${field.scalarKind === \"decimal\" ? \"?::numeric\" : \"?::text::jsonb\"}))`,\n args: [\n field.propertyId,\n field.propertyId,\n field.propertyId,\n field.propertyId,\n field.propertyId,\n field.scalarKind === \"decimal\" ? cursor.value : jsonbValue(cursor.value),\n ],\n }\n}\n\nfunction encodePageToken(row: PgObjectQueryPageRow, fields: readonly CompiledOrderField[]): string {\n const properties = objectProperties(row._cursor_properties ?? row.properties)\n const token: EncodedPageToken = {\n version: 1,\n order: fields.map(orderFieldKey),\n values: fields.map((field) => cursorValueForField(row, properties, field)),\n }\n return `${PAGE_TOKEN_PREFIX}${Buffer.from(JSON.stringify(token)).toString(\"base64url\")}`\n}\n\nfunction decodePageToken(\n token: string,\n fields: readonly CompiledOrderField[]\n): readonly EncodedCursorValue[] {\n if (!token.startsWith(PAGE_TOKEN_PREFIX)) {\n throwInvalidPageToken(\"Invalid PostgreSQL object query page token\")\n }\n\n const raw = token.slice(PAGE_TOKEN_PREFIX.length)\n let decoded: unknown\n try {\n decoded = JSON.parse(Buffer.from(raw, \"base64url\").toString(\"utf8\"))\n } catch {\n throwInvalidPageToken(\"Invalid PostgreSQL object query page token\")\n }\n\n if (!isEncodedPageToken(decoded)) {\n throwInvalidPageToken(\"Invalid PostgreSQL object query page token\")\n }\n\n const expectedOrder = fields.map(orderFieldKey)\n if (\n decoded.order.length !== expectedOrder.length ||\n decoded.order.some((field, index) => field !== expectedOrder[index])\n ) {\n throwInvalidPageToken(\"PostgreSQL object query page token does not match query order\")\n }\n\n return decoded.values\n}\n\nfunction throwInvalidPageToken(message: string): never {\n throw new ObjectQueryExecutionError(\"invalid_page_token\", message, \"$.pageToken\")\n}\n\nfunction isEncodedPageToken(value: unknown): value is EncodedPageToken {\n if (!isPlainObject(value)) return false\n if (value.version !== 1) return false\n if (!Array.isArray(value.order) || value.order.some((item) => typeof item !== \"string\")) {\n return false\n }\n if (!Array.isArray(value.values)) return false\n return value.values.every(\n (item) =>\n isPlainObject(item) &&\n typeof item.nullish === \"boolean\" &&\n (item.nullish || Object.hasOwn(item, \"value\"))\n )\n}\n\nfunction cursorValueForField(\n row: PgObjectQueryPageRow,\n properties: Record<string, unknown>,\n field: CompiledOrderField\n): EncodedCursorValue {\n const value =\n field.kind === \"column\"\n ? field.column === \"object_type_id\"\n ? row.object_type_id\n : row.primary_id\n : properties[field.propertyId]\n\n return value === null || value === undefined ? { nullish: true } : { nullish: false, value }\n}\n\nfunction orderFieldKey(field: CompiledOrderField): string {\n return field.kind === \"column\"\n ? `column:${field.column}:${field.direction}`\n : `property:${field.propertyId}:${field.scalarKind ?? \"json\"}:${field.direction}`\n}\n\nfunction compiledPropertyValueExpression(\n field: Extract<CompiledOrderField, { kind: \"property\" }>,\n propertyColumn = \"properties\"\n): string {\n return field.scalarKind === \"decimal\"\n ? `(${jsonTextExpression(propertyColumn)})::numeric`\n : jsonValueExpression(propertyColumn)\n}\n\nfunction columnExpression(column: \"object_type_id\" | \"primary_id\", qualifier?: string): string {\n return qualifier ? `${qualifier}.${column}` : column\n}\n\nfunction jsonValueExpression(column = \"properties\"): string {\n return `${column} -> (?::text)`\n}\n\nfunction jsonTextExpression(column = \"properties\"): string {\n return `${column} ->> (?::text)`\n}\n\nfunction jsonTypeExpression(column = \"properties\"): string {\n return `jsonb_typeof(${jsonValueExpression(column)})`\n}\n\nfunction jsonbValue(value: unknown): string {\n if (value instanceof Date) return JSON.stringify(value.toISOString())\n const json = JSON.stringify(value)\n return json === undefined ? \"null\" : json\n}\n\nfunction tokenize(query: string): string[] {\n return query\n .trim()\n .toLowerCase()\n .split(/\\s+/)\n .filter((term) => term.length > 0)\n}\n\nfunction sqlComparisonOperator(op: \"lt\" | \"lte\" | \"gt\" | \"gte\"): \"<\" | \"<=\" | \">\" | \">=\" {\n switch (op) {\n case \"lt\":\n return \"<\"\n case \"lte\":\n return \"<=\"\n case \"gt\":\n return \">\"\n case \"gte\":\n return \">=\"\n }\n}\n\nfunction numberPlaceholders(sql: string): string {\n let index = 0\n return sql.replace(/\\?/g, () => `$${++index}`)\n}\n\nfunction numberCompiledQuery<T extends { sql: string; args: unknown[] }>(compiled: T): T {\n return {\n ...compiled,\n sql: numberPlaceholders(compiled.sql),\n }\n}\n\nfunction objectProperties(value: unknown): Record<string, unknown> {\n if (typeof value === \"string\") {\n const parsed = JSON.parse(value) as unknown\n return isPlainObject(parsed) ? parsed : {}\n }\n\n return isPlainObject(value) ? value : {}\n}\n\nfunction identityRows<T>(rows: readonly T[]): readonly T[] {\n return rows\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n",
40
+ "import type { ObjectQuery } from \"@sixb/core\"\nimport type {\n CountObjectsInput,\n CountObjectsResult,\n ExistsObjectsInput,\n ExistsObjectsResult,\n ExpandedLinkValue,\n ExpandedObjectRow,\n FacetObjectsInput,\n FacetObjectsResult,\n LinkDirection,\n ObjectLinkRow,\n ObjectQueryCapabilities,\n ObjectRow,\n ObjectRowLinks,\n ObjectStorage,\n QueryObjectsInput,\n QueryObjectsResult,\n} from \"@sixb/core/storage\"\nimport type { SQLClient, SqlParameter } from \"./pg-client\"\nimport {\n type CompiledPgObjectQuery,\n compilePgObjectCountQuery,\n compilePgObjectExistsQuery,\n compilePgObjectFacetQuery,\n compilePgObjectQuery,\n} from \"./pg-object-query-compiler\"\nimport type { PgStoreClient } from \"./transactions\"\n\nconst PG_OBJECT_QUERY_CAPABILITIES: ObjectQueryCapabilities = {\n queryObjects: true,\n countObjects: true,\n existsObjects: true,\n facetObjects: true,\n nodes: {\n start: true,\n filter: true,\n text: true,\n sort: true,\n limit: true,\n page: true,\n traverse: true,\n set: true,\n project: true,\n expand: true,\n },\n predicateOps: {\n and: true,\n or: true,\n not: true,\n eq: true,\n neq: true,\n lt: true,\n lte: true,\n gt: true,\n gte: true,\n in: true,\n exists: true,\n contains: true,\n },\n sortKinds: {\n property: true,\n },\n traversalDirections: {\n outgoing: true,\n incoming: true,\n },\n setOps: {\n union: true,\n intersect: true,\n subtract: true,\n },\n scalarOperations: {\n string: { equality: true, ordering: true },\n uuid: { equality: true, ordering: true },\n boolean: { equality: true },\n integer: { equality: true, ordering: true },\n double: { equality: true, ordering: true },\n decimal: { equality: true, ordering: true },\n date: { equality: true, ordering: true },\n timestamp: { equality: true, ordering: true },\n },\n limits: {\n totalCount: true,\n stablePageTokens: true,\n },\n notes: [\n \"PostgreSQL object query pushdown supports start/filter/text/sort/limit/page/traverse/set/project/expand over JSONB properties and object links.\",\n \"expand hydrates linked objects in-database (top-N per parent via LATERAL + jsonb_agg); core resolves each expansion's cardinality before pushdown, and a mixed/unresolved one stays on the fallback.\",\n \"Exact decimal predicates, ordering, and keyset pagination use PostgreSQL numeric casts.\",\n \"Relevance sorting, vector search, and unresolved start.includeSubtypes remain planner fallback or rejection cases.\",\n ],\n}\n\n/**\n * Build a `SELECT ... JOIN (VALUES ...) AS t(...) ON ... WHERE ...` query\n * with positional parameters. Bun SQL's tagged-template helpers don't\n * support VALUES inside SELECT/JOIN, so we construct the query string\n * manually while keeping all user data in the parameter array.\n */\nfunction valuesJoin<Row = unknown>(\n sql: SQLClient,\n select: string,\n columns: string[],\n tuples: unknown[][],\n where: string,\n whereParams: unknown[]\n): Promise<Row[]> {\n const alias = \"t\"\n const colWidth = columns.length\n\n // $1 … $N are reserved for the WHERE params that come first.\n const base = whereParams.length\n const valuePlaceholders = tuples\n .map((_, i) => {\n const cols = columns.map((_, j) => `$${base + i * colWidth + j + 1}`)\n return `(${cols.join(\",\")})`\n })\n .join(\",\")\n\n const onClause = columns\n .map((c) => {\n // Infer the table alias from the SELECT clause (first word after SELECT ... FROM)\n const srcAlias = select.match(/FROM\\s+\\w+\\s+(\\w+)/i)?.[1] ?? select.split(\" \").pop()\n return `${srcAlias}.${c} = ${alias}.${c}`\n })\n .join(\" AND \")\n\n const query = `${select} JOIN (VALUES ${valuePlaceholders}) AS ${alias}(${columns.join(\",\")}) ON ${onClause} ${where}`\n const params = [...whereParams, ...tuples.flat()]\n\n return sql.unsafe(query, params as SqlParameter[]) as unknown as Promise<Row[]>\n}\n\n/**\n * PostgreSQL-based ObjectStorage implementation.\n *\n * Stores object projections and links. V1 object-query IR pushdown covers the\n * scalar JSONB-property and link-traversal subset declared by queryCapabilities().\n *\n * Requires `search_path` to be set to the Sixb schema on the connection.\n *\n * JSONB handling notes (Bun SQL specifics):\n * - Writes use `${JSON.stringify(v)}::text::jsonb`. The `::text` forces the\n * text wire type so that `::jsonb` parses the JSON text into a proper JSONB\n * value (object, number, etc.) instead of a JSONB string literal.\n * - The `@>` containment operator receives a plain JS object which Bun SQL\n * auto-serialises as JSONB.\n * - Reads return JSONB as native JS types (objects, numbers, booleans) when\n * the data was stored correctly.\n */\nexport class PgObjectStorage implements ObjectStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n queryCapabilities(): ObjectQueryCapabilities {\n return PG_OBJECT_QUERY_CAPABILITIES\n }\n\n async queryObjects(params: QueryObjectsInput): Promise<QueryObjectsResult> {\n const compiled = compilePgObjectQuery(params.projectId, params.query, {\n includeTotal: params.includeTotal,\n })\n const total = params.includeTotal === false ? undefined : await readTotal(this.sql, compiled)\n const rawRows = await this.sql.unsafe<ObjectQueryDatabaseRow[]>(\n compiled.sql,\n compiled.args as SqlParameter[]\n )\n const rows = compiled.trimRows(rawRows) as readonly ObjectQueryDatabaseRow[]\n const hasMore =\n total === undefined && compiled.hasMoreProbe\n ? compiled.hasMoreProbe.hasMore(\n (\n await this.sql.unsafe(\n compiled.hasMoreProbe.sql,\n compiled.hasMoreProbe.args as SqlParameter[]\n )\n ).length\n )\n : compiled.hasMore(rawRows.length, total)\n\n return {\n objects: rows.map((row) => queryRowToObject(row)),\n hasMore,\n nextPageToken: compiled.nextPageToken(rows, rawRows.length),\n ...(total === undefined ? {} : { total }),\n }\n }\n\n async countObjects(params: CountObjectsInput): Promise<CountObjectsResult> {\n const compiled = compilePgObjectCountQuery(params.projectId, stripOuterRowShape(params.query))\n const [row] = await this.sql.unsafe<{ count: string | number | bigint }[]>(\n compiled.sql,\n compiled.args as SqlParameter[]\n )\n return { count: Number(row?.count ?? 0) }\n }\n\n async existsObjects(params: ExistsObjectsInput): Promise<ExistsObjectsResult> {\n const compiled = compilePgObjectExistsQuery(params.projectId, stripOuterRowShape(params.query))\n const [row] = await this.sql.unsafe<unknown[]>(compiled.sql, compiled.args as SqlParameter[])\n return { exists: row !== undefined }\n }\n\n async facetObjects(params: FacetObjectsInput): Promise<FacetObjectsResult> {\n return {\n facets: await Promise.all(\n params.facets.map(async (facet) => ({\n propertyId: facet.propertyId,\n buckets: await readFacetBuckets(\n this.sql,\n compilePgObjectFacetQuery(\n params.projectId,\n stripOuterRowShape(params.query),\n facet.propertyId,\n facet.limit\n )\n ),\n }))\n ),\n }\n }\n\n async getByPrimaryId(params: {\n projectId: string\n objectTypeId: string\n primaryId: string\n }): Promise<ObjectRow | null> {\n const [row] = await this.sql<ObjectDatabaseRow[]>`\n SELECT * FROM objects\n WHERE project_id = ${params.projectId}\n AND object_type_id = ${params.objectTypeId}\n AND primary_id = ${params.primaryId}\n `\n\n return row ? rowToObject(row) : null\n }\n\n async listLinks(params: {\n projectId: string\n objectTypeId: string\n objectId: string\n linkId?: string\n direction?: LinkDirection\n }): Promise<readonly ObjectLinkRow[]> {\n const direction = params.direction ?? \"outgoing\"\n const directionWhere =\n direction === \"incoming\"\n ? \"target_type_id = $2 AND target_id = $3\"\n : direction === \"both\"\n ? \"((source_type_id = $2 AND source_id = $3) OR (target_type_id = $2 AND target_id = $3))\"\n : \"source_type_id = $2 AND source_id = $3\"\n const query = `SELECT * FROM links WHERE project_id = $1 AND ${directionWhere}${\n params.linkId ? \" AND link_id = $4\" : \"\"\n }`\n const args = params.linkId\n ? [params.projectId, params.objectTypeId, params.objectId, params.linkId]\n : [params.projectId, params.objectTypeId, params.objectId]\n const rows = await this.sql.unsafe<LinkDatabaseRow[]>(query, args)\n\n return rows.map((row) => rowToLink(row))\n }\n\n async getByPrimaryIdBatch(params: {\n projectId: string\n items: readonly { objectTypeId: string; primaryId: string }[]\n }): Promise<Map<string, ObjectRow>> {\n const result = new Map<string, ObjectRow>()\n if (params.items.length === 0) return result\n const rows = await valuesJoin<ObjectDatabaseRow>(\n this.sql,\n \"SELECT o.* FROM objects o\",\n [\"object_type_id\", \"primary_id\"],\n params.items.map((i) => [i.objectTypeId, i.primaryId]),\n `WHERE o.project_id = $1`,\n [params.projectId]\n )\n\n for (const row of rows) {\n result.set(`${row.object_type_id}:${row.primary_id}`, rowToObject(row))\n }\n return result\n }\n\n async listLinksBatch(params: {\n projectId: string\n items: readonly { objectTypeId: string; objectId: string; linkId: string }[]\n }): Promise<Map<string, ObjectLinkRow[]>> {\n const result = new Map<string, ObjectLinkRow[]>()\n if (params.items.length === 0) return result\n const rows = await valuesJoin<LinkDatabaseRow>(\n this.sql,\n \"SELECT l.* FROM links l\",\n [\"source_type_id\", \"source_id\", \"link_id\"],\n params.items.map((i) => [i.objectTypeId, i.objectId, i.linkId]),\n `WHERE l.project_id = $1`,\n [params.projectId]\n )\n\n for (const row of rows) {\n const key = `${row.source_type_id}:${row.source_id}:${row.link_id}`\n const existing = result.get(key) ?? []\n existing.push(rowToLink(row))\n result.set(key, existing)\n }\n return result\n }\n\n async listIncidentLinksBatch(params: {\n projectId: string\n items: readonly { objectTypeId: string; objectId: string }[]\n }): Promise<readonly ObjectLinkRow[]> {\n if (params.items.length === 0) return []\n const tuples = params.items.map((item) => [item.objectTypeId, item.objectId])\n\n // Cover both link directions with two index-friendly equality joins (source-side, then\n // target-side) rather than a single OR-join, which would defeat index usage. This is a constant\n // number of round trips regardless of how many objects are deleted — issued sequentially because\n // these reads run on the serializable commit transaction's single connection. A link incident to\n // two listed objects matches both halves and is de-duplicated below.\n const sourceRows = await valuesJoin<LinkDatabaseRow>(\n this.sql,\n \"SELECT l.* FROM links l\",\n [\"source_type_id\", \"source_id\"],\n tuples,\n \"WHERE l.project_id = $1\",\n [params.projectId]\n )\n const targetRows = await valuesJoin<LinkDatabaseRow>(\n this.sql,\n \"SELECT l.* FROM links l\",\n [\"target_type_id\", \"target_id\"],\n tuples,\n \"WHERE l.project_id = $1\",\n [params.projectId]\n )\n\n const deduped = new Map<string, ObjectLinkRow>()\n for (const row of [...sourceRows, ...targetRows]) {\n const link = rowToLink(row)\n deduped.set(\n `${link.sourceTypeId}:${link.sourceId}:${link.linkId}:${link.targetTypeId}:${link.targetId}`,\n link\n )\n }\n return [...deduped.values()]\n }\n\n async listByPrimaryIdPage(params: {\n projectId: string\n objectTypeId: string\n afterPrimaryId?: string\n limit: number\n }): Promise<{ objects: readonly ObjectRow[]; nextPrimaryId?: string }> {\n assertReconciliationPageLimit(params.limit)\n const rows = await this.sql<ObjectDatabaseRow[]>`\n SELECT * FROM objects\n WHERE project_id = ${params.projectId}\n AND object_type_id = ${params.objectTypeId}\n ${params.afterPrimaryId ? this.sql`AND primary_id > ${params.afterPrimaryId}` : this.sql``}\n ORDER BY primary_id ASC\n LIMIT ${params.limit + 1}\n `\n const hasMore = rows.length > params.limit\n const objects = rows.slice(0, params.limit).map((row) => rowToObject(row))\n const last = objects.at(-1)\n return {\n objects,\n ...(hasMore && last ? { nextPrimaryId: last.primaryId } : {}),\n }\n }\n\n async list(params: {\n projectId: string\n objectTypeId?: string | readonly string[]\n primaryIdPrefix?: string\n primaryIdSuffix?: string\n updatedAfter?: Date\n updatedBefore?: Date\n createdAfter?: Date\n createdBefore?: Date\n limit?: number\n offset?: number\n orderBy?: \"createdAt\" | \"updatedAt\" | \"primaryId\"\n order?: \"asc\" | \"desc\"\n }): Promise<{ objects: readonly ObjectRow[]; hasMore: boolean; total: number }> {\n const queryOffset = params.offset ?? 0\n const limit = params.limit ?? 50\n const orderBy = params.orderBy ?? \"updatedAt\"\n const order = params.order ?? \"desc\"\n const orderColumn =\n orderBy === \"primaryId\" ? \"primary_id\" : orderBy === \"createdAt\" ? \"created_at\" : \"updated_at\"\n\n // Build WHERE conditions using conditional fragments\n const typeFilter =\n params.objectTypeId === undefined\n ? this.sql``\n : typeof params.objectTypeId === \"string\"\n ? this.sql`AND object_type_id = ${params.objectTypeId}`\n : this.sql`AND object_type_id IN ${this.sql(params.objectTypeId as string[])}`\n\n const primaryIdPrefixFilter = params.primaryIdPrefix\n ? this.sql`AND primary_id LIKE ${`${params.primaryIdPrefix}%`}`\n : this.sql``\n\n const primaryIdSuffixFilter = params.primaryIdSuffix\n ? this.sql`AND primary_id LIKE ${`%${params.primaryIdSuffix}`}`\n : this.sql``\n\n const updatedAfterFilter = params.updatedAfter\n ? this.sql`AND updated_at >= ${params.updatedAfter}`\n : this.sql``\n\n const updatedBeforeFilter = params.updatedBefore\n ? this.sql`AND updated_at <= ${params.updatedBefore}`\n : this.sql``\n\n const createdAfterFilter = params.createdAfter\n ? this.sql`AND created_at >= ${params.createdAfter}`\n : this.sql``\n\n const createdBeforeFilter = params.createdBefore\n ? this.sql`AND created_at <= ${params.createdBefore}`\n : this.sql``\n\n const filters = this.sql`\n ${typeFilter}\n ${primaryIdPrefixFilter}\n ${primaryIdSuffixFilter}\n ${updatedAfterFilter}\n ${updatedBeforeFilter}\n ${createdAfterFilter}\n ${createdBeforeFilter}\n `\n\n // Get total count\n const [countResult] = await this.sql<{ total: number }[]>`\n SELECT COUNT(*)::int AS total FROM objects\n WHERE project_id = ${params.projectId}\n ${filters}\n `\n const total = countResult.total\n\n if (limit === 0) return { objects: [], hasMore: queryOffset < total, total }\n\n // Get paginated results (+1 for hasMore check)\n // Column and direction derived from a fixed mapping — safe to use as identifiers\n const fetchLimit = limit + 1\n const rows = await this.sql<ObjectDatabaseRow[]>`\n SELECT * FROM objects\n WHERE project_id = ${params.projectId}\n ${filters}\n ORDER BY ${this.sql(orderColumn)} ${order === \"asc\" ? this.sql`ASC` : this.sql`DESC`}\n LIMIT ${fetchLimit}\n OFFSET ${queryOffset}\n `\n\n const hasMore = rows.length > limit\n const objects = rows.slice(0, limit).map((row) => rowToObject(row))\n\n return { objects, hasMore, total }\n }\n}\n\nfunction assertReconciliationPageLimit(limit: number): void {\n if (!Number.isSafeInteger(limit) || limit <= 0) {\n throw new Error(\"Object reconciliation page limit must be a positive safe integer.\")\n }\n}\n\nasync function readTotal(sql: SQLClient, compiled: CompiledPgObjectQuery): Promise<number> {\n const [row] = await sql.unsafe<\n {\n total: string | number | bigint\n }[]\n >(compiled.totalSql, compiled.totalArgs as SqlParameter[])\n return Number(row?.total ?? 0)\n}\n\nasync function readFacetBuckets(\n sql: SQLClient,\n compiled: { sql: string; args: readonly unknown[] }\n): Promise<{ value: unknown; count: number }[]> {\n const rows = await sql.unsafe<FacetDatabaseRow[]>(compiled.sql, [\n ...compiled.args,\n ] as SqlParameter[])\n\n return rows.map((row) => ({\n value: pgFacetValue(row.value_type, row.value_text),\n count: Number(row.count),\n }))\n}\n\nfunction pgFacetValue(valueType: string | null, valueText: string | null): unknown {\n switch (valueType) {\n case \"string\":\n return valueText ?? \"\"\n case \"number\":\n return valueText === null ? null : Number(valueText)\n case \"boolean\":\n return valueText === \"true\"\n case \"null\":\n return null\n case \"array\":\n case \"object\":\n return valueText === null ? null : JSON.parse(valueText)\n default:\n return valueText\n }\n}\n\nfunction stripOuterRowShape(query: ObjectQuery): ObjectQuery {\n switch (query.kind) {\n case \"limit\":\n case \"page\":\n case \"project\":\n case \"sort\":\n return stripOuterRowShape(query.input)\n default:\n return query\n }\n}\n\nfunction rowToObject(row: ObjectDatabaseRow): ObjectRow {\n return {\n projectId: row.project_id,\n objectTypeId: row.object_type_id,\n primaryId: row.primary_id,\n properties: row.properties as Record<string, unknown>,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n version: row.version,\n lastCommitId: row.last_commit_id,\n }\n}\n\n// Map a query row, attaching `links` when an `expand` pushdown produced them. The\n// base columns map as usual; `_expand` (a `jsonb_build_object`) is revived into\n// the runtime link shape the core executor's fallback also produces.\nfunction queryRowToObject(row: ObjectQueryDatabaseRow): ObjectRow {\n const base = rowToObject(row)\n const links = reviveExpandedLinks(row._expand)\n return links ? { ...base, links } : base\n}\n\nfunction reviveExpandedLinks(value: unknown): ObjectRowLinks | undefined {\n if (!isPlainRecord(value)) return undefined\n const links: ObjectRowLinks = {}\n for (const [linkId, raw] of Object.entries(value)) {\n links[linkId] = reviveExpandedLinkValue(raw)\n }\n return links\n}\n\n// A \"one\" expansion arrives as a single object or null; a \"many\" expansion as an\n// array (already ordered and trimmed in the database).\nfunction reviveExpandedLinkValue(value: unknown): ExpandedLinkValue {\n if (value === null || value === undefined) return null\n if (Array.isArray(value)) return value.map(reviveExpandedRow)\n return reviveExpandedRow(value)\n}\n\n// Revive one hydrated neighbour from `compileExpansionChildJson`: JSONB timestamp\n// strings back to `Date`, empty link properties dropped (matching the fallback),\n// and nested links recursed.\nfunction reviveExpandedRow(value: unknown): ExpandedObjectRow {\n const row = isPlainRecord(value) ? value : {}\n const expanded: ExpandedObjectRow = {\n projectId: String(row.projectId),\n objectTypeId: String(row.objectTypeId),\n primaryId: String(row.primaryId),\n properties: isPlainRecord(row.properties) ? row.properties : {},\n createdAt: new Date(row.createdAt as string),\n updatedAt: new Date(row.updatedAt as string),\n version: Number(row.version),\n lastCommitId: String(row.lastCommitId),\n }\n if (isPlainRecord(row.linkProperties) && Object.keys(row.linkProperties).length > 0) {\n expanded.linkProperties = row.linkProperties\n }\n const links = reviveExpandedLinks(row.links)\n if (links) expanded.links = links\n return expanded\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction rowToLink(row: LinkDatabaseRow): ObjectLinkRow {\n return {\n projectId: row.project_id,\n sourceTypeId: row.source_type_id,\n sourceId: row.source_id,\n linkId: row.link_id,\n targetTypeId: row.target_type_id,\n targetId: row.target_id,\n properties: row.properties ? (row.properties as Record<string, unknown>) : undefined,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n lastCommitId: row.last_commit_id,\n }\n}\n\ninterface ObjectDatabaseRow {\n project_id: string\n object_type_id: string\n primary_id: string\n properties: unknown\n created_at: Date | string\n updated_at: Date | string\n version: number\n last_commit_id: string\n}\n\ninterface ObjectQueryDatabaseRow extends ObjectDatabaseRow {\n _cursor_properties?: unknown\n /** `jsonb_build_object(linkId, value, ...)` from an `expand` pushdown; absent otherwise. */\n _expand?: unknown\n}\n\ninterface FacetDatabaseRow {\n value_type: string | null\n value_text: string | null\n count: string | number | bigint\n}\n\ninterface LinkDatabaseRow {\n project_id: string\n source_type_id: string\n source_id: string\n link_id: string\n target_type_id: string\n target_id: string\n properties: unknown | null\n created_at: Date | string\n updated_at: Date | string\n last_commit_id: string\n}\n",
41
+ "import type { DatasetVersionRef } from \"@sixb/core/lake-storage\"\nimport type {\n FinishPipelineRunInput,\n FinishPipelineStepRunInput,\n ListLatestPipelineRunsInput,\n ListLatestPipelineRunsResult,\n ListPipelineRunsInput,\n ListPipelineRunsResult,\n ListPipelineStepRunsInput,\n ListPipelineStepRunsResult,\n PipelineRunFailure,\n PipelineRunRecord,\n PipelineRunStorage,\n PipelineStepRunRecord,\n StartPipelineRunInput,\n StartPipelineStepRunInput,\n} from \"@sixb/core/storage\"\nimport { PipelineRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport type { SqlParameter } from \"./pg-client\"\nimport { appendRunListFilters, hasEmptyStatuses, queryRunList } from \"./run-list-query\"\nimport { isUniqueViolation } from \"./storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgPipelineRunStorage implements PipelineRunStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async start(input: StartPipelineRunInput): Promise<PipelineRunRecord> {\n try {\n const [row] = await this.sql<PipelineRunDatabaseRow[]>`\n INSERT INTO pipeline_runs (\n project_id,\n id,\n pipeline_id,\n status,\n started_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.pipelineId},\n ${\"running\"},\n ${input.startedAt ?? new Date()}\n )\n RETURNING *\n `\n\n return rowToPipelineRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new PipelineRunError(\n `[SixbPg] Pipeline run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async finish(input: FinishPipelineRunInput): Promise<PipelineRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<PipelineRunDatabaseRow[]>`\n SELECT * FROM pipeline_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n `\n\n if (!existing) {\n throw new PipelineRunError(\n `[SixbPg] Pipeline run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new PipelineRunError(\n `[SixbPg] Pipeline run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n const [updated] =\n input.status === \"succeeded\"\n ? await tx<PipelineRunDatabaseRow[]>`\n UPDATE pipeline_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n output_dataset_id = ${input.output?.datasetId ?? null},\n output_version_id = ${input.output?.versionId ?? null},\n error_name = ${null},\n error_message = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n : await tx<PipelineRunDatabaseRow[]>`\n UPDATE pipeline_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n output_dataset_id = ${null},\n output_version_id = ${null},\n error_name = ${input.error?.name ?? null},\n error_message = ${input.error?.message ?? null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToPipelineRunRecord(updated)\n })\n }\n\n async startStep(input: StartPipelineStepRunInput): Promise<PipelineStepRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [pipelineRun] = await tx<PipelineRunDatabaseRow[]>`\n SELECT * FROM pipeline_runs\n WHERE project_id = ${input.projectId} AND id = ${input.pipelineRunId}\n `\n\n if (!pipelineRun) {\n throw new PipelineRunError(\n `[SixbPg] Pipeline run '${input.pipelineRunId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (pipelineRun.status !== \"running\") {\n throw new PipelineRunError(\n `[SixbPg] Pipeline run '${input.pipelineRunId}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n if (pipelineRun.pipeline_id !== input.pipelineId) {\n throw new PipelineRunError(\n `[SixbPg] Pipeline step run '${input.id}' pipeline '${input.pipelineId}' does not match pipeline run '${input.pipelineRunId}' pipeline '${pipelineRun.pipeline_id}'.`\n )\n }\n\n try {\n const [row] = await tx<PipelineStepRunDatabaseRow[]>`\n INSERT INTO pipeline_step_runs (\n project_id,\n id,\n pipeline_run_id,\n pipeline_id,\n step_id,\n dataset_id,\n mode,\n status,\n started_at,\n inputs\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.pipelineRunId},\n ${input.pipelineId},\n ${input.stepId},\n ${input.datasetId},\n ${input.mode},\n ${\"running\"},\n ${input.startedAt ?? new Date()},\n ${JSON.stringify(input.inputs)}::text::jsonb\n )\n RETURNING *\n `\n\n return rowToPipelineStepRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new PipelineRunError(\n `[SixbPg] Pipeline step run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n })\n }\n\n async finishStep(input: FinishPipelineStepRunInput): Promise<PipelineStepRunRecord> {\n assertOptionalNonNegativeInteger(input.rowsWritten, \"rowsWritten\")\n\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<PipelineStepRunDatabaseRow[]>`\n SELECT * FROM pipeline_step_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n `\n\n if (!existing) {\n throw new PipelineRunError(\n `[SixbPg] Pipeline step run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new PipelineRunError(\n `[SixbPg] Pipeline step run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n if (input.status === \"succeeded\" && input.output.datasetId !== existing.dataset_id) {\n throw new PipelineRunError(\n `[SixbPg] Pipeline step run '${input.id}' output dataset '${input.output.datasetId}' does not match '${existing.dataset_id}'.`\n )\n }\n\n const [updated] =\n input.status === \"succeeded\"\n ? await tx<PipelineStepRunDatabaseRow[]>`\n UPDATE pipeline_step_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n output_version_id = ${input.output.versionId},\n rows_written = ${input.rowsWritten ?? existing.rows_written ?? null},\n error_name = ${null},\n error_message = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n : await tx<PipelineStepRunDatabaseRow[]>`\n UPDATE pipeline_step_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n output_version_id = ${null},\n rows_written = ${input.rowsWritten ?? existing.rows_written ?? null},\n error_name = ${input.error?.name ?? null},\n error_message = ${input.error?.message ?? null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToPipelineStepRunRecord(updated)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<PipelineRunRecord | null> {\n const [row] = await this.sql<PipelineRunDatabaseRow[]>`\n SELECT * FROM pipeline_runs\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToPipelineRunRecord(row) : null\n }\n\n async list(input: ListPipelineRunsInput): Promise<ListPipelineRunsResult> {\n if (hasEmptyStatuses(input) || input.pipelineIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.pipelineId) {\n whereClauses.push(`pipeline_id = $${index++}`)\n params.push(input.pipelineId)\n }\n\n if (input.pipelineIds) {\n const placeholders = input.pipelineIds.map(() => `$${index++}`).join(\", \")\n whereClauses.push(`pipeline_id IN (${placeholders})`)\n params.push(...input.pipelineIds)\n }\n\n index = appendRunListFilters(whereClauses, params, index, input)\n\n const { rows, total, hasMore } = await queryRunList<PipelineRunDatabaseRow>({\n sql: this.sql,\n tableName: \"pipeline_runs\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n const runs = rows.map(rowToPipelineRunRecord)\n\n return {\n runs,\n hasMore,\n total,\n }\n }\n\n async listLatestByPipelineIds(\n input: ListLatestPipelineRunsInput\n ): Promise<ListLatestPipelineRunsResult> {\n const rows = await queryLatestRunsByOwnerId<PipelineRunDatabaseRow>({\n sql: this.sql,\n tableName: \"pipeline_runs\",\n ownerColumn: \"pipeline_id\",\n ownerIds: input.pipelineIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.pipeline_id,\n })\n\n return {\n runs: rows.map(rowToPipelineRunRecord),\n }\n }\n\n async listSteps(input: ListPipelineStepRunsInput): Promise<ListPipelineStepRunsResult> {\n if (hasEmptyStatuses(input)) {\n return {\n steps: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.pipelineRunId) {\n whereClauses.push(`pipeline_run_id = $${index++}`)\n params.push(input.pipelineRunId)\n }\n\n if (input.pipelineId) {\n whereClauses.push(`pipeline_id = $${index++}`)\n params.push(input.pipelineId)\n }\n\n if (input.stepId) {\n whereClauses.push(`step_id = $${index++}`)\n params.push(input.stepId)\n }\n\n if (input.datasetId) {\n whereClauses.push(`dataset_id = $${index++}`)\n params.push(input.datasetId)\n }\n\n index = appendRunListFilters(whereClauses, params, index, input)\n\n const { rows, total, hasMore } = await queryRunList<PipelineStepRunDatabaseRow>({\n sql: this.sql,\n tableName: \"pipeline_step_runs\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n const steps = rows.map(rowToPipelineStepRunRecord)\n\n return {\n steps,\n hasMore,\n total,\n }\n }\n}\n\nfunction toFailure(row: {\n readonly error_name: string | null\n readonly error_message: string | null\n}): PipelineRunFailure | undefined {\n if (!row.error_message) {\n return undefined\n }\n\n return {\n name: row.error_name ?? undefined,\n message: row.error_message,\n }\n}\n\nfunction rowToPipelineRunRecord(row: PipelineRunDatabaseRow): PipelineRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n pipelineId: row.pipeline_id,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n output:\n row.output_dataset_id && row.output_version_id\n ? {\n datasetId: row.output_dataset_id,\n versionId: row.output_version_id,\n }\n : undefined,\n error: toFailure(row),\n }\n}\n\nfunction rowToPipelineStepRunRecord(row: PipelineStepRunDatabaseRow): PipelineStepRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n pipelineRunId: row.pipeline_run_id,\n pipelineId: row.pipeline_id,\n stepId: row.step_id,\n datasetId: row.dataset_id,\n mode: row.mode,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n inputs: parseDatasetVersionRefs(row.inputs),\n output: row.output_version_id\n ? {\n datasetId: row.dataset_id,\n versionId: row.output_version_id,\n }\n : undefined,\n rowsWritten: row.rows_written != null ? Number(row.rows_written) : undefined,\n error: toFailure(row),\n }\n}\n\nfunction parseDatasetVersionRefs(\n value: readonly DatasetVersionRef[] | string\n): readonly DatasetVersionRef[] {\n return typeof value === \"string\" ? (JSON.parse(value) as readonly DatasetVersionRef[]) : value\n}\n\nfunction assertOptionalNonNegativeInteger(value: number | undefined, fieldName: string): void {\n if (value !== undefined && (!Number.isInteger(value) || value < 0)) {\n throw new PipelineRunError(`[SixbPg] Pipeline run ${fieldName} must be a non-negative integer.`)\n }\n}\n\ninterface PipelineRunDatabaseRow {\n project_id: string\n id: string\n pipeline_id: string\n status: PipelineRunRecord[\"status\"]\n started_at: Date | string\n finished_at: Date | string | null\n output_dataset_id: string | null\n output_version_id: string | null\n error_name: string | null\n error_message: string | null\n}\n\ninterface PipelineStepRunDatabaseRow {\n project_id: string\n id: string\n pipeline_run_id: string\n pipeline_id: string\n step_id: string\n dataset_id: string\n mode: PipelineStepRunRecord[\"mode\"]\n status: PipelineStepRunRecord[\"status\"]\n started_at: Date | string\n finished_at: Date | string | null\n inputs: readonly DatasetVersionRef[] | string\n output_version_id: string | null\n rows_written: number | string | null\n error_name: string | null\n error_message: string | null\n}\n",
42
+ "import type { SQLClient, SqlParameter } from \"./pg-client\"\n\ntype PgLatestRunTarget =\n | { readonly tableName: \"pipeline_runs\"; readonly ownerColumn: \"pipeline_id\" }\n | { readonly tableName: \"projection_runs\"; readonly ownerColumn: \"projection_id\" }\n | { readonly tableName: \"sync_runs\"; readonly ownerColumn: \"sync_id\" }\n | { readonly tableName: \"workflow_runs\"; readonly ownerColumn: \"workflow_id\" }\n\ntype PgLatestRunSelectList = \"*\" | \"*, checkpoint IS NOT NULL AS checkpoint_present\"\n\nexport async function queryLatestRunsByOwnerId<TRow>(\n input: {\n readonly sql: SQLClient\n readonly ownerIds: readonly string[]\n readonly projectId: string\n readonly ownerIdFor: (row: TRow) => string\n readonly selectList?: PgLatestRunSelectList\n } & PgLatestRunTarget\n): Promise<readonly TRow[]> {\n const ownerIds = [...new Set(input.ownerIds)]\n if (ownerIds.length === 0) {\n return []\n }\n\n const placeholders = ownerIds.map((_, index) => `$${index + 2}`).join(\", \")\n const rows = await input.sql.unsafe<TRow[]>(\n `\n SELECT DISTINCT ON (${input.ownerColumn}) ${input.selectList ?? \"*\"}\n FROM ${input.tableName}\n WHERE project_id = $1 AND ${input.ownerColumn} IN (${placeholders})\n ORDER BY ${input.ownerColumn}, started_at DESC, id DESC\n `,\n [input.projectId, ...ownerIds] as SqlParameter[]\n )\n\n const latestByOwnerId = new Map(rows.map((row) => [input.ownerIdFor(row), row]))\n\n return ownerIds.flatMap((ownerId) => {\n const row = latestByOwnerId.get(ownerId)\n return row ? [row] : []\n })\n}\n",
43
+ "import { randomUUID } from \"node:crypto\"\nimport {\n advanceProjectionTelemetry,\n assertGenericProgressDoesNotAdvanceTelemetry,\n assertProjectionMissingTarget,\n assertProjectionRunExecution,\n assertProjectionRunListWindow,\n assertProjectionRunNonEmpty,\n assertProjectionRunRunning,\n assertProjectionRunStartInput,\n createProjectionRunClaim,\n immutableDatasetVersionConflict,\n mergeProjectionRunProgress,\n type PersistedProjectionRunRecord,\n planProjectionRunFinish,\n planProjectionRunReclaim,\n projectionRunNotFound,\n publicProjectionRunRecord,\n requireProjectionRunExecutionToken,\n requireTelemetryProjectionRun,\n restoreProjectionRun,\n type StoredProjectionRunRecord,\n staleProjectionRunExecution,\n} from \"@sixb/core/internal/projection-run-storage-provider\"\nimport type {\n AdvanceProjectionTelemetryCheckpointInput,\n FinishProjectionRunInput,\n ListLatestProjectionRunsInput,\n ListLatestProjectionRunsResult,\n ListProjectionRunsInput,\n ListProjectionRunsResult,\n LockProjectionRunForMaterializationInput,\n ProjectionKind,\n ProjectionRunClaim,\n ProjectionRunRecord,\n ProjectionRunStatus,\n ProjectionRunStorage,\n RecordProjectionMissingTargetInput,\n StartOrReclaimProjectionRunInput,\n TelemetryProjectionRunRecord,\n UpdateProjectionRunInput,\n} from \"@sixb/core/storage\"\nimport { ProjectionRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport type { SQLClient, SqlParameter } from \"./pg-client\"\nimport { lockAdvisoryKeys, type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgProjectionRunStorage implements ProjectionRunStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async startOrReclaim(input: StartOrReclaimProjectionRunInput): Promise<ProjectionRunClaim> {\n assertProjectionRunStartInput(input)\n\n return runPgTransaction(this.sql, async (tx) => {\n await lockAdvisoryKeys(tx, [\n projectionRunLockKey(input.projectId, input.id),\n datasetVersionLockKey(\n input.projectId,\n input.identity.datasetVersion.datasetId,\n input.identity.datasetVersion.versionId\n ),\n ])\n const [metadataConflict] = await tx<{ readonly id: string }[]>`\n SELECT id FROM projection_runs\n WHERE project_id = ${input.projectId}\n AND id <> ${input.id}\n AND dataset_id = ${input.identity.datasetVersion.datasetId}\n AND dataset_version_id = ${input.identity.datasetVersion.versionId}\n AND dataset_version_created_at IS NOT NULL\n AND dataset_version_created_at <> ${input.identity.datasetVersion.createdAt}\n LIMIT 1\n `\n if (metadataConflict) {\n throw immutableDatasetVersionConflict(input.identity)\n }\n\n const [existingRow] = await tx<DatabaseRow[]>`\n SELECT * FROM projection_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n const existing = existingRow ? restoreProjectionRunRow(existingRow) : undefined\n const executionToken = createFreshExecutionToken(existing?.executionToken)\n\n if (existingRow && existing) {\n const { attempt } = planProjectionRunReclaim(existing, input)\n const previousExecutionToken = requireProjectionRunExecutionToken(existing)\n\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE projection_runs\n SET attempt = ${attempt}, execution_token = ${executionToken}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n AND status = ${\"running\"}\n AND execution_token = ${previousExecutionToken}\n RETURNING *\n `\n if (!updated) throw staleProjectionRunExecution(input.id)\n return projectionRunClaim(updated)\n }\n\n const [inserted] = await tx<DatabaseRow[]>`\n INSERT INTO projection_runs (\n project_id,\n id,\n projection_id,\n projection_kind,\n dataset_id,\n dataset_version_id,\n object_type_id,\n source_object_type_id,\n target_object_type_id,\n status,\n started_at,\n attempt,\n execution_token,\n materialization_protocol,\n dataset_version_created_at,\n ontology_revision,\n projection_revision,\n ownership_hash,\n fixed_batch_size,\n next_batch_ordinal,\n next_row_offset,\n input_exhausted\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.identity.projectionId},\n ${input.identity.projectionKind},\n ${input.identity.datasetVersion.datasetId},\n ${input.identity.datasetVersion.versionId},\n ${\"objectTypeId\" in input.target ? input.target.objectTypeId : null},\n ${\"sourceObjectTypeId\" in input.target ? input.target.sourceObjectTypeId : null},\n ${\"sourceObjectTypeId\" in input.target ? input.target.targetObjectTypeId : null},\n ${\"running\"},\n ${input.startedAt ?? new Date()},\n ${1},\n ${executionToken},\n ${input.identity.protocol},\n ${input.identity.datasetVersion.createdAt},\n ${input.identity.ontologyRevision},\n ${input.identity.projectionRevision},\n ${input.identity.ownershipHash},\n ${input.fixedBatchSize ?? null},\n ${input.fixedBatchSize === undefined ? null : 0},\n ${input.fixedBatchSize === undefined ? null : 0},\n ${input.fixedBatchSize === undefined ? null : false}\n )\n RETURNING *\n `\n\n return projectionRunClaim(inserted)\n })\n }\n\n async lockForMaterialization(\n input: LockProjectionRunForMaterializationInput\n ): Promise<ProjectionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const row = await requireMaterializationExecution(tx, input)\n return rowToProjectionRunRecord(row)\n })\n }\n\n async update(input: UpdateProjectionRunInput): Promise<ProjectionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existingRow = await requireMaterializationExecution(tx, input)\n const existing = restoreProjectionRunRow(existingRow)\n assertGenericProgressDoesNotAdvanceTelemetry(existing, input.progress)\n const progress = mergeProjectionRunProgress(existing.progress, input.progress)\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE projection_runs\n SET\n source_rows_read = ${progress.sourceRowsRead},\n source_rows_skipped = ${progress.sourceRowsSkipped}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n AND status = ${\"running\"}\n AND execution_token = ${input.executionToken}\n RETURNING *\n `\n if (!updated) throw staleProjectionRunExecution(input.id)\n return rowToProjectionRunRecord(updated)\n })\n }\n\n async finish(input: FinishProjectionRunInput): Promise<ProjectionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existingRow = await requireMaterializationExecution(tx, input)\n const existing = restoreProjectionRunRow(existingRow)\n const plan = planProjectionRunFinish(existing, input)\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE projection_runs\n SET\n status = ${input.status},\n finished_at = ${plan.finishedAt},\n execution_token = ${null},\n source_rows_read = ${plan.progress.sourceRowsRead},\n source_rows_skipped = ${plan.progress.sourceRowsSkipped},\n input_exhausted = ${plan.inputExhausted ?? existingRow.input_exhausted},\n error_message = ${plan.errorMessage ?? null}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n AND status = ${\"running\"}\n AND execution_token = ${input.executionToken}\n RETURNING *\n `\n if (!updated) throw staleProjectionRunExecution(input.id)\n return rowToProjectionRunRecord(updated)\n })\n }\n\n async advanceTelemetryCheckpoint(\n input: AdvanceProjectionTelemetryCheckpointInput\n ): Promise<TelemetryProjectionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existingRow = await requireMaterializationExecution(tx, input)\n const advance = advanceProjectionTelemetry(restoreProjectionRunRow(existingRow), input)\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE projection_runs\n SET\n next_batch_ordinal = ${advance.checkpoint.nextBatchOrdinal},\n next_row_offset = ${advance.checkpoint.nextRowOffset},\n input_exhausted = ${advance.checkpoint.inputExhausted},\n source_rows_read = ${advance.progress.sourceRowsRead},\n source_rows_skipped = ${advance.progress.sourceRowsSkipped},\n missing_target_object_type_id = ${null},\n missing_target_object_id = ${null},\n missing_target_batch_ordinal = ${null},\n missing_target_first_seen_at = ${null}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n AND status = ${\"running\"}\n AND execution_token = ${input.executionToken}\n AND next_batch_ordinal = ${input.batchOrdinal}\n AND input_exhausted = ${false}\n RETURNING *\n `\n if (!updated) throw staleProjectionRunExecution(input.id)\n return rowToTelemetryProjectionRunRecord(updated)\n })\n }\n\n async recordMissingTarget(\n input: RecordProjectionMissingTargetInput\n ): Promise<TelemetryProjectionRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existingRow = await requireMaterializationExecution(tx, input)\n const existing = requireTelemetryProjectionRun(restoreProjectionRunRow(existingRow))\n const missingTarget = assertProjectionMissingTarget(existing, input.missingTarget)\n const [updated] = await tx<DatabaseRow[]>`\n UPDATE projection_runs\n SET\n missing_target_object_type_id = ${missingTarget.objectTypeId},\n missing_target_object_id = ${missingTarget.objectId},\n missing_target_batch_ordinal = ${missingTarget.batchOrdinal},\n missing_target_first_seen_at = ${missingTarget.firstSeenAt}\n WHERE project_id = ${input.projectId}\n AND id = ${input.id}\n AND status = ${\"running\"}\n AND execution_token = ${input.executionToken}\n AND next_batch_ordinal = ${missingTarget.batchOrdinal}\n RETURNING *\n `\n if (!updated) throw staleProjectionRunExecution(input.id)\n return rowToTelemetryProjectionRunRecord(updated)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<ProjectionRunRecord | null> {\n const [row] = await this.sql<DatabaseRow[]>`\n SELECT * FROM projection_runs\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToProjectionRunRecord(row) : null\n }\n\n async list(input: ListProjectionRunsInput): Promise<ListProjectionRunsResult> {\n assertProjectionRunNonEmpty(input.projectId, \"projectId\")\n\n if (input.statuses && input.statuses.length === 0) {\n return { runs: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.projectionId) {\n whereClauses.push(`projection_id = $${index++}`)\n params.push(input.projectionId)\n }\n if (input.projectionKind) {\n whereClauses.push(`projection_kind = $${index++}`)\n params.push(input.projectionKind)\n }\n if (input.datasetId) {\n whereClauses.push(`dataset_id = $${index++}`)\n params.push(input.datasetId)\n }\n if (input.datasetVersionId) {\n whereClauses.push(`dataset_version_id = $${index++}`)\n params.push(input.datasetVersionId)\n }\n\n if (input.objectTypeIds) {\n if (input.objectTypeIds.length === 0) {\n return { runs: [], hasMore: false, total: 0 }\n }\n const placeholders = input.objectTypeIds.map(() => `$${index++}`)\n const list = placeholders.join(\", \")\n const sourceList = input.objectTypeIds.map(() => `$${index++}`).join(\", \")\n const targetList = input.objectTypeIds.map(() => `$${index++}`).join(\", \")\n whereClauses.push(\n `(object_type_id IN (${list})` +\n ` OR (source_object_type_id IN (${sourceList})` +\n ` AND target_object_type_id IN (${targetList})))`\n )\n params.push(...input.objectTypeIds, ...input.objectTypeIds, ...input.objectTypeIds)\n }\n\n if (input.statuses) {\n const placeholders = input.statuses.map(() => `$${index++}`)\n whereClauses.push(`status IN (${placeholders.join(\", \")})`)\n params.push(...input.statuses)\n }\n if (input.startedAfter) {\n whereClauses.push(`started_at >= $${index++}`)\n params.push(input.startedAfter)\n }\n if (input.startedBefore) {\n whereClauses.push(`started_at <= $${index++}`)\n params.push(input.startedBefore)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n assertProjectionRunListWindow(input.limit, \"limit\")\n assertProjectionRunListWindow(offset, \"offset\")\n\n const [totalRow] = await this.sql.unsafe<{ count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM projection_runs ${where}`,\n params\n )\n\n const queryParams = [...params]\n let query = `\n SELECT * FROM projection_runs\n ${where}\n ORDER BY started_at ${order}, id ${order}\n `\n if (input.limit !== undefined) {\n query += ` LIMIT $${index++} OFFSET $${index++}`\n queryParams.push(input.limit, offset)\n } else if (offset > 0) {\n query += ` OFFSET $${index++}`\n queryParams.push(offset)\n }\n\n const rows = await this.sql.unsafe<DatabaseRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n const runs = rows.map(rowToProjectionRunRecord)\n return { runs, hasMore: offset + runs.length < total, total }\n }\n\n async listLatestByProjectionIds(\n input: ListLatestProjectionRunsInput\n ): Promise<ListLatestProjectionRunsResult> {\n const rows = await queryLatestRunsByOwnerId<DatabaseRow>({\n sql: this.sql,\n tableName: \"projection_runs\",\n ownerColumn: \"projection_id\",\n ownerIds: input.projectionIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.projection_id,\n })\n\n return { runs: rows.map(rowToProjectionRunRecord) }\n }\n}\n\nasync function requireMaterializationExecution(\n sql: SQLClient,\n input: LockProjectionRunForMaterializationInput\n): Promise<DatabaseRow> {\n const row = await requireRunning(sql, input.projectId, input.id)\n assertProjectionRunExecution(restoreProjectionRunRow(row), input)\n return row\n}\n\nasync function requireRunning(sql: SQLClient, projectId: string, id: string): Promise<DatabaseRow> {\n assertProjectionRunNonEmpty(projectId, \"projectId\")\n assertProjectionRunNonEmpty(id, \"id\")\n\n const [row] = await sql<DatabaseRow[]>`\n SELECT * FROM projection_runs\n WHERE project_id = ${projectId} AND id = ${id}\n FOR UPDATE\n `\n if (!row) throw projectionRunNotFound(projectId, id)\n assertProjectionRunRunning(restoreProjectionRunRow(row))\n return row\n}\n\nfunction createFreshExecutionToken(previous: string | undefined): string {\n let token = randomUUID()\n while (token === previous) token = randomUUID()\n return token\n}\n\nfunction projectionRunLockKey(projectId: string, id: string): string {\n return `projection-run:${JSON.stringify([projectId, id])}`\n}\n\nfunction datasetVersionLockKey(projectId: string, datasetId: string, versionId: string): string {\n return `projection-dataset-version:${JSON.stringify([projectId, datasetId, versionId])}`\n}\n\nfunction rowToProjectionRunRecord(row: DatabaseRow): ProjectionRunRecord {\n return publicProjectionRunRecord(restoreProjectionRunRow(row))\n}\n\nfunction projectionRunClaim(row: DatabaseRow): ProjectionRunClaim {\n return createProjectionRunClaim(restoreProjectionRunRow(row))\n}\n\nfunction rowToTelemetryProjectionRunRecord(row: DatabaseRow): TelemetryProjectionRunRecord {\n return requireTelemetryProjectionRun(rowToProjectionRunRecord(row))\n}\n\nfunction restoreProjectionRunRow(row: DatabaseRow): StoredProjectionRunRecord {\n const persisted: PersistedProjectionRunRecord = {\n id: row.id,\n projectId: row.project_id,\n projectionId: row.projection_id,\n projectionKind: row.projection_kind,\n protocol: row.materialization_protocol ?? undefined,\n datasetId: row.dataset_id,\n datasetVersionId: row.dataset_version_id,\n datasetVersionCreatedAt: row.dataset_version_created_at ?? undefined,\n ontologyRevision: row.ontology_revision ?? undefined,\n projectionRevision: row.projection_revision ?? undefined,\n ownershipHash: row.ownership_hash ?? undefined,\n objectTypeId: row.object_type_id ?? undefined,\n sourceObjectTypeId: row.source_object_type_id ?? undefined,\n targetObjectTypeId: row.target_object_type_id ?? undefined,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n attempt: databaseSafeInteger(row.attempt, \"attempt\"),\n executionToken: row.execution_token ?? undefined,\n fixedBatchSize: optionalDatabaseSafeInteger(row.fixed_batch_size, \"fixedBatchSize\"),\n nextBatchOrdinal: optionalDatabaseSafeInteger(row.next_batch_ordinal, \"nextBatchOrdinal\"),\n nextRowOffset: optionalDatabaseSafeInteger(row.next_row_offset, \"nextRowOffset\"),\n inputExhausted: row.input_exhausted ?? undefined,\n missingTargetObjectTypeId: row.missing_target_object_type_id ?? undefined,\n missingTargetObjectId: row.missing_target_object_id ?? undefined,\n missingTargetBatchOrdinal: optionalDatabaseSafeInteger(\n row.missing_target_batch_ordinal,\n \"missingTargetBatchOrdinal\"\n ),\n missingTargetFirstSeenAt: row.missing_target_first_seen_at\n ? new Date(row.missing_target_first_seen_at)\n : undefined,\n progress: {\n sourceRowsRead: databaseSafeInteger(row.source_rows_read, \"sourceRowsRead\"),\n sourceRowsSkipped: databaseSafeInteger(row.source_rows_skipped, \"sourceRowsSkipped\"),\n },\n errorMessage: row.error_message ?? undefined,\n }\n return restoreProjectionRun(persisted)\n}\n\nfunction optionalDatabaseSafeInteger(\n value: number | string | null,\n fieldName: string\n): number | undefined {\n return value === null ? undefined : databaseSafeInteger(value, fieldName)\n}\n\nfunction databaseSafeInteger(value: number | string | null, fieldName: string): number {\n const result = Number(value)\n if (!Number.isSafeInteger(result) || result < 0) {\n throw new ProjectionRunError(\n `[SixbPg] Projection run persisted ${fieldName} is not a non-negative safe integer.`\n )\n }\n return result\n}\n\ninterface DatabaseRow {\n project_id: string\n id: string\n projection_id: string\n projection_kind: ProjectionKind\n dataset_id: string\n dataset_version_id: string\n object_type_id: string | null\n source_object_type_id: string | null\n target_object_type_id: string | null\n status: ProjectionRunStatus\n started_at: Date | string\n finished_at: Date | string | null\n attempt: number | string\n execution_token: string | null\n materialization_protocol: \"replacement\" | \"telemetry\" | null\n dataset_version_created_at: string | null\n ontology_revision: string | null\n projection_revision: string | null\n ownership_hash: string | null\n fixed_batch_size: number | string | null\n next_batch_ordinal: number | string | null\n next_row_offset: number | string | null\n input_exhausted: boolean | null\n missing_target_object_type_id: string | null\n missing_target_object_id: string | null\n missing_target_batch_ordinal: number | string | null\n missing_target_first_seen_at: Date | string | null\n source_rows_read: number | string\n source_rows_skipped: number | string\n error_message: string | null\n}\n",
44
+ "import type { RuleEventSubject } from \"@sixb/core\"\nimport type {\n ListActiveRuleStatesInput,\n ListActiveRuleStatesResult,\n ListRuleStatesReconciliationPageInput,\n ListRuleStatesReconciliationPageResult,\n RuleStateRecord,\n RuleStateTransitionEvent,\n RulesStorage,\n StoredRuleResolvedEvent,\n StoredRuleTriggeredEvent,\n} from \"@sixb/core/storage\"\nimport type { SqlParameter } from \"./pg-client\"\nimport type { PgStoreClient } from \"./transactions\"\n\nexport class PgRulesStorage implements RulesStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async getActive(params: {\n projectId: string\n ruleId: string\n subject: RuleEventSubject\n }): Promise<RuleStateRecord | null> {\n const [row] = await this.sql<RuleStateRow[]>`\n SELECT\n project_id,\n rule_id,\n subject_kind,\n object_type_id,\n primary_id,\n triggered_at\n FROM rule_states\n WHERE project_id = ${params.projectId}\n AND rule_id = ${params.ruleId}\n AND subject_kind = ${params.subject.kind}\n AND object_type_id = ${params.subject.objectTypeId}\n AND primary_id = ${params.subject.primaryId}\n `\n\n return row ? rowToRuleStateRecord(row) : null\n }\n\n async getActiveBatch(params: {\n projectId: string\n items: readonly {\n readonly ruleId: string\n readonly subject: RuleEventSubject\n }[]\n }): Promise<readonly RuleStateRecord[]> {\n if (params.items.length === 0) return []\n const requested = JSON.stringify(\n params.items.map((item) => ({\n rule_id: item.ruleId,\n subject_kind: item.subject.kind,\n object_type_id: item.subject.objectTypeId,\n primary_id: item.subject.primaryId,\n }))\n )\n const rows = await this.sql<RuleStateRow[]>`\n WITH requested AS (\n SELECT *\n FROM jsonb_to_recordset(${requested}::text::jsonb) AS identity(\n rule_id text,\n subject_kind text,\n object_type_id text,\n primary_id text\n )\n )\n SELECT project_id, rule_id, subject_kind, object_type_id, primary_id, triggered_at\n FROM rule_states AS states\n JOIN requested USING (rule_id, subject_kind, object_type_id, primary_id)\n WHERE states.project_id = ${params.projectId}\n `\n return rows.map(rowToRuleStateRecord)\n }\n\n async listActive(input: ListActiveRuleStatesInput): Promise<ListActiveRuleStatesResult> {\n if (input.objectTypeIds?.length === 0) {\n return { states: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.ruleId) {\n whereClauses.push(`rule_id = $${index++}`)\n params.push(input.ruleId)\n }\n\n if (input.objectTypeId) {\n whereClauses.push(`object_type_id = $${index++}`)\n params.push(input.objectTypeId)\n }\n\n if (input.objectTypeIds) {\n const placeholders = input.objectTypeIds.map(() => `$${index++}`)\n whereClauses.push(`object_type_id IN (${placeholders.join(\", \")})`)\n params.push(...input.objectTypeIds)\n }\n\n if (input.primaryId) {\n whereClauses.push(`primary_id = $${index++}`)\n params.push(input.primaryId)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n\n const [totalRow] = await this.sql.unsafe<{ count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM rule_states ${where}`,\n params\n )\n\n const queryParams = [...params]\n let query = `\n SELECT\n project_id,\n rule_id,\n subject_kind,\n object_type_id,\n primary_id,\n triggered_at\n FROM rule_states\n ${where}\n ORDER BY triggered_at ${order}, rule_id ${order}, object_type_id ${order}, primary_id ${order}\n `\n\n if (input.limit !== undefined) {\n query += ` LIMIT $${index++} OFFSET $${index++}`\n queryParams.push(input.limit, offset)\n } else if (offset > 0) {\n query += ` OFFSET $${index++}`\n queryParams.push(offset)\n }\n\n const rows = await this.sql.unsafe<RuleStateRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n const states = rows.map(rowToRuleStateRecord)\n\n return {\n states,\n hasMore: offset + states.length < total,\n total,\n }\n }\n\n async listReconciliationPage(\n input: ListRuleStatesReconciliationPageInput\n ): Promise<ListRuleStatesReconciliationPageResult> {\n assertPositiveLimit(input.limit)\n const params: SqlParameter[] = [input.projectId]\n const cursor = input.after ? \"AND (rule_id, object_type_id, primary_id) > ($2, $3, $4)\" : \"\"\n if (input.after) {\n params.push(input.after.ruleId, input.after.objectTypeId, input.after.primaryId)\n }\n params.push(input.limit + 1)\n const limitParameter = `$${params.length}`\n const rows = await this.sql.unsafe<RuleStateRow[]>(\n `\n SELECT project_id, rule_id, subject_kind, object_type_id, primary_id, triggered_at\n FROM rule_states\n WHERE project_id = $1 AND subject_kind = 'object' ${cursor}\n ORDER BY rule_id ASC, object_type_id ASC, primary_id ASC\n LIMIT ${limitParameter}\n `,\n params\n )\n return reconciliationPage(rows, input.limit)\n }\n\n async applyTriggered(event: StoredRuleTriggeredEvent): Promise<void> {\n await this.sql`\n INSERT INTO rule_states (\n project_id,\n rule_id,\n subject_kind,\n object_type_id,\n primary_id,\n triggered_at\n ) VALUES (\n ${event.projectId},\n ${event.payload.ruleId},\n ${event.payload.subject.kind},\n ${event.payload.subject.objectTypeId},\n ${event.payload.subject.primaryId},\n ${event.payload.triggeredAt}\n )\n ON CONFLICT (project_id, rule_id, subject_kind, object_type_id, primary_id)\n DO UPDATE SET triggered_at = excluded.triggered_at\n `\n }\n\n async applyResolved(event: StoredRuleResolvedEvent): Promise<void> {\n await this.sql`\n DELETE FROM rule_states\n WHERE project_id = ${event.projectId}\n AND rule_id = ${event.payload.ruleId}\n AND subject_kind = ${event.payload.subject.kind}\n AND object_type_id = ${event.payload.subject.objectTypeId}\n AND primary_id = ${event.payload.subject.primaryId}\n `\n }\n\n async applyTransitions(events: readonly RuleStateTransitionEvent[]): Promise<void> {\n if (events.length === 0) return\n const rows = JSON.stringify(events.map(transitionRow))\n await this.sql`\n WITH transitions AS MATERIALIZED (\n SELECT *\n FROM jsonb_to_recordset(${rows}::text::jsonb) AS transition(\n type text,\n project_id text,\n rule_id text,\n subject_kind text,\n object_type_id text,\n primary_id text,\n transition_at timestamptz\n )\n ), upserted AS (\n INSERT INTO rule_states (\n project_id, rule_id, subject_kind, object_type_id, primary_id, triggered_at\n )\n SELECT project_id, rule_id, subject_kind, object_type_id, primary_id, transition_at\n FROM transitions\n WHERE type = 'rule.triggered'\n ON CONFLICT (project_id, rule_id, subject_kind, object_type_id, primary_id)\n DO UPDATE SET triggered_at = excluded.triggered_at\n RETURNING 1\n )\n DELETE FROM rule_states AS states\n USING transitions\n WHERE transitions.type = 'rule.resolved'\n AND states.project_id = transitions.project_id\n AND states.rule_id = transitions.rule_id\n AND states.subject_kind = transitions.subject_kind\n AND states.object_type_id = transitions.object_type_id\n AND states.primary_id = transitions.primary_id\n `\n }\n}\n\nfunction transitionRow(event: RuleStateTransitionEvent) {\n return {\n type: event.type,\n project_id: event.projectId,\n rule_id: event.payload.ruleId,\n subject_kind: event.payload.subject.kind,\n object_type_id: event.payload.subject.objectTypeId,\n primary_id: event.payload.subject.primaryId,\n transition_at:\n event.type === \"rule.triggered\" ? event.payload.triggeredAt : event.payload.resolvedAt,\n }\n}\n\nfunction reconciliationPage(\n rows: readonly RuleStateRow[],\n limit: number\n): ListRuleStatesReconciliationPageResult {\n const hasMore = rows.length > limit\n const states = rows.slice(0, limit).map(rowToRuleStateRecord)\n const last = states.at(-1)\n return {\n states,\n ...(hasMore && last\n ? {\n next: {\n ruleId: last.ruleId,\n objectTypeId: last.subject.objectTypeId,\n primaryId: last.subject.primaryId,\n },\n }\n : {}),\n }\n}\n\nfunction assertPositiveLimit(limit: number): void {\n if (!Number.isSafeInteger(limit) || limit <= 0) {\n throw new Error(\"Rules reconciliation page limit must be a positive safe integer.\")\n }\n}\n\ninterface RuleStateRow {\n readonly project_id: string\n readonly rule_id: string\n readonly subject_kind: RuleEventSubject[\"kind\"]\n readonly object_type_id: string\n readonly primary_id: string\n readonly triggered_at: Date | string\n}\n\nfunction rowToRuleStateRecord(row: RuleStateRow): RuleStateRecord {\n return {\n projectId: row.project_id,\n ruleId: row.rule_id,\n subject: {\n kind: row.subject_kind,\n objectTypeId: row.object_type_id,\n primaryId: row.primary_id,\n },\n triggeredAt: toIsoString(row.triggered_at),\n }\n}\n\nfunction toIsoString(value: Date | string): string {\n return value instanceof Date ? value.toISOString() : new Date(value).toISOString()\n}\n",
45
+ "import type { JsonValue } from \"@sixb/core\"\nimport type {\n FinishSyncRunInput,\n ListLatestSyncRunsInput,\n ListLatestSyncRunsResult,\n ListSyncRunsInput,\n ListSyncRunsResult,\n StartSyncRunInput,\n SyncRunFailure,\n SyncRunRecord,\n SyncRunStorage,\n} from \"@sixb/core/storage\"\nimport { SyncRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport type { SqlParameter } from \"./pg-client\"\nimport { appendRunListFilters, hasEmptyStatuses, queryRunList } from \"./run-list-query\"\nimport { isUniqueViolation } from \"./storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgSyncRunStorage implements SyncRunStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async start(input: StartSyncRunInput): Promise<SyncRunRecord> {\n try {\n const [row] = await this.sql<DatabaseRow[]>`\n INSERT INTO sync_runs (\n project_id,\n id,\n sync_id,\n dataset_id,\n mode,\n status,\n started_at,\n expected_latest_version_id,\n commit_message\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.syncId},\n ${input.datasetId},\n ${input.mode},\n ${\"running\"},\n ${input.startedAt ?? new Date()},\n ${input.expectedLatestVersionId ?? null},\n ${input.commitMessage ?? null}\n )\n RETURNING *, checkpoint IS NOT NULL AS checkpoint_present\n `\n\n return rowToSyncRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new SyncRunError(\n `[SixbPg] Sync run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async finish(input: FinishSyncRunInput): Promise<SyncRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<DatabaseRow[]>`\n SELECT *, checkpoint IS NOT NULL AS checkpoint_present FROM sync_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n `\n\n if (!existing) {\n throw new SyncRunError(\n `[SixbPg] Sync run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (input.status === \"succeeded\") {\n if (input.output && input.output.datasetId !== existing.dataset_id) {\n throw new SyncRunError(\n `[SixbPg] Sync run '${input.id}' output dataset '${input.output.datasetId}' does not match '${existing.dataset_id}'.`\n )\n }\n if (!input.output && (existing.mode !== \"append\" || input.rowsRead !== 0)) {\n throw new SyncRunError(\n `[SixbPg] Sync run '${input.id}' may omit its output only for an empty append.`\n )\n }\n }\n\n const [updated] =\n input.status === \"succeeded\"\n ? await tx<DatabaseRow[]>`\n UPDATE sync_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n rows_read = ${input.rowsRead},\n output_version_id = ${input.output?.versionId ?? null},\n error_name = ${null},\n error_message = ${null},\n checkpoint = ${serializeCheckpoint(input.checkpoint)}::text::jsonb\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *, checkpoint IS NOT NULL AS checkpoint_present\n `\n : await tx<DatabaseRow[]>`\n UPDATE sync_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n rows_read = ${input.rowsRead ?? existing.rows_read ?? null},\n output_version_id = ${null},\n error_name = ${input.error?.name ?? null},\n error_message = ${input.error?.message ?? null},\n checkpoint = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *, checkpoint IS NOT NULL AS checkpoint_present\n `\n\n return rowToSyncRunRecord(updated)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<SyncRunRecord | null> {\n const [row] = await this.sql<DatabaseRow[]>`\n SELECT *, checkpoint IS NOT NULL AS checkpoint_present FROM sync_runs\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToSyncRunRecord(row) : null\n }\n\n async list(input: ListSyncRunsInput): Promise<ListSyncRunsResult> {\n if (hasEmptyStatuses(input) || input.syncIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.syncId) {\n whereClauses.push(`sync_id = $${index++}`)\n params.push(input.syncId)\n }\n\n if (input.syncIds) {\n const placeholders = input.syncIds.map(() => `$${index++}`)\n whereClauses.push(`sync_id IN (${placeholders.join(\", \")})`)\n params.push(...input.syncIds)\n }\n\n if (input.datasetId) {\n whereClauses.push(`dataset_id = $${index++}`)\n params.push(input.datasetId)\n }\n\n index = appendRunListFilters(whereClauses, params, index, input)\n\n const { rows, total, hasMore } = await queryRunList<DatabaseRow>({\n sql: this.sql,\n tableName: \"sync_runs\",\n selectList: \"*, checkpoint IS NOT NULL AS checkpoint_present\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n runs: rows.map(rowToSyncRunRecord),\n hasMore,\n total,\n }\n }\n\n async listLatestBySyncIds(input: ListLatestSyncRunsInput): Promise<ListLatestSyncRunsResult> {\n const rows = await queryLatestRunsByOwnerId<DatabaseRow>({\n sql: this.sql,\n tableName: \"sync_runs\",\n ownerColumn: \"sync_id\",\n ownerIds: input.syncIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.sync_id,\n selectList: \"*, checkpoint IS NOT NULL AS checkpoint_present\",\n })\n\n return {\n runs: rows.map(rowToSyncRunRecord),\n }\n }\n}\n\nfunction serializeCheckpoint(checkpoint: JsonValue | undefined): string | null {\n return checkpoint !== undefined ? JSON.stringify(checkpoint) : null\n}\n\nfunction toSyncRunFailure(row: DatabaseRow): SyncRunFailure | undefined {\n if (!row.error_message) {\n return undefined\n }\n\n return {\n name: row.error_name ?? undefined,\n message: row.error_message,\n }\n}\n\nfunction rowToSyncRunRecord(row: DatabaseRow): SyncRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n syncId: row.sync_id,\n datasetId: row.dataset_id,\n mode: row.mode,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n rowsRead: row.rows_read != null ? Number(row.rows_read) : undefined,\n output: row.output_version_id\n ? {\n datasetId: row.dataset_id,\n versionId: row.output_version_id,\n }\n : undefined,\n expectedLatestVersionId: row.expected_latest_version_id ?? undefined,\n commitMessage: row.commit_message ?? undefined,\n error: toSyncRunFailure(row),\n checkpoint: hasCheckpoint(row) ? row.checkpoint : undefined,\n }\n}\n\nfunction hasCheckpoint(row: DatabaseRow): boolean {\n return (\n row.checkpoint_present === true ||\n row.checkpoint_present === 1 ||\n row.checkpoint_present === \"1\" ||\n row.checkpoint_present === \"t\" ||\n row.checkpoint_present === \"true\"\n )\n}\n\ninterface DatabaseRow {\n project_id: string\n id: string\n sync_id: string\n dataset_id: string\n mode: SyncRunRecord[\"mode\"]\n status: SyncRunRecord[\"status\"]\n started_at: Date | string\n finished_at: Date | string | null\n rows_read: number | string | null\n output_version_id: string | null\n expected_latest_version_id: string | null\n commit_message: string | null\n error_name: string | null\n error_message: string | null\n checkpoint: JsonValue | null\n checkpoint_present: boolean | number | string\n}\n",
46
+ "import type {\n TimeseriesHistoryBatchInput,\n TimeseriesHistoryBatchResult,\n TimeseriesPoint,\n TimeseriesStorage,\n} from \"@sixb/core/storage\"\nimport type { SqlParameter } from \"./pg-client\"\nimport type { PgStoreClient } from \"./transactions\"\n\n/**\n * PostgreSQL-based TimeseriesStorage implementation.\n *\n * Stores time-series data with JSONB values and TIMESTAMPTZ timestamps\n * for efficient querying of history and latest values.\n *\n * Requires `search_path` to be set to the Sixb schema on the connection.\n */\nexport class PgTimeseriesStorage implements TimeseriesStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async getHistory(params: {\n projectId: string\n objectTypeId: string\n objectId: string\n propertyId: string\n from?: Date\n to?: Date\n limit?: number\n order?: \"asc\" | \"desc\"\n }): Promise<readonly TimeseriesPoint[]> {\n const order = params.order ?? \"asc\"\n\n // Build WHERE conditions using conditional fragments\n const fromFilter = params.from ? this.sql`AND at >= ${params.from}` : this.sql``\n const toFilter = params.to ? this.sql`AND at <= ${params.to}` : this.sql``\n const limitFilter = params.limit !== undefined ? this.sql`LIMIT ${params.limit}` : this.sql``\n\n const rows = await this.sql<TimeseriesDatabaseRow[]>`\n SELECT * FROM timeseries\n WHERE project_id = ${params.projectId}\n AND object_type_id = ${params.objectTypeId}\n AND object_id = ${params.objectId}\n AND property_id = ${params.propertyId}\n ${fromFilter}\n ${toFilter}\n ORDER BY at ${order === \"asc\" ? this.sql`ASC` : this.sql`DESC`}\n ${limitFilter}\n `\n\n return rows.map((row) => rowToPoint(row))\n }\n\n async getHistoryBatch(\n input: TimeseriesHistoryBatchInput\n ): Promise<readonly TimeseriesHistoryBatchResult[]> {\n if (input.series.length === 0) {\n return []\n }\n\n const order = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const params: unknown[] = []\n let nextIndex = 1\n const values = input.series\n .map((series, seriesIndex) => {\n const placeholders = [\n `$${nextIndex++}`,\n `$${nextIndex++}`,\n `$${nextIndex++}`,\n `$${nextIndex++}`,\n ]\n params.push(seriesIndex, series.objectTypeId, series.objectId, series.propertyId)\n return `(${placeholders.join(\", \")})`\n })\n .join(\", \")\n\n const projectIdPlaceholder = `$${nextIndex++}`\n params.push(input.projectId)\n\n const whereClauses = [\"1 = 1\"]\n if (input.from) {\n whereClauses.push(`timeseries.at >= $${nextIndex++}`)\n params.push(input.from)\n }\n if (input.to) {\n whereClauses.push(`timeseries.at <= $${nextIndex++}`)\n params.push(input.to)\n }\n\n let query = `\n WITH requested(series_index, object_type_id, object_id, property_id) AS (\n VALUES ${values}\n ),\n ranked AS (\n SELECT\n requested.series_index,\n timeseries.*,\n ROW_NUMBER() OVER (\n PARTITION BY requested.series_index\n ORDER BY timeseries.at ${order}\n ) AS series_row_number\n FROM requested\n JOIN timeseries\n ON timeseries.project_id = ${projectIdPlaceholder}\n AND timeseries.object_type_id = requested.object_type_id\n AND timeseries.object_id = requested.object_id\n AND timeseries.property_id = requested.property_id\n WHERE ${whereClauses.join(\" AND \")}\n )\n SELECT * FROM ranked\n `\n\n if (input.limitPerSeries !== undefined) {\n query += ` WHERE series_row_number <= $${nextIndex++}`\n params.push(Math.max(0, input.limitPerSeries))\n }\n\n query += ` ORDER BY series_index ASC, at ${order}`\n\n const rows = await this.sql.unsafe<\n (TimeseriesDatabaseRow & {\n series_index: number | string\n series_row_number: number | string\n })[]\n >(query, params as SqlParameter[])\n const results = input.series.map((series) => ({\n ...series,\n points: [] as TimeseriesPoint[],\n }))\n\n for (const row of rows) {\n const result = results[Number(row.series_index)]\n if (result) {\n result.points.push(rowToPoint(row))\n }\n }\n\n return results\n }\n\n async getLatest(params: {\n projectId: string\n objectTypeId: string\n objectId: string\n propertyId: string\n }): Promise<TimeseriesPoint | null> {\n const [row] = await this.sql<TimeseriesDatabaseRow[]>`\n SELECT * FROM timeseries_latest\n WHERE project_id = ${params.projectId}\n AND object_type_id = ${params.objectTypeId}\n AND object_id = ${params.objectId}\n AND property_id = ${params.propertyId}\n `\n\n return row ? rowToPoint(row) : null\n }\n}\n\nfunction rowToPoint(row: TimeseriesDatabaseRow): TimeseriesPoint {\n return {\n projectId: row.project_id,\n objectTypeId: row.object_type_id,\n objectId: row.object_id,\n propertyId: row.property_id,\n value: row.value,\n unit: row.unit ?? undefined,\n at: new Date(row.at),\n lastCommitId: row.last_commit_id,\n }\n}\n\ninterface TimeseriesDatabaseRow {\n project_id: string\n object_type_id: string\n object_id: string\n property_id: string\n value: unknown\n unit: string | null\n at: Date | string\n last_commit_id: string\n}\n",
47
+ "import type {\n WebhookDeliveryClaimRecord,\n WebhookDeliveryClaimResult,\n WebhookDeliveryKey,\n WebhookDeliveryRecord,\n WebhookDeliveryStorage,\n} from \"@sixb/core/storage\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgWebhookDeliveryStorage implements WebhookDeliveryStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async claim(\n input: WebhookDeliveryKey & { receivedAt: string }\n ): Promise<WebhookDeliveryClaimRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n // Atomic first claim: only one transaction can insert this scoped delivery key.\n const [inserted] = await tx<WebhookDeliveryRow[]>`\n INSERT INTO webhook_deliveries (\n project_id,\n connector_id,\n webhook_id,\n idempotency_key,\n status,\n received_at\n ) VALUES (\n ${input.projectId},\n ${input.connectorId},\n ${input.webhookId},\n ${input.idempotencyKey},\n ${\"in_progress\"},\n ${input.receivedAt}\n )\n ON CONFLICT (project_id, connector_id, webhook_id, idempotency_key) DO NOTHING\n RETURNING *\n `\n\n if (inserted) {\n return toWebhookDeliveryClaimRecord(inserted, \"claimed\")\n }\n\n const [existing] = await tx<WebhookDeliveryRow[]>`\n SELECT * FROM webhook_deliveries\n WHERE project_id = ${input.projectId}\n AND connector_id = ${input.connectorId}\n AND webhook_id = ${input.webhookId}\n AND idempotency_key = ${input.idempotencyKey}\n FOR UPDATE\n `\n\n if (existing?.status === \"completed\") {\n return toWebhookDeliveryClaimRecord(existing, \"duplicate\")\n }\n\n if (existing?.status === \"in_progress\") {\n return toWebhookDeliveryClaimRecord(existing, \"in_progress\")\n }\n\n if (existing?.status !== \"failed\") {\n throw new Error(\"[SixbPg] Webhook delivery row disappeared during claim.\")\n }\n\n // Failed deliveries are intentionally claimable so provider retries can run again.\n const [updated] = await tx<WebhookDeliveryRow[]>`\n UPDATE webhook_deliveries\n SET status = ${\"in_progress\"},\n received_at = ${input.receivedAt},\n completed_at = ${null},\n failed_at = ${null},\n error = ${null}\n WHERE project_id = ${input.projectId}\n AND connector_id = ${input.connectorId}\n AND webhook_id = ${input.webhookId}\n AND idempotency_key = ${input.idempotencyKey}\n RETURNING *\n `\n\n if (!updated) {\n throw new Error(\n `[SixbPg] Missing webhook delivery row after claim for ${serializeKey(input)}.`\n )\n }\n\n return toWebhookDeliveryClaimRecord(updated, \"claimed\")\n })\n }\n\n async complete(\n input: WebhookDeliveryKey & { completedAt: string }\n ): Promise<WebhookDeliveryRecord> {\n const [updated] = await this.sql<WebhookDeliveryRow[]>`\n UPDATE webhook_deliveries\n SET status = ${\"completed\"},\n completed_at = ${input.completedAt},\n failed_at = ${null},\n error = ${null}\n WHERE project_id = ${input.projectId}\n AND connector_id = ${input.connectorId}\n AND webhook_id = ${input.webhookId}\n AND idempotency_key = ${input.idempotencyKey}\n RETURNING *\n `\n\n if (!updated) {\n throw new Error(\n `[SixbPg] Missing webhook delivery row after complete for ${serializeKey(input)}.`\n )\n }\n\n return toWebhookDeliveryRecord(updated)\n }\n\n async fail(\n input: WebhookDeliveryKey & { failedAt: string; error: string }\n ): Promise<WebhookDeliveryRecord> {\n const [updated] = await this.sql<WebhookDeliveryRow[]>`\n UPDATE webhook_deliveries\n SET status = ${\"failed\"},\n failed_at = ${input.failedAt},\n error = ${input.error}\n WHERE project_id = ${input.projectId}\n AND connector_id = ${input.connectorId}\n AND webhook_id = ${input.webhookId}\n AND idempotency_key = ${input.idempotencyKey}\n RETURNING *\n `\n\n if (!updated) {\n throw new Error(\n `[SixbPg] Missing webhook delivery row after fail for ${serializeKey(input)}.`\n )\n }\n\n return toWebhookDeliveryRecord(updated)\n }\n}\n\nfunction toWebhookDeliveryClaimRecord(\n row: WebhookDeliveryRow,\n claimResult: WebhookDeliveryClaimResult\n): WebhookDeliveryClaimRecord {\n return {\n ...toWebhookDeliveryRecord(row),\n claimResult,\n }\n}\n\nfunction toWebhookDeliveryRecord(row: WebhookDeliveryRow): WebhookDeliveryRecord {\n return {\n projectId: row.project_id,\n connectorId: row.connector_id,\n webhookId: row.webhook_id,\n idempotencyKey: row.idempotency_key,\n status: row.status,\n receivedAt: toIsoString(row.received_at),\n completedAt: row.completed_at ? toIsoString(row.completed_at) : undefined,\n failedAt: row.failed_at ? toIsoString(row.failed_at) : undefined,\n error: row.error ?? undefined,\n }\n}\n\nfunction toIsoString(value: Date | string): string {\n return value instanceof Date ? value.toISOString() : new Date(value).toISOString()\n}\n\nfunction serializeKey(key: WebhookDeliveryKey): string {\n return JSON.stringify([key.projectId, key.connectorId, key.webhookId, key.idempotencyKey])\n}\n\ninterface WebhookDeliveryRow {\n readonly project_id: string\n readonly connector_id: string\n readonly webhook_id: string\n readonly idempotency_key: string\n readonly status: WebhookDeliveryRecord[\"status\"]\n readonly received_at: Date | string\n readonly completed_at: Date | string | null\n readonly failed_at: Date | string | null\n readonly error: string | null\n}\n",
48
+ "import type {\n FinishWebhookRunInput,\n ListWebhookRunsInput,\n ListWebhookRunsResult,\n StartWebhookRunInput,\n WebhookRunRecord,\n WebhookRunStorage,\n} from \"@sixb/core/storage\"\nimport { WebhookRunError } from \"@sixb/core/storage\"\nimport type { SqlParameter } from \"./pg-client\"\nimport { appendRunListFilters, hasEmptyStatuses, queryRunList } from \"./run-list-query\"\nimport { isUniqueViolation } from \"./storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgWebhookRunStorage implements WebhookRunStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async start(input: StartWebhookRunInput): Promise<WebhookRunRecord> {\n try {\n const [row] = await this.sql<WebhookRunDatabaseRow[]>`\n INSERT INTO webhook_runs (\n project_id,\n id,\n connector_id,\n webhook_id,\n status,\n method,\n route,\n started_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.connectorId},\n ${input.webhookId},\n ${\"running\"},\n ${input.method},\n ${input.route},\n ${input.startedAt ?? new Date()}\n )\n RETURNING *\n `\n\n return rowToWebhookRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new WebhookRunError(\n `[SixbPg] Webhook run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async finish(input: FinishWebhookRunInput): Promise<WebhookRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<WebhookRunDatabaseRow[]>`\n SELECT * FROM webhook_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new WebhookRunError(\n `[SixbPg] Webhook run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new WebhookRunError(\n `[SixbPg] Webhook run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n const [updated] = await tx<WebhookRunDatabaseRow[]>`\n UPDATE webhook_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n request_body_bytes = ${input.requestBodyBytes ?? null},\n response_status = ${input.responseStatus ?? null},\n idempotency_key = ${input.idempotencyKey ?? null},\n delivery_claim_result = ${input.deliveryClaimResult ?? null},\n error = ${input.status === \"succeeded\" ? null : (input.error ?? null)}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWebhookRunRecord(updated)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<WebhookRunRecord | null> {\n const [row] = await this.sql<WebhookRunDatabaseRow[]>`\n SELECT * FROM webhook_runs\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToWebhookRunRecord(row) : null\n }\n\n async list(input: ListWebhookRunsInput): Promise<ListWebhookRunsResult> {\n if (hasEmptyStatuses(input)) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.connectorId) {\n whereClauses.push(`connector_id = $${index++}`)\n params.push(input.connectorId)\n }\n\n if (input.webhookId) {\n whereClauses.push(`webhook_id = $${index++}`)\n params.push(input.webhookId)\n }\n\n if (input.idempotencyKey) {\n whereClauses.push(`idempotency_key = $${index++}`)\n params.push(input.idempotencyKey)\n }\n\n index = appendRunListFilters(whereClauses, params, index, input)\n\n const { rows, total, hasMore } = await queryRunList<WebhookRunDatabaseRow>({\n sql: this.sql,\n tableName: \"webhook_runs\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n runs: rows.map(rowToWebhookRunRecord),\n hasMore,\n total,\n }\n }\n}\n\nfunction rowToWebhookRunRecord(row: WebhookRunDatabaseRow): WebhookRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n connectorId: row.connector_id,\n webhookId: row.webhook_id,\n status: row.status,\n method: row.method,\n route: row.route,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n requestBodyBytes: row.request_body_bytes != null ? Number(row.request_body_bytes) : undefined,\n responseStatus: row.response_status != null ? Number(row.response_status) : undefined,\n idempotencyKey: row.idempotency_key ?? undefined,\n deliveryClaimResult: row.delivery_claim_result ?? undefined,\n error: row.error ?? undefined,\n }\n}\n\ninterface WebhookRunDatabaseRow {\n readonly project_id: string\n readonly id: string\n readonly connector_id: string\n readonly webhook_id: string\n readonly status: WebhookRunRecord[\"status\"]\n readonly method: string\n readonly route: string\n readonly started_at: Date | string\n readonly finished_at: Date | string | null\n readonly request_body_bytes: number | string | null\n readonly response_status: number | string | null\n readonly idempotency_key: string | null\n readonly delivery_claim_result: WebhookRunRecord[\"deliveryClaimResult\"] | null\n readonly error: string | null\n}\n",
49
+ "import type { WorkflowIOSnapshot } from \"@sixb/core/internal/workflows\"\nimport type {\n CancelWorkflowInterventionInput,\n CreateWorkflowInterventionInput,\n ExpireWorkflowInterventionInput,\n ListWorkflowInterventionsInput,\n ListWorkflowInterventionsResult,\n SubmitWorkflowInterventionInput,\n WorkflowInterventionActor,\n WorkflowInterventionRecord,\n WorkflowInterventionStorage,\n} from \"@sixb/core/storage\"\nimport { WorkflowInterventionError } from \"@sixb/core/storage\"\nimport type { SQLClient, SqlParameter } from \"./pg-client\"\nimport { isUniqueViolation } from \"./storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgWorkflowInterventionStorage implements WorkflowInterventionStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n assertNonNegativeInteger(input.nodeIndex, \"nodeIndex\")\n\n try {\n const [row] = await this.sql<WorkflowInterventionDatabaseRow[]>`\n INSERT INTO workflow_interventions (\n project_id,\n id,\n workflow_id,\n workflow_run_id,\n node_run_id,\n node_index,\n node_id,\n node_key,\n intervention_id,\n input,\n default_response,\n status,\n requested_at,\n expires_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.workflowId},\n ${input.workflowRunId},\n ${input.nodeRunId},\n ${input.nodeIndex},\n ${input.nodeId},\n ${input.nodeKey},\n ${input.interventionId},\n ${serializeRecord(input.input)}::text::jsonb,\n ${serializeRecord(input.defaultResponse)}::text::jsonb,\n ${\"pending\"},\n ${input.requestedAt ?? new Date()},\n ${input.expiresAt ?? null}\n )\n RETURNING *\n `\n\n return rowToWorkflowInterventionRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new WorkflowInterventionError(\n `[SixbPg] Workflow intervention '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async submit(input: SubmitWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await requirePendingIntervention(tx, input.projectId, input.id)\n\n const [updated] = await tx<WorkflowInterventionDatabaseRow[]>`\n UPDATE workflow_interventions\n SET\n status = ${\"submitted\"},\n submitted_at = ${input.submittedAt ?? new Date()},\n submitted_by = ${serializeActor(input.submittedBy)}::text::jsonb,\n response = ${serializeRecord(input.response)}::text::jsonb\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowInterventionRecord(updated)\n })\n }\n\n async cancel(input: CancelWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await requirePendingIntervention(tx, input.projectId, input.id)\n\n const [updated] = await tx<WorkflowInterventionDatabaseRow[]>`\n UPDATE workflow_interventions\n SET\n status = ${\"cancelled\"},\n cancelled_at = ${input.cancelledAt ?? new Date()},\n cancelled_by = ${serializeActor(input.cancelledBy)}::text::jsonb\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowInterventionRecord(updated)\n })\n }\n\n async expire(input: ExpireWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n await requirePendingIntervention(tx, input.projectId, input.id)\n\n const [updated] = await tx<WorkflowInterventionDatabaseRow[]>`\n UPDATE workflow_interventions\n SET\n status = ${\"expired\"},\n expired_at = ${input.expiredAt ?? new Date()}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowInterventionRecord(updated)\n })\n }\n\n async getById(params: {\n projectId: string\n id: string\n }): Promise<WorkflowInterventionRecord | null> {\n const [row] = await this.sql<WorkflowInterventionDatabaseRow[]>`\n SELECT * FROM workflow_interventions\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToWorkflowInterventionRecord(row) : null\n }\n\n async list(input: ListWorkflowInterventionsInput): Promise<ListWorkflowInterventionsResult> {\n if ((input.statuses && input.statuses.length === 0) || input.workflowIds?.length === 0) {\n return {\n interventions: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.statuses) {\n const placeholders = input.statuses.map(() => `$${index++}`)\n whereClauses.push(`status IN (${placeholders.join(\", \")})`)\n params.push(...input.statuses)\n }\n\n if (input.workflowId) {\n whereClauses.push(`workflow_id = $${index++}`)\n params.push(input.workflowId)\n }\n\n if (input.workflowIds) {\n const placeholders = input.workflowIds.map(() => `$${index++}`)\n whereClauses.push(`workflow_id IN (${placeholders.join(\", \")})`)\n params.push(...input.workflowIds)\n }\n\n if (input.workflowRunId) {\n whereClauses.push(`workflow_run_id = $${index++}`)\n params.push(input.workflowRunId)\n }\n\n if (input.nodeRunId) {\n whereClauses.push(`node_run_id = $${index++}`)\n params.push(input.nodeRunId)\n }\n\n if (input.nodeId) {\n whereClauses.push(`node_id = $${index++}`)\n params.push(input.nodeId)\n }\n\n if (input.nodeKey) {\n whereClauses.push(`node_key = $${index++}`)\n params.push(input.nodeKey)\n }\n\n if (input.interventionId) {\n whereClauses.push(`intervention_id = $${index++}`)\n params.push(input.interventionId)\n }\n\n if (input.requestedAfter) {\n whereClauses.push(`requested_at >= $${index++}`)\n params.push(input.requestedAfter)\n }\n\n if (input.requestedBefore) {\n whereClauses.push(`requested_at <= $${index++}`)\n params.push(input.requestedBefore)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n const [totalRow] = await this.sql.unsafe<{ count: string | number }[]>(\n `SELECT COUNT(*)::bigint AS count FROM workflow_interventions ${where}`,\n params\n )\n\n const queryParams = [...params]\n let query = `\n SELECT * FROM workflow_interventions\n ${where}\n ORDER BY requested_at ${order}, id ${order}\n `\n\n if (input.limit !== undefined) {\n query += ` LIMIT $${index++} OFFSET $${index++}`\n queryParams.push(input.limit, offset)\n } else if (offset > 0) {\n query += ` OFFSET $${index++}`\n queryParams.push(offset)\n }\n\n const rows = await this.sql.unsafe<WorkflowInterventionDatabaseRow[]>(query, queryParams)\n const total = Number(totalRow?.count ?? 0)\n\n return {\n interventions: rows.map(rowToWorkflowInterventionRecord),\n hasMore: offset + rows.length < total,\n total,\n }\n }\n}\n\nasync function requirePendingIntervention(\n sql: SQLClient,\n projectId: string,\n id: string\n): Promise<WorkflowInterventionDatabaseRow> {\n const [row] = await sql<WorkflowInterventionDatabaseRow[]>`\n SELECT * FROM workflow_interventions\n WHERE project_id = ${projectId} AND id = ${id}\n FOR UPDATE\n `\n\n if (!row) {\n throw new WorkflowInterventionError(\n `[SixbPg] Workflow intervention '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.status !== \"pending\") {\n throw new WorkflowInterventionError(\n `[SixbPg] Workflow intervention '${id}' for project '${projectId}' is not pending.`\n )\n }\n\n return row\n}\n\nfunction serializeRecord(value: WorkflowIOSnapshot): string {\n return JSON.stringify(value)\n}\n\nfunction parseRecord(value: WorkflowIOSnapshot | string): WorkflowIOSnapshot {\n return typeof value === \"string\" ? (JSON.parse(value) as WorkflowIOSnapshot) : value\n}\n\nfunction serializeActor(actor: WorkflowInterventionActor | undefined): string | null {\n return actor ? JSON.stringify(actor) : null\n}\n\nfunction parseActor(\n value: WorkflowInterventionActor | string | null\n): WorkflowInterventionActor | undefined {\n return typeof value === \"string\"\n ? (JSON.parse(value) as WorkflowInterventionActor)\n : (value ?? undefined)\n}\n\nfunction rowToWorkflowInterventionRecord(\n row: WorkflowInterventionDatabaseRow\n): WorkflowInterventionRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n workflowId: row.workflow_id,\n workflowRunId: row.workflow_run_id,\n nodeRunId: row.node_run_id,\n nodeIndex: Number(row.node_index),\n nodeId: row.node_id,\n nodeKey: row.node_key,\n interventionId: row.intervention_id,\n input: parseRecord(row.input),\n defaultResponse: parseRecord(row.default_response),\n status: row.status,\n requestedAt: new Date(row.requested_at),\n expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,\n submittedAt: row.submitted_at ? new Date(row.submitted_at) : undefined,\n submittedBy: parseActor(row.submitted_by),\n response: row.response ? parseRecord(row.response) : undefined,\n cancelledAt: row.cancelled_at ? new Date(row.cancelled_at) : undefined,\n cancelledBy: parseActor(row.cancelled_by),\n expiredAt: row.expired_at ? new Date(row.expired_at) : undefined,\n }\n}\n\nfunction assertNonNegativeInteger(value: number, fieldName: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new WorkflowInterventionError(\n `[SixbPg] Workflow intervention ${fieldName} must be a non-negative integer.`\n )\n }\n}\n\ninterface WorkflowInterventionDatabaseRow {\n project_id: string\n id: string\n workflow_id: string\n workflow_run_id: string\n node_run_id: string\n node_index: number | string\n node_id: string\n node_key: string\n intervention_id: string\n input: WorkflowIOSnapshot | string\n default_response: WorkflowIOSnapshot | string\n status: WorkflowInterventionRecord[\"status\"]\n requested_at: Date | string\n expires_at: Date | string | null\n submitted_at: Date | string | null\n submitted_by: WorkflowInterventionActor | string | null\n response: WorkflowIOSnapshot | string | null\n cancelled_at: Date | string | null\n cancelled_by: WorkflowInterventionActor | string | null\n expired_at: Date | string | null\n}\n",
50
+ "import type { Principal, WorkflowRunSource } from \"@sixb/core\"\nimport type { WorkflowIOSnapshot } from \"@sixb/core/internal/workflows\"\nimport type {\n CancelWorkflowAgentNodeRunInput,\n ConfirmWorkflowAgentNodeRunExecutionOwnershipInput,\n ConfirmWorkflowRunExecutionOwnershipInput,\n CreateWorkflowAgentNodeRunInput,\n FinishWorkflowAgentNodeRunInput,\n FinishWorkflowNodeRunInput,\n FinishWorkflowRunInput,\n ListLatestWorkflowRunsInput,\n ListLatestWorkflowRunsResult,\n ListWorkflowAgentNodeRunsInput,\n ListWorkflowAgentNodeRunsResult,\n ListWorkflowNodeRunsInput,\n ListWorkflowNodeRunsResult,\n ListWorkflowRunsInput,\n ListWorkflowRunsResult,\n QueueWorkflowRunInput,\n ReclaimWorkflowAgentNodeRunInput,\n ReclaimWorkflowRunInput,\n ResumeWorkflowRunInput,\n StartWorkflowAgentNodeRunInput,\n StartWorkflowNodeRunInput,\n StartWorkflowRunInput,\n WaitWorkflowNodeRunInput,\n WaitWorkflowRunInput,\n WorkflowAgentNodeRunRecord,\n WorkflowAgentNodeRunStorage,\n WorkflowNodeRunRecord,\n WorkflowNodeRunStorage,\n WorkflowRunRecord,\n WorkflowRunStorage,\n} from \"@sixb/core/storage\"\nimport { WorkflowRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport type { SqlParameter } from \"./pg-client\"\nimport { appendRunListFilters, hasEmptyStatuses, queryRunList } from \"./run-list-query\"\nimport { isUniqueViolation } from \"./storage-errors\"\nimport { type PgStoreClient, runPgTransaction } from \"./transactions\"\n\nexport class PgWorkflowRunStorage implements WorkflowRunStorage {\n readonly nodes: PgWorkflowNodeRunStorage\n readonly agentNodes: PgWorkflowAgentNodeRunStorage\n\n constructor(private readonly sql: PgStoreClient) {\n this.nodes = new PgWorkflowNodeRunStorage(sql)\n this.agentNodes = new PgWorkflowAgentNodeRunStorage(sql)\n }\n\n async queue(input: QueueWorkflowRunInput): Promise<WorkflowRunRecord> {\n const queuedAt = input.queuedAt ?? new Date()\n\n try {\n const [row] = await this.sql<WorkflowRunDatabaseRow[]>`\n INSERT INTO workflow_runs (\n project_id,\n id,\n workflow_id,\n status,\n input,\n queued_at,\n started_at,\n source,\n requested_by_principal_type,\n requested_by_principal_id,\n attempt\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.workflowId},\n ${\"queued\"},\n ${serializeRecord(input.input)}::text::jsonb,\n ${queuedAt},\n ${queuedAt},\n ${input.source ? JSON.stringify(input.source) : null}::text::jsonb,\n ${input.requestedByPrincipal?.type ?? \"system\"},\n ${input.requestedByPrincipal?.id ?? \"system\"},\n ${0}\n )\n RETURNING *\n `\n\n return rowToWorkflowRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n }\n\n async start(input: StartWorkflowRunInput): Promise<WorkflowRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const startedAt = input.startedAt ?? new Date()\n const [existing] = await tx<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (existing) {\n if (existing.status !== \"queued\") {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n if (existing.workflow_id !== input.workflowId) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' workflow '${input.workflowId}' does not match existing workflow '${existing.workflow_id}'.`\n )\n }\n\n const [updated] = await tx<WorkflowRunDatabaseRow[]>`\n UPDATE workflow_runs\n SET\n status = ${\"running\"},\n input = ${serializeRecord(input.input)}::text::jsonb,\n started_at = ${startedAt},\n finished_at = ${null},\n error = ${null},\n source = COALESCE(\n source,\n ${input.source ? JSON.stringify(input.source) : null}::text::jsonb\n ),\n attempt = attempt + 1,\n execution_token = ${input.execution?.token ?? null},\n execution_queue_lease_expires_at = ${input.execution?.queueLeaseExpiresAt ?? null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowRunRecord(updated)\n }\n\n try {\n const [row] = await tx<WorkflowRunDatabaseRow[]>`\n INSERT INTO workflow_runs (\n project_id,\n id,\n workflow_id,\n status,\n input,\n started_at,\n source,\n requested_by_principal_type,\n requested_by_principal_id,\n attempt,\n execution_token,\n execution_queue_lease_expires_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.workflowId},\n ${\"running\"},\n ${serializeRecord(input.input)}::text::jsonb,\n ${startedAt},\n ${input.source ? JSON.stringify(input.source) : null}::text::jsonb,\n ${input.requestedByPrincipal?.type ?? \"system\"},\n ${input.requestedByPrincipal?.id ?? \"system\"},\n ${1},\n ${input.execution?.token ?? null},\n ${input.execution?.queueLeaseExpiresAt ?? null}\n )\n RETURNING *\n `\n\n return rowToWorkflowRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n })\n }\n\n async reclaim(input: ReclaimWorkflowRunInput): Promise<WorkflowRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existing = await lockWorkflowRun(tx, input.projectId, input.id, \"running\")\n const [updated] = await tx<WorkflowRunDatabaseRow[]>`\n UPDATE workflow_runs SET\n attempt = ${Number(existing.attempt) + 1},\n execution_token = ${input.execution.token},\n execution_queue_lease_expires_at = ${input.execution.queueLeaseExpiresAt}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n return rowToWorkflowRunRecord(updated)\n })\n }\n\n async confirmExecutionOwnership(\n input: ConfirmWorkflowRunExecutionOwnershipInput\n ): Promise<WorkflowRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const existing = await lockWorkflowRun(tx, input.projectId, input.id, \"running\")\n assertWorkflowRunExecutionOwnership(existing, input.executionToken)\n const current = existing.execution_queue_lease_expires_at\n ? new Date(existing.execution_queue_lease_expires_at)\n : input.queueLeaseExpiresAt\n const [updated] = await tx<WorkflowRunDatabaseRow[]>`\n UPDATE workflow_runs SET execution_queue_lease_expires_at = ${new Date(\n Math.max(current.getTime(), input.queueLeaseExpiresAt.getTime())\n )}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n return rowToWorkflowRunRecord(updated)\n })\n }\n\n async finish(input: FinishWorkflowRunInput): Promise<WorkflowRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (!canFinishWorkflowRun(existing.status, input.status)) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' for project '${input.projectId}' cannot be finished from status '${existing.status}'.`\n )\n }\n assertWorkflowRunExecutionOwnership(existing, input.executionToken)\n\n const [updated] =\n input.status === \"succeeded\"\n ? await tx<WorkflowRunDatabaseRow[]>`\n UPDATE workflow_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n error = ${null},\n execution_token = ${null},\n execution_queue_lease_expires_at = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n : await tx<WorkflowRunDatabaseRow[]>`\n UPDATE workflow_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n error = ${input.error ?? null},\n execution_token = ${null},\n execution_queue_lease_expires_at = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowRunRecord(updated)\n })\n }\n\n async wait(input: WaitWorkflowRunInput): Promise<WorkflowRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' for project '${input.projectId}' must be running.`\n )\n }\n assertWorkflowRunExecutionOwnership(existing, input.executionToken)\n\n const [updated] = await tx<WorkflowRunDatabaseRow[]>`\n UPDATE workflow_runs\n SET\n status = ${\"waiting\"},\n finished_at = ${null},\n error = ${null},\n execution_token = ${null},\n execution_queue_lease_expires_at = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowRunRecord(updated)\n })\n }\n\n async resume(input: ResumeWorkflowRunInput): Promise<WorkflowRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"waiting\") {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.id}' for project '${input.projectId}' must be waiting.`\n )\n }\n\n const [updated] = await tx<WorkflowRunDatabaseRow[]>`\n UPDATE workflow_runs\n SET\n status = ${\"running\"},\n finished_at = ${null},\n error = ${null},\n attempt = attempt + 1,\n execution_token = ${input.execution?.token ?? null},\n execution_queue_lease_expires_at = ${input.execution?.queueLeaseExpiresAt ?? null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowRunRecord(updated)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<WorkflowRunRecord | null> {\n const [row] = await this.sql<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToWorkflowRunRecord(row) : null\n }\n\n async list(input: ListWorkflowRunsInput): Promise<ListWorkflowRunsResult> {\n if (hasEmptyStatuses(input) || input.workflowIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.workflowId) {\n whereClauses.push(`workflow_id = $${index++}`)\n params.push(input.workflowId)\n }\n\n if (input.workflowIds) {\n const placeholders = input.workflowIds.map(() => `$${index++}`)\n whereClauses.push(`workflow_id IN (${placeholders.join(\", \")})`)\n params.push(...input.workflowIds)\n }\n\n index = appendRunListFilters(whereClauses, params, index, input)\n\n const { rows, total, hasMore } = await queryRunList<WorkflowRunDatabaseRow>({\n sql: this.sql,\n tableName: \"workflow_runs\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n const runs = rows.map(rowToWorkflowRunRecord)\n\n return {\n runs,\n hasMore,\n total,\n }\n }\n\n async listLatestByWorkflowIds(\n input: ListLatestWorkflowRunsInput\n ): Promise<ListLatestWorkflowRunsResult> {\n const rows = await queryLatestRunsByOwnerId<WorkflowRunDatabaseRow>({\n sql: this.sql,\n tableName: \"workflow_runs\",\n ownerColumn: \"workflow_id\",\n ownerIds: input.workflowIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.workflow_id,\n })\n\n return {\n runs: rows.map(rowToWorkflowRunRecord),\n }\n }\n}\n\nexport class PgWorkflowAgentNodeRunStorage implements WorkflowAgentNodeRunStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async create(input: CreateWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n try {\n const [row] = await this.sql<WorkflowAgentNodeRunDatabaseRow[]>`\n INSERT INTO workflow_agent_node_runs (\n project_id, node_run_id, agent_id, status, prompt, attempt, created_at\n ) VALUES (\n ${input.projectId}, ${input.nodeRunId}, ${input.agentId}, ${\"queued\"},\n ${input.prompt}, ${0}, ${input.createdAt ?? new Date()}\n ) RETURNING *\n `\n return rowToWorkflowAgentNodeRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new WorkflowRunError(\n `[SixbPg] Agent execution already exists for workflow node run '${input.nodeRunId}'.`\n )\n }\n throw error\n }\n }\n\n async start(input: StartWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const row = await lockWorkflowAgentNodeRun(tx, input.projectId, input.nodeRunId, \"queued\")\n const [updated] = await tx<WorkflowAgentNodeRunDatabaseRow[]>`\n UPDATE workflow_agent_node_runs SET\n status = ${\"running\"},\n execution_principal_type = ${input.executionPrincipal?.type ?? null},\n execution_principal_id = ${input.executionPrincipal?.id ?? null},\n model_id = ${input.modelId ?? null},\n attempt = ${1},\n execution_token = ${input.execution.token},\n execution_queue_lease_expires_at = ${input.execution.queueLeaseExpiresAt},\n started_at = ${input.startedAt ?? new Date()}\n WHERE project_id = ${row.project_id} AND node_run_id = ${row.node_run_id}\n RETURNING *\n `\n return rowToWorkflowAgentNodeRunRecord(updated)\n })\n }\n\n async reclaim(input: ReclaimWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const row = await lockWorkflowAgentNodeRun(tx, input.projectId, input.nodeRunId, \"running\")\n const [updated] = await tx<WorkflowAgentNodeRunDatabaseRow[]>`\n UPDATE workflow_agent_node_runs SET\n attempt = ${Number(row.attempt) + 1},\n execution_token = ${input.execution.token},\n execution_queue_lease_expires_at = ${input.execution.queueLeaseExpiresAt}\n WHERE project_id = ${input.projectId} AND node_run_id = ${input.nodeRunId}\n RETURNING *\n `\n return rowToWorkflowAgentNodeRunRecord(updated)\n })\n }\n\n async confirmExecutionOwnership(\n input: ConfirmWorkflowAgentNodeRunExecutionOwnershipInput\n ): Promise<WorkflowAgentNodeRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const row = await lockWorkflowAgentNodeRun(tx, input.projectId, input.nodeRunId, \"running\")\n assertWorkflowAgentNodeOwnership(row, input.executionToken)\n const currentLease = row.execution_queue_lease_expires_at\n ? new Date(row.execution_queue_lease_expires_at)\n : input.queueLeaseExpiresAt\n const [updated] = await tx<WorkflowAgentNodeRunDatabaseRow[]>`\n UPDATE workflow_agent_node_runs SET\n execution_queue_lease_expires_at = ${new Date(\n Math.max(currentLease.getTime(), input.queueLeaseExpiresAt.getTime())\n )}\n WHERE project_id = ${input.projectId} AND node_run_id = ${input.nodeRunId}\n RETURNING *\n `\n return rowToWorkflowAgentNodeRunRecord(updated)\n })\n }\n\n async finish(input: FinishWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const row = await lockWorkflowAgentNodeRun(tx, input.projectId, input.nodeRunId, \"running\")\n assertWorkflowAgentNodeOwnership(row, input.executionToken)\n const [updated] = await tx<WorkflowAgentNodeRunDatabaseRow[]>`\n UPDATE workflow_agent_node_runs SET\n status = ${input.status},\n model_id = COALESCE(${input.modelId ?? null}, model_id),\n finish_reason = ${input.finishReason ?? null},\n usage = ${input.usage ? JSON.stringify(input.usage) : null}::text::jsonb,\n trace = ${input.trace ? JSON.stringify(input.trace) : null}::text::jsonb,\n diagnostics = ${input.diagnostics ? JSON.stringify(input.diagnostics) : null}::text::jsonb,\n error = ${input.status === \"succeeded\" ? null : (input.error ?? null)},\n execution_token = ${null},\n execution_queue_lease_expires_at = ${null},\n completed_at = ${input.completedAt ?? new Date()}\n WHERE project_id = ${input.projectId} AND node_run_id = ${input.nodeRunId}\n RETURNING *\n `\n return rowToWorkflowAgentNodeRunRecord(updated)\n })\n }\n\n async cancel(input: CancelWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [row] = await tx<WorkflowAgentNodeRunDatabaseRow[]>`\n SELECT * FROM workflow_agent_node_runs\n WHERE project_id = ${input.projectId} AND node_run_id = ${input.nodeRunId}\n FOR UPDATE\n `\n if (!row) {\n throw new WorkflowRunError(\n `[SixbPg] Agent workflow node run '${input.nodeRunId}' not found.`\n )\n }\n if (row.status !== \"queued\" && row.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbPg] Agent workflow node run '${input.nodeRunId}' cannot be cancelled from status '${row.status}'.`\n )\n }\n const [updated] = await tx<WorkflowAgentNodeRunDatabaseRow[]>`\n UPDATE workflow_agent_node_runs SET\n status = ${\"cancelled\"},\n error = ${input.error ?? null},\n execution_token = ${null},\n execution_queue_lease_expires_at = ${null},\n completed_at = ${input.completedAt ?? new Date()}\n WHERE project_id = ${input.projectId} AND node_run_id = ${input.nodeRunId}\n RETURNING *\n `\n return rowToWorkflowAgentNodeRunRecord(updated)\n })\n }\n\n async getByNodeRunId(params: {\n projectId: string\n nodeRunId: string\n }): Promise<WorkflowAgentNodeRunRecord | null> {\n const [row] = await this.sql<WorkflowAgentNodeRunDatabaseRow[]>`\n SELECT * FROM workflow_agent_node_runs\n WHERE project_id = ${params.projectId} AND node_run_id = ${params.nodeRunId}\n `\n return row ? rowToWorkflowAgentNodeRunRecord(row) : null\n }\n\n async list(input: ListWorkflowAgentNodeRunsInput): Promise<ListWorkflowAgentNodeRunsResult> {\n if (hasEmptyStatuses(input)) return { runs: [], total: 0, hasMore: false }\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n if (input.agentId) {\n whereClauses.push(`agent_id = $${index++}`)\n params.push(input.agentId)\n }\n index = appendRunListFilters(whereClauses, params, index, input)\n const result = await queryRunList<WorkflowAgentNodeRunDatabaseRow>({\n sql: this.sql,\n tableName: \"workflow_agent_node_runs\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n return { ...result, runs: result.rows.map(rowToWorkflowAgentNodeRunRecord) }\n }\n}\n\nexport class PgWorkflowNodeRunStorage implements WorkflowNodeRunStorage {\n constructor(private readonly sql: PgStoreClient) {}\n\n async start(input: StartWorkflowNodeRunInput): Promise<WorkflowNodeRunRecord> {\n assertNonNegativeInteger(input.nodeIndex, \"nodeIndex\")\n\n return runPgTransaction(this.sql, async (tx) => {\n const [workflowRun] = await tx<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs\n WHERE project_id = ${input.projectId} AND id = ${input.workflowRunId}\n FOR UPDATE\n `\n\n if (!workflowRun) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.workflowRunId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (workflowRun.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${input.workflowRunId}' for project '${input.projectId}' must be running.`\n )\n }\n assertWorkflowRunExecutionOwnership(workflowRun, input.executionToken)\n\n if (workflowRun.workflow_id !== input.workflowId) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow node run '${input.id}' workflow '${input.workflowId}' does not match workflow run '${input.workflowRunId}' workflow '${workflowRun.workflow_id}'.`\n )\n }\n\n try {\n const [row] = await tx<WorkflowNodeRunDatabaseRow[]>`\n INSERT INTO workflow_node_runs (\n project_id,\n id,\n workflow_run_id,\n workflow_id,\n node_index,\n node_type,\n node_id,\n node_key,\n status,\n input,\n started_at\n ) VALUES (\n ${input.projectId},\n ${input.id},\n ${input.workflowRunId},\n ${input.workflowId},\n ${input.nodeIndex},\n ${input.nodeType},\n ${input.nodeId},\n ${input.nodeKey},\n ${\"running\"},\n ${serializeRecord(input.input)}::text::jsonb,\n ${input.startedAt ?? new Date()}\n )\n RETURNING *\n `\n\n return rowToWorkflowNodeRunRecord(row)\n } catch (error) {\n if (isUniqueViolation(error)) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow node run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n })\n }\n\n async finish(input: FinishWorkflowNodeRunInput): Promise<WorkflowNodeRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<WorkflowNodeRunDatabaseRow[]>`\n SELECT * FROM workflow_node_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow node run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n await assertWorkflowNodeParentExecutionOwnership(tx, existing, input.executionToken)\n\n if (existing.status !== \"running\" && existing.status !== \"waiting\") {\n throw new WorkflowRunError(\n `[SixbPg] Workflow node run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n const [updated] =\n input.status === \"succeeded\"\n ? await tx<WorkflowNodeRunDatabaseRow[]>`\n UPDATE workflow_node_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n output = ${input.output ? serializeRecord(input.output) : null}::text::jsonb,\n error = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n : await tx<WorkflowNodeRunDatabaseRow[]>`\n UPDATE workflow_node_runs\n SET\n status = ${input.status},\n finished_at = ${input.finishedAt ?? new Date()},\n output = ${null},\n error = ${input.error ?? null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowNodeRunRecord(updated)\n })\n }\n\n async wait(input: WaitWorkflowNodeRunInput): Promise<WorkflowNodeRunRecord> {\n return runPgTransaction(this.sql, async (tx) => {\n const [existing] = await tx<WorkflowNodeRunDatabaseRow[]>`\n SELECT * FROM workflow_node_runs\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n FOR UPDATE\n `\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow node run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n await assertWorkflowNodeParentExecutionOwnership(tx, existing, input.executionToken)\n\n if (existing.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbPg] Workflow node run '${input.id}' for project '${input.projectId}' must be running.`\n )\n }\n\n const [updated] = await tx<WorkflowNodeRunDatabaseRow[]>`\n UPDATE workflow_node_runs\n SET\n status = ${\"waiting\"},\n finished_at = ${null},\n output = ${null},\n error = ${null}\n WHERE project_id = ${input.projectId} AND id = ${input.id}\n RETURNING *\n `\n\n return rowToWorkflowNodeRunRecord(updated)\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<WorkflowNodeRunRecord | null> {\n const [row] = await this.sql<WorkflowNodeRunDatabaseRow[]>`\n SELECT * FROM workflow_node_runs\n WHERE project_id = ${params.projectId} AND id = ${params.id}\n `\n\n return row ? rowToWorkflowNodeRunRecord(row) : null\n }\n\n async list(input: ListWorkflowNodeRunsInput): Promise<ListWorkflowNodeRunsResult> {\n if (hasEmptyStatuses(input)) {\n return {\n nodes: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = $1\"]\n const params: SqlParameter[] = [input.projectId]\n let index = 2\n\n if (input.workflowRunId) {\n whereClauses.push(`workflow_run_id = $${index++}`)\n params.push(input.workflowRunId)\n }\n\n if (input.workflowId) {\n whereClauses.push(`workflow_id = $${index++}`)\n params.push(input.workflowId)\n }\n\n if (input.nodeType) {\n whereClauses.push(`node_type = $${index++}`)\n params.push(input.nodeType)\n }\n\n if (input.nodeId) {\n whereClauses.push(`node_id = $${index++}`)\n params.push(input.nodeId)\n }\n\n if (input.nodeKey) {\n whereClauses.push(`node_key = $${index++}`)\n params.push(input.nodeKey)\n }\n\n index = appendRunListFilters(whereClauses, params, index, input)\n\n const { rows, total, hasMore } = await queryRunList<WorkflowNodeRunDatabaseRow>({\n sql: this.sql,\n tableName: \"workflow_node_runs\",\n whereClauses,\n params,\n nextIndex: index,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n const nodes = rows.map(rowToWorkflowNodeRunRecord)\n\n return {\n nodes,\n hasMore,\n total,\n }\n }\n}\n\nfunction serializeRecord(value: WorkflowIOSnapshot): string {\n return JSON.stringify(value)\n}\n\nfunction parseRecord(value: WorkflowIOSnapshot | string): WorkflowIOSnapshot {\n return typeof value === \"string\" ? (JSON.parse(value) as WorkflowIOSnapshot) : value\n}\n\nfunction rowToWorkflowRunRecord(row: WorkflowRunDatabaseRow): WorkflowRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n workflowId: row.workflow_id,\n status: row.status,\n input: parseRecord(row.input),\n queuedAt: row.queued_at ? new Date(row.queued_at) : undefined,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n error: row.error ?? undefined,\n source: parseSource(row.source),\n requestedByPrincipal: {\n type: row.requested_by_principal_type,\n id: row.requested_by_principal_id,\n },\n attempt: Number(row.attempt),\n ...(row.execution_token && row.execution_queue_lease_expires_at\n ? {\n execution: {\n token: row.execution_token,\n queueLeaseExpiresAt: new Date(row.execution_queue_lease_expires_at),\n },\n }\n : {}),\n }\n}\n\nfunction parseSource(value: WorkflowRunSource | string | null): WorkflowRunSource | undefined {\n if (value === null || value === undefined) {\n return undefined\n }\n\n return typeof value === \"string\" ? (JSON.parse(value) as WorkflowRunSource) : value\n}\n\nfunction rowToWorkflowNodeRunRecord(row: WorkflowNodeRunDatabaseRow): WorkflowNodeRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n workflowRunId: row.workflow_run_id,\n workflowId: row.workflow_id,\n nodeIndex: Number(row.node_index),\n nodeType: row.node_type,\n nodeId: row.node_id,\n nodeKey: row.node_key,\n status: row.status,\n input: parseRecord(row.input),\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n output: row.output ? parseRecord(row.output) : undefined,\n error: row.error ?? undefined,\n }\n}\n\nfunction assertNonNegativeInteger(value: number, fieldName: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new WorkflowRunError(`[SixbPg] Workflow run ${fieldName} must be a non-negative integer.`)\n }\n}\n\nfunction canFinishWorkflowRun(\n current: WorkflowRunRecord[\"status\"],\n next: FinishWorkflowRunInput[\"status\"]\n): boolean {\n return (\n current === \"running\" ||\n (current === \"waiting\" && next !== \"succeeded\") ||\n (current === \"queued\" && next !== \"succeeded\")\n )\n}\n\ninterface WorkflowRunDatabaseRow {\n project_id: string\n id: string\n workflow_id: string\n status: WorkflowRunRecord[\"status\"]\n input: WorkflowIOSnapshot | string\n queued_at: Date | string | null\n started_at: Date | string\n finished_at: Date | string | null\n error: string | null\n source: WorkflowRunSource | string | null\n requested_by_principal_type: Principal[\"type\"]\n requested_by_principal_id: string\n attempt: number | string\n execution_token: string | null\n execution_queue_lease_expires_at: Date | string | null\n}\n\ninterface WorkflowNodeRunDatabaseRow {\n project_id: string\n id: string\n workflow_run_id: string\n workflow_id: string\n node_index: number | string\n node_type: WorkflowNodeRunRecord[\"nodeType\"]\n node_id: string\n node_key: string\n status: WorkflowNodeRunRecord[\"status\"]\n input: WorkflowIOSnapshot | string\n started_at: Date | string\n finished_at: Date | string | null\n output: WorkflowIOSnapshot | string | null\n error: string | null\n}\n\ninterface WorkflowAgentNodeRunDatabaseRow {\n project_id: string\n node_run_id: string\n agent_id: string\n status: WorkflowAgentNodeRunRecord[\"status\"]\n prompt: string\n execution_principal_type: \"serviceAccount\" | null\n execution_principal_id: string | null\n model_id: string | null\n finish_reason: WorkflowAgentNodeRunRecord[\"finishReason\"] | null\n usage: WorkflowAgentNodeRunRecord[\"usage\"] | string | null\n trace: WorkflowAgentNodeRunRecord[\"trace\"] | string | null\n diagnostics: WorkflowAgentNodeRunRecord[\"diagnostics\"] | string | null\n error: string | null\n attempt: number | string\n execution_token: string | null\n execution_queue_lease_expires_at: Date | string | null\n created_at: Date | string\n started_at: Date | string | null\n completed_at: Date | string | null\n}\n\nasync function lockWorkflowAgentNodeRun(\n sql: PgStoreClient,\n projectId: string,\n nodeRunId: string,\n status: WorkflowAgentNodeRunRecord[\"status\"]\n): Promise<WorkflowAgentNodeRunDatabaseRow> {\n const [row] = await sql<WorkflowAgentNodeRunDatabaseRow[]>`\n SELECT * FROM workflow_agent_node_runs\n WHERE project_id = ${projectId} AND node_run_id = ${nodeRunId}\n FOR UPDATE\n `\n if (!row) {\n throw new WorkflowRunError(\n `[SixbPg] Agent workflow node run '${nodeRunId}' not found for project '${projectId}'.`\n )\n }\n if (row.status !== status) {\n throw new WorkflowRunError(\n `[SixbPg] Agent workflow node run '${nodeRunId}' must be ${status} (status '${row.status}').`\n )\n }\n return row\n}\n\nfunction assertWorkflowAgentNodeOwnership(\n row: WorkflowAgentNodeRunDatabaseRow,\n token: string\n): void {\n if (row.execution_token !== token) {\n throw new WorkflowRunError(\n `[SixbPg] Execution token is no longer current on agent workflow node run '${row.node_run_id}'.`\n )\n }\n}\n\nfunction rowToWorkflowAgentNodeRunRecord(\n row: WorkflowAgentNodeRunDatabaseRow\n): WorkflowAgentNodeRunRecord {\n return {\n projectId: row.project_id,\n nodeRunId: row.node_run_id,\n agentId: row.agent_id,\n status: row.status,\n prompt: row.prompt,\n ...(row.execution_principal_type && row.execution_principal_id\n ? {\n executionPrincipal: {\n type: row.execution_principal_type,\n id: row.execution_principal_id,\n },\n }\n : {}),\n ...(row.model_id ? { modelId: row.model_id } : {}),\n ...(row.finish_reason ? { finishReason: row.finish_reason } : {}),\n ...(row.usage ? { usage: parseJson(row.usage) } : {}),\n ...(row.trace ? { trace: parseJson(row.trace) } : {}),\n ...(row.diagnostics ? { diagnostics: parseJson(row.diagnostics) } : {}),\n ...(row.error ? { error: row.error } : {}),\n attempt: Number(row.attempt),\n ...(row.execution_token && row.execution_queue_lease_expires_at\n ? {\n execution: {\n token: row.execution_token,\n queueLeaseExpiresAt: new Date(row.execution_queue_lease_expires_at),\n },\n }\n : {}),\n createdAt: new Date(row.created_at),\n ...(row.started_at ? { startedAt: new Date(row.started_at) } : {}),\n ...(row.completed_at ? { completedAt: new Date(row.completed_at) } : {}),\n }\n}\n\nfunction parseJson<T>(value: T | string): T {\n return typeof value === \"string\" ? (JSON.parse(value) as T) : value\n}\n\nasync function lockWorkflowRun(\n sql: PgStoreClient,\n projectId: string,\n id: string,\n status: WorkflowRunRecord[\"status\"]\n): Promise<WorkflowRunDatabaseRow> {\n const [row] = await sql<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs WHERE project_id = ${projectId} AND id = ${id} FOR UPDATE\n `\n if (!row) throw new WorkflowRunError(`[SixbPg] Workflow run '${id}' not found.`)\n if (row.status !== status) {\n throw new WorkflowRunError(\n `[SixbPg] Workflow run '${id}' must be ${status} (status '${row.status}').`\n )\n }\n return row\n}\n\nfunction assertWorkflowRunExecutionOwnership(row: WorkflowRunDatabaseRow, token?: string): void {\n if (row.execution_token !== (token ?? null)) {\n throw new WorkflowRunError(\n `[SixbPg] Execution token is no longer current on workflow run '${row.id}'.`\n )\n }\n}\n\nasync function assertWorkflowNodeParentExecutionOwnership(\n sql: PgStoreClient,\n node: WorkflowNodeRunDatabaseRow,\n token?: string\n): Promise<void> {\n const [run] = await sql<WorkflowRunDatabaseRow[]>`\n SELECT * FROM workflow_runs\n WHERE project_id = ${node.project_id} AND id = ${node.workflow_run_id}\n FOR UPDATE\n `\n if (!run) throw new WorkflowRunError(`[SixbPg] Parent workflow run was not found.`)\n assertWorkflowRunExecutionOwnership(run, token)\n}\n"
51
+ ],
52
+ "mappings": ";;AAIA;AAOA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAAA;;;ACpBA;AACA;AAAA;AAAA;;;ACKA,IAAM,mBAAmB;AAUzB,IAAM,uCAAuC,IAAI,IAAI,CAAC,SAAS,OAAO,CAAC;AAEvE,IAAM,yBAAyB,IAAI,IAAI;AAAA,EAErC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,SAAS,WAAW,CAAC,OAAoC;AAAA,EAC9D,IAAI,iBAAiB,OAAO;AAAA,IAC1B,MAAM,OAAQ,MAAsC;AAAA,IACpD,IAAI,OAAO,SAAS,UAAU;AAAA,MAC5B,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EACA;AAAA;AAIK,SAAS,iBAAiB,CAAC,OAAyB;AAAA,EACzD,OAAO,YAAY,KAAK,MAAM;AAAA;AAQzB,SAAS,8BAA8B,CAAC,OAAyB;AAAA,EACtE,MAAM,OAAO,YAAY,KAAK;AAAA,EAC9B,OAAO,SAAS,aAAa,qCAAqC,IAAI,IAAI;AAAA;;;ACvD5E;AAUA,eAAsB,gBAAmB,CACvC,KACA,KACA,UAAmC,CAAC,GACxB;AAAA,EACZ,IAAI,CAAC,sBAAsB,GAAG,GAAG;AAAA,IAC/B,OAAO,IAAI,GAAG;AAAA,EAChB;AAAA,EASA,IAAI,QAAQ,cAAc,gBAAgB;AAAA,IACxC,OAAO,IAAI,MAAM,gCAAgC,GAAG;AAAA,EACtD;AAAA,EACA,OAAO,IAAI,MAAM,GAAG;AAAA;AAGf,SAAS,WAAW,CAAC,SAAiB,OAAkC;AAAA,EAC7E,OAAO,CAAC,QAAQ,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG;AAAA;AAG1C,eAAsB,gBAAgB,CAAC,KAAgB,MAAwC;AAAA,EAC7F,MAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,iBAAiB;AAAA,EAC7D,IAAI,MAAM,WAAW;AAAA,IAAG;AAAA,EAExB,MAAM;AAAA;AAAA;AAAA,QAGA,IAAI,MAAM,MAAM,IAAI,EAAE,WAAW,KAAK,CAAC;AAAA,QACvC,IAAI,MAAM,MAAM,IAAI,IAAI,YAAY,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAMnD,SAAS,iBAAiB,CAAC,KAAwC;AAAA,EACjE,MAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO;AAAA,EACrD,OAAO,CAAC,KAAK,YAAY,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC;AAAA;AAGlD,SAAS,qBAAqB,CAAC,KAAgC;AAAA,EAC7D,OAAO,OAAQ,IAAqC,UAAU;AAAA;;;ACxDhE;AACA;AAAA;AAAA;AA0EO,SAAS,iBAAiB,CAAC,KAAwC;AAAA,EACxE,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,SAAS,IAAI;AAAA,IACb,gBAAgB,EAAE,MAAM,IAAI,sBAAsB,IAAI,IAAI,mBAAmB;AAAA,IAC7E,OAAO,IAAI,SAAS;AAAA,IACpB,QAAQ,IAAI;AAAA,IACZ,aAAa,IAAI;AAAA,IACjB,eAAe,IAAI,kBAAkB,IAAI,KAAK,IAAI,eAAe,IAAI;AAAA,IACrE,cAAc,OAAO,IAAI,aAAa;AAAA,IACtC,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,EACpC;AAAA;AAGK,SAAS,cAAc,CAAC,KAAkC;AAAA,EAC/D,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,UAAU,IAAI;AAAA,IACd,SAAS,IAAI;AAAA,IACb,kBAAkB,IAAI;AAAA,IACtB,sBACE,qBAAqB,IAAI,6BAA6B,IAAI,yBAAyB,KACnF;AAAA,IACF,oBAAoB,mCAClB,IAAI,0BACJ,IAAI,sBACN;AAAA,IACA,QAAQ,IAAI;AAAA,IACZ,SAAS,IAAI,YAAY;AAAA,IACzB,cAAc,2BAA2B,IAAI,aAAa;AAAA,IAC1D,OAAO,WAAW,GAAG;AAAA,IACrB,OAAO,IAAI,SAAS;AAAA,IACpB,aAAa,qBAAqB,IAAI,WAAW;AAAA,IACjD,SAAS,OAAO,IAAI,OAAO;AAAA,IAC3B,WACE,IAAI,mBAAmB,IAAI,mCACvB;AAAA,MACE,OAAO,IAAI;AAAA,MACX,qBAAqB,IAAI,KAAK,IAAI,gCAAgC;AAAA,IACpE,IACA;AAAA,IACN,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,WAAW,IAAI,aAAa,IAAI,KAAK,IAAI,UAAU,IAAI;AAAA,IACvD,aAAa,IAAI,eAAe,IAAI,KAAK,IAAI,YAAY,IAAI;AAAA,EAC/D;AAAA;AAGK,SAAS,kBAAkB,CAAC,KAA0C;AAAA,EAC3E,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,UAAU,IAAI;AAAA,IACd,OAAO,IAAI;AAAA,IACX,MAAM,IAAI;AAAA,IACV,iBAAiB,qBAAqB,IAAI,uBAAuB,IAAI,mBAAmB;AAAA,IACxF,KAAK,OAAO,IAAI,GAAG;AAAA,IACnB,OACE,OAAO,IAAI,UAAU,WAAY,KAAK,MAAM,IAAI,KAAK,IAA2B,IAAI;AAAA,IAGtF,UAAU,kBAAkB,IAAI,QAAQ;AAAA,IACxC,gBAAgB,OAAO,IAAI,eAAe;AAAA,IAC1C,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,aAAa,IAAI,eAAe,IAAI,KAAK,IAAI,YAAY,IAAI;AAAA,EAC/D;AAAA;AAGF,SAAS,oBAAoB,CAC3B,MACA,IACuB;AAAA,EACvB,OAAO,QAAQ,KAAK,EAAE,MAAM,GAAG,IAAI;AAAA;AAGrC,SAAS,kCAAkC,CACzC,MACA,IACqE;AAAA,EACrE,OAAO,SAAS,oBAAoB,KAAK,EAAE,MAAM,GAAG,IAAI;AAAA;AAG1D,SAAS,UAAU,CAAC,KAA6C;AAAA,EAC/D,MAAM,QAAuB;AAAA,OACvB,IAAI,uBAAuB,OAAO,CAAC,IAAI,EAAE,aAAa,OAAO,IAAI,kBAAkB,EAAE;AAAA,OACrF,IAAI,wBAAwB,OAAO,CAAC,IAAI,EAAE,cAAc,OAAO,IAAI,mBAAmB,EAAE;AAAA,OACxF,IAAI,uBAAuB,OAAO,CAAC,IAAI,EAAE,aAAa,OAAO,IAAI,kBAAkB,EAAE;AAAA,OACrF,IAAI,2BAA2B,OAC/B,CAAC,IACD,EAAE,iBAAiB,OAAO,IAAI,sBAAsB,EAAE;AAAA,OACtD,IAAI,8BAA8B,OAClC,CAAC,IACD,EAAE,mBAAmB,OAAO,IAAI,yBAAyB,EAAE;AAAA,EACjE;AAAA,EACA,OAAO,OAAO,KAAK,KAAK,EAAE,WAAW,IAAI,YAAY;AAAA;AAGvD,SAAS,iBAAiB,CAAC,OAAgD;AAAA,EACzE,IAAI,UAAU,QAAQ,UAAU,WAAW;AAAA,IACzC;AAAA,EACF;AAAA,EACA,MAAM,SAAS,OAAO,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI;AAAA,EAC/D,OAAO,WAAW,OAAO,YAAa;AAAA;AAGxC,SAAS,oBAAoB,CAC3B,OAC2C;AAAA,EAC3C,IAAI,UAAU,MAAM;AAAA,IAClB;AAAA,EACF;AAAA,EACA,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAA6B;AAAA;AAKnF,eAAsB,cAAoB,CAAC,OASwD;AAAA,EACjG,MAAM,QAAQ,SAAS,MAAM,aAAa,KAAK,OAAO;AAAA,EACtD,MAAM,SAAS,MAAM,UAAU;AAAA,EAE/B,OAAO,YAAY,MAAM,MAAM,IAAI,OACjC,yCAAyC,MAAM,SAAS,SACxD,CAAC,GAAG,MAAM,MAAM,CAClB;AAAA,EAEA,MAAM,cAAc,CAAC,GAAG,MAAM,MAAM;AAAA,EACpC,IAAI,QAAQ,iBAAiB,MAAM,SAAS,kBAAkB,MAAM;AAAA,EACpE,IAAI,YAAY,MAAM;AAAA,EAEtB,IAAI,MAAM,UAAU,WAAW;AAAA,IAC7B,SAAS,WAAW,uBAAuB;AAAA,IAC3C,YAAY,KAAK,MAAM,OAAO,MAAM;AAAA,EACtC,EAAO,SAAI,SAAS,GAAG;AAAA,IACrB,SAAS,YAAY;AAAA,IACrB,YAAY,KAAK,MAAM;AAAA,EACzB;AAAA,EAEA,MAAM,OAAO,MAAM,MAAM,IAAI,OAAe,OAAO,WAAW;AAAA,EAC9D,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,EACzC,OAAO,EAAE,MAAM,OAAO,SAAS,SAAS,KAAK,SAAS,MAAM;AAAA;;;AHnNvD,MAAM,oBAAiD;AAAA,EAC/B;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAA6D;AAAA,IACxE,MAAM,YAAY,MAAM,aAAa,IAAI;AAAA,IAEzC,IAAI;AAAA,MACF,OAAO,MAAM,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,QACpD,OAAO,UAAU,MAAM;AAAA;AAAA,+BAEA,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,QAIzD,IAAI,CAAC,QAAQ;AAAA,UACX,MAAM,IAAI,kBACR,oBACA,0BAA0B,MAAM,oCAAoC,MAAM,aAC5E;AAAA,QACF;AAAA,QAEA,IAAI,MAAM,UAAU,MAAM;AAAA,UACxB,OAAO,OAAO,MAAM;AAAA,2DAC6B,MAAM,sBAAsB,MAAM;AAAA;AAAA,UAGnF,IAAI,CAAC,KAAK;AAAA,YACR,MAAM,IAAI,kBACR,iBACA,uBAAuB,MAAM,iCAAiC,MAAM,aACtE;AAAA,UACF;AAAA,QACF;AAAA,QAEA,OAAO,UAAU,MAAM;AAAA;AAAA,+BAEA,MAAM,6BAA6B,MAAM;AAAA;AAAA,QAGhE,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAgBd,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM,iBAAiB,QAAQ;AAAA,cAC/B,MAAM,iBAAiB,MAAM;AAAA,cAC7B,OAAO,OAAO,IAAI;AAAA,cAClB,KAAK,UAAU,MAAM,KAAK;AAAA,cAC1B,MAAM,aAAa,YAAY,OAAO,KAAK,UAAU,MAAM,QAAQ;AAAA,cACnE;AAAA,cACA;AAAA,cACA,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA,QAK3B,MAAM;AAAA;AAAA,qEAEuD,2BAA2B;AAAA,+BACjE,MAAM,sBAAsB,MAAM;AAAA;AAAA,QAGzD,OAAO,mBAAmB,GAAG;AAAA,OAC9B;AAAA,MACD,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,kBACR,gBACA,2BAA2B,MAAM,mCAAmC,MAAM,aAC5E;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,QAAO,CAAC,QAA+E;AAAA,IAC3F,OAAO,OAAO,MAAM,KAAK;AAAA,wDAC2B,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAGxF,OAAO,MAAM,mBAAmB,GAAG,IAAI;AAAA;AAAA,OAGnC,KAAI,CAAC,OAAiE;AAAA,IAC1E,IAAI,MAAM,UAAU,aAAa,MAAM,MAAM,WAAW,GAAG;AAAA,MACzD,OAAO,EAAE,UAAU,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IAClD;AAAA,IAEA,MAAM,eAAe,CAAC,mBAAmB,gBAAgB;AAAA,IACzD,MAAM,SAAyB,CAAC,MAAM,WAAW,MAAM,QAAQ;AAAA,IAC/D,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,OAAO;AAAA,MACf,MAAM,eAAe,MAAM,MAAM,IAAI,MAAM,IAAI,SAAS;AAAA,MACxD,aAAa,KAAK,YAAY,aAAa,KAAK,IAAI,IAAI;AAAA,MACxD,OAAO,KAAK,GAAG,MAAM,KAAK;AAAA,IAC5B;AAAA,IAEA,MAAM,MAAM,MAAM,UAAU,SAAS,SAAS;AAAA,IAC9C,QAAQ,MAAM,OAAO,YAAY,MAAM,eAAgC;AAAA,MACrE,KAAK,KAAK;AAAA,MACV,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,SAAS,OAAO;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IAED,OAAO,EAAE,UAAU,KAAK,IAAI,kBAAkB,GAAG,SAAS,MAAM;AAAA;AAEpE;;;AI/IA;AAAA,uBAGE;AAAA;;;ACaK,SAAS,gBAAgB,CAAC,OAA4D;AAAA,EAC3F,OAAO,MAAM,aAAa,aAAa,MAAM,SAAS,WAAW;AAAA;AAG5D,SAAS,oBAAoB,CAClC,cACA,QACA,OACA,OAKA,sBAA2C,cACnC;AAAA,EACR,IAAI,YAAY;AAAA,EAEhB,IAAI,MAAM,UAAU;AAAA,IAClB,IAAI,MAAM,SAAS,WAAW,GAAG;AAAA,MAC/B,aAAa,KAAK,OAAO;AAAA,IAC3B,EAAO;AAAA,MACL,MAAM,eAAe,MAAM,SAAS,IAAI,MAAM,IAAI,aAAa;AAAA,MAC/D,aAAa,KAAK,cAAc,aAAa,KAAK,IAAI,IAAI;AAAA,MAC1D,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA;AAAA,EAEjC;AAAA,EAEA,IAAI,MAAM,cAAc;AAAA,IACtB,aAAa,KAAK,GAAG,2BAA2B,aAAa;AAAA,IAC7D,OAAO,KAAK,MAAM,YAAY;AAAA,EAChC;AAAA,EAEA,IAAI,MAAM,eAAe;AAAA,IACvB,aAAa,KAAK,GAAG,2BAA2B,aAAa;AAAA,IAC7D,OAAO,KAAK,MAAM,aAAa;AAAA,EACjC;AAAA,EAEA,OAAO;AAAA;AAGT,eAAsB,YAAkB,CAAC,OAU0D;AAAA,EACjG,MAAM,QAAQ,SAAS,MAAM,aAAa,KAAK,OAAO;AAAA,EACtD,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,EAC9C,MAAM,SAAS,MAAM,UAAU;AAAA,EAE/B,OAAO,YAAY,MAAM,MAAM,IAAI,OACjC,yCAAyC,MAAM,aAAa,SAC5D,CAAC,GAAG,MAAM,MAAM,CAClB;AAAA,EAEA,MAAM,cAAc,CAAC,GAAG,MAAM,MAAM;AAAA,EACpC,MAAM,cACJ,MAAM,cAAc,eAChB,qCACA,MAAM,cAAc,6BAClB,eACA;AAAA,EACR,MAAM,WAAW,MAAM,cAAc,6BAA6B,gBAAgB;AAAA,EAClF,IAAI,QAAQ;AAAA,aACD,MAAM,cAAc,YAAY,MAAM;AAAA,MAC7C;AAAA,eACS,eAAe,UAAU,YAAY;AAAA;AAAA,EAElD,IAAI,YAAY,MAAM;AAAA,EAEtB,IAAI,MAAM,UAAU,WAAW;AAAA,IAC7B,SAAS,WAAW,uBAAuB;AAAA,IAC3C,YAAY,KAAK,MAAM,OAAO,MAAM;AAAA,EACtC,EAAO,SAAI,SAAS,GAAG;AAAA,IACrB,SAAS,YAAY;AAAA,IACrB,YAAY,KAAK,MAAM;AAAA,EACzB;AAAA,EAEA,MAAM,OAAO,MAAM,MAAM,IAAI,OAAe,OAAO,WAAW;AAAA,EAC9D,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,EAEzC,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS,SAAS,KAAK,SAAS;AAAA,EAClC;AAAA;;;ADvFF,IAAM,uBAAuB;AAAA;AAEtB,MAAM,gBAAyC;AAAA,EACvB;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAAqD;AAAA,IAChE,MAAM,YAAY,MAAM,aAAa,IAAI;AAAA,IAEzC,IAAI;AAAA,MACF,OAAO,MAAM,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,QACpD,OAAO,UAAU,MAAM;AAAA;AAAA,+BAEA,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,QAIzD,IAAI,CAAC,QAAQ;AAAA,UACX,MAAM,IAAI,mBACR,oBACA,0BAA0B,MAAM,oCAAoC,MAAM,aAC5E;AAAA,QACF;AAAA,QAEA,IAAI,OAAO,kBAAkB,MAAM;AAAA,UACjC,MAAM,IAAI,mBACR,qBACA,0BAA0B,MAAM,wCAAwC,OAAO,iBACjF;AAAA,QACF;AAAA,QAEA,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAad,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM,qBAAqB;AAAA,cAC3B,MAAM,qBAAqB;AAAA,cAC3B;AAAA,cACA;AAAA,cACA;AAAA;AAAA;AAAA;AAAA,QAKN,MAAM;AAAA,qDACuC,MAAM,oBAAoB;AAAA,+BAChD,MAAM,sBAAsB,MAAM;AAAA;AAAA,QAGzD,OAAO,eAAe,GAAG;AAAA,OAC1B;AAAA,MACD,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,mBACR,gBACA,uBAAuB,MAAM,mCAAmC,MAAM,aACxE;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,MAAK,CAAC,OAAoD;AAAA,IAC9D,MAAM,YAAY,MAAM,aAAa,IAAI;AAAA,IACzC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,KAAK,WAAW,IAAI,MAAM,WAAW,MAAM,IAAI,QAAQ;AAAA,MAC7D,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA,qBAGL;AAAA,uCACkB,MAAM,oBAAoB,QAAQ;AAAA,qCACpC,MAAM,oBAAoB,MAAM;AAAA,uBAC9C,MAAM,WAAW;AAAA,sBAClB;AAAA,8BACQ,MAAM,UAAU;AAAA,+CACC,MAAM,UAAU;AAAA,yBACtC;AAAA,6BACI,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAGzD,OAAO,eAAe,GAAG;AAAA,KAC1B;AAAA;AAAA,OAGG,aAAY,CAAC,OAA2D;AAAA,IAC5E,MAAM,cAAc,MAAM,eAAe,IAAI;AAAA,IAC7C,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,KAAK,WAAW,IAAI,MAAM,WAAW,MAAM,IAAI,QAAQ;AAAA,MACzE,OAAO,OAAO,MAAM;AAAA;AAAA,uBAEH,MAAM,mBAAmB,MAAM,SAAS,wBAAwB;AAAA,6BAC1D,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAGzD,MAAM,KAAK,cAAc,IAAI,KAAK,WAAW;AAAA,MAC7C,OAAO,eAAe,GAAG;AAAA,KAC1B;AAAA;AAAA,OAGG,QAAO,CAAC,OAAsD;AAAA,IAClE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,KAAK,YAAY,IAAI,MAAM,WAAW,MAAM,EAAE;AAAA,MACpD,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,8BAII,MAAM,UAAU;AAAA,+CACC,MAAM,UAAU;AAAA,6BAClC,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,eAAe,GAAG;AAAA,KAC1B;AAAA;AAAA,OAGG,0BAAyB,CAC7B,OACyB;AAAA,IACzB,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,KAAK,YAAY,IAAI,MAAM,WAAW,MAAM,EAAE;AAAA,MAChE,IAAI,IAAI,oBAAoB,MAAM,gBAAgB;AAAA,QAChD,MAAM,IAAI,mBACR,kBACA,+DAA+D,MAAM,MACvE;AAAA,MACF;AAAA,MAEA,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,YAId,MAAM;AAAA;AAAA,6BAEW,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAGzD,OAAO,eAAe,GAAG;AAAA,KAC1B;AAAA;AAAA,OAGG,OAAM,CAAC,OAAqD;AAAA,IAChE,MAAM,cAAc,MAAM,eAAe,IAAI;AAAA,IAC7C,MAAM,aAAa,MAAM,WAAW,cAAc,OAAQ,MAAM,SAAS;AAAA,IAEzE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,KAAK,YAAY,IAAI,MAAM,WAAW,MAAM,EAAE;AAAA,MAEhE,IAAI,IAAI,oBAAoB,MAAM,gBAAgB;AAAA,QAChD,MAAM,IAAI,mBACR,kBACA,+DAA+D,MAAM,MACvE;AAAA,MACF;AAAA,MAEA,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA,qBAGL,MAAM;AAAA,gCACK,MAAM,WAAW;AAAA,4BACrB,MAAM,gBAAgB;AAAA,iCACjB,MAAM,OAAO,eAAe;AAAA,kCAC3B,MAAM,OAAO,gBAAgB;AAAA,iCAC9B,MAAM,OAAO,eAAe;AAAA,qCACxB,MAAM,OAAO,mBAAmB;AAAA,wCAC7B,MAAM,OAAO,qBAAqB;AAAA,oBACtD;AAAA,0BACM,MAAM,gBAAgB,YAAY,OAAO,KAAK,UAAU,MAAM,WAAW;AAAA,8BACrE;AAAA,+CACiB;AAAA,2BACpB;AAAA,6BACE,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,MAAM,KAAK,cAAc,IAAI,KAAK,WAAW;AAAA,MAE7C,OAAO,eAAe,GAAG;AAAA,KAC1B;AAAA;AAAA,OAGG,QAAO,CAAC,QAA2E;AAAA,IACvF,OAAO,OAAO,MAAM,KAAK;AAAA,oDACuB,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAGpF,OAAO,MAAM,eAAe,GAAG,IAAI;AAAA;AAAA,OAG/B,SAAQ,CAAC,QAGwB;AAAA,IACrC,MAAM,MAAM,CAAC,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC;AAAA,IACnC,IAAI,IAAI,WAAW,GAAG;AAAA,MACpB,OAAO,CAAC;AAAA,IACV;AAAA,IAEA,MAAM,OAAsB,CAAC;AAAA,IAC7B,SAAS,SAAS,EAAG,SAAS,IAAI,QAAQ,UAAU,sBAAsB;AAAA,MACxE,MAAM,QAAQ,IAAI,MAAM,QAAQ,SAAS,oBAAoB;AAAA,MAC7D,MAAM,eAAe,MAAM,IAAI,CAAC,GAAG,UAAU,IAAI,QAAQ,GAAG,EAAE,KAAK,IAAI;AAAA,MACvE,KAAK,KACH,GAAI,MAAM,KAAK,IAAI,OACjB,6DAA6D,iBAC7D,CAAC,OAAO,WAAW,GAAG,KAAK,CAC7B,CACF;AAAA,IACF;AAAA,IACA,MAAM,OAAO,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,eAAe,GAAG,CAAC,CAAC,CAAC;AAAA,IACrE,OAAO,IAAI,QAAQ,CAAC,OAAO;AAAA,MACzB,MAAM,MAAM,KAAK,IAAI,EAAE;AAAA,MACvB,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;AAAA,KACvB;AAAA;AAAA,OAGG,KAAI,CAAC,OAAyD;AAAA,IAClE,IAAI,iBAAiB,KAAK,GAAG;AAAA,MAC3B,OAAO,EAAE,MAAM,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IAC9C;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,UAAU;AAAA,MAClB,aAAa,KAAK,gBAAgB,SAAS;AAAA,MAC3C,OAAO,KAAK,MAAM,QAAQ;AAAA,IAC5B;AAAA,IAEA,IAAI,MAAM,SAAS;AAAA,MACjB,aAAa,KAAK,eAAe,SAAS;AAAA,MAC1C,OAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,IAEA,QAAQ,qBACN,cACA,QACA,OACA,OACA,kCACF;AAAA,IAEA,QAAQ,MAAM,OAAO,YAAY,MAAM,aAA0B;AAAA,MAC/D,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IAED,OAAO,EAAE,MAAM,KAAK,IAAI,cAAc,GAAG,SAAS,MAAM;AAAA;AAAA,EAGlD,WAAW,CAAC,KAAgB,WAAmB,IAAkC;AAAA,IACvF,OAAO,KAAK,WAAW,KAAK,WAAW,IAAI,SAAS;AAAA;AAAA,OAGxC,WAAU,CACtB,KACA,WACA,IACA,QACsB;AAAA,IACtB,OAAO,OAAO,MAAM;AAAA;AAAA,2BAEG,sBAAsB;AAAA;AAAA;AAAA,IAI7C,IAAI,CAAC,KAAK;AAAA,MACR,MAAM,IAAI,mBACR,iBACA,uBAAuB,8BAA8B,aACvD;AAAA,IACF;AAAA,IAEA,IAAI,IAAI,WAAW,QAAQ;AAAA,MACzB,MAAM,IAAI,mBACR,iBACA,uBAAuB,cAAc,mBAAmB,IAAI,WAC9D;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAAA,OAGK,cAAa,CAAC,KAAgB,KAAkB,aAAkC;AAAA,IAC9F,MAAM;AAAA,iDACuC,sBAAsB;AAAA,2BAC5C,IAAI,uBAAuB,IAAI,iCAAiC,IAAI;AAAA;AAAA;AAG/F;;;AEzUA;AAAA,uBACE;AAAA;AAYK,MAAM,mBAA+C;AAAA,EAC7B;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAA2D;AAAA,IACtE,MAAM,YAAY,MAAM,aAAa,IAAI;AAAA,IACzC,MAAM,YAAY,MAAM,aAAa;AAAA,IAErC,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAYnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM,eAAe;AAAA,YACrB,MAAM,eAAe;AAAA,YACrB,MAAM,SAAS;AAAA,YACf,MAAM,UAAU;AAAA,YAChB;AAAA,YACA;AAAA;AAAA;AAAA;AAAA,MAKN,OAAO,kBAAkB,GAAG;AAAA,MAC5B,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,mBACR,gBACA,0BAA0B,MAAM,mCAAmC,MAAM,aAC3E;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,QAAO,CAAC,QAA8E;AAAA,IAC1F,OAAO,OAAO,MAAM,KAAK;AAAA,uDAC0B,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAGvF,OAAO,MAAM,kBAAkB,GAAG,IAAI;AAAA;AAAA,OAGlC,KAAI,CAAC,OAA+D;AAAA,IACxE,IACG,MAAM,aAAa,aAAa,MAAM,SAAS,WAAW,KAC1D,MAAM,aAAa,aAAa,MAAM,SAAS,WAAW,GAC3D;AAAA,MACA,OAAO,EAAE,SAAS,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IACjD;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,SAAS;AAAA,MACjB,aAAa,KAAK,eAAe,SAAS;AAAA,MAC1C,OAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,IAEA,IAAI,MAAM,UAAU;AAAA,MAClB,MAAM,eAAe,MAAM,SAAS,IAAI,MAAM,IAAI,SAAS;AAAA,MAC3D,aAAa,KAAK,gBAAgB,aAAa,KAAK,IAAI,IAAI;AAAA,MAC5D,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IAEA,IAAI,MAAM,UAAU;AAAA,MAClB,MAAM,eAAe,MAAM,SAAS,IAAI,MAAM,IAAI,SAAS;AAAA,MAC3D,aAAa,KAAK,cAAc,aAAa,KAAK,IAAI,IAAI;AAAA,MAC1D,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IAEA,IAAI,MAAM,gBAAgB;AAAA,MACxB,aAAa,KAAK,2BAA2B,qCAAqC,SAAS;AAAA,MAC3F,OAAO,KAAK,MAAM,eAAe,MAAM,MAAM,eAAe,EAAE;AAAA,IAChE;AAAA,IAEA,MAAM,MAAM,MAAM,UAAU,QAAQ,QAAQ;AAAA,IAC5C,QAAQ,MAAM,OAAO,YAAY,MAAM,eAA+B;AAAA,MACpE,KAAK,KAAK;AAAA,MACV,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,SAAS,yCAAyC,WAAW;AAAA,MAC7D,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IAED,OAAO,EAAE,SAAS,KAAK,IAAI,iBAAiB,GAAG,SAAS,MAAM;AAAA;AAElE;;;ACpGO,MAAM,eAAuC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EAET,WAAW,CAAC,SAAgC;AAAA,IAC1C,KAAK,UAAU,IAAI,mBAAmB,QAAQ,GAAG;AAAA,IACjD,KAAK,OAAO,IAAI,gBAAgB,QAAQ,GAAG;AAAA,IAC3C,KAAK,WAAW,IAAI,oBAAoB,QAAQ,GAAG;AAAA;AAEvD;;ACbA,6BAAS;;;ACLT,6BAAS;;;ACiJF,SAAS,eAAe,CAAC,KAAgC;AAAA,EAC9D,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,OAAO,IAAI;AAAA,IACX,aAAa,IAAI,gBAAgB;AAAA,IACjC,WAAW,IAAI,cAAc;AAAA,IAC7B,QAAQ,IAAI;AAAA,IACZ,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,EAClC;AAAA;AAGK,SAAS,mBAAmB,CAAC,KAAgD;AAAA,EAClF,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,YAAY,IAAI;AAAA,IAChB,SAAS,IAAI;AAAA,IACb,QAAQ,IAAI;AAAA,IACZ,QAAQ,oBAAoB,IAAI,MAAM;AAAA,IACtC,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,EAClC;AAAA;AAGK,SAAS,yBAAyB,CAAC,KAAoD;AAAA,EAC5F,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,MAAM,IAAI;AAAA,IACV,aAAa,IAAI,eAAe;AAAA,IAChC,QAAQ,IAAI;AAAA,IACZ,oBAAoB,sBAAqB,GAAG;AAAA,IAC5C,oBAAoB,IAAI,yBAAyB;AAAA,IACjD,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,EAClC;AAAA;AAGK,SAAS,wCAAwC,CACtD,KACqC;AAAA,EACrC,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,kBAAkB,IAAI;AAAA,IACtB,SAAS,IAAI;AAAA,IACb,QAAQ,IAAI;AAAA,IACZ,WAAW,OAAO,IAAI,UAAU;AAAA,EAClC;AAAA;AAGK,SAAS,kBAAkB,CAAC,KAAsC;AAAA,EACvE,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,QAAQ,IAAI;AAAA,IACZ,YAAY,IAAI;AAAA,IAChB,UAAU,IAAI;AAAA,IACd,WAAW,IAAI;AAAA,IACf,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,mBAAmB,IAAI,sBAAsB,OAAO,IAAI,mBAAmB,IAAI;AAAA,IAC/E,WAAW,IAAI,aAAa,OAAO,IAAI,UAAU,IAAI;AAAA,IACrD,YAAY,IAAI,eAAe,OAAO,IAAI,YAAY,IAAI;AAAA,IAC1D,WAAW,IAAI,cAAc;AAAA,IAC7B,WAAW,IAAI,cAAc;AAAA,EAC/B;AAAA;AAGK,SAAS,sBAAsB,CAAC,KAA8C;AAAA,EACnF,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,aAAa,IAAI;AAAA,IACjB,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,IACf,UAAU,yBAAyB,IAAI,SAAS;AAAA,IAChD,oBAAoB,sBAAqB,GAAG;AAAA,IAC5C,oBAAoB,IAAI,yBAAyB;AAAA,IACjD,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,IAAI,aAAa,OAAO,IAAI,UAAU,IAAI;AAAA,IACrD,YAAY,IAAI,eAAe,OAAO,IAAI,YAAY,IAAI;AAAA,IAC1D,mBAAmB,IAAI,wBAAwB;AAAA,IAC/C,mBAAmB,IAAI,wBAAwB;AAAA,EACjD;AAAA;AAGK,SAAS,qBAAqB,CACnC,KACA,UACkB;AAAA,EAClB,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,OAAO,IAAI;AAAA,IACX;AAAA,IACA,QAAQ,IAAI;AAAA,IACZ,oBAAoB,yBAAyB,GAAG;AAAA,IAChD,oBAAoB,IAAI,yBAAyB;AAAA,IACjD,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,YAAY,IAAI,cAAc,OAAO,IAAI,WAAW,IAAI;AAAA,IACxD,WAAW,IAAI,aAAa,OAAO,IAAI,UAAU,IAAI;AAAA,EACvD;AAAA;AAGK,SAAS,0BAA0B,CAAC,KAAsD;AAAA,EAC/F,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,QAAQ,IAAI;AAAA,IACZ,SAAS,IAAI;AAAA,IACb,QAAQ,IAAI;AAAA,IACZ,WAAW,OAAO,IAAI,UAAU;AAAA,EAClC;AAAA;AAGK,SAAS,oBAAoB,CAAC,KAA0C;AAAA,EAC7E,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,YAAY,IAAI;AAAA,IAChB,UAAU,IAAI;AAAA,IACd,OAAO,IAAI;AAAA,IACX,WAAW,IAAI;AAAA,IACf,UAAU,IAAI,aAAa;AAAA,IAC3B,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,YAAY,IAAI,cAAc,OAAO,IAAI,WAAW,IAAI;AAAA,IACxD,WAAW,IAAI,aAAa,OAAO,IAAI,UAAU,IAAI;AAAA,EACvD;AAAA;AAGK,SAAS,mCAAmC,CACjD,KACgC;AAAA,EAChC,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,YAAY,IAAI;AAAA,IAChB,UAAU,IAAI;AAAA,IACd,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,IACf,cAAc,IAAI;AAAA,IAClB,UAAU,IAAI,aAAa;AAAA,IAC3B,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,YAAY,IAAI,cAAc,OAAO,IAAI,WAAW,IAAI;AAAA,EAC1D;AAAA;AAGK,SAAS,uBAAuB,CACrC,OACe;AAAA,EACf,OAAO,QAAQ,KAAK,UAAU,KAAK,IAAI;AAAA;AAGlC,SAAS,4BAA4B,CAAC,OAAqD;AAAA,EAChG,OAAO,UAAU,YAAY,OAAO,KAAK,UAAU,KAAK;AAAA;AAG1D,SAAS,qBAAoB,CAAC,KAIJ;AAAA,EACxB,IAAI,IAAI;AAAA,IAAoB,OAAO,EAAE,MAAM,QAAQ,IAAI,IAAI,mBAAmB;AAAA,EAC9E,IAAI,IAAI,+BAA+B;AAAA,IACrC,OAAO,EAAE,MAAM,kBAAkB,IAAI,IAAI,8BAA8B;AAAA,EACzE;AAAA,EACA,IAAI,IAAI;AAAA,IAAsB,OAAO,EAAE,MAAM,UAAU,IAAI,IAAI,qBAAqB;AAAA,EACpF;AAAA;AAGF,SAAS,wBAAwB,CAAC,KAAiD;AAAA,EACjF,OAAO,sBAAqB,GAAG;AAAA;AAGjC,SAAS,mBAAmB,CAC1B,OAC+C;AAAA,EAC/C,IAAI,CAAC;AAAA,IAAO;AAAA,EACZ,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,KAAK,MAAM,KAAK;AAAA,EACtD,OAAO,gBAAgB,KAAK;AAAA;AAG9B,SAAS,wBAAwB,CAC/B,OAC+B;AAAA,EAC/B,IAAI,UAAU;AAAA,IAAM;AAAA,EACpB,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,KAAK,MAAM,KAAK;AAAA,EACtD,OAAO,CAAC,GAAG,KAAK;AAAA;AAGlB,SAAS,MAAM,CAAC,OAAqB;AAAA,EACnC,OAAO,iBAAiB,OAAO,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK;AAAA;;;AClVjE;AAuBO,SAAS,cAAc,CAAC,OAAe,OAAuB;AAAA,EACnE,MAAM,aAAa,MAAM,KAAK;AAAA,EAC9B,IAAI,CAAC,YAAY;AAAA,IACf,MAAM,IAAI,iBAAiB,iBAAiB,UAAU,mCAAmC;AAAA,EAC3F;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,cAAc,CAAC,OAAuB;AAAA,EACpD,OAAO,eAAe,OAAO,OAAO,EAAE,YAAY;AAAA;AAG7C,SAAS,iBAAiB,CAAC,UAA4D;AAAA,EAC5F,OAAO,CAAC,GAAG,IAAI,KAAK,YAAY,CAAC,GAAG,IAAI,CAAC,YAAY,eAAe,SAAS,UAAU,CAAC,CAAC,CAAC;AAAA;AAGrF,SAAS,SAAS,CAAC,OAA+B;AAAA,EACvD,OAAO,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI;AAAA;AAGhC,SAAS,cAAc,CAAC,QAAiD;AAAA,EAC9E,OAAO,WAAW,aAAa,OAAO,WAAW;AAAA;AAG5C,SAAS,gBAAgB,CAC9B,OACA,QACA,WACA,OACQ;AAAA,EACR,MAAM,SAAS,MAAM,UAAU;AAAA,EAE/B,IAAI,MAAM,UAAU,WAAW;AAAA,IAC7B,OAAO,KAAK,MAAM,OAAO,MAAM;AAAA,IAC/B,OAAO,GAAG,gBAAgB,uBAAuB;AAAA,EACnD;AAAA,EAEA,IAAI,SAAS,GAAG;AAAA,IACd,OAAO,KAAK,MAAM;AAAA,IAClB,OAAO,GAAG,iBAAiB;AAAA,EAC7B;AAAA,EAEA,OAAO;AAAA;AAGF,SAAS,YAAY,CAAC,YAAoB,OAAkC;AAAA,EACjF,OAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UAAU,IAAI,aAAa,OAAO;AAAA;AAG7E,eAAsB,cAAc,CAClC,KACA,QACA,UAA4C,CAAC,GACd;AAAA,EAC/B,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,OAAO,EAAE,CAC9B;AAAA,EAEA,OAAO,OAAO;AAAA;AAGhB,eAAsB,WAAW,CAC/B,KACA,QAC4B;AAAA,EAC5B,MAAM,MAAM,MAAM,eAAe,KAAK,MAAM;AAAA,EAC5C,OAAO,MAAM,gBAAgB,GAAG,IAAI;AAAA;AAGtC,eAAsB,iBAAiB,CACrC,KACA,QACA,UAA4C,CAAC,GACd;AAAA,EAC/B,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,eAAe,OAAO,KAAK,CAAC,CACjD;AAAA,EAEA,OAAO,OAAO;AAAA;AAWhB,eAAsB,eAAe,CACnC,KACA,QACqB;AAAA,EACrB,MAAM,OAAO,MAAM,YAAY,KAAK,MAAM;AAAA,EAC1C,IAAI,CAAC,MAAM;AAAA,IACT,MAAM,IAAI,iBACR,gBACA,gBAAgB,OAAO,8BAA8B,OAAO,aAC9D;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,eAAsB,uBAAuB,CAC3C,KACA,QAKA,UAA4C,CAAC,GACN;AAAA,EACvC,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,OAAO,YAAY,OAAO,OAAO,CACtD;AAAA,EAEA,OAAO,OAAO;AAAA;AAGhB,eAAsB,iBAAiB,CACrC,KACA,QACA,UAA4C,CAAC,GACX;AAAA,EAClC,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,OAAO,EAAE,CAC9B;AAAA,EAEA,OAAO,OAAO;AAAA;AAGhB,eAAsB,cAAc,CAClC,KACA,QACuD;AAAA,EACvD,MAAM,MAAM,MAAM,kBAAkB,KAAK,MAAM;AAAA,EAC/C,OAAO,MAAM,mBAAmB,GAAG,IAAI;AAAA;AAGzC,eAAsB,kBAAkB,CACtC,KACA,QACgD;AAAA,EAChD,MAAM,UAAU,MAAM,eAAe,KAAK,MAAM;AAAA,EAChD,IAAI,CAAC,SAAS;AAAA,IACZ,MAAM,IAAI,iBACR,mBACA,mBAAmB,OAAO,8BAA8B,OAAO,aACjE;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,eAAsB,qBAAqB,CACzC,KACA,QAC4B;AAAA,EAC5B,MAAM,OAAQ,MAAM;AAAA;AAAA;AAAA,yBAGG,OAAO;AAAA,4BACJ,OAAO;AAAA;AAAA;AAAA,EAIjC,OAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,QAAQ;AAAA;AAGvC,eAAsB,iBAAiB,CACrC,KACA,QACA,UAA4C,CAAC,GACX;AAAA,EAClC,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,OAAO,EAAE,CAC9B;AAAA,EAEA,OAAO,MAAM,sBAAsB,KAAK,GAAG,IAAI;AAAA;AAGjD,eAAsB,qBAAqB,CACzC,KACA,QACA,UAA4C,CAAC,GAClB;AAAA,EAC3B,MAAM,aAAa,MAAM,kBAAkB,KAAK,QAAQ,OAAO;AAAA,EAC/D,IAAI,CAAC,YAAY;AAAA,IACf,MAAM,IAAI,iBACR,sBACA,sBAAsB,OAAO,8BAA8B,OAAO,aACpE;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,eAAsB,0BAA0B,CAC9C,KACA,QACA,UAA4C,CAAC,GACX;AAAA,EAClC,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QASI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,eAAe,OAAO,KAAK,GAAG,OAAO,GAAG,CAC7D;AAAA,EAEA,OAAO,MAAM,sBAAsB,KAAK,GAAG,IAAI;AAAA;AAGjD,eAAsB,uBAAuB,CAC3C,KACA,QAKe;AAAA,EACf,MAAM;AAAA;AAAA,yBAEiB,OAAO;AAAA,4BACJ,OAAO;AAAA;AAAA,EAGjC,YAAY,OAAO,YAAY,OAAO,SAAS,QAAQ,GAAG;AAAA,IACxD,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOA,OAAO;AAAA,UACP,OAAO;AAAA,UACP;AAAA,UACA;AAAA;AAAA;AAAA,EAGR;AAAA;AAGF,eAAsB,mBAAmB,CACvC,KACA,QACA,UAA4C,CAAC,GACT;AAAA,EACpC,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,OAAO,EAAE,CAC9B;AAAA,EAEA,OAAO,OAAO;AAAA;AAGhB,eAAsB,gBAAgB,CACpC,KACA,QACiC;AAAA,EACjC,MAAM,MAAM,MAAM,oBAAoB,KAAK,MAAM;AAAA,EACjD,OAAO,MAAM,qBAAqB,GAAG,IAAI;AAAA;AAG3C,eAAsB,gBAAgB,CACpC,KACA,QAM0B;AAAA,EAC1B,MAAM,YAAY,eAAe,OAAO,WAAW,YAAY;AAAA,EAC/D,MAAM,KAAK,eAAe,OAAO,IAAI,eAAe;AAAA,EACpD,MAAM,YAAY,eAAe,OAAO,WAAW,uBAAuB;AAAA,EAC1E,MAAM,MAAM,MAAM,oBAAoB,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EAEjF,IAAI,CAAC,KAAK;AAAA,IACR,MAAM,IAAI,iBACR,sBACA,sBAAsB,8BAA8B,aACtD;AAAA,EACF;AAAA,EAEA,sBAAsB,WAAW,IAAI,WAAW,OAAO,YAAY,GAAG;AAAA,EAEtE,MAAM;AAAA;AAAA,wBAEgB,OAAO;AAAA,yBACN;AAAA,iBACR;AAAA;AAAA,EAGf,OAAO,qBAAqB;AAAA,OACvB;AAAA,IACH,aAAa,OAAO;AAAA,EACtB,CAAC;AAAA;AAGH,eAAsB,qBAAqB,CACzC,KACA,QACA,UAA4C,CAAC,GACP;AAAA,EACtC,OAAO,OAAO,MAAM,IAAI,OACtB;AAAA;AAAA;AAAA;AAAA;AAAA,QAKI,QAAQ,YAAY,eAAe;AAAA,OAEvC,CAAC,OAAO,WAAW,OAAO,EAAE,CAC9B;AAAA,EAEA,OAAO,OAAO;AAAA;AAGhB,eAAsB,kBAAkB,CACtC,KACA,QACgD;AAAA,EAChD,MAAM,MAAM,MAAM,sBAAsB,KAAK,MAAM;AAAA,EACnD,OAAO,MAAM,oCAAoC,GAAG,IAAI;AAAA;AAG1D,eAAsB,kBAAkB,CACtC,KACA,QAMyC;AAAA,EACzC,MAAM,YAAY,eAAe,OAAO,WAAW,YAAY;AAAA,EAC/D,MAAM,KAAK,eAAe,OAAO,IAAI,+BAA+B;AAAA,EACpE,MAAM,YAAY,eAAe,OAAO,WAAW,iBAAiB;AAAA,EACpE,MAAM,MAAM,MAAM,sBAAsB,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EAEnF,IAAI,CAAC,KAAK;AAAA,IACR,MAAM,IAAI,iBACR,wBACA,sCAAsC,8BAA8B,aACtE;AAAA,EACF;AAAA,EAEA,wBAAwB,WAAW,IAAI,WAAW,OAAO,YAAY,GAAG;AAAA,EAExE,MAAM;AAAA;AAAA,wBAEgB,OAAO;AAAA,yBACN;AAAA,iBACR;AAAA;AAAA,EAGf,OAAO,oCAAoC;AAAA,OACtC;AAAA,IACH,aAAa,OAAO;AAAA,EACtB,CAAC;AAAA;AAGH,eAAsB,4BAA4B,CAChD,KACA,WACA,SACe;AAAA,EACf,MAAM,YAAY,eAAe,QAAQ,IAAI,YAAY;AAAA,EACzD,eAAe,QAAQ,UAAU,kBAAkB;AAAA,EACnD,eAAe,QAAQ,WAAW,oBAAoB;AAAA,EACtD,MAAM,yBAAyB,KAAK,WAAW,SAAS;AAAA;AAG1D,eAAsB,wBAAwB,CAC5C,KACA,WACA,WACe;AAAA,EACf,IAAI,MAAM,kBAAkB,KAAK,EAAE,WAAW,IAAI,UAAU,CAAC,GAAG;AAAA,IAC9D,MAAM,IAAI,iBACR,qBACA,mBAAmB,0CAA0C,aAC/D;AAAA,EACF;AAAA;AAGF,eAAsB,aAAa,CACjC,KACA,OACwB;AAAA,EACxB,MAAM,KAAK,eAAe,MAAM,IAAI,YAAY;AAAA,EAChD,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,EAC9D,MAAM,SAAS,eAAe,MAAM,QAAQ,SAAS;AAAA,EACrD,MAAM,aAAa,eAAe,MAAM,YAAY,aAAa;AAAA,EACjE,MAAM,WAAW,eAAe,MAAM,UAAU,kBAAkB;AAAA,EAClE,MAAM,YAAY,eAAe,MAAM,WAAW,oBAAoB;AAAA,EAEtE,MAAM,gBAAgB,KAAK,EAAE,WAAW,IAAI,OAAO,CAAC;AAAA,EACpD,MAAM,yBAAyB,KAAK,WAAW,EAAE;AAAA,EAEjD,IAAI;AAAA,IACF,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAcd;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM,qBAAqB;AAAA,UAC3B,MAAM,aAAa;AAAA,UACnB,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA,IAKzB,OAAO,mBAAmB,GAAG;AAAA,IAC7B,OAAO,OAAO;AAAA,IACd,yBACE,OACA,qBACA,mBAAmB,mCAAmC,aACxD;AAAA;AAAA;AAIJ,eAAsB,2BAA2B,CAC/C,KACA,QAMmC;AAAA,EACnC,MAAM,OACJ,OAAO,aAAa,YAChB,MAAM;AAAA;AAAA;AAAA,2BAGa,OAAO;AAAA,wBACV,OAAO;AAAA;AAAA,2BAEJ,OAAO;AAAA,oEACkC,OAAO;AAAA;AAAA;AAAA,QAInE,MAAM;AAAA;AAAA;AAAA,2BAGa,OAAO;AAAA,wBACV,OAAO;AAAA,yBACN,OAAO;AAAA;AAAA,2BAEL,OAAO;AAAA,oEACkC,OAAO;AAAA;AAAA;AAAA;AAAA,EAKzE,IAAI,OAAO,aAAa,WAAW;AAAA,IACjC,MAAM;AAAA;AAAA,yBAEe,OAAO;AAAA,2BACL,OAAO;AAAA,wBACV,OAAO;AAAA;AAAA,2BAEJ,OAAO;AAAA,oEACkC,OAAO;AAAA;AAAA,EAEzE,EAAO;AAAA,IACL,MAAM;AAAA;AAAA,yBAEe,OAAO;AAAA,2BACL,OAAO;AAAA,wBACV,OAAO;AAAA,yBACN,OAAO;AAAA;AAAA,2BAEL,OAAO;AAAA,oEACkC,OAAO;AAAA;AAAA;AAAA,EAIzE,OAAO,KAAK,IAAI,CAAC,QACf,mBAAmB;AAAA,OACd;AAAA,IACH,YAAY,OAAO;AAAA,EACrB,CAAC,CACH;AAAA;AAGF,eAAsB,qBAAqB,CACzC,KACA,OACgC;AAAA,EAChC,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,EAC9D,MAAM,SAAS,eAAe,MAAM,QAAQ,SAAS;AAAA,EACrD,MAAM,UAAU,eAAe,MAAM,SAAS,UAAU;AAAA,EAExD,MAAM,gBAAgB,KAAK,EAAE,WAAW,IAAI,OAAO,CAAC;AAAA,EAEpD,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQA;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,UAAU,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA,EAK/B,MAAM,aAAa,MAAM,mBAAmB,KAAK,EAAE,WAAW,QAAQ,QAAQ,CAAC;AAAA,EAC/E,IAAI,CAAC,YAAY;AAAA,IACf,MAAM,IAAI,iBACR,gBACA,2CAA2C,sBAAsB,UACnE;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,eAAsB,qBAAqB,CACzC,KACA,QACuC;AAAA,EACvC,MAAM,YAAY,eAAe,OAAO,WAAW,YAAY;AAAA,EAC/D,MAAM,SAAS,eAAe,OAAO,QAAQ,SAAS;AAAA,EACtD,MAAM,UAAU,eAAe,OAAO,SAAS,UAAU;AAAA,EAEzD,OAAO,OAAO,MAAM;AAAA;AAAA,yBAEG;AAAA,sBACH;AAAA,uBACC;AAAA;AAAA;AAAA,EAIrB,OAAO,MAAM,2BAA2B,GAAG,IAAI;AAAA;AAGjD,eAAsB,kBAAkB,CACtC,KACA,QACuC;AAAA,EACvC,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA,yBAGG,OAAO;AAAA,sBACV,OAAO;AAAA,uBACN,OAAO;AAAA;AAAA,EAG5B,OAAO,MAAM,2BAA2B,GAAG,IAAI;AAAA;AAGjD,eAAsB,sBAAsB,CAC1C,KACA,QAC2C;AAAA,EAC3C,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA,yBAGI,OAAO;AAAA,sBACV,OAAO;AAAA;AAAA;AAAA,EAI3B,OAAO,KAAK,IAAI,0BAA0B;AAAA;AAG5C,eAAsB,8BAA8B,CAClD,KACA,QACqC;AAAA,EACrC,MAAM,QAAQ,eAAe,OAAO,KAAK;AAAA,EACzC,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA,yBAGI,OAAO;AAAA,oBACZ;AAAA;AAAA;AAAA,yBAGK,OAAO;AAAA;AAAA;AAAA;AAAA,EAK9B,MAAM;AAAA;AAAA,uBAEe,OAAO;AAAA,yBACL,OAAO;AAAA,oBACZ;AAAA;AAAA;AAAA,yBAGK,OAAO;AAAA;AAAA,EAG9B,OAAO,KAAK,IAAI,CAAC,QACf,qBAAqB;AAAA,OAChB;AAAA,IACH,YAAY,OAAO;AAAA,EACrB,CAAC,CACH;AAAA;AAGK,SAAS,wBAAwB,CAAC,WAIvC;AAAA,EACA,OAAO;AAAA,IACL,iBAAiB,WAAW,SAAS,SAAS,UAAU,KAAK;AAAA,IAC7D,2BAA2B,WAAW,SAAS,mBAAmB,UAAU,KAAK;AAAA,IACjF,mBAAmB,WAAW,SAAS,WAAW,UAAU,KAAK;AAAA,EACnE;AAAA;AAGK,SAAS,qBAAqB,CACnC,WACA,IACA,WACA,IACA,KACM;AAAA,EACN,IAAI,IAAI,eAAe,aAAa,IAAI,eAAe,IAAI,YAAY;AAAA,IACrE,MAAM,IAAI,iBACR,sBACA,sBAAsB,iCAAiC,aACzD;AAAA,EACF;AAAA,EAEA,IAAI,IAAI,KAAK,IAAI,UAAU,KAAK,IAAI;AAAA,IAClC,MAAM,IAAI,iBACR,sBACA,sBAAsB,+BAA+B,aACvD;AAAA,EACF;AAAA;AAGK,SAAS,uBAAuB,CACrC,WACA,IACA,WACA,IACA,KACM;AAAA,EACN,IAAI,IAAI,eAAe,aAAa,IAAI,aAAa;AAAA,IACnD,MAAM,IAAI,iBACR,wBACA,sCAAsC,iCAAiC,aACzE;AAAA,EACF;AAAA,EAEA,IAAI,IAAI,KAAK,IAAI,UAAU,KAAK,IAAI;AAAA,IAClC,MAAM,IAAI,iBACR,wBACA,sCAAsC,+BAA+B,aACvE;AAAA,EACF;AAAA;AAGK,SAAS,wBAAwB,CACtC,OACA,MASA,SACO;AAAA,EACP,IAAI,kBAAkB,KAAK,GAAG;AAAA,IAC5B,MAAM,IAAI,iBAAiB,MAAM,OAAO;AAAA,EAC1C;AAAA,EAEA,MAAM;AAAA;AAGR,eAAe,qBAAqB,CAClC,KACA,KAC2B;AAAA,EAC3B,OAAO,sBACL,KACA,MAAM,sBAAsB,KAAK;AAAA,IAC/B,WAAW,IAAI;AAAA,IACf,cAAc,IAAI;AAAA,EACpB,CAAC,CACH;AAAA;;;AF1wBK,MAAM,uBAAuD;AAAA,EACrC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAA+D;AAAA,IAC1E,MAAM,KAAK,eAAe,MAAM,IAAI,iBAAiB;AAAA,IACrD,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,IAC9D,MAAM,OAAO,eAAe,MAAM,MAAM,mBAAmB;AAAA,IAC3D,MAAM,YAAY,eAAe,MAAM,WAAW,yBAAyB;AAAA,IAC3E,MAAM,YAAY,eAAe,MAAM,WAAW,mBAAmB;AAAA,IACrE,yBAAyB,KAAK;AAAA,IAC9B,MAAM,KAAK,oBAAoB,WAAW,MAAM,aAAa,SAAS;AAAA,IACtE,MAAM,WAAW,MAAM,aAAa,YAAY,YAAY,kBAAkB,MAAM,QAAQ;AAAA,IAE5F,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAiBnB;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA,6BAA6B,QAAQ;AAAA,YACrC,MAAM,oBAAoB,SAAS,SAAS,MAAM,mBAAmB,KAAK;AAAA,YAE1E,MAAM,oBAAoB,SAAS,mBAAmB,MAAM,mBAAmB,KAAK;AAAA,YAEpF,MAAM,oBAAoB,SAAS,WAAW,MAAM,mBAAmB,KAAK;AAAA,YAC5E,MAAM,sBAAsB;AAAA,YAC5B,MAAM;AAAA,YACN,MAAM;AAAA;AAAA;AAAA;AAAA,MAKZ,OAAO,uBAAuB,GAAG;AAAA,MACjC,OAAO,OAAO;AAAA,MACd,yBACE,OACA,0BACA,wBAAwB,mCAAmC,aAC7D;AAAA;AAAA;AAAA,OAIE,QAAO,CAAC,QAGwB;AAAA,IACpC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,OAAO;AAAA,mBACf,OAAO;AAAA;AAAA,IAEtB,OAAO,MAAM,uBAAuB,GAAG,IAAI;AAAA;AAAA,OAGvC,KAAI,CAAC,OAAuE;AAAA,IAChF,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAoB,CAAC,MAAM,SAAS;AAAA,IAC1C,IAAI,YAAY;AAAA,IAChB,IAAI,MAAM,MAAM;AAAA,MACd,aAAa,KAAK,WAAW,aAAa;AAAA,MAC1C,OAAO,KAAK,MAAM,IAAI;AAAA,IACxB;AAAA,IACA,IAAI,MAAM,aAAa;AAAA,MACrB,aAAa,KAAK,mBAAmB,aAAa;AAAA,MAClD,OAAO,KAAK,MAAM,WAAW;AAAA,IAC/B;AAAA,IACA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,iBAAiB,aAAa;AAAA,MAChD,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IACA,IAAI,CAAC,MAAM,gBAAgB;AAAA,MACzB,aAAa,KAAK,oBAAoB;AAAA,IACxC;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,SAAS,SAAS;AAAA,IAChD,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,4DAA4D,SAC5D,CAAC,GAAG,MAAM,CACZ;AAAA,IACA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,MAAM,QAAQ,iBACZ;AAAA;AAAA;AAAA,UAGI;AAAA,8BACoB,aAAa;AAAA,SAErC,aACA,WACA,KACF;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,IAAI,OAA+B,OAAO,WAAW;AAAA,IAC7E,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IAEzC,OAAO;AAAA,MACL,cAAc,KAAK,IAAI,sBAAsB;AAAA,MAC7C,SAAS,MAAM,UAAU,YAAY,SAAS,MAAM,UAAU,KAAK,MAAM,QAAQ;AAAA,MACjF;AAAA,IACF;AAAA;AAAA,OAGI,qBAAoB,CAAC,QAMW;AAAA,IACpC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,OAAO;AAAA,mBACf,OAAO;AAAA,qBACL,OAAO;AAAA,2BACD,OAAO;AAAA;AAAA,2BAEP,OAAO;AAAA;AAAA,IAG9B,OAAO,MAAM,uBAAuB,GAAG,IAAI;AAAA;AAAA,OAGvC,OAAM,CAAC,QAIkB;AAAA,IAC7B,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,yBAEJ,OAAO;AAAA,2BACL,OAAO;AAAA,mBACf,OAAO;AAAA;AAAA;AAAA,IAGtB,IAAI,CAAC,KAAK;AAAA,MACR,MAAM,IAAI,kBACR,wBACA,wBAAwB,OAAO,8BAA8B,OAAO,aACtE;AAAA,IACF;AAAA,IACA,OAAO,uBAAuB,GAAG;AAAA;AAAA,OAG7B,MAAK,CAAC,QAMmB;AAAA,IAC7B,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO;AAAA,4CACU,OAAO,aAAa;AAAA,4CACpB,OAAO,aAAa;AAAA,2BACrC,OAAO;AAAA,mBACf,OAAO;AAAA;AAAA;AAAA,IAGtB,IAAI,CAAC,KAAK;AAAA,MACR,MAAM,IAAI,kBACR,wBACA,wBAAwB,OAAO,8BAA8B,OAAO,aACtE;AAAA,IACF;AAAA,IACA,OAAO,uBAAuB,GAAG;AAAA;AAAA,OAGrB,oBAAmB,CAC/B,WACA,aACA,WACe;AAAA,IACf,IAAI,gBAAgB,QAAQ;AAAA,MAC1B,OAAO,QAAO,MAAM,KAAK;AAAA;AAAA;AAAA,6BAGF;AAAA,qBACR;AAAA;AAAA,MAEf,IAAI;AAAA,QAAK;AAAA,MACT,MAAM,IAAI,kBACR,gBACA,gBAAgB,qCAAqC,aACvD;AAAA,IACF;AAAA,IAEA,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF;AAAA,mBACR;AAAA;AAAA,IAEf,IAAI;AAAA,MAAK;AAAA,IACT,MAAM,IAAI,kBACR,2BACA,2BAA2B,qCAAqC,aAClE;AAAA;AAEJ;AAEA,SAAS,wBAAwB,CAAC,OAAyC;AAAA,EACzE,IACG,MAAM,SAAS,cAAc,MAAM,gBAAgB,UACnD,MAAM,SAAS,oBAAoB,MAAM,gBAAgB,kBAC1D;AAAA,IACA;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,kBACR,iBACA,6BAA6B,MAAM,qCAAqC,MAAM,eAChF;AAAA;;;AGlPK,MAAM,2BAA+D;AAAA,EAC7C;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAAuE;AAAA,IAClF,OAAO,sBAAsB,KAAK,KAAK,KAAK;AAAA;AAAA,OAGxC,OAAM,CAAC,QAI6B;AAAA,IACxC,OAAO,sBAAsB,KAAK,KAAK,MAAM;AAAA;AAAA,OAGzC,YAAW,CAAC,QAG4B;AAAA,IAC5C,OAAO,uBAAuB,KAAK,KAAK,MAAM;AAAA;AAAA,OAG1C,aAAY,CAAC,QAG2B;AAAA,IAC5C,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGD,OAAO;AAAA,yBACT,OAAO;AAAA;AAAA;AAAA,IAI5B,OAAO,KAAK,IAAI,0BAA0B;AAAA;AAE9C;;;ACpCO,MAAM,wBAAyD;AAAA,EACvC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAAiE;AAAA,IAC5E,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,IAC9D,MAAM,aAAa,eAAe,MAAM,YAAY,aAAa;AAAA,IACjE,MAAM,UAAU,eAAe,MAAM,SAAS,SAAS;AAAA,IACvD,MAAM,SAAS,eAAe,MAAM,QAAQ,SAAS;AAAA,IACrD,MAAM,WAAW,MAAM,wBAAwB,KAAK,KAAK;AAAA,MACvD;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACD,MAAM,YAAY,WAAW,IAAI,KAAK,SAAS,UAAU,IAAI,UAAU,MAAM,SAAS;AAAA,IACtF,MAAM,YAAY,MAAM,YACpB,IAAI,KAAK,MAAM,SAAS,IACxB,WACE,IAAI,OACJ;AAAA,IAEN,MAAM,gBAAgB,KAAK,KAAK,EAAE,WAAW,IAAI,OAAO,CAAC;AAAA,IAEzD,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAUnB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,wBAAwB,MAAM,MAAM;AAAA,UACpC;AAAA,UACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUN,OAAO,oBAAoB,GAAG;AAAA;AAAA,OAG1B,aAAY,CAAC,QAIoB;AAAA,IACrC,MAAM,MAAM,MAAM,wBAAwB,KAAK,KAAK,MAAM;AAAA,IAC1D,OAAO,MAAM,oBAAoB,GAAG,IAAI;AAAA;AAAA,OAGpC,YAAW,CAAC,QAGyB;AAAA,IACzC,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGD,OAAO;AAAA,wBACV,OAAO;AAAA;AAAA;AAAA,IAI3B,OAAO,KAAK,IAAI,mBAAmB;AAAA;AAEvC;;;AC7EA,6BAAS;AA8BF,MAAM,sBAAqD;AAAA,EACnC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,qBAAoB,CAAC,OAAqE;AAAA,IAC9F,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,KAAK,eAAe,MAAM,IAAI,eAAe;AAAA,MACnD,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,MAC9D,MAAM,QAAQ,eAAe,MAAM,KAAK;AAAA,MACxC,MAAM,WAAW,kBAAkB,MAAM,QAAQ;AAAA,MACjD,MAAM,MAAM,UAAU,MAAM,aAAa,MAAM,SAAS;AAAA,MACxD,MAAM,UAAU,yBAAyB,MAAM,kBAAkB;AAAA,MAEjE,MAAM,iBAAiB,IAAI,CAAC,YAAY,eAAe,WAAW,KAAK,CAAC,CAAC;AAAA,MACzE,MAAM,KAAK,gBAAgB,IAAI,WAAW,KAAK;AAAA,MAE/C,MAAM,iBAAiB,MAAM,2BAC3B,IACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,MACF,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MAEA,IAAI,gBAAgB;AAAA,QAClB,MAAM;AAAA;AAAA,qCAEuB,QAAQ;AAAA,gDACG,QAAQ;AAAA,uCACjB,QAAQ;AAAA,wCACP,MAAM,sBAAsB;AAAA,6BACvC,MAAM;AAAA,6BACN;AAAA,+BACE;AAAA,uBACR,eAAe;AAAA;AAAA,QAE9B,MAAM,wBAAwB,IAAI;AAAA,UAChC;AAAA,UACA,cAAc,eAAe;AAAA,UAC7B;AAAA,QACF,CAAC;AAAA,QAED,OAAO,sBAAsB,IAAI,EAAE,WAAW,IAAI,eAAe,GAAG,CAAC;AAAA,MACvE;AAAA,MAEA,IAAI,MAAM,kBAAkB,IAAI,EAAE,WAAW,GAAG,CAAC,GAAG;AAAA,QAClD,MAAM,IAAI,kBACR,wBACA,sBAAsB,qDAAqD,aAC7E;AAAA,MACF;AAAA,MAEA,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,MAC3C,IAAI;AAAA,QACF,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAcA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,MAAM,sBAAsB;AAAA,cAC5B;AAAA,cACA;AAAA,cACA,MAAM;AAAA;AAAA;AAAA,QAGZ,OAAO,OAAO;AAAA,QACd,yBACE,OACA,wBACA,sBAAsB,mCAAmC,aAC3D;AAAA;AAAA,MAGF,MAAM,wBAAwB,IAAI,EAAE,WAAW,cAAc,IAAI,SAAS,CAAC;AAAA,MAC3E,OAAO,sBAAsB,IAAI,EAAE,WAAW,GAAG,CAAC;AAAA,KACnD;AAAA;AAAA,OAGG,QAAO,CAAC,QAGuB;AAAA,IACnC,OAAO,kBAAkB,KAAK,KAAK,MAAM;AAAA;AAAA,OAGrC,iBAAgB,CAAC,QAIc;AAAA,IACnC,OAAO,2BAA2B,KAAK,KAAK,MAAM;AAAA;AAAA,OAG9C,KAAI,CAAC,OAAqE;AAAA,IAC9E,IAAI,eAAe,MAAM,QAAQ,KAAK,eAAe,MAAM,QAAQ,GAAG;AAAA,MACpE,OAAO,EAAE,aAAa,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IACrD;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAoB,CAAC,MAAM,SAAS;AAAA,IAC1C,IAAI,YAAY;AAAA,IAEhB,IAAI,MAAM,OAAO;AAAA,MACf,aAAa,KAAK,YAAY,aAAa;AAAA,MAC3C,OAAO,KAAK,eAAe,MAAM,KAAK,CAAC;AAAA,IACzC;AAAA,IAEA,IAAI,MAAM,UAAU;AAAA,MAClB,MAAM,qBAAqB,aAAa,WAAW,MAAM,SAAS,MAAM;AAAA,MACxE,aAAa,MAAM,SAAS;AAAA,MAC5B,aAAa,KAAK,cAAc,mBAAmB,KAAK,IAAI,IAAI;AAAA,MAChE,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IAEA,MAAM,WAAW,MAAM,WAAW,kBAAkB,MAAM,QAAQ,IAAI;AAAA,IACtE,IAAI,UAAU;AAAA,MACZ,MAAM,oBAAoB,aAAa,WAAW,SAAS,MAAM;AAAA,MACjE,aAAa,SAAS;AAAA,MACtB,aAAa,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iDAMyB,kBAAkB,KAAK,IAAI;AAAA;AAAA,OAErE;AAAA,MACD,OAAO,KAAK,GAAG,QAAQ;AAAA,IACzB;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,IAC9C,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,0DAA0D,SAC1D,CAAC,GAAG,MAAM,CACZ;AAAA,IAEA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,MAAM,QAAQ,iBACZ;AAAA;AAAA;AAAA,UAGI;AAAA,8BACoB,aAAa;AAAA,SAErC,aACA,WACA,KACF;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,IAAI,OAA8B,OAAO,WAAW;AAAA,IAC5E,MAAM,cAAc,MAAM,QAAQ,IAChC,KAAK,IAAI,OAAO,QACd,sBACE,KACA,MAAM,sBAAsB,KAAK,KAAK;AAAA,MACpC,WAAW,IAAI;AAAA,MACf,cAAc,IAAI;AAAA,IACpB,CAAC,CACH,CACF,CACF;AAAA,IACA,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IAEzC,OAAO;AAAA,MACL;AAAA,MACA,UAAU,MAAM,UAAU,KAAK,KAAK,SAAS;AAAA,MAC7C;AAAA,IACF;AAAA;AAAA,OAGI,OAAM,CAAC,QAIiB;AAAA,IAC5B,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,sBAAsB,IAAI,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,MAE3D,MAAM;AAAA;AAAA;AAAA,4BAGgB,OAAO;AAAA,2BACR,OAAO;AAAA,6BACL,OAAO;AAAA,qBACf,OAAO;AAAA;AAAA,MAGtB,OAAO,sBAAsB,IAAI,MAAM;AAAA,KACxC;AAAA;AAAA,OAGG,OAAM,CAAC,QAIiB;AAAA,IAC5B,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,sBAAsB,IAAI,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,MAE3D,MAAM;AAAA;AAAA;AAAA,2BAGe,OAAO;AAAA,2BACP,OAAO;AAAA,6BACL,OAAO;AAAA,qBACf,OAAO;AAAA;AAAA,MAGtB,OAAO,sBAAsB,IAAI,MAAM;AAAA,KACxC;AAAA;AAAA,OAGW,gBAAe,CAC3B,KACA,WACA,OACe;AAAA,IACf,IAAI,MAAM,oBAAoB,SAAS,QAAQ;AAAA,MAC7C,MAAM,gBAAgB,KAAK,EAAE,WAAW,IAAI,MAAM,mBAAmB,GAAG,CAAC;AAAA,IAC3E;AAAA,IAEA,IAAI,MAAM,oBAAoB;AAAA,MAC5B,MAAM,mBAAmB,KAAK,EAAE,WAAW,IAAI,MAAM,mBAAmB,CAAC;AAAA,IAC3E;AAAA;AAEJ;;;ACvRA;AAMA,6BAAS;AAmBF,MAAM,qBAAmD;AAAA,EACjC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAA2D;AAAA,IACtE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,KAAK,eAAe,MAAM,IAAI,eAAe;AAAA,MACnD,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,MAC9D,MAAM,aAAa,eAAe,MAAM,YAAY,aAAa;AAAA,MACjE,MAAM,WAAW,2BAA2B,MAAM,QAAQ;AAAA,MAC1D,MAAM,QAAQ,eAAe,MAAM,KAAK;AAAA,MACxC,MAAM,YAAY,eAAe,MAAM,WAAW,uBAAuB;AAAA,MAEzE,MAAM,iBAAiB,IAAI,CAAC,YAAY,eAAe,WAAW,KAAK,CAAC,CAAC;AAAA,MAEzE,IAAI,MAAM,oBAAoB,IAAI,EAAE,WAAW,GAAG,CAAC,GAAG;AAAA,QACpD,MAAM,IAAI,kBACR,wBACA,sBAAsB,mCAAmC,aAC3D;AAAA,MACF;AAAA,MAEA,MAAM,+BAA+B,IAAI;AAAA,QACvC;AAAA,QACA;AAAA,QACA,WAAW,MAAM;AAAA,MACnB,CAAC;AAAA,MAED,IAAI;AAAA,QACF,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYd;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,MAAM,YAAY;AAAA,cAClB,MAAM;AAAA,cACN,MAAM;AAAA;AAAA;AAAA;AAAA,QAKZ,OAAO,qBAAqB,GAAG;AAAA,QAC/B,OAAO,OAAO;AAAA,QACd,yBACE,OACA,wBACA,sBAAsB,mCAAmC,aAC3D;AAAA;AAAA,KAEH;AAAA;AAAA,OAGG,QAAO,CAAC,QAGsB;AAAA,IAClC,OAAO,iBAAiB,KAAK,KAAK,MAAM;AAAA;AAAA,OAGpC,iBAAgB,CAAC,QAIa;AAAA,IAClC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,OAAO;AAAA,sBACZ,eAAe,OAAO,KAAK;AAAA;AAAA;AAAA,2BAGtB,OAAO;AAAA;AAAA;AAAA;AAAA,IAK9B,OAAO,MAAM,qBAAqB,GAAG,IAAI;AAAA;AAAA,OAGrC,QAAO,CAAC,QAKe;AAAA,IAC3B,OAAO,iBAAiB,KAAK,KAAK,CAAC,OAAO,iBAAiB,IAAI,MAAM,CAAC;AAAA;AAAA,OAGlE,qBAAoB,CAAC,QAIa;AAAA,IACtC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,QAAQ,eAAe,OAAO,KAAK;AAAA,MACzC,MAAM,iBAAiB,IAAI,CAAC,YAAY,eAAe,OAAO,WAAW,KAAK,CAAC,CAAC;AAAA,MAChF,OAAO,+BAA+B,IAAI;AAAA,WACrC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,KACF;AAAA;AAEL;;;AC3IA,uCAAS;AAMT,6BAAS;AAYF,MAAM,oCAAiF;AAAA,EAC/D;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CACV,OACyC;AAAA,IACzC,MAAM,KAAK,eAAe,MAAM,IAAI,+BAA+B;AAAA,IACnE,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,IAC9D,MAAM,aAAa,eAAe,MAAM,YAAY,aAAa;AAAA,IACjE,MAAM,WAAW,4BAA2B,MAAM,QAAQ;AAAA,IAC1D,MAAM,YAAY,eAAe,MAAM,WAAW,iBAAiB;AAAA,IACnE,MAAM,YAAY,eAAe,MAAM,WAAW,iBAAiB;AAAA,IACnE,MAAM,eAAe,eAAe,MAAM,cAAc,oBAAoB;AAAA,IAE5E,IAAI,MAAM,sBAAsB,KAAK,KAAK,EAAE,WAAW,GAAG,CAAC,GAAG;AAAA,MAC5D,MAAM,IAAI,kBACR,0BACA,sCAAsC,mCAAmC,aAC3E;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAanB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM,YAAY;AAAA,YAClB,MAAM;AAAA,YACN,MAAM;AAAA;AAAA;AAAA;AAAA,MAKZ,OAAO,oCAAoC,GAAG;AAAA,MAC9C,OAAO,OAAO;AAAA,MACd,yBACE,OACA,0BACA,sCAAsC,mCAAmC,aAC3E;AAAA;AAAA;AAAA,OAIE,QAAO,CAAC,QAGqC;AAAA,IACjD,OAAO,mBAAmB,KAAK,KAAK,MAAM;AAAA;AAAA,OAGtC,QAAO,CAAC,QAK8B;AAAA,IAC1C,OAAO,iBAAiB,KAAK,KAAK,CAAC,OAAO,mBAAmB,IAAI,MAAM,CAAC;AAAA;AAE5E;;;ACtFA,6BAAS;AAMF,MAAM,yCAEb;AAAA,EAC+B;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CACV,OAC8C;AAAA,IAC9C,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,IAC9D,MAAM,mBAAmB,eAAe,MAAM,kBAAkB,oBAAoB;AAAA,IACpF,MAAM,UAAU,eAAe,MAAM,SAAS,UAAU;AAAA,IACxD,OAAO,kBAAkB,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGb;AAAA,mBACR;AAAA;AAAA,IAEf,IAAI,CAAC,gBAAgB;AAAA,MACnB,MAAM,IAAI,kBACR,2BACA,2BAA2B,4CAA4C,aACzE;AAAA,IACF;AAAA,IAEA,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQnB;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,UACN,UAAU,MAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO/B,OAAO,yCAAyC,GAAG;AAAA;AAAA,OAG/C,2BAA0B,CAC9B,OACyD;AAAA,IACzD,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,IAC9D,MAAM,mBAAmB,eAAe,MAAM,kBAAkB,oBAAoB;AAAA,IACpF,MAAM,WAAW;AAAA,MACf,GAAG,IAAI,IAAI,MAAM,SAAS,IAAI,CAAC,YAAY,eAAe,SAAS,UAAU,CAAC,CAAC;AAAA,IACjF;AAAA,IACA,OAAO,kBAAkB,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGb;AAAA,mBACR;AAAA;AAAA,IAEf,IAAI,CAAC,gBAAgB;AAAA,MACnB,MAAM,IAAI,kBACR,2BACA,2BAA2B,4CAA4C,aACzE;AAAA,IACF;AAAA,IAEA,IAAI,SAAS,WAAW,GAAG;AAAA,MACzB,MAAM,KAAK;AAAA;AAAA,6BAEY;AAAA,qCACQ;AAAA,yBACZ,MAAM;AAAA;AAAA,IAE3B,EAAO;AAAA,MACL,MAAM,KAAK;AAAA;AAAA,6BAEY;AAAA,qCACQ;AAAA,yBACZ,MAAM;AAAA,gCACC,KAAK,IAAI,QAAQ;AAAA;AAAA;AAAA,IAI7C,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,IAC3C,WAAW,WAAW,UAAU;AAAA,MAC9B,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAQL;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM;AAAA,YACN;AAAA;AAAA;AAAA;AAAA;AAAA,IAKR;AAAA,IAEA,OAAO,KAAK,sBAAsB,EAAE,WAAW,iBAAiB,CAAC;AAAA;AAAA,OAG7D,sBAAqB,CAAC,QAGgC;AAAA,IAC1D,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGD,OAAO;AAAA,mCACC,OAAO;AAAA;AAAA;AAAA,IAItC,OAAO,KAAK,IAAI,wCAAwC;AAAA;AAAA,OAGpD,aAAY,CAAC,QAGyC;AAAA,IAC1D,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGD,OAAO;AAAA,yBACT,OAAO;AAAA;AAAA;AAAA,IAI5B,OAAO,KAAK,IAAI,wCAAwC;AAAA;AAE5D;;;AC7IA,6BAAS;AAaF,MAAM,0BAA6D;AAAA,EAC3C;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAAqE;AAAA,IAChF,MAAM,KAAK,eAAe,MAAM,IAAI,oBAAoB;AAAA,IACxD,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,IAC9D,MAAM,OAAO,eAAe,MAAM,MAAM,sBAAsB;AAAA,IAC9D,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,IAC3C,MAAM,YAAY,MAAM,YAAY,IAAI,KAAK,MAAM,SAAS,IAAI;AAAA,IAEhE,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAcnB;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM,eAAe;AAAA,YACrB,MAAM,UAAU;AAAA,YAChB,MAAM,oBAAoB,SAAS,SAAS,MAAM,mBAAmB,KAAK;AAAA,YAE1E,MAAM,oBAAoB,SAAS,mBAAmB,MAAM,mBAAmB,KAAK;AAAA,YAEpF,MAAM,oBAAoB,SAAS,WAAW,MAAM,mBAAmB,KAAK;AAAA,YAC5E,MAAM,sBAAsB;AAAA,YAC5B;AAAA,YACA;AAAA;AAAA;AAAA;AAAA,MAKN,OAAO,0BAA0B,GAAG;AAAA,MACpC,OAAO,OAAO;AAAA,MACd,yBACE,OACA,6BACA,2BAA2B,mCAAmC,aAChE;AAAA;AAAA;AAAA,OAIE,QAAO,CAAC,QAG2B;AAAA,IACvC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,OAAO;AAAA,mBACf,OAAO;AAAA;AAAA,IAEtB,OAAO,MAAM,0BAA0B,GAAG,IAAI;AAAA;AAAA,OAG1C,OAAM,CAAC,OAAqE;AAAA,IAChF,MAAM,WAAW,MAAM,KAAK,QAAQ,KAAK;AAAA,IACzC,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,kBACR,2BACA,2BAA2B,MAAM,8BAA8B,MAAM,aACvE;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,IAC3C,MAAM,OACJ,MAAM,SAAS,YAAY,SAAS,OAAO,eAAe,MAAM,MAAM,sBAAsB;AAAA,IAC9F,MAAM,cAAc,MAAM,gBAAgB,YAAY,SAAS,cAAc,MAAM;AAAA,IACnF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,mBAEV;AAAA,0BACO,eAAe;AAAA,qBACpB,MAAM,UAAU,SAAS;AAAA,yBACrB;AAAA,2BACE,MAAM;AAAA,mBACd,MAAM;AAAA;AAAA;AAAA,IAIrB,OAAO,0BAA0B,GAAG;AAAA;AAAA,OAGhC,KAAI,CAAC,OAA6E;AAAA,IACtF,IAAI,eAAe,MAAM,QAAQ,GAAG;AAAA,MAClC,OAAO,EAAE,iBAAiB,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IACzD;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAoB,CAAC,MAAM,SAAS;AAAA,IAC1C,IAAI,YAAY;AAAA,IAChB,IAAI,MAAM,UAAU;AAAA,MAClB,aAAa,KAAK,cAAc,MAAM,SAAS,IAAI,MAAM,IAAI,aAAa,EAAE,KAAK,IAAI,IAAI;AAAA,MACzF,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,SAAS,SAAS;AAAA,IAChD,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,+DAA+D,SAC/D,CAAC,GAAG,MAAM,CACZ;AAAA,IACA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,MAAM,QAAQ,iBACZ;AAAA;AAAA;AAAA,UAGI;AAAA,8BACoB,aAAa;AAAA,SAErC,aACA,WACA,KACF;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,IAAI,OAAkC,OAAO,WAAW;AAAA,IAChF,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IAEzC,OAAO;AAAA,MACL,iBAAiB,KAAK,IAAI,yBAAyB;AAAA,MACnD,SAAS,MAAM,UAAU,YAAY,SAAS,MAAM,UAAU,KAAK,MAAM,QAAQ;AAAA,MACjF;AAAA,IACF;AAAA;AAEJ;;;ACvJA,6BAAS;AAiBF,MAAM,mBAA+C;AAAA,EAC7B;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAAuD;AAAA,IAGlE,OAAO,iBAAiB,KAAK,KAAK,CAAC,OAAO,cAAc,IAAI,KAAK,CAAC;AAAA;AAAA,OAG9D,QAAO,CAAC,QAGoB;AAAA,IAChC,OAAO,eAAe,KAAK,KAAK,MAAM;AAAA;AAAA,OAGlC,kBAAiB,CAAC,QAKU;AAAA,IAChC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,OAAO;AAAA,wBACV,OAAO;AAAA,yBACN,OAAO;AAAA;AAAA,2BAEL,OAAO;AAAA,oEACkC,OAAO;AAAA;AAAA;AAAA;AAAA,IAKvE,OAAO,MAAM,mBAAmB,GAAG,IAAI;AAAA;AAAA,OAGnC,mBAAkB,CAAC,QAIa;AAAA,IACpC,MAAM,OAAQ,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,OAAO;AAAA,wBACV,OAAO;AAAA;AAAA,2BAEJ,OAAO;AAAA,oEACkC,OAAO;AAAA;AAAA;AAAA,IAIvE,OAAO,KAAK,IAAI,kBAAkB;AAAA;AAAA,OAG9B,qBAAoB,CAAC,QAMO;AAAA,IAChC,MAAM,MAAM,MAAM,kBAAkB,KAAK,KAAK,MAAM;AAAA,IAEpD,IACE,CAAC,OACD,IAAI,aAAa,OAAO,YACxB,IAAI,eAAe,OAAO,aAC1B,IAAI,cACJ,IAAI,KAAK,IAAI,UAAU,KAAK,OAAO,OAClC,IAAI,wBAAwB,QAAQ,IAAI,KAAK,IAAI,mBAAmB,KAAK,OAAO,KACjF;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IAEA,OAAO,mBAAmB,GAAG;AAAA;AAAA,OAGzB,aAAY,CAAC,QAOe;AAAA,IAChC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,gBAKb,OAAO;AAAA,8CACuB,OAAO;AAAA;AAAA;AAAA,2BAG1B,OAAO;AAAA,2BACP,OAAO;AAAA,mBACf,OAAO;AAAA,yBACD,OAAO;AAAA,2BACL,OAAO;AAAA;AAAA,2BAEP,OAAO;AAAA,oEACkC,OAAO;AAAA;AAAA;AAAA,IAIvE,OAAO,MAAM,mBAAmB,GAAG,IAAI;AAAA;AAAA,OAGnC,OAAM,CAAC,QAIc;AAAA,IACzB,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,WAAW,MAAM,kBAAkB,IAAI,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,MAExE,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,kBACR,mBACA,mBAAmB,OAAO,8BAA8B,OAAO,aACjE;AAAA,MACF;AAAA,MAEA,OAAO,OAAO,MAAM;AAAA;AAAA,2BAEC,OAAO;AAAA,6BACL,OAAO;AAAA,qBACf,OAAO;AAAA;AAAA;AAAA,MAItB,OAAO,mBAAmB,GAAG;AAAA,KAC9B;AAAA;AAAA,OAGG,oBAAmB,CAAC,QAKY;AAAA,IACpC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,QAAQ,CAAC,YAAY,YAAY,OAAO,WAAW,OAAO,MAAM,CAAC;AAAA,MACvE,IAAI,OAAO,UAAU;AAAA,QACnB,MAAM,KAAK,YAAY,YAAY,OAAO,WAAW,OAAO,QAAQ,OAAO,QAAQ,CAAC;AAAA,MACtF;AAAA,MACA,MAAM,iBAAiB,IAAI,KAAK;AAAA,MAChC,OAAO,4BAA4B,IAAI,MAAM;AAAA,KAC9C;AAAA;AAAA,OAGG,MAAK,CAAC,QAIe;AAAA,IACzB,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,mBAAmB,IAAI,MAAM;AAAA,MAEnC,OAAO,OAAO,MAAM;AAAA;AAAA,6BAEG,OAAO;AAAA,6BACP,OAAO;AAAA,qBACf,OAAO;AAAA;AAAA;AAAA,MAItB,OAAO,mBAAmB,GAAG;AAAA,KAC9B;AAAA;AAEL;;;ACvLA,6BAAS;AAgBF,MAAM,gBAAyC;AAAA,EACvB;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAAiD;AAAA,IAC5D,MAAM,KAAK,eAAe,MAAM,IAAI,SAAS;AAAA,IAC7C,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,IAC9D,MAAM,QAAQ,eAAe,MAAM,KAAK;AAAA,IAExC,IAAI,MAAM,eAAe,KAAK,KAAK,EAAE,WAAW,GAAG,CAAC,GAAG;AAAA,MACrD,MAAM,IAAI,kBACR,kBACA,gBAAgB,mCAAmC,aACrD;AAAA,IACF;AAAA,IAEA,IAAI,MAAM,kBAAkB,KAAK,KAAK,EAAE,WAAW,MAAM,CAAC,GAAG;AAAA,MAC3D,MAAM,IAAI,kBACR,kBACA,sBAAsB,sCAAsC,aAC9D;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,IAC3C,MAAM,YAAY,MAAM,YAAY,IAAI,KAAK,MAAM,SAAS,IAAI;AAAA,IAEhE,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAWnB;AAAA,YACA;AAAA,YACA;AAAA,YACA,MAAM,eAAe;AAAA,YACrB,MAAM,aAAa;AAAA,YACnB,MAAM,UAAU;AAAA,YAChB;AAAA,YACA;AAAA;AAAA;AAAA;AAAA,MAKN,OAAO,gBAAgB,GAAG;AAAA,MAC1B,OAAO,OAAO;AAAA,MACd,yBACE,OACA,kBACA,gBAAgB,mCAAmC,aACrD;AAAA;AAAA;AAAA,OAIE,QAAO,CAAC,QAGiB;AAAA,IAC7B,MAAM,MAAM,MAAM,eAAe,KAAK,KAAK,MAAM;AAAA,IACjD,OAAO,MAAM,gBAAgB,GAAG,IAAI;AAAA;AAAA,OAGhC,WAAU,CAAC,QAGc;AAAA,IAC7B,MAAM,MAAM,MAAM,kBAAkB,KAAK,KAAK,MAAM;AAAA,IACpD,OAAO,MAAM,gBAAgB,GAAG,IAAI;AAAA;AAAA,OAGhC,cAAa,CAAC,OAAwD;AAAA,IAC1E,MAAM,WAAW,MAAM,eAAe,KAAK,KAAK;AAAA,MAC9C,WAAW,MAAM;AAAA,MACjB,IAAI,MAAM;AAAA,IACZ,CAAC;AAAA,IAED,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,kBACR,gBACA,gBAAgB,MAAM,8BAA8B,MAAM,aAC5D;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,IAC3C,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,MAAM,eAAe;AAAA,yBACvB,MAAM,aAAa;AAAA,yBACnB;AAAA,2BACE,MAAM;AAAA,mBACd,MAAM;AAAA;AAAA;AAAA,IAIrB,OAAO,gBAAgB,GAAG;AAAA;AAAA,OAGtB,aAAY,CAAC,OAAuD;AAAA,IACxE,MAAM,WAAW,MAAM,eAAe,KAAK,KAAK;AAAA,MAC9C,WAAW,MAAM;AAAA,MACjB,IAAI,MAAM;AAAA,IACZ,CAAC;AAAA,IAED,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,kBACR,gBACA,gBAAgB,MAAM,8BAA8B,MAAM,aAC5D;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,UAAU,MAAM,SAAS;AAAA,IAC3C,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,qBAER,MAAM;AAAA,yBACF;AAAA,2BACE,MAAM;AAAA,mBACd,MAAM;AAAA;AAAA;AAAA,IAIrB,OAAO,gBAAgB,GAAG;AAAA;AAAA,OAGtB,KAAI,CAAC,OAAyD;AAAA,IAClE,IAAI,eAAe,MAAM,QAAQ,GAAG;AAAA,MAClC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IAC/C;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAoB,CAAC,MAAM,SAAS;AAAA,IAC1C,IAAI,YAAY;AAAA,IAEhB,IAAI,MAAM,UAAU;AAAA,MAClB,aAAa,KAAK,cAAc,MAAM,SAAS,IAAI,MAAM,IAAI,aAAa,EAAE,KAAK,IAAI,IAAI;AAAA,MACzF,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,IAC9C,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,oDAAoD,SACpD,CAAC,GAAG,MAAM,CACZ;AAAA,IAEA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,MAAM,QAAQ,iBACZ;AAAA;AAAA;AAAA,UAGI;AAAA,8BACoB,aAAa;AAAA,SAErC,aACA,WACA,KACF;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,IAAI,OAAwB,OAAO,WAAW;AAAA,IACtE,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IAEzC,OAAO;AAAA,MACL,OAAO,KAAK,IAAI,eAAe;AAAA,MAC/B,UAAU,MAAM,UAAU,KAAK,KAAK,SAAS;AAAA,MAC7C;AAAA,IACF;AAAA;AAEJ;;;AZjIO,MAAM,cAAqC;AAAA,EAC/B;AAAA,EAER;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,WAAW,CAAC,SAA+B;AAAA,IACzC,KAAK,MAAM,QAAQ;AAAA,IACnB,KAAK,QAAQ,IAAI,gBAAgB,KAAK,GAAG;AAAA,IACzC,KAAK,aAAa,IAAI,wBAAwB,KAAK,GAAG;AAAA,IACtD,KAAK,kBAAkB,IAAI,0BAA0B,KAAK,GAAG;AAAA,IAC7D,KAAK,iCAAiC,IAAI,yCAAyC,KAAK,GAAG;AAAA,IAC3F,KAAK,WAAW,IAAI,mBAAmB,KAAK,GAAG;AAAA,IAC/C,KAAK,eAAe,IAAI,uBAAuB,KAAK,GAAG;AAAA,IACvD,KAAK,cAAc,IAAI,sBAAsB,KAAK,GAAG;AAAA,IACrD,KAAK,mBAAmB,IAAI,2BAA2B,KAAK,GAAG;AAAA,IAC/D,KAAK,aAAa,IAAI,qBAAqB,KAAK,GAAG;AAAA,IACnD,KAAK,4BAA4B,IAAI,oCAAoC,KAAK,GAAG;AAAA;AAAA,OAG7E,wBAAuB,CAC3B,OAC+B;AAAA,IAC/B,MAAM,SAAS,MAAM,iBACnB,KAAK,KACL,OAAO,OAA6D;AAAA,MAClE,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,MAC9D,MAAM,cAAc,IAAI,KAAK,MAAM,WAAW;AAAA,MAC9C,MAAM,mBAAmB,MAAM,oBAAoB,IAAI;AAAA,QACrD;AAAA,QACA,IAAI,MAAM;AAAA,MACZ,CAAC;AAAA,MAED,IAAI,CAAC,kBAAkB;AAAA,QACrB,MAAM,IAAI,mBACR,sBACA,sBAAsB,MAAM,uCAAuC,aACrE;AAAA,MACF;AAAA,MAEA,MAAM,QAAQ,eAAe,iBAAiB,KAAK;AAAA,MACnD,MAAM,iBAAiB,IAAI;AAAA,QACzB,YAAY,aAAa,SAAS;AAAA,QAClC,YAAY,eAAe,WAAW,KAAK;AAAA,QAC3C,YAAY,eAAe,WAAW,KAAK;AAAA,QAC3C,YAAY,SAAS,WAAW,KAAK;AAAA,MACvC,CAAC;AAAA,MAED,MAAM,YAAY,MAAM,oBACtB,IACA;AAAA,QACE;AAAA,QACA,IAAI,MAAM;AAAA,MACZ,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MAEA,KAAK,sBACH,WACA,MAAM,aACN,MAAM,WACN,aACA,SACF;AAAA,MAEA,MAAM,kBAAkB,MAAM,kBAC5B,IACA;AAAA,QACE;AAAA,QACA;AAAA,MACF,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MACA,MAAM,mBAAmB,MAAM,2BAC7B,IACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MACA,MAAM,mBAAmB,CAAC;AAAA,MAC1B,MAAM,iBAAiB,kBAAkB,MAAM,cAAc;AAAA,MAE7D,IAAI,iBAAiB,WAAW,aAAa;AAAA,QAC3C,MAAM,iBAAiB,IAAI;AAAA,UACzB;AAAA,UACA,IAAI,MAAM;AAAA,UACV,WAAW,MAAM;AAAA,UACjB,YAAY;AAAA,QACd,CAAC;AAAA,QACD,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,kBACA,gBAAgB,gBAAgB,iCAAiC,aACnE;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IAAI,oBAAoB,CAAC,oBAAoB,CAAC,MAAM,oCAAoC;AAAA,QACtF,MAAM,iBAAiB,IAAI;AAAA,UACzB;AAAA,UACA,IAAI,MAAM;AAAA,UACV,WAAW,MAAM;AAAA,UACjB,YAAY;AAAA,QACd,CAAC;AAAA,QACD,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,6BACA,sBAAsB,MAAM,kDAAkD,aAChF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IACE,oBACA,CAAC,oBACD,MAAM,sCACN,MAAM,uCACL,MAAM,eAAe,IAAI,SAAS,GACnC;AAAA,QACA,MAAM,iBAAiB,IAAI;AAAA,UACzB;AAAA,UACA,IAAI,MAAM;AAAA,UACV,WAAW,MAAM;AAAA,UACjB,YAAY;AAAA,QACd,CAAC;AAAA,QACD,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,6BACA,sBAAsB,MAAM,kDAAkD,aAChF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,6BAA6B,IAAI,WAAW,MAAM,OAAO;AAAA,MAC/D,4BAA4B,WAAW,MAAM,QAAQ,UAAU,UAAU,QAAQ;AAAA,MAEjF,IAAI;AAAA,MACJ,IAAI,kBAAkB;AAAA,QACpB,YAAY,eAAe,MAAM,WAAW,SAAS;AAAA,QACrD,IAAI,MAAM,eAAe,IAAI,EAAE,WAAW,IAAI,UAAU,CAAC,GAAG;AAAA,UAC1D,MAAM,IAAI,mBACR,kBACA,gBAAgB,0CAA0C,aAC5D;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,gBAAgB,iBAAiB,MAAM,aAAa,MAAM;AAAA,MAChE,MAAM,iBAAiB,IAAI,CAAC,YAAY,YAAY,WAAW,aAAa,CAAC,CAAC;AAAA,MAE9E,MAAM,iBAAiB,IAAI;AAAA,QACzB;AAAA,QACA,IAAI,MAAM;AAAA,QACV,WAAW,MAAM;AAAA,QACjB,YAAY;AAAA,MACd,CAAC;AAAA,MAED,MAAM,OAAO,kBACT,gBAAgB,eAAe,IAC/B,MAAM,KAAK,WAAW,IAAI;AAAA,QACxB,IAAI,aAAa,eAAe,MAAM,WAAW,SAAS;AAAA,QAC1D;AAAA,QACA;AAAA,QACA,aAAa,MAAM;AAAA,QACnB,WAAW,MAAM;AAAA,QACjB,WAAW;AAAA,MACb,CAAC;AAAA,MAEL,MAAM,aAAa,MAAM,KAAK,+BAA+B,IAAI;AAAA,QAC/D;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD,MAAM,mBAAmB,MAAM,KAAK,kBAAkB,IAAI;AAAA,QACxD;AAAA,QACA,UAAU,WAAW;AAAA,QACrB,UAAU;AAAA,QACV;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,MACD,MAAM,UAAU,MAAM,KAAK,oBAAoB,IAAI;AAAA,QACjD;AAAA,QACA,YAAY,UAAU;AAAA,QACtB,SAAS,MAAM;AAAA,QACf,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,MAED,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,YAAY,WAAW;AAAA,QACvB;AAAA,MACF;AAAA,KAEJ;AAAA,IAEA,IAAI,WAAW,QAAQ;AAAA,MACrB,MAAM,OAAO;AAAA,IACf;AAAA,IAEA,OAAO;AAAA;AAAA,OAGH,mBAAkB,CAAC,OAA+D;AAAA,IACtF,MAAM,SAAS,MAAM,iBACnB,KAAK,KACL,OAAO,OAA6D;AAAA,MAClE,MAAM,YAAY,eAAe,MAAM,WAAW,YAAY;AAAA,MAC9D,MAAM,cAAc,IAAI,KAAK,MAAM,WAAW;AAAA,MAC9C,MAAM,UAAU,MAAM,sBACpB,IACA;AAAA,QACE;AAAA,QACA,IAAI,MAAM;AAAA,MACZ,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MAEA,KAAK,wBACH,WACA,MAAM,4BACN,MAAM,WACN,aACA,OACF;AAAA,MAEA,MAAM,UAAU,eAAe,MAAM,SAAS,SAAS;AAAA,MACvD,MAAM,QAAQ,eAAe,MAAM,KAAK;AAAA,MACxC,MAAM,iBAAiB,IAAI;AAAA,QACzB,YAAY,aAAa,SAAS;AAAA,QAClC,YAAY,eAAe,WAAW,KAAK;AAAA,QAC3C,YAAY,cAAc,WAAW,QAAQ,aAAa,OAAO;AAAA,QACjE,YAAY,SAAS,WAAW,KAAK;AAAA,MACvC,CAAC;AAAA,MAED,MAAM,WAAW,MAAM,wBACrB,IACA;AAAA,QACE;AAAA,QACA,YAAY,QAAQ;AAAA,QACpB;AAAA,MACF,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MACA,MAAM,mBAAmB,WACrB,OACA,MAAM,2BACJ,IACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,KAAK;AAAA,MACP,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MACJ,IAAI,UAAU,WACV,MAAM,eAAe,IAAI,EAAE,WAAW,IAAI,SAAS,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC,IACjF,MAAM,kBAAkB,IAAI,EAAE,WAAW,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,MACzE,MAAM,mBAAmB,CAAC,YAAY,CAAC;AAAA,MACvC,MAAM,iBAAiB,kBAAkB,MAAM,cAAc;AAAA,MAE7D,IAAI,YAAY,CAAC,SAAS;AAAA,QACxB,MAAM,KAAK,mBAAmB,OAAO,aAAa,WAAW,EAAE;AAAA,QAC/D,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,gBACA,gBAAgB,SAAS,8CAC3B;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IAAI,CAAC,YAAY,YAAY,CAAC,MAAM,2BAA2B,CAAC,MAAM,gBAAgB;AAAA,QACpF,MAAM,KAAK,mBAAmB,OAAO,aAAa,WAAW,EAAE;AAAA,QAC/D,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,0BACA,kDAAkD,QAAQ,oBAAoB,aAChF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IAAI,SAAS,WAAW,aAAa;AAAA,QACnC,MAAM,KAAK,mBAAmB,OAAO,aAAa,WAAW,EAAE;AAAA,QAC/D,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,kBACA,gBAAgB,QAAQ,iCAAiC,aAC3D;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IAAI,oBAAoB,CAAC,MAAM,eAAe;AAAA,QAC5C,MAAM,KAAK,mBAAmB,OAAO,aAAa,WAAW,EAAE;AAAA,QAC/D,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,6BACA,sCAAsC,MAAM,iEAAiE,aAC/G;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IAAI,oBAAoB,CAAC,oBAAoB,CAAC,MAAM,oCAAoC;AAAA,QACtF,MAAM,KAAK,mBAAmB,OAAO,aAAa,WAAW,EAAE;AAAA,QAC/D,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,6BACA,sCAAsC,MAAM,iEAAiE,aAC/G;AAAA,QACF;AAAA,MACF;AAAA,MAEA,IACE,oBACA,CAAC,oBACD,MAAM,sCACN,MAAM,uCACL,MAAM,eAAe,IAAI,SAAS,GACnC;AAAA,QACA,MAAM,KAAK,mBAAmB,OAAO,aAAa,WAAW,EAAE;AAAA,QAC/D,OAAO;AAAA,UACL,OAAO,IAAI,mBACT,6BACA,sCAAsC,MAAM,iEAAiE,aAC/G;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,6BAA6B,IAAI,WAAW,MAAM,OAAO;AAAA,MAC/D,4BAA4B,WAAW,MAAM,QAAQ,UAAU,QAAQ,QAAQ;AAAA,MAE/E,IAAI;AAAA,MACJ,IAAI,kBAAkB;AAAA,QACpB,YAAY,eAAe,MAAM,WAAW,SAAS;AAAA,QACrD,IAAI,MAAM,eAAe,IAAI,EAAE,WAAW,IAAI,UAAU,CAAC,GAAG;AAAA,UAC1D,MAAM,IAAI,mBACR,kBACA,gBAAgB,0CAA0C,aAC5D;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,iBAAiB,IAAI;AAAA,QACzB,YAAY,YAAY,WAAW,SAAS,MAAM,aAAa,MAAM,SAAS;AAAA,MAChF,CAAC;AAAA,MACD,MAAM,KAAK,mBAAmB,OAAO,aAAa,WAAW,EAAE;AAAA,MAE/D,IAAI;AAAA,MACJ,IAAI,CAAC,SAAS;AAAA,QACZ,OAAO,MAAM,KAAK,WAAW,IAAI;AAAA,UAC/B,IAAI,aAAa,eAAe,MAAM,WAAW,SAAS;AAAA,UAC1D;AAAA,UACA;AAAA,UACA,aAAa,MAAM;AAAA,UACnB,WAAW,MAAM;AAAA,UACjB,WAAW;AAAA,QACb,CAAC;AAAA,QACD,UAAU;AAAA,UACR,YAAY,KAAK;AAAA,UACjB,IAAI,KAAK;AAAA,UACT,OAAO,KAAK;AAAA,UACZ,cAAc,KAAK,eAAe;AAAA,UAClC,YAAY,KAAK,aAAa;AAAA,UAC9B,QAAQ,KAAK;AAAA,UACb,YAAY,KAAK;AAAA,UACjB,YAAY,KAAK;AAAA,QACnB;AAAA,MACF,EAAO;AAAA,QACL,OAAO,gBAAgB,OAAO;AAAA;AAAA,MAGhC,MAAM,aAAa,MAAM,KAAK,+BAA+B,IAAI;AAAA,QAC/D;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD,MAAM,mBAAmB,MAAM,KAAK,kBAAkB,IAAI;AAAA,QACxD;AAAA,QACA,UAAU,WAAW;AAAA,QACrB,UAAU;AAAA,QACV;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,MACD,MAAM,eAAe,MAAM,KAAK,eAAe,IAAI;AAAA,QACjD;AAAA,QACA,YAAY,QAAQ;AAAA,QACpB;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,QAAQ,MAAM;AAAA,QACd,WAAW,WAAW,IAAI,KAAK,SAAS,UAAU,IAAI;AAAA,QACtD,WAAW;AAAA,MACb,CAAC;AAAA,MACD,MAAM,UAAU,MAAM,KAAK,oBAAoB,IAAI;AAAA,QACjD;AAAA,QACA,YAAY,QAAQ;AAAA,QACpB,SAAS,MAAM;AAAA,QACf,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,MAED,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,YAAY,WAAW;AAAA,QACvB;AAAA,MACF;AAAA,KAEJ;AAAA,IAEA,IAAI,WAAW,QAAQ;AAAA,MACrB,MAAM,OAAO;AAAA,IACf;AAAA,IAEA,OAAO;AAAA;AAAA,OAGH,6BAA4B,CAChC,OACqB;AAAA,IACrB,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,iBAAiB,IAAI,CAAC,YAAY,YAAY,MAAM,WAAW,MAAM,MAAM,CAAC,CAAC;AAAA,MACnF,MAAM,WAAW,MAAM,eACrB,IACA;AAAA,QACE,WAAW,MAAM;AAAA,QACjB,IAAI,MAAM;AAAA,MACZ,GACA,EAAE,WAAW,KAAK,CACpB;AAAA,MAEA,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,mBACR,gBACA,gBAAgB,MAAM,kCAAkC,MAAM,aAChE;AAAA,MACF;AAAA,MAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,2BAGH,MAAM;AAAA,6BACJ,MAAM;AAAA,qBACd,MAAM;AAAA;AAAA;AAAA,MAIrB,MAAM,4BAA4B,IAAI;AAAA,QACpC,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd,WAAW,MAAM;AAAA,MACnB,CAAC;AAAA,MAED,OAAO,gBAAgB,OAAO;AAAA,KAC/B;AAAA;AAAA,EAGK,qBAAqB,CAC3B,WACA,IACA,WACA,aACA,KACmC;AAAA,IACnC,IAAI,CAAC,KAAK;AAAA,MACR,MAAM,IAAI,mBACR,sBACA,sBAAsB,8BAA8B,aACtD;AAAA,IACF;AAAA,IAEA,sBAAsB,WAAW,IAAI,WAAW,aAAa,GAAG;AAAA;AAAA,EAG1D,uBAAuB,CAC7B,WACA,IACA,WACA,aACA,KACqC;AAAA,IACrC,IAAI,CAAC,KAAK;AAAA,MACR,MAAM,IAAI,mBACR,wBACA,sCAAsC,8BAA8B,aACtE;AAAA,IACF;AAAA,IAEA,wBAAwB,WAAW,IAAI,WAAW,aAAa,GAAG;AAAA;AAAA,OAGtD,WAAU,CACtB,KACA,OAQqB;AAAA,IACrB,IAAI;AAAA,MACF,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAWd,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM,eAAe;AAAA,YACrB,MAAM,aAAa;AAAA,YACnB;AAAA,YACA,MAAM;AAAA,YACN,MAAM;AAAA;AAAA;AAAA;AAAA,MAKZ,OAAO,gBAAgB,GAAG;AAAA,MAC1B,OAAO,OAAO;AAAA,MACd,yBACE,OACA,kBACA,gBAAgB,MAAM,mCAAmC,MAAM,aACjE;AAAA;AAAA;AAAA,OAIU,+BAA8B,CAC1C,KACA,OASC;AAAA,IACD,IAAI,CAAC,MAAM,kBAAkB;AAAA,MAC3B,OAAO,EAAE,kBAAkB,CAAC,EAAE;AAAA,IAChC;AAAA,IAEA,MAAM;AAAA;AAAA;AAAA,0BAGgB,MAAM;AAAA,yBACP,MAAM;AAAA,2BACJ,MAAM;AAAA,mBACd,MAAM,iBAAiB;AAAA;AAAA,IAGtC,MAAM,aAA+B;AAAA,SAChC,MAAM;AAAA,MACT,QAAQ;AAAA,MACR,YAAY,IAAI,KAAK,MAAM,WAAW;AAAA,MACtC,WAAW,IAAI,KAAK,MAAM,WAAW;AAAA,IACvC;AAAA,IACA,MAAM,mBAA4C,CAAC;AAAA,IACnD,WAAW,WAAW,MAAM,iBAAiB,UAAU;AAAA,MACrD,iBAAiB,KACf,MAAM,sBAAsB,KAAK;AAAA,QAC/B,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM,KAAK;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,QACR,WAAW,MAAM;AAAA,MACnB,CAAC,CACH;AAAA,IACF;AAAA,IAEA,OAAO,EAAE,YAAY,iBAAiB;AAAA;AAAA,OAG1B,kBAAiB,CAC7B,KACA,OAO2C;AAAA,IAC3C,MAAM,mBAAmB,CAAC,GAAG,MAAM,QAAQ;AAAA,IAE3C,WAAW,WAAW,MAAM,UAAU;AAAA,MACpC,iBAAiB,KACf,MAAM,sBAAsB,KAAK;AAAA,QAC/B,WAAW,MAAM;AAAA,QACjB,QAAQ,MAAM;AAAA,QACd;AAAA,QACA,QAAQ;AAAA,QACR,WAAW,MAAM;AAAA,MACnB,CAAC,CACH;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAAA,OAGK,oBAAmB,CAC/B,KACA,OAMwB;AAAA,IACxB,MAAM,iBAAiB,KAAK;AAAA,MAC1B,YAAY,YAAY,MAAM,WAAW,MAAM,MAAM;AAAA,MACrD,YAAY,YAAY,MAAM,WAAW,MAAM,QAAQ,MAAM,QAAQ,QAAQ;AAAA,IAC/E,CAAC;AAAA,IAED,OAAO,cAAc,KAAK;AAAA,MACxB,IAAI,MAAM,QAAQ;AAAA,MAClB,WAAW,MAAM;AAAA,MACjB,QAAQ,MAAM;AAAA,MACd,YAAY,MAAM;AAAA,MAClB,UAAU,MAAM,QAAQ;AAAA,MACxB,WAAW,MAAM,QAAQ;AAAA,MACzB,WAAW,MAAM,QAAQ;AAAA,MACzB,WAAW,MAAM,QAAQ;AAAA,MACzB,mBAAmB,MAAM,QAAQ;AAAA,MACjC,WAAW,MAAM,QAAQ;AAAA,MACzB,WAAW,MAAM,QAAQ;AAAA,IAC3B,CAAC;AAAA;AAAA,OAGW,mBAAkB,CAC9B,OACA,aACA,WACA,KACe;AAAA,IACf,MAAM,mBAAmB,KAAK;AAAA,MAC5B;AAAA,MACA,IAAI,MAAM;AAAA,MACV,WAAW,MAAM;AAAA,MACjB,YAAY;AAAA,IACd,CAAC;AAAA;AAAA,OAGW,eAAc,CAC1B,KACA,OAS6B;AAAA,IAC7B,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAUd,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,MAAM;AAAA,UACN,wBAAwB,MAAM,MAAM;AAAA,UACpC,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUZ,OAAO,oBAAoB,GAAG;AAAA;AAElC;AAEA,eAAe,cAAc,CAAC,KAAgB,WAAqC;AAAA,EACjF,MAAM,OAAQ,MAAM;AAAA;AAAA;AAAA,yBAGG;AAAA;AAAA;AAAA;AAAA,EAKvB,OAAO,KAAK,SAAS;AAAA;AAGvB,SAAS,2BAA2B,CAClC,WACA,iBACA,gBACM;AAAA,EACN,IAAI,oBAAoB,gBAAgB;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,mBACR,iBACA,oCAAoC,yDAAyD,gCAAgC,aAC/H;AAAA;;Aa5xBF,uBAAS;AAST;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaO,IAAM,8BAA8B;AAEpC,SAAS,KAAK,CAAC,IAAY,SAA0D;AAAA,EAC1F,OAAO,OAAO,IAAI,CAAC,YAAY,QAAQ,KAAK,OAAO,GAAG,EAAE,UAAU,SAAS,OAAO,EAAE,CAAC;AAAA;AAGhF,SAAS,MAAM,CACpB,IACA,IACA,UAAgC,CAAC,GACQ;AAAA,EACzC,OAAO,KAA+B,IAAI,IAAI,OAAO;AAAA;AAGhD,SAAS,8BAA8B,CAC5C,KACA,YAC4B;AAAA,EAC5B,OAAO;AAAA,IACL,uBAAuB;AAAA,MACrB;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAAA;AAGK,SAAS,sBAAsB,CAAC,QAInB;AAAA,EAClB,OAAO;AAAA,IACL,WAAW,OAAO,WAAW;AAAA,IAC7B,eAAe,OAAO,WAAW;AAAA,SAC3B,OAAM,GAAG;AAAA,MACb,OAAO,yBAAyB;AAAA,QAC9B,YAAY,OAAO;AAAA,QACnB,MAAM,MAAM,oBAAoB,OAAO,KAAK,OAAO,YAAY,OAAO,WAAW,SAAS;AAAA,MAC5F,CAAC;AAAA;AAAA,IAEH,OAAO,GAAG;AAAA,MACR,OAAO,0BAA0B,QAAQ,OAAO,QAAQ;AAAA,QACtD,MAAM,UAAU,yBAAyB,KAAK,OAAO,UAAU;AAAA,QAC/D,OAAO,gBAAgB;AAAA,UACrB,SAAS,QAAQ;AAAA,UACjB,YAAY,OAAO;AAAA,UACnB,OAAO,QAAQ;AAAA,QACjB,CAAC;AAAA,OACF;AAAA;AAAA,EAEL;AAAA;AAGF,eAAsB,sBAAsB,CAAC,KAAU,YAAmC;AAAA,EACxF,MAAM,uBAAuB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EACd,CAAC,EAAE,QAAQ;AAAA;AAGb,eAAsB,UAAU,CAAC,KAAU,YAAmC;AAAA,EAC5E,MAAM,IAAI,OAAO,yBAAyB,WAAW,UAAU,WAAW;AAAA;AAGrE,SAAS,UAAU,CAAC,YAA4B;AAAA,EACrD,IAAI,CAAC,2BAA2B,KAAK,UAAU,GAAG;AAAA,IAChD,MAAM,IAAI,MAAM,gCAAgC,YAAY;AAAA,EAC9D;AAAA,EACA,OAAO,IAAI;AAAA;AAGb,SAAS,wBAAwB,CAC/B,KACA,YACqE;AAAA,EACrE,MAAM,SAAS,WAAW,UAAU;AAAA,EACpC,MAAM,kBAAkB,GAAG;AAAA,EAE3B,IAAI,SAA2B;AAAA,EAC/B,MAAM,aAAa,MAAiB,UAAU;AAAA,EAE9C,OAAO;AAAA,IACL,SAAS;AAAA,WACD,KAAI,CAAC,SAAS;AAAA,QAClB,MAAM,WAAW,EAAE,OAAO,OAAO;AAAA;AAAA,IAErC;AAAA,IACA,OAAO;AAAA,WACC,OAAM,GAAG;AAAA,QACb,MAAM,IAAI,OAAO;AAAA,wCACe;AAAA;AAAA,uCAED;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAU9B;AAAA;AAAA,WAEG,YAAW,CAAC,WAAW;AAAA,QAC3B,MAAM,OAAO,MAAM,IAAI,OACrB,iBAAiB,0DACjB,CAAC,SAAS,CACZ;AAAA,QACA,OAAO,KAAK,IAAI,oBAAoB;AAAA;AAAA,WAEhC,YAAW,CAAC,WAAW,WAAW,IAAI;AAAA,QAC1C,MAAM,WAAW,EAAE,OACjB;AAAA,0BACgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAUhB,CAAC,WAAW,UAAU,SAAS,UAAU,IAAI,UAAU,YAAY,MAAM,EAAE,CAC7E;AAAA;AAAA,WAEI,YAAW,CAAC,WAAW,WAAW,IAAI;AAAA,QAC1C,MAAM,WAAW,EAAE,OACjB;AAAA,qBACW;AAAA;AAAA;AAAA,aAIX,CAAC,IAAI,WAAW,UAAU,OAAO,CACnC;AAAA;AAAA,WAEI,YAAW,CAAC,KAAK;AAAA,QAIrB,MAAM,WAAW;AAAA,QACjB,SAAS;AAAA,QACT,MAAM,IAAI,OAAO,OAAO;AAAA,QACxB,IAAI;AAAA,UACF,MAAM,IAAI,OAAO,4BAA4B,QAAQ;AAAA,UACrD,MAAM,SAAS,MAAM,IAAI;AAAA,UACzB,MAAM,IAAI,OAAO,QAAQ;AAAA,UACzB,OAAO;AAAA,UACP,OAAO,OAAO;AAAA,UACd,MAAM,IAAI,OAAO,UAAU;AAAA,UAC3B,MAAM;AAAA,kBACN;AAAA,UACA,SAAS;AAAA;AAAA;AAAA,IAGf;AAAA,EACF;AAAA;AAeF,eAAe,mBAAmB,CAChC,KACA,YACA,WAC4C;AAAA,EAC5C,MAAM,SAAS,WAAW,UAAU;AAAA,EACpC,MAAM,QAAQ,MAAM,IAAI,OAAiC,iCAAiC;AAAA,IACxF,GAAG;AAAA,EACL,CAAC;AAAA,EACD,IAAI,CAAC,MAAM,IAAI,KAAK;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,OAAO,MAAM,IAAI,OACrB,iBAAiB,iEACjB,CAAC,SAAS,CACZ;AAAA,EACA,OAAO,KAAK,IAAI,oBAAoB;AAAA;AAGtC,eAAe,yBAA4B,CACzC,QAKA,KACY;AAAA,EACZ,MAAM,MAAM,MAAM,OAAO,IAAI,QAAQ;AAAA,EACrC,OAAO,OAAO,UAAU,mBACtB,qBAAqB,OAAO,cAAc,OAAO,WAAW,WAC9D;AAAA,EAEA,IAAI;AAAA,IACF,MAAM,8BAA8B,UAAU;AAAA,IAC9C,IAAI;AAAA,MACF,OAAO,MAAM,IAAI,GAAG;AAAA,cACpB;AAAA,MACA,MAAM,gCAAgC,UAAU;AAAA;AAAA,YAElD;AAAA,IACA,IAAI,QAAQ;AAAA;AAAA;AAIhB,SAAS,kBAAiB,CAAC,KAAwC;AAAA,EACjE,MAAM,OAAO,YAAW,QAAQ,EAAE,OAAO,GAAG,EAAE,OAAO;AAAA,EACrD,OAAO,CAAC,KAAK,YAAY,CAAC,GAAG,KAAK,YAAY,CAAC,CAAC;AAAA;AAGlD,SAAS,oBAAoB,CAAC,KAA4C;AAAA,EACxE,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,SAAS,IAAI;AAAA,IACb,IAAI,IAAI;AAAA,IACR,UAAU,IAAI,YAAY;AAAA,IAC1B,QAAQ,IAAI;AAAA,IACZ,WAAW,YAAY,IAAI,UAAU;AAAA,IACrC,YAAY,IAAI,cAAc,YAAY,IAAI,WAAW,IAAI;AAAA,EAC/D;AAAA;AAGF,SAAS,WAAW,CAAC,OAA8B;AAAA,EACjD,OAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI,IAAI,KAAK,KAAK,EAAE,YAAY;AAAA;AAGnF,SAAS,QAAQ,CAAC,OAAuB;AAAA,EACvC,OAAO,YAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAAA;AAGjD,IAAM,4BAA4B,iBAA2C;AAAA,EAClF,WAAW;AAAA,EACX,OAAO,CAAC,MAAM,sBAAsB,2BAAgB,CAAC;AACvD,CAAC;;;AC5QD;AAWA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6FO,SAAS,aAAa,CAAC,KAAgB,OAA+C;AAAA,EAC3F,OAAO,IAAI,KAAK,KAAoB;AAAA;AAG/B,SAAS,gBAAgB,CAC9B,KACA,cAC+B;AAAA,EAC/B,OAAO,cAAc,KAAK,KAAK,MAAM,YAAY,CAAC;AAAA;AAG7C,SAAS,YAAW,CAAC,OAA8B;AAAA,EACxD,OAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI,IAAI,KAAK,KAAK,EAAE,YAAY;AAAA;AAG5E,SAAS,iBAAiB,CAAC,OAA4C;AAAA,EAC5E,OAAO,UAAU,OAAO,OAAO,aAAY,KAAK;AAAA;AAG3C,SAAS,mBAAmB,CAAC,OAAwB,OAAuB;AAAA,EACjF,MAAM,SAAS,OAAO,KAAK;AAAA,EAC3B,IAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,GAAG;AAAA,IAC/C,MAAM,IAAI,6BACR,mBACA,GAAG,sDACL;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGF,SAAS,YAAY,CAAC,KAAgD;AAAA,EAC3E,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,QAAQ,EAAE,cAAc,IAAI,UAAU;AAAA,IACtC,mBAAmB,IAAI;AAAA,IACvB,iBAAiB,IAAI;AAAA,IACrB,gBAAgB,IAAI;AAAA,IACpB,UAAU,IAAI;AAAA,IACd,QAAQ,IAAI;AAAA,IACZ,gBAAgB,IAAI;AAAA,IACpB,gBAAgB;AAAA,MACd,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,MACf,WAAW,aAAY,IAAI,0BAA0B;AAAA,IACvD;AAAA,IACA,oBAAoB,IAAI;AAAA,IACxB,eAAe,IAAI;AAAA,IACnB,kBAAkB,IAAI;AAAA,IACtB,WACE,IAAI,eAAe,OAAO,OAAO,oBAAoB,IAAI,YAAY,mBAAmB;AAAA,IAC1F,gBACE,IAAI,oBAAoB,OACpB,OACA,oBAAoB,IAAI,iBAAiB,wBAAwB;AAAA,IACvE,WAAW,aAAY,IAAI,UAAU;AAAA,IACrC,SAAS,kBAAkB,IAAI,QAAQ;AAAA,IACvC,aAAa,kBAAkB,IAAI,YAAY;AAAA,IAC/C,YAAY,kBAAkB,IAAI,WAAW;AAAA,IAC7C,cAAc,IAAI;AAAA,IAClB,WAAW,aAAY,IAAI,UAAU;AAAA,EACvC;AAAA;AAGK,SAAS,eAAe,CAAC,KAAyD;AAAA,EACvF,OAAO;AAAA,IACL,MAAM,gBAAgB,IAAI,IAAI;AAAA,IAC9B,WAAW,gBAAgB,IAAI,SAAS;AAAA,IACxC,gBAAgB,oBAAoB,IAAI,iBAAiB,wBAAwB;AAAA,EACnF;AAAA;AAGK,SAAS,YAAY,CAAC,KAAgD;AAAA,EAC3E,MAAM,OAAO;AAAA,IACX,WAAW,IAAI;AAAA,IACf,IAAI,IAAI;AAAA,IACR,gBAAgB,IAAI;AAAA,IACpB,aAAa,IAAI;AAAA,IACjB,QAAQ,gBAAgB,IAAI,MAAM;AAAA,OAC9B,IAAI,UAAU,OACd,CAAC,IACD;AAAA,MACE,OAAO,gBAAgB,IAAI,KAAK;AAAA,IAClC;AAAA,IACJ,kBAAkB,IAAI;AAAA,OAClB,IAAI,wBAAwB,OAAO,CAAC,IAAI,EAAE,oBAAoB,IAAI,oBAAoB;AAAA,OACtF,IAAI,mBAAmB,OAAO,CAAC,IAAI,EAAE,eAAe,IAAI,eAAe;AAAA,IAC3E,aAAa,aAAY,IAAI,YAAY;AAAA,EAC3C;AAAA,EACA,MAAM,SAAS,gBAAgB,IAAI,MAAM;AAAA,EACzC,MAAM,SAAS,gBAAgB,IAAI,MAAM;AAAA,EACzC,OAAO,KAAK,MAAM,QAAQ,OAAO;AAAA;AAG5B,SAAS,YAAY,CAAC,KAAgD;AAAA,EAC3E,OAAO;AAAA,IACL,UAAU,gBAAgB,IAAI,QAAQ;AAAA,IACtC,aAAa,aAAY,IAAI,YAAY;AAAA,IACzC,UAAU,oBAAoB,IAAI,UAAU,0BAA0B;AAAA,IACtE,SAAS,IAAI;AAAA,IACb,gBAAgB,kBAAkB,IAAI,gBAAgB;AAAA,IACtD,aAAa,kBAAkB,IAAI,YAAY;AAAA,IAC/C,WAAW,IAAI;AAAA,IACf,WAAW,aAAY,IAAI,UAAU;AAAA,EACvC;AAAA;AAGF,eAAsB,yBAAyB,CAC7C,KACA,OAOe;AAAA,EACf,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,yBAmBG,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,EAGzD,IAAI,CAAC,OAAO,IAAI,WAAW,WAAW;AAAA,IACpC,MAAM,IAAI,6BACR,mBACA,mBAAmB,MAAM,gDAC3B;AAAA,EACF;AAAA,EACA,IAAI,IAAI,kBAAkB,MAAM,YAAY,IAAI,6BAA6B,eAAe;AAAA,IAC1F,MAAM,IAAI,6BACR,mBACA,mBAAmB,MAAM,qDAAqD,MAAM,YACtF;AAAA,EACF;AAAA,EACA,IAAI,IAAI,oBAAoB,MAAM,gBAAgB;AAAA,IAChD,MAAM,IAAI,6BACR,kBACA,mBAAmB,MAAM,4CAC3B;AAAA,EACF;AAAA,EACA,MAAM,WAAW,MAAM;AAAA,EACvB,IACE,aACC,IAAI,oBAAoB,SAAS,kBAChC,IAAI,6BAA6B,SAAS,YAC1C,IAAI,eAAe,SAAS,eAAe,aAC3C,IAAI,uBAAuB,SAAS,eAAe,aACnD,IAAI,+BAA+B,QACnC,aAAY,IAAI,0BAA0B,MAAM,SAAS,eAAe,aACxE,IAAI,sBAAsB,SAAS,oBACnC,IAAI,wBAAwB,SAAS,sBACrC,IAAI,mBAAmB,SAAS,gBAClC;AAAA,IACA,MAAM,IAAI,6BACR,mBACA,mBAAmB,MAAM,4DAC3B;AAAA,EACF;AAAA;AAYK,SAAS,eAAe,CAAC,SAAiB,OAAkC;AAAA,EACjF,OAAO,YAAY,QAAQ,KAAK,UAAU,KAAK;AAAA;;;ACjR1C,MAAM,wBAAyD;AAAA,EACvC;AAAA,EAA7B,WAAW,CAAkB,kBAAmC;AAAA,IAAnC;AAAA;AAAA,OAEvB,oBAAmB,CACvB,OACsC;AAAA,IACtC,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,4BAA4B;AAAA,MAC5D,eAAe,MAAM,gBAAgB,iCAAiC;AAAA,MACtE,OAAO,OAAO,MAAM;AAAA;AAAA,6BAEG,MAAM,mCAAmC,MAAM;AAAA;AAAA,MAEtE,OAAO,MAAM,aAAa,GAAG,IAAI;AAAA,KAClC;AAAA;AAAA,OAGG,QAAO,CAAC,OAAyE;AAAA,IACrF,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,4BAA4B;AAAA,MAC5D,eAAe,MAAM,IAAI,oBAAoB;AAAA,MAC7C,OAAO,OAAO,MAAM;AAAA;AAAA,6BAEG,MAAM,sBAAsB,MAAM;AAAA;AAAA,MAEzD,OAAO,MAAM,aAAa,GAAG,IAAI;AAAA,KAClC;AAAA;AAAA,OAGG,YAAW,CAAC,OAA6E;AAAA,IAC7F,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,4BAA4B;AAAA,MAC5D,MAAM,SAAS,YAAY,MAAM,MAAM;AAAA,MACvC,eAAe,OAAO,OAAO,+BAA+B;AAAA,MAC5D,IAAI,OAAO,iBAAiB,MAAM;AAAA,QAChC,yBAAyB,OAAO,cAAc,yCAAyC;AAAA,MACzF;AAAA,MACA,OAAO,OACL,OAAO,iBAAiB,OACpB,MAAM;AAAA;AAAA,mCAEiB,MAAM;AAAA,oCACL,OAAO;AAAA,sCACL,OAAO;AAAA;AAAA,gBAGjC,MAAM;AAAA;AAAA,mCAEiB,MAAM;AAAA,oCACL,OAAO;AAAA,sCACL,OAAO;AAAA,6CACA,OAAO;AAAA;AAAA,MAE9C,OAAO,MAAM,aAAa,GAAG,IAAI;AAAA,KAClC;AAAA;AAAA,OAGG,KAAI,CAAC,OAAqE;AAAA,IAC9E,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,4BAA4B;AAAA,MAC5D,IAAI,MAAM;AAAA,QAAK,eAAe,MAAM,IAAI,IAAI,wBAAwB;AAAA,MACpE,MAAM,SAAS,MAAM,UAAU;AAAA,MAC/B,MAAM,QAAQ,MAAM;AAAA,MACpB,yBAAyB,QAAQ,6BAA6B;AAAA,MAC9D,IAAI,UAAU;AAAA,QAAW,yBAAyB,OAAO,4BAA4B;AAAA,MAErF,MAAM,YACJ,MAAM,KAAK,SAAS,WAChB,qDAAqD,MAAM,IAAI,OAC/D,MAAM,KAAK,SAAS,eAClB,0BAA0B,MAAM,IAAI;AAAA,oEAEpC;AAAA,MACR,SAAS,WAAW,MAAM;AAAA;AAAA;AAAA,6BAGH,MAAM,aAAa;AAAA;AAAA,MAE1C,MAAM,YAAY,MAAM,UAAU,SAAS,YAAY;AAAA,MACvD,MAAM,QACJ,MAAM,KAAK,SAAS,eAChB;AAAA,kBACM,2BAA2B,iBAAiB,cAClD,mBAAmB,iBAAiB;AAAA,MAC1C,MAAM,gBAAgB,UAAU,YAAY,QAAQ,YAAY;AAAA,MAChE,MAAM,OAAO,MAAM;AAAA;AAAA,6BAEI,MAAM,aAAa;AAAA,mBAC7B;AAAA,UACT,wBAAwB;AAAA;AAAA,MAE5B,MAAM,QAAQ,OAAO,KAAK;AAAA,MAC1B,MAAM,UAAU,KAAK,IAAI,YAAY;AAAA,MACrC,OAAO,EAAE,SAAS,OAAO,OAAO,SAAS,SAAS,QAAQ,SAAS,MAAM;AAAA,KAC1E;AAAA;AAEL;;;AC7GA;AAAA;AAAA,gBAEE;AAAA;AAAA,sBAEA;AAAA,kCACA;AAAA,kBACA;AAAA;AAAA,uBAEA;AAAA,2BACA;AAAA;AAEF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAOE;AAAA,2BACA;AAAA;AAAA;;;ACxBF,yCAAS;AACT;AAAA;AAAA,kCAEE;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKF;AAAA;AAAA;AAAA,kCAGE;AAAA;AAAA;AAAA;AAAA;AAAA;AAMF;AAAA;AAAA;AAAA;AAAA;AA8BO,IAAM,gCAAgC;AACtC,IAAM,4BAA4B;AAAA;AAgGlC,MAAM,6BAA6B;AAAA,EAErB;AAAA,EACR;AAAA,EAFX,WAAW,CACQ,KACR,WACT;AAAA,IAFiB;AAAA,IACR;AAAA;AAAA,OAGL,YAAW,CAAC,KAA6D;AAAA,IAC7E,OAAO,SAAS,MAAM,KAAK,aAAa,CAAC,GAAG,CAAC;AAAA,IAC7C,OAAO;AAAA;AAAA,OAGH,aAAY,CAChB,MACgD;AAAA,IAChD,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IAC/B,MAAM,YAAY,KAAK,IAAI,CAAC,SAAS;AAAA,MACnC,gBAAgB,IAAI;AAAA,MACpB,YAAY,IAAI;AAAA,IAClB,EAAE;AAAA,IACF,MAAM,qBAAqB,cAAc,KAAK,KAAK,SAAS;AAAA,IAC5D,OAAO,eAAe,YAAY,cAAc,iBAAiB,MAAM,QAAQ,IAAI;AAAA,MACjF,KAAK;AAAA;AAAA,sDAE2C;AAAA;AAAA;AAAA;AAAA;AAAA,qCAKjB,KAAK;AAAA;AAAA,MAEpC,KAAK;AAAA;AAAA,sDAE2C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAUpB,KAAK;AAAA;AAAA;AAAA;AAAA,MAIjC,KAAK;AAAA;AAAA,sDAE2C;AAAA;AAAA;AAAA;AAAA;AAAA,uCAKf,KAAK;AAAA;AAAA;AAAA,MAGtC,KAAK;AAAA;AAAA,sDAE2C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAQhB,KAAK;AAAA;AAAA,IAEvC,CAAC;AAAA,IAED,MAAM,YAAY,IAAI,IACpB,cAAc,IAAI,CAAC,QAAQ,CAAC,aAAa,qBAAqB,GAAG,CAAC,GAAG,GAAG,CAAU,CACpF;AAAA,IACA,MAAM,UAAU,gBAAgB,UAAU;AAAA,IAC1C,MAAM,YAAY,IAAI,IACpB,aAAa,IACX,CAAC,QAAQ,CAAC,aAAa,qBAAqB,GAAG,CAAC,GAAG,qBAAqB,GAAG,CAAC,CAC9E,CACF;AAAA,IACA,MAAM,YAAY,IAAI;AAAA,IACtB,WAAW,OAAO,eAAe;AAAA,MAC/B,MAAM,MAAM,aAAa,EAAE,cAAc,IAAI,gBAAgB,WAAW,IAAI,UAAU,CAAC;AAAA,MACvF,MAAM,SAAS,UAAU,IAAI,GAAG,KAAK,CAAC;AAAA,MACtC,OAAO,KAAK,YAAY,GAAG,CAAC;AAAA,MAC5B,UAAU,IAAI,KAAK,MAAM;AAAA,IAC3B;AAAA,IACA,WAAW,UAAU,UAAU,OAAO,GAAG;AAAA,MACvC,OAAO,KAAK,CAAC,MAAM,UACjB,sBAAsB,KAAK,QAAQ,KAAK,EAAE,EAAE,cAC1C,sBAAsB,MAAM,QAAQ,MAAM,EAAE,CAC9C,CACF;AAAA,IACF;AAAA,IAEA,OAAO,KAAK,IAAI,CAAC,QAAQ;AAAA,MACvB,MAAM,MAAM,aAAa,GAAG;AAAA,MAC5B,MAAM,eAAe,UAAU,IAAI,GAAG;AAAA,MACtC,OAAO;AAAA,QACL,KAAK,gBAAgB,GAAG;AAAA,QACxB,QAAQ,aAAa,QAAQ,IAAI,oBAAoB,EAAE,MAAM,UAAU,IAAI,CAAC,CAAC,CAAC;AAAA,QAC9E,UAAU,UAAU,IAAI,GAAG,KAAK;AAAA,QAChC,WAAW,eAAe,wBAAwB,YAAY,IAAI;AAAA,QAClE,iBAAiB,UAAU,IAAI,GAAG,KAAK,CAAC;AAAA,MAC1C;AAAA,KACD;AAAA;AAAA,OAGG,UAAS,CAAC,KAAyD;AAAA,IACvE,OAAO,SAAS,MAAM,KAAK,WAAW,CAAC,GAAG,CAAC;AAAA,IAC3C,OAAO;AAAA;AAAA,OAGH,WAAU,CAAC,MAAgF;AAAA,IAC/F,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IAC/B,MAAM,YAAY,KAAK,IAAI,CAAC,SAAS;AAAA,MACnC,gBAAgB,IAAI,OAAO;AAAA,MAC3B,WAAW,IAAI,OAAO;AAAA,MACtB,mBAAmB,IAAI,OAAO;AAAA,MAC9B,SAAS,IAAI;AAAA,MACb,gBAAgB,IAAI,OAAO;AAAA,MAC3B,WAAW,IAAI,OAAO;AAAA,MACtB,mBAAmB,IAAI,OAAO;AAAA,IAChC,EAAE;AAAA,IACF,MAAM,qBAAqB,cAAc,KAAK,KAAK,SAAS;AAAA,IAC5D,OAAO,eAAe,YAAY,gBAAgB,MAAM,QAAQ,IAAI;AAAA,MAClE,KAAK;AAAA;AAAA,sDAE2C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAOnB,KAAK;AAAA;AAAA,MAElC,KAAK;AAAA;AAAA,sDAE2C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAcpB,KAAK;AAAA;AAAA;AAAA;AAAA,MAIjC,KAAK;AAAA;AAAA,sDAE2C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCASf,KAAK;AAAA;AAAA;AAAA,IAGxC,CAAC;AAAA,IACD,MAAM,YAAY,IAAI,IACpB,cAAc,IAAI,CAAC,QAAQ,CAAC,WAAW,mBAAmB,GAAG,CAAC,GAAG,GAAG,CAAU,CAChF;AAAA,IACA,MAAM,UAAU,gBAAgB,UAAU;AAAA,IAC1C,MAAM,YAAY,IAAI,IACpB,aAAa,IACX,CAAC,QAAQ,CAAC,WAAW,2BAA2B,GAAG,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAChF,CACF;AAAA,IACA,OAAO,KAAK,IAAI,CAAC,QAAQ;AAAA,MACvB,MAAM,MAAM,WAAW,GAAG;AAAA,MAC1B,MAAM,eAAe,UAAU,IAAI,GAAG;AAAA,MACtC,OAAO;AAAA,QACL,KAAK,gBAAgB,GAAG;AAAA,QACxB,QAAQ,WAAW,QAAQ,IAAI,oBAAoB,EAAE,MAAM,QAAQ,IAAI,CAAC,CAAC,CAAC;AAAA,QAC1E,UAAU,UAAU,IAAI,GAAG,KAAK;AAAA,QAChC,WAAW,eAAe,sBAAsB,YAAY,IAAI;AAAA,MAClE;AAAA,KACD;AAAA;AAAA,OAGG,WAAU,CACd,QACA,IACA,OAAO,OAC+B;AAAA,IACtC,QAAQ,MAAM,KAAK,YAAY,CAAC,EAAE,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,MAAM;AAAA;AAAA,OAG1D,YAAW,CACf,QACA,OAAO,OACmC;AAAA,IAC1C,IAAI,OAAO,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IACjC,MAAM,YAAY,OAAO,IAAI,GAAG,QAAQ,UAAU;AAAA,MAChD,gBAAgB,OAAO,OAAO;AAAA,MAC9B,WAAW,OAAO,OAAO;AAAA,MACzB,aAAa,OAAO;AAAA,MACpB;AAAA,IACF,EAAE;AAAA,IACF,MAAM,eAAe,OAAO,KAAK,gCAAgC,KAAK;AAAA,IACtE,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,oDAEwB,cAAc,KAAK,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAM/C,KAAK;AAAA,QACnC;AAAA;AAAA,IAEJ,MAAM,QAAQ,IAAI,IAChB,KAAK,IAAI,CAAC,QAAQ;AAAA,MAChB,MAAM,QAAQ,YAAY,GAAG;AAAA,MAC7B,OAAO,CAAC,kBAAkB,MAAM,QAAQ,MAAM,EAAE,GAAG,KAAK;AAAA,KACzD,CACH;AAAA,IACA,OAAO,OAAO,QAAQ,CAAC,UAAU;AAAA,MAC/B,MAAM,SAAS,MAAM,IAAI,kBAAkB,MAAM,QAAQ,MAAM,EAAE,CAAC;AAAA,MAClE,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC;AAAA,KAC7B;AAAA;AAAA,OAGG,WAAU,CACd,QACmD;AAAA,IACnD,IAAI,OAAO,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IACjC,MAAM,YAAY,OAAO,IAAI,GAAG,QAAQ,cAAc;AAAA,MACpD,gBAAgB,iBAAiB,QAAQ,MAAM;AAAA,MAC/C,gBAAgB,OAAO;AAAA,MACvB,WAAW,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,EAAE;AAAA,IACF,MAAM,eAAe,IAAI,IACvB,OAAO,IAAI,GAAG,QAAQ,aAAa;AAAA,MACjC,MAAM,MAAM,iBAAiB,QAAQ,MAAM;AAAA,MAC3C,OAAO,CAAC,KAAK,sBAAsB,QAAQ,QAAQ,GAAG,CAAC;AAAA,KACxD,CACH;AAAA,IACA,IAAI,cAA6B;AAAA,IACjC,IAAI,aAA4B;AAAA,IAChC,OAAO,MAAM;AAAA,MACX,MAAM,OAAuB,MAAM,KAAK;AAAA;AAAA,sDAEQ,cAAc,KAAK,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAMzE,KAAK,IAAI,OAAO,mBAAmB,OAAO,CAAC;AAAA;AAAA;AAAA,qCAGpB,KAAK;AAAA;AAAA;AAAA,iBAGzB;AAAA,aACJ,gBAAgB;AAAA;AAAA;AAAA;AAAA,MAIvB,WAAW,OAAO,MAAM;AAAA,QACtB,MAAM,cAAc,aAAa,IAAI,IAAI,cAAc;AAAA,QACvD,IAAI,CAAC,aAAa;AAAA,UAChB,MAAM,IAAI,8BACR,mBACA,0BAA0B,IAAI,sCAChC;AAAA,QACF;AAAA,QACA,oBAAoB,aAAa,sBAAsB,GAAG,CAAC;AAAA,MAC7D;AAAA,MACA,IAAI,KAAK,SAAS;AAAA,QAAK;AAAA,MACvB,MAAM,OAAqB,KAAK,KAAK,SAAS;AAAA,MAC9C,cAAc,KAAK;AAAA,MACnB,aAAa,KAAK;AAAA,IACpB;AAAA,IACA,OAAO,OAAO,IAAI,GAAG,QAAQ,aAC3B,uBAAuB,aAAa,IAAI,iBAAiB,QAAQ,MAAM,CAAC,CAAE,CAC5E;AAAA;AAAA,OAGI,UAAS,CACb,QACA,QACwC;AAAA,IACxC,OAAO,SAAS,MAAM,KAAK,WAAW,CAAC,EAAE,QAAQ,OAAO,CAAC,CAAC;AAAA,IAC1D,IAAI,CAAC,OAAO;AAAA,MACV,MAAM,IAAI,8BACR,mBACA,oCACF;AAAA,IACF;AAAA,IACA,OAAO;AAAA;AAAA,SAGF,aAAa,CAClB,SACA,UACkC;AAAA,IAClC,IAAI,QAAQ,WAAW;AAAA,MAAG;AAAA,IAC1B,MAAM,YAAY,QAAQ,IAAI,CAAC,SAAS;AAAA,MACtC,gBAAgB,IAAI;AAAA,MACpB,YAAY,IAAI;AAAA,IAClB,EAAE;AAAA,IACF,IAAI,SAAwB;AAAA,IAC5B,OAAO,MAAM;AAAA,MACX,MAAM,OAA0B,MAAM,KAAK;AAAA;AAAA;AAAA,oCAGb,cAAc,KAAK,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAShC,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAQL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCASD,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCASL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAYV,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAcL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,cAK3B,KAAK,IAAI,OAAO,mBAAmB,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA,iBAIxC,sCAAsC;AAAA;AAAA,gBAEvC;AAAA;AAAA,MAEV,IAAI,KAAK,WAAW;AAAA,QAAG;AAAA,MACvB,MAAM,KAAK,IAAI,kBAAkB;AAAA,MACjC,SAAS,KAAK,KAAK,SAAS,IAAI,YAAY;AAAA,IAC9C;AAAA;AAAA,SAGK,qBAAqB,CAC1B,OACsC;AAAA,IACtC,MAAM,KAAK,6BAA6B,KAAK;AAAA,IAC7C,IAAI,SAAwB;AAAA,IAC5B,OAAO,MAAM;AAAA,MACX,MAAM,OAA6B,MAAM,KAAK;AAAA;AAAA,eAErC,KAAK,IAAI,yBAAyB;AAAA,6BACpB,MAAM,+BAA+B,MAAM;AAAA,iBACvD,sCAAsC;AAAA;AAAA,gBAEvC,MAAM;AAAA;AAAA,MAEhB,IAAI,KAAK,WAAW;AAAA,QAAG;AAAA,MACvB,MAAM,KAAK,IAAI,mBAAmB;AAAA,MAClC,SAAS,KAAK,KAAK,SAAS,IAAI,YAAY;AAAA,IAC9C;AAAA;AAAA,OAGI,wBAAuB,CAC3B,UACA,4BACA,MACkD;AAAA,IAClD,MAAM,OAAO,MAAM,KAAK,aAAa,IAAI;AAAA,IACzC,MAAM,aAAa,MAAM,KAAK,mBAC5B,UACA,CAAC,0BAA0B,GAC3B,KAAK,IAAI,CAAC,SAAS,EAAE,MAAM,UAAmB,IAAI,EAAE,CACtD;AAAA,IACA,OAAO,KAAK,IAAI,CAAC,WAAW;AAAA,MAC1B,KAAK,MAAM;AAAA,MACX,iBAAiB,aACf,WAAW,kBACR,IAAI,0BAA0B,GAC7B,IAAI,oBAAoB,EAAE,MAAM,UAAU,KAAK,MAAM,IAAI,CAAC,CAAC,CACjE;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,iBAAiB,MAAM;AAAA,IACzB,EAAE;AAAA;AAAA,OAGE,sBAAqB,CACzB,UACA,4BACA,oBACA,YACgD;AAAA,IAChD,MAAM,OAAO,WAAW,IAAI,CAAC,aAAa,SAAS,GAAG;AAAA,IACtD,MAAM,OAAO,MAAM,KAAK,WAAW,IAAI;AAAA,IACvC,MAAM,eAAe,MAAM,KAAK,mBAC9B,UACA,oBACA,KAAK,IAAI,CAAC,SAAS,EAAE,MAAM,QAAiB,IAAI,EAAE,CACpD;AAAA,IACA,MAAM,YAAY,aAAa,kBAAkB,IAAI,0BAA0B;AAAA,IAC/E,OAAO,KAAK,IAAI,CAAC,OAAO,UAAU;AAAA,MAChC,MAAM,MAAM,oBAAoB,EAAE,MAAM,QAAQ,KAAK,MAAM,IAAI,CAAC;AAAA,MAChE,OAAO;AAAA,QACL,KAAK,MAAM;AAAA,QACX,iBAAiB,aAAa,MAAM,IAAI,GAAG,IACvC,WAAW,WAAW,IAAI,GAAG,CAAC,IAC9B,MAAM;AAAA,QACV,UAAU,MAAM;AAAA,QAChB,WAAW,MAAM;AAAA,QACjB,cAAc,WAAW,OAAQ;AAAA,MACnC;AAAA,KACD;AAAA;AAAA,OAGG,wBAAuB,CAC3B,KACA,OAAO,OAC6E;AAAA,IACpF,QAAQ,MAAM,KAAK,yBAAyB,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,aAAa,GAAG,CAAC,KAAK;AAAA;AAAA,OAGhF,yBAAwB,CAC5B,MACA,OAAO,OAGP;AAAA,IACA,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO,IAAI;AAAA,IAClC,MAAM,YAAY,KAAK,IAAI,CAAC,SAAS;AAAA,MACnC,gBAAgB,IAAI;AAAA,MACpB,YAAY,IAAI;AAAA,IAClB,EAAE;AAAA,IACF,MAAM,eAAe,OAAO,KAAK,6BAA6B,KAAK;AAAA,IACnE,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,oDASwB,cAAc,KAAK,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAMlD,KAAK;AAAA,QAChC;AAAA;AAAA,IAEJ,OAAO,IAAI,IACT,KAAK,IACH,CAAC,QACC;AAAA,MACE,aAAa,qBAAqB,GAAG,CAAC;AAAA,MACtC,EAAE,SAAS,IAAI,SAAS,cAAc,IAAI,eAAe;AAAA,IAC3D,CACJ,CACF;AAAA;AAAA,OAGI,wBAAuB,CAC3B,KACA,OAAO,OAC6B;AAAA,IACpC,QAAQ,MAAM,KAAK,yBAAyB,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,WAAW,GAAG,CAAC;AAAA;AAAA,OAGzE,yBAAwB,CAC5B,MACA,OAAO,OACsC;AAAA,IAC7C,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO,IAAI;AAAA,IAClC,MAAM,YAAY,KAAK,IAAI,CAAC,SAAS;AAAA,MACnC,gBAAgB,IAAI,OAAO;AAAA,MAC3B,WAAW,IAAI,OAAO;AAAA,MACtB,SAAS,IAAI;AAAA,MACb,gBAAgB,IAAI,OAAO;AAAA,MAC3B,WAAW,IAAI,OAAO;AAAA,IACxB,EAAE;AAAA,IACF,MAAM,eAAe,OAAO,KAAK,2BAA2B,KAAK;AAAA,IACjE,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,oDAEwB,cAAc,KAAK,KAAK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAQpD,KAAK;AAAA,QAC9B;AAAA;AAAA,IAEJ,OAAO,IAAI,IACT,KAAK,IAAI,CAAC,QAAQ,CAAC,WAAW,mBAAmB,GAAG,CAAC,GAAG,IAAI,cAAc,CAAU,CACtF;AAAA;AAAA,OAGI,mBAAkB,CAAC,MAAyB,WAA2C;AAAA,IAC3F,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,KAAK;AAAA,4BACJ;AAAA,2BACD,iBAAiB,KAAK,KAAK,SAAS;AAAA;AAAA,IAE3D,OAAO,KAAK,kBAAkB;AAAA;AAAA,OAGlB,mBAAkB,CAC9B,UACA,oBACA,MAC6B;AAAA,IAC7B,IAAI,mBAAmB,WAAW,KAAK,KAAK,WAAW,GAAG;AAAA,MACxD,OAAO,EAAE,OAAO,IAAI,KAAO,mBAAmB,IAAI,IAAM;AAAA,IAC1D;AAAA,IACA,MAAM,OAAO,KAAK,IAAI,CAAC,SAAS;AAAA,MAC9B,aAAa,IAAI;AAAA,MACjB,YAAY,KAAK,MAAM,oBAAoB,GAAG,CAAC;AAAA,IACjD,EAAE;AAAA,IACF,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,kCAGM,cAAc,KAAK,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,gCAK9B,KAAK;AAAA,+BACN;AAAA;AAAA,YAEnB,KAAK,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,kBAAkB,CAAC,CAAC;AAAA;AAAA;AAAA,IAGvD,MAAM,QAAQ,IAAI;AAAA,IAClB,MAAM,oBAAoB,IAAI;AAAA,IAC9B,WAAW,OAAO,MAAM;AAAA,MACtB,MAAM,SAAS,aAAa,GAAG;AAAA,MAC/B,MAAM,MAAM,oBAAoB,OAAO,SAAS;AAAA,MAChD,MAAM,IAAI,GAAG;AAAA,MACb,MAAM,kBAAkB,kBAAkB,IAAI,IAAI,kBAAkB,KAAK,IAAI;AAAA,MAC7E,gBAAgB,IAAI,KAAK,MAAM;AAAA,MAC/B,kBAAkB,IAAI,IAAI,oBAAoB,eAAe;AAAA,IAC/D;AAAA,IACA,OAAO,EAAE,OAAO,kBAAkB;AAAA;AAAA,OAGtB,6BAA4B,CAAC,OAAgD;AAAA,IACzF,IAAI,MAAM,SAAS,UAAU;AAAA,MAC3B,MAAM,KAAK,0BAA0B,KAAK;AAAA,MAC1C;AAAA,IACF;AAAA,IACA,MAAM,KAAK,wBAAwB,KAAK;AAAA;AAAA,OAG5B,0BAAyB,CAAC,OAAgD;AAAA,IACtF,MAAM,qBAAqB;AAAA,MACzB,MAAM;AAAA,MACN,GAAI,MAAM,4BAA4B,CAAC,MAAM,yBAAyB,IAAI,CAAC;AAAA,IAC7E;AAAA,IACA,MAAM,KAAK;AAAA;AAAA;AAAA,YAGH,KAAK,IAAI,OAAO,oBAAoB,MAAM,CAAC;AAAA,YAC3C,KAAK,IAAI,OAAO,qBAAqB,MAAM,CAAC;AAAA;AAAA,6BAE3B,KAAK;AAAA,4BACN,MAAM;AAAA;AAAA,yCAEO,KAAK,IAAI,MAAM,kBAAkB;AAAA;AAAA,oBAEtD,KAAK,IAAI,yBAAyB;AAAA;AAAA;AAAA,eAGvC,MAAM;AAAA;AAAA;AAAA,0BAGK,KAAK,IAAI,yBAAyB;AAAA;AAAA;AAAA;AAAA,OAK5C,wBAAuB,CAAC,OAAgD;AAAA,IACpF,MAAM,qBAAqB;AAAA,MACzB,MAAM;AAAA,MACN,GAAI,MAAM,4BAA4B,CAAC,MAAM,yBAAyB,IAAI,CAAC;AAAA,IAC7E;AAAA,IACA,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,eAIA,KAAK,IAAI,6BAA6B;AAAA,6BACxB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,6BAKN,KAAK;AAAA,4BACN,MAAM;AAAA;AAAA,yCAEO,KAAK,IAAI,MAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAQvC,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAQL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCASD,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCASL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAYV,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCAcL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAeJ,KAAK;AAAA;AAAA;AAAA,YAG5B,KAAK,IAAI,OAAO,kBAAkB,WAAW,CAAC;AAAA,YAC9C,KAAK,IAAI,OAAO,mBAAmB,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,oBAKvC,KAAK,IAAI,yBAAyB;AAAA;AAAA;AAAA,eAGvC,MAAM;AAAA;AAAA;AAAA,0BAGK,KAAK,IAAI,yBAAyB;AAAA;AAAA;AAAA;AAI5D;AAEA,SAAS,mBAAmB,CAAC,KAA8C;AAAA,EACzE,MAAM,QAAQ,KAAK,MAAM,IAAI,YAAY;AAAA,EACzC,IAAI,IAAI,gBAAgB,UAAU;AAAA,IAChC,OAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,EAAE,cAAc,MAAM,IAAK,WAAW,MAAM,GAAI;AAAA,MACrD,SAAS,IAAI;AAAA,MACb,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,KAAK;AAAA,MACH,QAAQ,EAAE,cAAc,MAAM,IAAK,WAAW,MAAM,GAAI;AAAA,MACxD,QAAQ,MAAM;AAAA,MACd,QAAQ,EAAE,cAAc,MAAM,IAAK,WAAW,MAAM,GAAI;AAAA,IAC1D;AAAA,IACA,SAAS,IAAI;AAAA,IACb,cAAc,IAAI;AAAA,EACpB;AAAA;AAGF,SAAS,eAAe,CACtB,MAC4C;AAAA,EAC5C,MAAM,SAAS,IAAI;AAAA,EACnB,WAAW,OAAO,MAAM;AAAA,IACtB,MAAM,SAAS,aAAa,GAAG;AAAA,IAC/B,MAAM,MAAM,oBAAoB,OAAO,SAAS;AAAA,IAChD,IAAI,OAAO,IAAI,GAAG,GAAG;AAAA,MACnB,MAAM,IAAI,8BACR,0BACA,kCAAkC,MACpC;AAAA,IACF;AAAA,IACA,OAAO,IAAI,KAAK,MAAM;AAAA,EACxB;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,YAAY,CACnB,QACoC;AAAA,EACpC,OAAO,QAAQ,UAAU,SAAS,WAAY,SAAyC;AAAA;AAGzF,SAAS,UAAU,CAAC,QAA6E;AAAA,EAC/F,OAAO,QAAQ,UAAU,SAAS,SAAU,SAAuC;AAAA;AAGrF,SAAS,oBAAoB,CAAC,KAA8C;AAAA,EAC1E,MAAM,MAAM,qBAAqB,GAAG;AAAA,EACpC,OAAO;AAAA,IACL;AAAA,IACA,OAAO,gBAAgB,IAAI,KAAK;AAAA,IAChC,cAAc,IAAI;AAAA,IAClB,WAAW,aAAY,IAAI,UAAU;AAAA,EACvC;AAAA;AAGF,SAAS,kBAAkB,CAAC,KAA0C;AAAA,EACpE,MAAM,MAAM,2BAA2B,GAAG;AAAA,EAC1C,OAAO;AAAA,IACL;AAAA,IACA,OAAO,gBAAgB,IAAI,KAAK;AAAA,IAChC,cAAc,IAAI;AAAA,IAClB,WAAW,aAAY,IAAI,UAAU;AAAA,EACvC;AAAA;AAGF,SAAS,0BAA0B,CAAC,KAAuC;AAAA,EACzE,OAAO;AAAA,IACL,QAAQ,EAAE,cAAc,IAAI,gBAAgB,WAAW,IAAI,kBAAkB;AAAA,IAC7E,QAAQ,IAAI;AAAA,IACZ,QAAQ,EAAE,cAAc,IAAI,gBAAgB,WAAW,IAAI,kBAAkB;AAAA,EAC/E;AAAA;AAGF,SAAS,YAAY,CAAC,KAA0D;AAAA,EAC9E,OAAO;AAAA,IACL,QAAQ,EAAE,cAAc,IAAI,UAAU;AAAA,IACtC,mBAAmB,IAAI;AAAA,IACvB,MAAM,gBAAgB,IAAI,IAAI;AAAA,IAC9B,WAAW,gBAAgB,IAAI,SAAS;AAAA,IACxC,gBAAgB,oBAAoB,IAAI,iBAAiB,wBAAwB;AAAA,EACnF;AAAA;AAGF,SAAS,uBAAuB,CAAC,KAAkD;AAAA,EACjF,IAAI,CAAC,IAAI,gBAAgB;AAAA,IACvB,MAAM,IAAI,8BACR,mBACA,oBAAoB,IAAI,kBAAkB,IAAI,2CAChD;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,KAAK,qBAAqB,GAAG;AAAA,IAC7B,YAAY,gBAAgB,IAAI,UAAU;AAAA,IAC1C,SAAS,IAAI;AAAA,IACb,WAAW,aAAY,IAAI,UAAU;AAAA,IACrC,WAAW,aAAY,IAAI,UAAU;AAAA,IACrC,cAAc,IAAI;AAAA,EACpB;AAAA;AAGF,SAAS,qBAAqB,CAAC,KAA8C;AAAA,EAC3E,IAAI,CAAC,IAAI,gBAAgB;AAAA,IACvB,MAAM,IAAI,8BACR,mBACA,kBAAkB,WAAW,mBAAmB,GAAG,CAAC,kCACtD;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,KAAK,mBAAmB,GAAG;AAAA,OACvB,IAAI,eAAe,OACnB,CAAC,IACD;AAAA,MACE,YAAY,gBAAgB,IAAI,UAAU;AAAA,IAG5C;AAAA,IACJ,WAAW,aAAY,IAAI,UAAU;AAAA,IACrC,WAAW,aAAY,IAAI,UAAU;AAAA,IACrC,cAAc,IAAI;AAAA,EACpB;AAAA;AAGF,SAAS,WAAW,CAAC,KAAyC;AAAA,EAC5D,MAAM,KAAK,aAAY,IAAI,EAAE;AAAA,EAC7B,IAAI,CAAC,IAAI,gBAAgB;AAAA,IACvB,MAAM,IAAI,8BACR,oBACA,mBAAmB,sBACjB;AAAA,MACE,QAAQ,EAAE,cAAc,IAAI,gBAAgB,WAAW,IAAI,UAAU;AAAA,MACrE,YAAY,IAAI;AAAA,IAClB,GACA,EACF,kCACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL,QAAQ;AAAA,MACN,QAAQ,EAAE,cAAc,IAAI,gBAAgB,WAAW,IAAI,UAAU;AAAA,MACrE,YAAY,IAAI;AAAA,IAClB;AAAA,IACA,OAAO,gBAAgB,IAAI,KAAK;AAAA,OAC5B,IAAI,SAAS,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK;AAAA,IAC9C;AAAA,IACA,cAAc,IAAI;AAAA,EACpB;AAAA;AAGK,SAAS,oBAAoB,CAAC,OAAwB;AAAA,EAC3D,MAAM,SAAS,QAAQ,GAAG,WAAW;AAAA,EACrC,OAAO,mBAAmB;AAAA,IACxB,YAAY;AAAA,IACZ,YAAY;AAAA,EACd,CAAC;AAAA;AAGH,SAAS,mBAAmB,CAAC,OAAwB;AAAA,EACnD,MAAM,SAAS,QAAQ,GAAG,WAAW;AAAA,EACrC,OAAO,oBAAoB;AAAA,IACzB,YAAY;AAAA,IACZ,YAAY;AAAA,EACd,CAAC;AAAA;AAGI,SAAS,kBAAkB,CAAC,OAAwB;AAAA,EACzD,MAAM,SAAS,QAAQ,GAAG,WAAW;AAAA,EACrC,OAAO,mBAAmB;AAAA,IACxB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,EACd,CAAC;AAAA;AAGH,SAAS,iBAAiB,CAAC,OAAwB;AAAA,EACjD,MAAM,SAAS,QAAQ,GAAG,WAAW;AAAA,EACrC,OAAO,oBAAoB;AAAA,IACzB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,EACd,CAAC;AAAA;AAaH,SAAS,kBAAkB,CAAC,OAAkC;AAAA,EAC5D,OAAO,qBAAqB,oBAAoB,KAAK;AAAA;AAGvD,SAAS,mBAAmB,CAAC,OAAkC;AAAA,EAC7D,OAAO,eAAe,MAAM,KAAK,SAAS;AAAA;;;ADtiCrC,MAAM,sCAAsC,oCAAoC;AAAA,EACrF,oBAAuC;AAAA,EACvC,qBAAwC;AAC1C;AAAA;AAWO,MAAM,0BAA0B;AAAA,EAMlB;AAAA,EACA;AAAA,EANF,WAAW,IAAI;AAAA,EACf,OAAO,IAAI;AAAA,EACpB,cAAc;AAAA,EAEtB,WAAW,CACQ,KACA,SACjB;AAAA,IAFiB;AAAA,IACA;AAAA;AAAA,OAGb,OAAM,CAAC,QAA2E;AAAA,IACtF,IAAI,CAAC,KAAK,SAAS,QAAQ;AAAA,MACzB,MAAM,IAAI,8BACR,mBACA,iEACF;AAAA,IACF;AAAA,IACA,MAAM,KAAK,aAAa;AAAA,IACxB,MAAM,UAAU,IAAI,8BAA8B,gBAAgB,MAAM,GAAG,KAAK,QAAQ,EAAE;AAAA,IAC1F,KAAK,SAAS,IAAI,QAAQ,eAAe,OAAO;AAAA,IAChD,KAAK,KAAK,IAAI,OAAO;AAAA,IACrB,KAAK,QAAQ,iBAAiB,SAAS,QAAQ,aAAa;AAAA,IAC5D,OAAO;AAAA;AAAA,EAGT,OAAO,CAAC,SAAgE;AAAA,IACtE,MAAM,QAAQ,KAAK,SAAS,IAAI,QAAQ,aAAa;AAAA,IACrD,IACE,CAAC,SACD,CAAC,MAAM,UACP,CAAC,KAAK,SAAS,UACf,MAAM,kBAAkB,KAAK,QAAQ,IACrC;AAAA,MACA,MAAM,IAAI,8BACR,mBACA,sCACF;AAAA,IACF;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,QAAO,CAAC,SAAuD;AAAA,IACnE,IAAI,CAAC,QAAQ;AAAA,MAAQ;AAAA,IACrB,MAAM,KAAK,WAAW,QAAQ,EAAE;AAAA,IAChC,QAAQ,SAAS;AAAA,IACjB,QAAQ,cAAc;AAAA,IACtB,KAAK,KAAK,OAAO,OAAO;AAAA,IACxB,KAAK,SAAS,iBAAiB,SAAS,QAAQ,aAAa;AAAA;AAAA,EAG/D,aAAa,GAAS;AAAA,IACpB,WAAW,WAAW,KAAK,MAAM;AAAA,MAC/B,QAAQ,SAAS;AAAA,MACjB,QAAQ,cAAc;AAAA,IACxB;AAAA,IACA,KAAK,KAAK,MAAM;AAAA;AAAA,OAGZ,MAAK,CAAC,OAAqD;AAAA,IAC/D,MAAM,UAAU,KAAK,QAAQ,MAAM,OAAO;AAAA,IAC1C,MAAM,UAAU,2BAA2B,SAAS,KAAK;AAAA,IACzD,IAAI,QAAQ,WAAW;AAAA,MAAG;AAAA,IAC1B,MAAM,OAAO,QAAQ,IAAI,GAAG,aAAa,OAAO,SAAS;AAAA,IACzD,MAAM,aAAa,QAAQ,IAAI,GAAG,gBAAgB,SAAS;AAAA,IAE3D,OAAO,aAAa,MAAM,KAAK;AAAA;AAAA,aAEtB,KAAK,IAAI,6BAA6B;AAAA,2BACxB,QAAQ;AAAA;AAAA,6BAEN,KAAK,IAAI,MAAM,IAAI;AAAA,gCAChB,KAAK,IAAI,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,IAIrD,IAAI;AAAA,MAAW,MAAM,cAAc,UAAU,UAAU;AAAA,IAEvD,MAAM,UAAU,QAAQ,IAAI,GAAG,QAAQ,WAAW,cAAc;AAAA,MAC9D,OAAO;AAAA,QACL,WAAW,OAAO;AAAA,QAClB;AAAA,QACA,MAAM,OAAO;AAAA,QACb,MAAM,QAAQ;AAAA,QACd,YAAY,QAAQ;AAAA,QACpB,YAAY,QAAQ;AAAA,QACpB,SAAS,QAAQ;AAAA,QACjB,SAAS,QAAQ;AAAA,QACjB;AAAA,MACF;AAAA,KACD;AAAA,IACD,MAAM,KAAK;AAAA;AAAA,iDAEkC,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA,oBAE5D,KAAK,IAAI,6BAA6B;AAAA;AAAA;AAAA;AAAA,eAI3C,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAOd,MAAM,CAAC,OAA+E;AAAA,IAC3F,MAAM,UAAU,KAAK,QAAQ,MAAM,OAAO;AAAA,IAC1C,MAAM,SAAS,QAAQ,YAAY,MAAM;AAAA,IACzC,IAAI,OAAO,SAAS;AAAA,MAClB,MAAM,IAAI,8BACR,mBACA,mBAAmB,MAAM,mDAC3B;AAAA,IACF;AAAA,IACA,OAAO,UAAU;AAAA,IACjB,QAAQ,aAAa;AAAA,IACrB,IAAI,SAA4B;AAAA,IAChC,OAAO,MAAM;AAAA,MACX,KAAK,QAAQ,MAAM,OAAO;AAAA,MAC1B,MAAM,OAAO,MAAM,KAAK,SAAS,MAAM,OAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAAA,MAChF,IAAI,KAAK,WAAW;AAAA,QAAG;AAAA,MACvB,MAAM,UAAU,KAAK,IAAI,CAAC,QACxB,gBAAgB,IAAI,OAAO,CAC7B;AAAA,MACA,SAAS,WAAW,KAAK,KAAK,SAAS,EAAG;AAAA,MAC1C,OAAO,gBAAgB,QAAQ;AAAA,MAC/B,MAAM,EAAE,QAAQ;AAAA,IAClB;AAAA,IACA,KAAK,QAAQ,MAAM,OAAO;AAAA,IAC1B,OAAO,YAAY;AAAA;AAAA,OAGf,oBAAmB,CACvB,SACA,MAMA;AAAA,IACA,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IAC/B,MAAM,OAAO,KAAK,IAChB,CAAC,QAAQ,oBAAoB,KAAK,UAAU,CAAC,IAAI,cAAc,IAAI,SAAS,CAAC,GAC/E;AAAA,IACA,MAAM,OAAO,MAAM,KAAK;AAAA,wCACY,KAAK,IAAI,6BAA6B;AAAA,2BACnD,QAAQ;AAAA,+BACJ,KAAK,IAAI,MAAM,IAAI;AAAA;AAAA;AAAA,IAG9C,MAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,YAAY,IAAI,OAAO,CAAU,CAAC;AAAA,IAC/E,OAAO,KAAK,QAAQ,CAAC,QAAQ;AAAA,MAC3B,MAAM,UAAU,MAAM,IAAI,GAAG;AAAA,MAC7B,IAAI,CAAC;AAAA,QAAS,OAAO,CAAC;AAAA,MACtB,MAAM,SAAS,gBAAgB,OAAO;AAAA,MAItC,OAAO,CAAC,EAAE,KAAK,OAAO,KAAK,QAAQ,OAAO,OAAO,CAAC;AAAA,KACnD;AAAA;AAAA,OAGG,qBAAoB,CACxB,SACA,OACkC;AAAA,IAClC,MAAM,QAAQ,yBAAyB,KAAK;AAAA,IAC5C,MAAM,WAAW,MAAM,KAAK,SAC1B,SACA,QAAQ,IACR,QAAQ,mBACR,MAAM,MACR;AAAA,IACA,MAAM,gBAAgB,SAAS,IAC7B,CAAC,QAEG,gBAAgB,IAAI,OAAO,EAI3B,IACN;AAAA,IACA,MAAM,YAAY,MAAM,KAAK,SAC3B,SACA,QAAQ,IACR,QAAQ,oBACR,MAAM,OAAO,MACf;AAAA,IACA,MAAM,iBAAiB,UAAU,IAC/B,CAAC,QAAQ,gBAAgB,IAAI,OAAO,CACtC;AAAA,IACA,MAAM,WAAW,8BACf,SACA,OACA,OACA,eACA,cACF;AAAA,IAEA,OAAO;AAAA,SACF;AAAA,MACH,mBACE,SAAS,WAAW,IAChB,QAAQ,oBACR,WAAW,SAAS,SAAS,SAAS,EAAG;AAAA,MAC/C,oBACE,UAAU,WAAW,IACjB,QAAQ,qBACR,WAAW,UAAU,UAAU,SAAS,EAAG;AAAA,IACnD;AAAA;AAAA,EAGF,mBAAmB,CACjB,SACA,UACM;AAAA,IACN,QAAQ,mBAAmB,SAAS;AAAA,IACpC,QAAQ,qBAAqB,SAAS;AAAA,IACtC,QAAQ,oBAAoB,SAAS;AAAA,IACrC,QAAQ,qBAAqB,SAAS;AAAA;AAAA,OAGlC,MAAK,CAAC,SAAwC,MAA+B;AAAA,IACjF,OAAO,OAAO,MAAM,KAAK;AAAA,sCACS,KAAK,IAAI,6BAA6B;AAAA,2BACjD,QAAQ,iBAAiB;AAAA;AAAA,IAEhD,OAAO,OAAO,KAAK,SAAS,CAAC;AAAA;AAAA,OAGzB,WAAU,CAAC,SAId;AAAA,IACD,MAAM,OAAO,MAAM,KAAK;AAAA,4CAGgB,KAAK,IAAI,6BAA6B;AAAA,2BACvD,QAAQ;AAAA;AAAA;AAAA,IAG/B,MAAM,SAAS,EAAE,OAAO,GAAG,aAAa,GAAG,OAAO,EAAE;AAAA,IACpD,WAAW,OAAO;AAAA,MAAM,OAAO,IAAI,QAAQ,OAAO,IAAI,KAAK;AAAA,IAC3D,OAAO;AAAA;AAAA,OAGH,6BAA4B,CAAC,SAAuD;AAAA,IACxF,IAAI,CAAC,QAAQ;AAAA,MAAa;AAAA,IAC1B,MAAM,iBAAiB,QAAQ,YAAY,mBAAmB;AAAA,IAC9D,OAAO,YAAY,MAAM,KAAK;AAAA;AAAA;AAAA,eAGnB,KAAK,IAAI,yBAAyB;AAAA,6BACpB,QAAQ;AAAA,yCACI;AAAA;AAAA;AAAA;AAAA,eAI1B,KAAK,IAAI,6BAA6B;AAAA,6BACxB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kCASH,KAAK,IAAI,6BAA6B;AAAA,6BAC3C,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAKjC,IAAI,UAAU;AAAA,MACZ,mBACE,mFACF;AAAA,IACF;AAAA;AAAA,OAGY,SAAQ,CACpB,MACA,WACA,QACA,OAC4B;AAAA,IAC5B,IAAI,UAAU;AAAA,MAAG,OAAO,CAAC;AAAA,IACzB,MAAM,QAAQ,SACV,KAAK;AAAA,aACA,OAAO,eAAe,OAAO,eAAe,OAAO,YAAY,OAAO;AAAA,cACrE,OAAO,eACb,KAAK;AAAA,IACT,OAAO,KAAK;AAAA;AAAA,aAEH,KAAK,IAAI,6BAA6B;AAAA,2BACxB,wBAAwB,QAAQ;AAAA;AAAA,cAE7C;AAAA;AAAA;AAAA,OAIE,aAAY,GAAkB;AAAA,IAC1C,IAAI,KAAK;AAAA,MAAa;AAAA,IACtB,MAAM,KAAK;AAAA,0BACW,KAAK,IAAI,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe5D,MAAM,KAAK;AAAA;AAAA,WAEJ,KAAK,IAAI,6BAA6B;AAAA;AAAA;AAAA;AAAA,IAI7C,MAAM,KAAK;AAAA,0BACW,KAAK,IAAI,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASxD,MAAM,KAAK;AAAA;AAAA,WAEJ,KAAK,IAAI,yBAAyB;AAAA;AAAA;AAAA;AAAA,IAIzC,KAAK,cAAc;AAAA;AAAA,OAGP,WAAU,CAAC,WAAkC;AAAA,IACzD,IAAI,CAAC,KAAK;AAAA,MAAa;AAAA,IACvB,MAAM,KAAK;AAAA,oBACK,KAAK,IAAI,6BAA6B,wBAAwB;AAAA;AAAA,IAE9E,MAAM,KAAK;AAAA,oBACK,KAAK,IAAI,yBAAyB,wBAAwB;AAAA;AAAA;AAG9E;AAEA,SAAS,UAAU,CAAC,KAAkC;AAAA,EACpD,OAAO;AAAA,IACL,YAAY,IAAI;AAAA,IAChB,YAAY,IAAI;AAAA,IAChB,SAAS,IAAI;AAAA,IACb,SAAS,IAAI;AAAA,IACb,WAAW,IAAI;AAAA,EACjB;AAAA;;;AExaF;AAAA,gBACE;AAAA,kCACA;AAAA,kBACA;AAAA,uBACA;AAAA;AAEF;AAAA;AAAA,2BAGE;AAAA;AAOK,MAAM,wBAAwB;AAAA,EACN;AAAA,EAA7B,WAAW,CAAkB,KAAgB;AAAA,IAAhB;AAAA;AAAA,OAEvB,MAAK,CAAC,WAAmB,UAAkB,OAAgD;AAAA,IAC/F,MAAM,KAAK,eAAe,WAAW,KAAK;AAAA,IAC1C,MAAM,KAAK,eAAe,WAAW,KAAK;AAAA,IAC1C,MAAM,KAAK,gBAAgB,WAAW,KAAK;AAAA,IAC3C,MAAM,KAAK,YAAY,WAAW,UAAU,KAAK;AAAA;AAAA,OAGrC,eAAc,CAAC,WAAmB,OAAgD;AAAA,IAC9F,MAAM,UAAU;AAAA,MACd,GAAG,MAAM,UAAU,cAAc,IAAI,CAAC,SACpC,cAAc,EAAE,MAAM,UAAU,KAAK,KAAK,IAAI,GAAG,IAAI,CACvD;AAAA,MACA,GAAG,MAAM,UAAU,YAAY,IAAI,CAAC,SAClC,cAAc,EAAE,MAAM,QAAQ,KAAK,KAAK,IAAI,GAAG,IAAI,CACrD;AAAA,IACF;AAAA,IACA,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,KAAK,yBAAyB,IAAI;AAAA,IAC3E,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAQjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASX,IAAI,KAAK,WAAW,QAAQ;AAAA,QAAQ,MAAM,iBAAiB,QAAQ,GAAI,IAAI;AAAA,IAC7E;AAAA,IAEA,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,KAAK,yBAAyB,IAAI;AAAA,IAC3E,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCAM3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMjC,IAAI,KAAK,WAAW,QAAQ;AAAA,QAAQ,MAAM,iBAAiB,QAAQ,GAAI,IAAI;AAAA,IAC7E;AAAA,IAEA,MAAM,UAAU;AAAA,MACd,GAAG,MAAM,UAAU,cAAc,IAAI,CAAC,UAAU;AAAA,QAC9C,MAAM;AAAA,QACN,WAAW,KAAK,MAAM,cAAa,KAAK,GAAG,CAAC;AAAA,QAC5C,sBAAsB,KAAK;AAAA,MAC7B,EAAE;AAAA,MACF,GAAG,MAAM,UAAU,YAAY,IAAI,CAAC,UAAU;AAAA,QAC5C,MAAM;AAAA,QACN,WAAW,KAAK,MAAM,YAAW,KAAK,GAAG,CAAC;AAAA,QAC1C,sBAAsB,KAAK;AAAA,MAC7B,EAAE;AAAA,IACJ;AAAA,IACA,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA,uCAG3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMjC,IAAI,KAAK,WAAW,QAAQ;AAAA,QAAQ,MAAM,iBAAiB,QAAQ,GAAI,IAAI;AAAA,IAC7E;AAAA;AAAA,OAGY,eAAc,CAAC,WAAmB,OAAgD;AAAA,IAC9F,MAAM,cAAc,MAAM,UAAU,YAAY,IAAI,CAAC,UAAU;AAAA,MAC7D,cAAc,KAAK,IAAI,OAAO;AAAA,MAC9B,UAAU,KAAK,IAAI,OAAO;AAAA,MAC1B,QAAQ,KAAK,IAAI;AAAA,MACjB,cAAc,KAAK,IAAI,OAAO;AAAA,MAC9B,UAAU,KAAK,IAAI,OAAO;AAAA,MAC1B,sBAAsB,KAAK,SAAS;AAAA,IACtC,EAAE;AAAA,IACF,IAAI,YAAY,SAAS,GAAG;AAAA,MAC1B,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,WAAW;AAAA;AAAA;AAAA,uCAG/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASjC,IAAI,KAAK,WAAW,YAAY;AAAA,QAAQ,MAAM,sBAAsB,YAAY,EAAG;AAAA,IACrF;AAAA,IAEA,MAAM,gBAAgB,MAAM,UAAU,cAAc,IAAI,CAAC,UAAU;AAAA,MACjE,cAAc,KAAK,IAAI;AAAA,MACvB,WAAW,KAAK,IAAI;AAAA,MACpB,iBAAiB,KAAK,SAAS;AAAA,MAC/B,sBAAsB,KAAK,SAAS;AAAA,IACtC,EAAE;AAAA,IACF,IAAI,cAAc,SAAS,GAAG;AAAA,MAC5B,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,aAAa;AAAA;AAAA;AAAA,uCAGjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOjC,IAAI,KAAK,WAAW,cAAc;AAAA,QAAQ,MAAM,wBAAwB,cAAc,EAAG;AAAA,IAC3F;AAAA,IAEA,MAAM,KAAK,aAAa,WAAW,MAAM,UAAU,aAAa;AAAA,IAChE,MAAM,KAAK,WAAW,WAAW,MAAM,UAAU,WAAW;AAAA;AAAA,OAGhD,aAAY,CACxB,WACA,OACe;AAAA,IACf,MAAM,UAAU,MAAM,IAAI,GAAG,KAAK,gBAAgB;AAAA,MAChD,cAAc,IAAI,IAAI;AAAA,MACtB,WAAW,IAAI,IAAI;AAAA,MACnB,YAAY,IAAI;AAAA,MAChB,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,MACf,SAAS,IAAI;AAAA,MACb,cAAc,IAAI;AAAA,MAClB,gBAAgB,SAAS;AAAA,MACzB,iBAAiB,SAAS,SAAS,SAAS,UAAU;AAAA,MACtD,sBAAsB,SAAS,SAAS,SAAS,eAAe;AAAA,IAClE,EAAE;AAAA,IACF,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,CAAC,KAAK,cAAc;AAAA,IAC7D,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAMjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQX,IAAI,KAAK,WAAW,QAAQ,QAAQ;AAAA,QAClC,MAAM,kBAAkB,mBAAmB,kBAAkB,QAAQ,EAAG,iBAAiB;AAAA,MAC3F;AAAA,IACF;AAAA,IAEA,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,KAAK,cAAc;AAAA,IAC5D,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCAS3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOjC,IAAI,KAAK,WAAW,QAAQ;AAAA,QAAQ,MAAM,wBAAwB,QAAQ,EAAG;AAAA,IAC/E;AAAA;AAAA,OAGY,WAAU,CACtB,WACA,OACe;AAAA,IACf,MAAM,UAAU,MAAM,IAAI,GAAG,KAAK,gBAAgB;AAAA,MAChD,cAAc,IAAI,IAAI,OAAO;AAAA,MAC7B,UAAU,IAAI,IAAI,OAAO;AAAA,MACzB,QAAQ,IAAI,IAAI;AAAA,MAChB,cAAc,IAAI,IAAI,OAAO;AAAA,MAC7B,UAAU,IAAI,IAAI,OAAO;AAAA,SACrB,IAAI,eAAe,YAAY,CAAC,IAAI,EAAE,YAAY,IAAI,WAAW;AAAA,MACrE,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,MACf,cAAc,IAAI;AAAA,MAClB,gBAAgB,SAAS;AAAA,MACzB,sBAAsB,SAAS,SAAS,SAAS,eAAe;AAAA,IAClE,EAAE;AAAA,IACF,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,CAAC,KAAK,cAAc;AAAA,IAC7D,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAMjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASX,IAAI,KAAK,WAAW,QAAQ,QAAQ;AAAA,QAClC,MAAM,kBAAkB,iBAAiB,gBAAgB,QAAQ,EAAG,iBAAiB;AAAA,MACvF;AAAA,IACF;AAAA,IAEA,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,KAAK,cAAc;AAAA,IAC5D,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCAW3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASjC,IAAI,KAAK,WAAW,QAAQ;AAAA,QAAQ,MAAM,sBAAsB,QAAQ,EAAG;AAAA,IAC7E;AAAA;AAAA,OAGY,gBAAe,CAAC,WAAmB,OAAgD;AAAA,IAC/F,MAAM,UAAU,MAAM,WAAW,aAAa,IAAI,GAAG,OAAO,gBAAgB;AAAA,MAC1E,cAAc,MAAM,OAAO,OAAO;AAAA,MAClC,UAAU,MAAM,OAAO,OAAO;AAAA,MAC9B,YAAY,MAAM,OAAO;AAAA,MACzB,OAAO,MAAM;AAAA,MACb,MAAM,MAAM,QAAQ;AAAA,MACpB,IAAI,MAAM;AAAA,MACV,cAAc,MAAM;AAAA,MACpB,sBAAsB,SAAS;AAAA,IACjC,EAAE;AAAA,IACF,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,KAAK,yBAAyB,IAAI;AAAA,IAC3E,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAM/D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MA4Bb,IAAI,KAAK,WAAW,QAAQ;AAAA,QAAQ,MAAM,cAAc,QAAQ,EAAG;AAAA,IACrE;AAAA,IAEA,MAAM,UAAU,QAAQ,OAAO,CAAC,SAAS,KAAK,yBAAyB,IAAI;AAAA,IAC3E,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,mDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAM5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MA6BhC,IAAI,KAAK,WAAW,QAAQ;AAAA,QAAQ,MAAM,cAAc,QAAQ,EAAG;AAAA,IACrE;AAAA;AAAA,OAGY,YAAW,CACvB,WACA,UACA,OACe;AAAA,IACf,IAAI,MAAM,OAAO,WAAW;AAAA,MAAG;AAAA,IAC/B,MAAM,UAAU,MAAM,OAAO,IAAI,CAAC,SAAS;AAAA,MACzC,gBAAgB,KAAK,aAAa,oBAAoB;AAAA,MACtD,gBAAgB,KAAK,WAAW,kBAAkB;AAAA,MAClD,OAAO;AAAA,QACL,IAAI,KAAK,SAAS;AAAA,QAClB,eAAe,KAAK,SAAS;AAAA,QAC7B,UAAU,KAAK;AAAA,QACf,aAAa,KAAK;AAAA,QAClB,WAAW,KAAK;AAAA,MAClB;AAAA,KACD;AAAA,IACD,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,iDAEqB,cAAc,KAAK,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAOjE,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQvC,IAAI,KAAK,WAAW,QAAQ,QAAQ;AAAA,MAClC,MAAM,WAAW,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;AAAA,MAClD,MAAM,YAAY,QAAQ,KAAK,CAAC,SAAS,CAAC,SAAS,IAAI,KAAK,EAAE,CAAC,KAAK,QAAQ;AAAA,MAC5E,MAAM,kBAAkB,2BAA2B,UAAU,MAAM;AAAA,IACrE;AAAA;AAEJ;AAEA,SAAS,aAAa,CACpB,QACA,MAMA;AAAA,EACA,MAAM,MAAM,OAAO,SAAS,WAAW,cAAa,OAAO,GAAG,IAAI,YAAW,OAAO,GAAG;AAAA,EACvF,MAAM,UAAU,gBAAgB,MAAM;AAAA,EACtC,OAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,WAAW,KAAK,MAAM,GAAG;AAAA,OACtB;AAAA,IACH,OAAO,KAAK;AAAA,IACZ,cAAc,KAAK;AAAA,IACnB,WAAW,KAAK;AAAA,IAChB,sBAAsB,KAAK;AAAA,EAC7B;AAAA;AAGF,SAAS,gBAAgB,CAAC,MAAuD;AAAA,EAC/E,OAAO,kBAAkB,YAAY,wBAAwB;AAAA;AAG/D,SAAS,iBAAiB,CAAC,MAGhB;AAAA,EACT,OAAO,cAAa,EAAE,cAAc,KAAK,cAAc,WAAW,KAAK,UAAU,CAAC;AAAA;AAGpF,SAAS,eAAe,CAAC,MAMd;AAAA,EACT,OAAO,YAAW;AAAA,IAChB,QAAQ,EAAE,cAAc,KAAK,cAAc,WAAW,KAAK,SAAS;AAAA,IACpE,QAAQ,KAAK;AAAA,IACb,QAAQ,EAAE,cAAc,KAAK,cAAc,WAAW,KAAK,SAAS;AAAA,EACtE,CAAC;AAAA;AAGH,SAAS,uBAAuB,CAAC,MAGA;AAAA,EAC/B,OAAO,kBAAkB,mBAAmB,kBAAkB,IAAI,YAAY;AAAA;AAGhF,SAAS,qBAAqB,CAAC,MAME;AAAA,EAC/B,OAAO,kBAAkB,iBAAiB,gBAAgB,IAAI,YAAY;AAAA;AAG5E,SAAS,aAAa,CAAC,MAKU;AAAA,EAC/B,OAAO,IAAI,8BACT,oBACA,mBAAmB,mBACjB;AAAA,IACE,QAAQ,EAAE,cAAc,KAAK,cAAc,WAAW,KAAK,SAAS;AAAA,IACpE,YAAY,KAAK;AAAA,EACnB,GACA,KAAK,EACP,YACF;AAAA;;;AHlaK,MAAM,iCAA2E;AAAA,EAKnE;AAAA,EAJF;AAAA,EACA;AAAA,EAEjB,WAAW,CACQ,KACjB,SACA;AAAA,IAFiB;AAAA,IAGjB,KAAK,WAAW,IAAI,0BAA0B,KAAK,OAAO;AAAA,IAC1D,KAAK,SAAS,IAAI,wBAAwB,GAAG;AAAA;AAAA,OAGzC,MAAK,CAAC,OAAmE;AAAA,IAC7E,4BAA4B,KAAK;AAAA,IACjC,MAAM,UAAU,MAAM,KAAK,SAAS,OAAO,KAAK;AAAA,IAChD,IAAI;AAAA,MACF,MAAM,iBAAiB,KAAK,KAAK,wBAAwB,KAAK,CAAC;AAAA,MAC/D,MAAM,KAAK,mBAAmB,KAAK;AAAA,MACnC,MAAM,SAAS,IAAI,6BAA6B,KAAK,KAAK,MAAM,OAAO,SAAS;AAAA,MAChF,MAAM,KAAK,cAAc,MAAM,SAAS,SAAS,MAAM,OAAO,SAAS;AAAA,MACvE,MAAM,kBAAkB,MAAM,OAAO,yBACnC,MAAM,SAAS,QAAQ,IAAI,CAAC,aAAa,SAAS,GAAG,GACrD,IACF;AAAA,MACA,WAAW,YAAY,MAAM,SAAS,SAAS;AAAA,QAC7C,KAAK,aAAa,gBAAgB,IAAI,cAAa,SAAS,GAAG,CAAC,KAAK,MAAM,QAAQ;AAAA,MACrF;AAAA,MACA,MAAM,gBAAgB,MAAM,OAAO,yBACjC,MAAM,SAAS,MAAM,IAAI,CAAC,aAAa,SAAS,GAAG,GACnD,IACF;AAAA,MACA,WAAW,YAAY,MAAM,SAAS,OAAO;AAAA,QAC3C,KAAK,WAAW,cAAc,IAAI,YAAW,SAAS,GAAG,CAAC,GAAG,QAAQ;AAAA,MACvE;AAAA,MACA,MAAM,aAAa,MAAM,OAAO,WAAW,MAAM,SAAS,UAAU;AAAA,MACpE,YAAY,OAAO,aAAa,MAAM,SAAS,WAAW,QAAQ,GAAG;AAAA,QACnE,IAAI,WAAW,QAAQ,gBAAgB,SAAS,aAAa;AAAA,UAC3D,MAAM,IAAI,8BACR,mBACA,mCAAmC,SAAS,OAAO,gBAAgB,SAAS,OAAO,aAAa,SAAS,SAC3G;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,SAAS,MAAM,OAAO,YAAY,MAAM,SAAS,QAAQ,IAAI;AAAA,MACnE,MAAM,iBAAiB,IAAI,IACzB,OAAO,IACL,CAAC,UAAU,CAAC,mBAAkB,MAAM,QAAQ,MAAM,EAAE,GAAG,MAAM,YAAY,CAC3E,CACF;AAAA,MACA,WAAW,YAAY,MAAM,SAAS,QAAQ;AAAA,QAC5C,KACG,eAAe,IAAI,mBAAkB,SAAS,QAAQ,SAAS,EAAE,CAAC,KAAK,UACxE,SAAS,cACT;AAAA,UACA,MAAM,IAAI,8BACR,oBACA,mBAAmB,mBAAkB,SAAS,QAAQ,SAAS,EAAE,YACnE;AAAA,QACF;AAAA,MACF;AAAA,MACA,OAAO,QAAQ,cAAc;AAAA,MAC7B,OAAO,OAAO;AAAA,MACd,MAAM,KAAK,SAAS,QAAQ,OAAO;AAAA,MACnC,MAAM;AAAA;AAAA;AAAA,SAIH,WAAW,CAChB,OACyC;AAAA,IACzC,MAAM,UAAU,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,IACnD,eAAe,MAAM,QAAQ;AAAA,IAC7B,MAAM,SAAS,IAAI,6BAA6B,KAAK,KAAK,QAAQ,OAAO,OAAO,SAAS;AAAA,IACzF,iBAAiB,WAAW,MAAM,UAAU;AAAA,MAC1C,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,MACnC,MAAM,UAAU,aAAa,QAAQ,SAAS,eAAc,gBAAgB;AAAA,MAC5E,SAAS,SAAS,EAAG,SAAS,QAAQ,QAAQ,UAAU,MAAM,UAAU;AAAA,QACtE,MAAM,SAAS,MAAM,OAAO,aAAa,QAAQ,MAAM,QAAQ,SAAS,MAAM,QAAQ,CAAC;AAAA,QACvF,MAAM,EAAE,SAAS,QAAQ,OAAO,CAAC,GAAG,YAAY,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,MACjE;AAAA,MACA,MAAM,QAAQ,aAAa,QAAQ,OAAO,aAAY,cAAc;AAAA,MACpE,SAAS,SAAS,EAAG,SAAS,MAAM,QAAQ,UAAU,MAAM,UAAU;AAAA,QACpE,MAAM,SAAS,MAAM,OAAO,WAAW,MAAM,MAAM,QAAQ,SAAS,MAAM,QAAQ,CAAC;AAAA,QACnF,MAAM,EAAE,SAAS,CAAC,GAAG,OAAO,QAAQ,YAAY,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,MACjE;AAAA,MACA,iBAAiB,QAAQ,OAAO,cAAc,QAAQ,iBAAiB,MAAM,QAAQ,GAAG;AAAA,QACtF,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,QACnC,MAAM;AAAA,UACJ,SAAS,CAAC;AAAA,UACV,OAAO,MAAM,OAAO,WAAW,IAAI;AAAA,UACnC,YAAY,CAAC;AAAA,UACb,QAAQ,CAAC;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,SAAS,aACb,QAAQ,YACR,CAAC,UACC,KAAK,UAAU,CAAC,MAAM,OAAO,cAAc,MAAM,OAAO,WAAW,MAAM,MAAM,CAAC,GAClF,CAAC,UAAU,kBAAiB,MAAM,QAAQ,MAAM,MAAM,CACxD;AAAA,MACA,SAAS,SAAS,EAAG,SAAS,OAAO,QAAQ,UAAU,MAAM,UAAU;AAAA,QACrE,MAAM;AAAA,UACJ,SAAS,CAAC;AAAA,UACV,OAAO,CAAC;AAAA,UACR,YAAY,MAAM,OAAO,WAAW,OAAO,MAAM,QAAQ,SAAS,MAAM,QAAQ,CAAC;AAAA,UACjF,QAAQ,CAAC;AAAA,QACX;AAAA,MACF;AAAA,MACA,MAAM,SAAS,aACb,QAAQ,QACR,CAAC,UAAU,mBAAkB,MAAM,QAAQ,MAAM,EAAE,GACnD,CAAC,UAAU,uBAAsB,MAAM,QAAQ,MAAM,EAAE,CACzD;AAAA,MACA,SAAS,SAAS,EAAG,SAAS,OAAO,QAAQ,UAAU,MAAM,UAAU;AAAA,QACrE,MAAM,SAAS,MAAM,OAAO,YAAY,OAAO,MAAM,QAAQ,SAAS,MAAM,QAAQ,CAAC;AAAA,QACrF,IAAI,OAAO,SAAS,GAAG;AAAA,UACrB,MAAM,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,YAAY,CAAC,GAAG,QAAQ,OAAO;AAAA,QACjE;AAAA,MACF;AAAA,IACF;AAAA;AAAA,SAGK,4BAA4B,CACjC,OAC2C;AAAA,IAC3C,MAAM,UAAU,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,IACnD,eAAe,MAAM,QAAQ;AAAA,IAC7B,MAAM,cAAc,MAAM,KAAK,mBAAmB,SAAS,KAAK;AAAA,IAChE,MAAM,SAAS,IAAI,6BAA6B,KAAK,KAAK,QAAQ,OAAO,OAAO,SAAS;AAAA,IACzF,IAAI,MAAM,eAAe,UAAU;AAAA,MACjC,IAAI,YAAY,mBAAmB,UAAU;AAAA,QAC3C,MAAM,IAAI,8BACR,0BACA,yDACF;AAAA,MACF;AAAA,MACA,IAAI,YAAY,qBAAqB;AAAA,QACnC,MAAM,IAAI,8BACR,mBACA,iEACF;AAAA,MACF;AAAA,MACA,YAAY,sBAAsB;AAAA,MAClC,iBAAiB,cAAc,OAAO,sBAAsB;AAAA,QAC1D,WAAW,QAAQ;AAAA,QACnB,UAAU,YAAY;AAAA,QACtB,4BAA4B,YAAY;AAAA,QACxC,2BAA2B,YAAY;AAAA,QACvC,MAAM;AAAA,QACN,UAAU,MAAM;AAAA,MAClB,CAAC,GAAG;AAAA,QACF,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,QACnC,MAAM,OAAO,WAAW,IAAI,CAAC,aAAa;AAAA,UACxC,IAAI,SAAS,SAAS,UAAU;AAAA,YAC9B,oBAAmB,8CAA8C;AAAA,UACnE;AAAA,UACA,OAAO,SAAS;AAAA,SACjB;AAAA,QACD,MAAM,UAAU,MAAM,OAAO,wBAC3B,YAAY,UACZ,YAAY,4BACZ,IACF;AAAA,QACA,MAAM,EAAE,SAAS,OAAO,CAAC,EAAE;AAAA,MAC7B;AAAA,MACA,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,MACnC,YAAY,wBAAwB;AAAA,MACpC;AAAA,IACF;AAAA,IAEA,IAAI,YAAY,mBAAmB,YAAY,CAAC,YAAY,uBAAuB;AAAA,MACjF,MAAM,IAAI,8BACR,mBACA,iFACF;AAAA,IACF;AAAA,IACA,IAAI,YAAY,mBAAmB;AAAA,MACjC,MAAM,IAAI,8BACR,mBACA,+DACF;AAAA,IACF;AAAA,IACA,YAAY,oBAAoB;AAAA,IAChC,MAAM,qBAAqB;AAAA,MACzB,YAAY;AAAA,MACZ,GAAI,YAAY,4BAA4B,CAAC,YAAY,yBAAyB,IAAI,CAAC;AAAA,IACzF;AAAA,IACA,iBAAiB,cAAc,OAAO,sBAAsB;AAAA,MAC1D,WAAW,QAAQ;AAAA,MACnB,UAAU,YAAY;AAAA,MACtB,4BAA4B,YAAY;AAAA,MACxC,2BAA2B,YAAY;AAAA,MACvC,MAAM;AAAA,MACN,UAAU,MAAM;AAAA,IAClB,CAAC,GAAG;AAAA,MACF,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,MACnC,MAAM,iBAAiB,WAAW,IAAI,CAAC,aAAa;AAAA,QAClD,IAAI,SAAS,SAAS,QAAQ;AAAA,UAC5B,oBAAmB,+CAA+C;AAAA,QACpE;AAAA,QACA,OAAO;AAAA,OACR;AAAA,MACD,MAAM,QAAQ,MAAM,OAAO,sBACzB,YAAY,UACZ,YAAY,4BACZ,oBACA,cACF;AAAA,MACA,MAAM,EAAE,SAAS,CAAC,GAAG,MAAM;AAAA,IAC7B;AAAA,IACA,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,IACnC,YAAY,sBAAsB;AAAA;AAAA,OAG9B,UAAS,CAAC,OAAqD;AAAA,IACnE,MAAM,KAAK,SAAS,MAAM,KAAK;AAAA;AAAA,EAGjC,UAAU,CAAC,OAA+E;AAAA,IACxF,eAAe,MAAM,QAAQ;AAAA,IAC7B,OAAO,KAAK,SAAS,OAAO,KAAK;AAAA;AAAA,OAG7B,oBAAmB,CACvB,OACoD;AAAA,IACpD,MAAM,UAAU,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,IACnD,OAAO,KAAK,SAAS,oBAAoB,SAAS,MAAM,IAAI;AAAA;AAAA,OAGxD,WAAU,CAAC,OAAsD;AAAA,IACrE,MAAM,UAAU,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,IACnD,QAAQ,WAAW,QAAQ;AAAA,IAC3B,4BAA4B,MAAM,OAAO,MAAM;AAAA,IAC/C,MAAM,WAAW,MAAM,KAAK,SAAS,qBAAqB,SAAS,MAAM,KAAK;AAAA,IAC9E,MAAM,KAAK,OAAO,MAAM,OAAO,WAAW,OAAO,IAAI,MAAM,KAAK;AAAA,IAChE,KAAK,SAAS,oBAAoB,SAAS,QAAQ;AAAA;AAAA,OAG/C,SAAQ,CAAC,OAA0E;AAAA,IACvF,MAAM,UAAU,KAAK,SAAS,QAAQ,MAAM,OAAO;AAAA,IACnD,MAAM,KAAK,mBAAmB,QAAQ,MAAM;AAAA,IAC5C,MAAM,KAAK,mBAAmB,SAAS,KAAK;AAAA,IAC5C,WAAW,cAAc,MAAM,aAAa,mBAAmB;AAAA,MAC7D,MAAM,KAAK,eAAe,SAAS,UAAU;AAAA,IAC/C;AAAA,IACA,MAAM,SAAS,MAAM,KAAK,aAAa,QAAQ,QAAQ,KAAK;AAAA,IAC5D,MAAM,KAAK,SAAS,QAAQ,OAAO;AAAA,IACnC,OAAO,EAAE,QAAQ,OAAO;AAAA;AAAA,EAG1B,kBAAkB,GAAS;AAAA,IACzB,KAAK,SAAS,cAAc;AAAA;AAAA,OAGhB,mBAAkB,CAC9B,SACA,OACoE;AAAA,IACpE,IAAI,QAAQ,aAAa;AAAA,MACvB,IACE,QAAQ,YAAY,aAAa,MAAM,OAAO,gBAC9C,QAAQ,YAAY,+BAA+B,MAAM,4BACzD;AAAA,QACA,MAAM,IAAI,8BACR,0BACA,iEACF;AAAA,MACF;AAAA,MACA,OAAO,QAAQ;AAAA,IACjB;AAAA,IACA,MAAM,YAAY,QAAQ,OAAO,OAAO;AAAA,IACxC,MAAM,YAAY,MAAM,KAAK,UAC3B,WACA,MAAM,OAAO,cACb,MAAM,4BACN,IACF;AAAA,IACA,IAAI,CAAC,aAAa,UAAU,WAAW,WAAW,UAAU,oBAAoB,MAAM;AAAA,MACpF,MAAM,IAAI,8BACR,0BACA,qCAAqC,MAAM,yDAC7C;AAAA,IACF;AAAA,IACA,MAAM,0BAA0B,KAAK,KAAK;AAAA,MACxC;AAAA,MACA,UAAU,MAAM,OAAO;AAAA,MACvB,iBAAiB,UAAU;AAAA,MAC3B,gBAAgB,UAAU;AAAA,IAC5B,CAAC;AAAA,IACD,MAAM,WAAW,MAAM,KAAK,gBAAgB,WAAW,MAAM,OAAO,cAAc,IAAI;AAAA,IACtF,IACE,UAAU,aAAa,iBACtB,aACE,SAAS,aAAa,UAAU,YAC/B,SAAS,oBAAoB,UAAU,kBAC3C;AAAA,MACA,MAAM,IAAI,8BACR,0BACA,gFACF;AAAA,IACF;AAAA,IACA,QAAQ,cAAc;AAAA,MACpB,UAAU,MAAM,OAAO;AAAA,MACvB,4BAA4B,MAAM;AAAA,MAClC,2BAA2B,UAAU,sBAAsB;AAAA,MAC3D,gBAAgB,UAAU;AAAA,MAC1B,qBAAqB;AAAA,MACrB,uBAAuB;AAAA,MACvB,mBAAmB;AAAA,MACnB,qBAAqB;AAAA,IACvB;AAAA,IACA,OAAO,QAAQ;AAAA;AAAA,OAGH,mBAAkB,CAAC,QAAkD;AAAA,IACjF,OAAO,qBAAqB,MAAM,KAAK;AAAA;AAAA;AAAA,2BAKhB,OAAO,OAAO;AAAA,oBACrB,OAAO,OAAO,2BAA2B,OAAO,OAAO;AAAA,gCAC3C,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,IAI1C,IAAI,mBAAmB;AAAA,MACrB,MAAM,IAAI,8BACR,eACA,kBAAkB,OAAO,OAAO,OAAO,KACnC,oBAAoB,OAAO,OAAO,wBAClC,0CACN;AAAA,IACF;AAAA,IAEA,MAAM,SAAS,cAAc,OAAO,OAAO,MAAM;AAAA,IACjD,IAAI,OAAO,UAAU;AAAA,MAAM;AAAA,IAC3B,OAAO,mBACL,OAAO,iBAAiB,OACpB,MAAM,KAAK;AAAA;AAAA,iCAEY,OAAO,OAAO;AAAA,kCACb,OAAO;AAAA,oCACL,OAAO;AAAA;AAAA;AAAA;AAAA,cAKjC,MAAM,KAAK;AAAA;AAAA,iCAEY,OAAO,OAAO;AAAA,kCACb,OAAO;AAAA,oCACL,OAAO;AAAA,2CACA,OAAO;AAAA;AAAA;AAAA;AAAA,IAI9C,IAAI,iBAAiB;AAAA,MACnB,MAAM,IAAI,8BACR,mBACA,6DACF;AAAA,IACF;AAAA;AAAA,OAGY,cAAa,CACzB,iBACA,WACe;AAAA,IACf,IAAI,gBAAgB,WAAW;AAAA,MAAG;AAAA,IAClC,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,2BAED;AAAA;AAAA,YAEf,KAAK,IAAI,MAAM,gBAAgB,IAAI,CAAC,aAAa,SAAS,OAAO,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAKtF,MAAM,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,WAAW,GAAG,CAAU,CAAC;AAAA,IACvE,WAAW,YAAY,iBAAiB;AAAA,MACtC,KAAK,gBAAgB,UAAU,OAAO,IAAI,SAAS,OAAO,YAAY,KAAK,IAAI;AAAA,IACjF;AAAA;AAAA,EAGM,eAAe,CACrB,UACA,QACM;AAAA,IACN,KACG,QAAQ,sBAAsB,UAAU,SAAS,4BACjD,QAAQ,kBAAkB,UAAU,SAAS,cAC9C;AAAA,MACA,MAAM,IAAI,8BACR,oBACA,WAAW,SAAS,OAAO,wBAC7B;AAAA,IACF;AAAA;AAAA,EAGM,YAAY,CAClB,KACA,UACM;AAAA,IACN,IAAI,CAAC,SAAS,QAAQ;AAAA,MACpB,IAAI,KAAK;AAAA,QACP,MAAM,IAAI,8BACR,mBACA,mBAAmB,cAAa,SAAS,GAAG,iBAC9C;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,IACA,IAAI,CAAC,OAAO,IAAI,YAAY,SAAS,WAAW,IAAI,iBAAiB,SAAS,cAAc;AAAA,MAC1F,MAAM,IAAI,8BACR,mBACA,mBAAmB,cAAa,SAAS,GAAG,YAC9C;AAAA,IACF;AAAA;AAAA,EAGM,UAAU,CAChB,cACA,UACM;AAAA,IACN,IAAI,CAAC,SAAS,QAAQ;AAAA,MACpB,IAAI,iBAAiB,WAAW;AAAA,QAC9B,MAAM,IAAI,8BACR,mBACA,iBAAiB,YAAW,SAAS,GAAG,iBAC1C;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,IACA,IAAI,iBAAiB,aAAa,iBAAiB,SAAS,cAAc;AAAA,MACxE,MAAM,IAAI,8BACR,mBACA,iBAAiB,YAAW,SAAS,GAAG,YAC1C;AAAA,IACF;AAAA;AAAA,OAGY,mBAAkB,CAC9B,SACA,OACe;AAAA,IACf,QAAQ,WAAW,QAAQ;AAAA,IAC3B,QAAQ,WAAW,MAAM;AAAA,IACzB,6CAA6C,SAAS,KAAK;AAAA,IAC3D,MAAM,aAAa,MAAM,KAAK,SAAS,WAAW,OAAO;AAAA,IACzD,oCAAoC,SAAS,UAAU;AAAA,IACvD,MAAM,KAAK,uBAAuB,OAAO;AAAA,IACzC,MAAM,aAAa,WAAW;AAAA,IAC9B,OAAO,UAAU,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,2BAUL,OAAO,6BAA6B,OAAO;AAAA;AAAA,IAElE,MAAM,cAAc,OAAO,QAAQ,SAAS,CAAC;AAAA,IAC7C,MAAM,UAAU,QAAQ,YAAY,OAAO,OAAO,OAAO,QAAQ,OAAO;AAAA,IACxE,MAAM,UAAU,QAAQ,YAAY,OAAO,OAAO,OAAO,QAAQ,OAAO;AAAA,IACxE,IACE,gBAAgB,cACf,aAAa,MAAM,YAAY,KAAK,YAAY,aAAa,IAC9D;AAAA,MACA,oBAAmB,qDAAqD;AAAA,IAC1E;AAAA,IAEA,IAAI,OAAO,OAAO,SAAS,aAAa;AAAA,MACtC,MAAM,UAAU,MAAM,KAAK,iBAAiB,SAAS,OAAO,OAAO,UAAU;AAAA,MAC7E,IAAI,QAAQ,qBAAqB,OAAO,OAAO,YAAY;AAAA,QACzD,oBACE,2EACF;AAAA,MACF;AAAA,MACA,IAAI,OAAO,SAAS,eAAe,CAAC,WAAW,QAAQ,QAAQ,MAAM,GAAG;AAAA,QACtE,oBAAmB,+DAA+D;AAAA,MACpF;AAAA,IACF;AAAA,IACA,IAAI,OAAO,OAAO,SAAS,cAAc;AAAA,MACvC,IAAI,OAAO,SAAS;AAAA,QAAc;AAAA,MAClC,MAAM,KAAK,SAAS,6BAA6B,OAAO;AAAA,MACxD,IAAI,CAAC,WAAW,OAAO,QAAQ,MAAM,KAAK,iBAAiB,OAAO,CAAC,GAAG;AAAA,QACpE,oBAAmB,gEAAgE;AAAA,MACrF;AAAA,IACF;AAAA;AAAA,OAGY,uBAAsB,CAAC,SAAuD;AAAA,IAC1F,OAAO,aAAa,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eAQpB,KAAK,IAAI,6BAA6B;AAAA,6BACxB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAUzB,KAAK,IAAI,OAAO,mBAAmB,OAAO,CAAC;AAAA;AAAA;AAAA,mCAGpB,QAAQ,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAWrD,IAAI,WAAW,WAAW,aAAa;AAAA,MACrC,oBAAmB,4DAA4D;AAAA,IACjF;AAAA,IACA,IAAI,WAAW;AAAA,MACb,oBACE,iFACF;AAAA,IACF;AAAA;AAAA,OAGY,iBAAgB,CAC5B,SACgC;AAAA,IAChC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aA8BhB,KAAK,IAAI,6BAA6B;AAAA,2BACxB,QAAQ;AAAA;AAAA,IAE/B,MAAM,iBAAiB,cAAc,KAAK,eAAe;AAAA,IACzD,MAAM,iBAAiB,cAAc,KAAK,eAAe;AAAA,IACzD,MAAM,iBAAiB,cAAc,KAAK,eAAe;AAAA,IACzD,MAAM,eAAe,cAAc,KAAK,aAAa;AAAA,IACrD,MAAM,eAAe,cAAc,KAAK,aAAa;AAAA,IACrD,MAAM,eAAe,cAAc,KAAK,aAAa;AAAA,IACrD,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,kBACE,cAAc,KAAK,sBAAsB,IACzC,iBACA,iBACA;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBACE,cAAc,KAAK,oBAAoB,IAAI,eAAe,eAAe;AAAA,IAC7E;AAAA;AAAA,OAGY,iBAAgB,CAAC,SAAwC,YAAoB;AAAA,IACzF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAgBhB,KAAK,IAAI,6BAA6B;AAAA,2BACxB,QAAQ;AAAA;AAAA,IAE/B,MAAM,gBAAgB,cAAc,KAAK,cAAc;AAAA,IACvD,MAAM,gBAAgB,cAAc,KAAK,cAAc;AAAA,IACvD,OAAO;AAAA,MACL,kBAAkB,cAAc,KAAK,iBAAiB;AAAA,MACtD,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA,iBAAiB,aAAa,gBAAgB;AAAA,QAC9C,sBAAsB,cAAc,KAAK,sBAAsB;AAAA,MACjE;AAAA,IACF;AAAA;AAAA,OAGY,eAAc,CAC1B,SACA,YACe;AAAA,IACf,QAAQ,WAAW,QAAQ;AAAA,IAC3B,kCAAkC,SAAS,UAAU;AAAA,IACrD,MAAM,YAAY,MAAM,KAAK,UAC3B,OAAO,WACP,WAAW,OAAO,cAClB,WAAW,mBACX,IACF;AAAA,IACA,IAAI,CAAC,aAAa,UAAU,WAAW,WAAW,UAAU,oBAAoB,MAAM;AAAA,MACpF,MAAM,IAAI,8BACR,0BACA,yDACF;AAAA,IACF;AAAA,IACA,MAAM,0BAA0B,KAAK,KAAK;AAAA,MACxC,WAAW,OAAO;AAAA,MAClB,UAAU,WAAW,OAAO;AAAA,MAC5B,iBAAiB,WAAW,UAAU;AAAA,MACtC,gBAAgB,WAAW,UAAU;AAAA,IACvC,CAAC;AAAA,IACD,IACE,UAAU,sBAAsB,WAAW,UAAU,mBACrD,UAAU,oBAAoB,WAAW,UAAU,kBACnD,UAAU,oBAAoB,WAAW,kBACzC,UAAU,aAAa,WAAW,YAClC,UAAU,eAAe,WAAW,eAAe,aACnD,UAAU,uBAAuB,WAAW,eAAe,aAC3D,aAAY,UAAU,0BAA0B,MAAM,WAAW,eAAe,aAChF,UAAU,wBAAwB,WAAW,sBAC7C,UAAU,mBAAmB,WAAW,iBACxC,UAAU,sBAAsB,WAAW,oBAC3C,UAAU,aAAa,QACvB,WAAW,YAAY,aAAY,UAAU,QAAQ,GACrD;AAAA,MACA,oBAAmB,gEAAgE;AAAA,IACrF;AAAA,IACA,MAAM,WAAW,MAAM,KAAK,gBAC1B,OAAO,WACP,WAAW,OAAO,cAClB,IACF;AAAA,IACA,KAAK,gBAAgB,WAAW,UAAU,QAAQ;AAAA,IAClD,IAAI,UAAU;AAAA,MACZ,6BACE;AAAA,QACE,WAAW,SAAS;AAAA,QACpB,WAAW,SAAS;AAAA,QACpB,WAAW,aAAY,SAAS,0BAA0B;AAAA,MAC5D,GACA,WAAW,gBACX,mBACF;AAAA,MACA,IAAI,WAAW,YAAY,aAAY,SAAS,UAAU,GAAG;AAAA,QAC3D,oBAAmB,qEAAqE;AAAA,MAC1F;AAAA,MACA,MAAM,aAAa,MAAM,KAAK;AAAA;AAAA;AAAA,0BAGV,WAAW,2BAA2B,WAAW;AAAA,6BAC9C,OAAO;AAAA,4BACR,WAAW,OAAO;AAAA,qCACT,SAAS;AAAA;AAAA,oDAEM,WAAW,SAAS;AAAA;AAAA;AAAA,MAGlE,IAAI,WAAW,WAAW,GAAG;AAAA,QAC3B,MAAM,IAAI,8BACR,oBACA,WAAW,WAAW,OAAO,wBAC/B;AAAA,MACF;AAAA,IACF;AAAA,IACA,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,YAAY,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,WAAW,+BAA+B,WAAW;AAAA,yBACvD,WAAW;AAAA,6BACP,OAAO;AAAA,4BACR,WAAW,OAAO;AAAA,qCACT,WAAW;AAAA;AAAA,kCAEd,WAAW,UAAU;AAAA;AAAA;AAAA,MAGjD,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,8BACR,oBACA,WAAW,WAAW,OAAO,wBAC/B;AAAA,MACF;AAAA,MACA,MAAM;AAAA;AAAA,IAER,IAAI,UAAU,WAAW,GAAG;AAAA,MAC1B,MAAM,IAAI,8BACR,0BACA,sCACF;AAAA,IACF;AAAA;AAAA,OAGY,aAAY,CACxB,QACA,OAC+B;AAAA,IAC/B,QAAQ,WAAW;AAAA,IACnB,MAAM,SAAS,cAAc,OAAO,MAAM;AAAA,IAC1C,MAAM,QAAQ,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,OAAO,KAAK;AAAA,IACtF,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOlB,OAAO,cAAc,OAAO,OAAO,OAAO,mBAAmB,OAAO;AAAA,UACpE,OAAO,SAAS,OAAO,UAAU,OAAO;AAAA,UACxC,cAAc,KAAK,KAAK,OAAO,MAAM,MAAM,UAAU,OAAO;AAAA,UAC5D,OAAO,sBAAsB,SAAS,OAAO,iBAAiB;AAAA,UAC9D,cAAc,KAAK,KAAK,OAAO,MAAM;AAAA,UACrC,cAAc,KAAK,KAAK,MAAM,aAAa,MAAM,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKpE,IAAI,CAAC,KAAK,IAAI;AAAA,MACZ,MAAM,KAAK,mBAAmB,MAAM;AAAA,MACpC,MAAM,IAAI,8BACR,eACA,0CACF;AAAA,IACF;AAAA,IACA,OAAO,aAAa,KAAK,EAAE;AAAA;AAAA,OAGf,gBAAe,CAC3B,WACA,UACA,OAAO,OAC8B;AAAA,IACrC,MAAM,eAAe,OAAO,KAAK,kBAAkB,KAAK;AAAA,IACxD,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,6BAA6B;AAAA,QAChD;AAAA;AAAA,IAEJ,OAAO,OAAO;AAAA;AAAA,OAGF,UAAS,CACrB,WACA,UACA,mBACA,OAAO,OAC8B;AAAA,IACrC,MAAM,eAAe,OAAO,KAAK,kBAAkB,KAAK;AAAA,IACxD,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF;AAAA,0BACD;AAAA,mCACS;AAAA,QAC3B;AAAA;AAAA,IAEJ,OAAO,OAAO;AAAA;AAElB;AAEA,SAAS,uBAAuB,CAAC,QAA6C;AAAA,EAC5E,QAAQ,QAAQ,aAAa;AAAA,EAC7B,MAAM,SAAS,cAAc,OAAO,MAAM;AAAA,EAC1C,OAAO;AAAA,IACL,gBAAgB,aAAa,OAAO,WAAW,OAAO,EAAE;AAAA,IACxD,gBAAgB,sBAAsB,OAAO,WAAW,OAAO,cAAc;AAAA,IAC7E,GAAI,OAAO,UAAU,OACjB,CAAC,IACD;AAAA,MACE,gBACE,iBACA,OAAO,WACP,OAAO,MACP,OAAO,OACP,OAAO,iBAAiB,OAAO,KAAK,OAAO,OAAO,YAAY,CAChE;AAAA,IACF;AAAA,IACJ,GAAG,SAAS,QAAQ,IAAI,CAAC,UACvB,gBAAgB,UAAU,OAAO,WAAW,MAAM,OAAO,YAAY,CACvE;AAAA,IACA,GAAG,SAAS,QAAQ,IAAI,CAAC,UACvB,gBAAgB,UAAU,OAAO,WAAW,cAAa,MAAM,GAAG,CAAC,CACrE;AAAA,IACA,GAAG,SAAS,MAAM,IAAI,CAAC,UACrB,gBAAgB,QAAQ,OAAO,WAAW,YAAW,MAAM,GAAG,CAAC,CACjE;AAAA,IACA,GAAG,SAAS,WAAW,IAAI,CAAC,UAC1B,gBACE,cACA,OAAO,WACP,MAAM,OAAO,cACb,MAAM,OAAO,WACb,MAAM,MACR,CACF;AAAA,IACA,GAAG,SAAS,OAAO,IAAI,CAAC,UACtB,gBAAgB,SAAS,OAAO,WAAW,mBAAkB,MAAM,QAAQ,MAAM,EAAE,CAAC,CACtF;AAAA,EACF;AAAA;AAGF,SAAS,aAAa,CAAC,OAA4C;AAAA,EACjE,OAAO,OAAO,SAAS,CAAC;AAAA;;;AIz6B1B;AAAA,kCACE;AAAA;AAAA;AAsBK,MAAM,wBAAyD;AAAA,EACvC;AAAA,EAA7B,WAAW,CAAkB,kBAAmC;AAAA,IAAnC;AAAA;AAAA,OAEvB,MAAK,CAAC,OAA+E;AAAA,IACzF,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,4BAA4B;AAAA,MAC5D,sBAAsB,MAAM,OAAO,uBAAuB;AAAA,MAC1D,MAAM,MAAM,gBAAgB,MAAM,KAAK,4BAA4B;AAAA,MACnE,MAAM,cAAc,gBAAgB,MAAM,gBAAgB,8BAA8B;AAAA,MACxF,eAAe,MAAM,SAAS,0BAA0B;AAAA,MACxD,IAAI,eAAe,KAAK;AAAA,QACtB,MAAM,IAAI,+BACR,iEACF;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,+BAIM,MAAM;AAAA;AAAA,kCAEH,MAAM;AAAA,mEAC2B,MAAM;AAAA;AAAA,kBAEvD,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,yBAKC,MAAM;AAAA,iCACE,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUjC,OAAO,KAAK,IAAI,CAAC,QAAQ;AAAA,QACvB,MAAM,SAAS,aAAa,GAAG;AAAA,QAC/B,IAAI,OAAO,YAAY,QAAQ,OAAO,mBAAmB,MAAM;AAAA,UAC7D,MAAM,IAAI,8BACR,gBACA,mDACF;AAAA,QACF;AAAA,QACA,OAAO,KAAK,QAAQ,SAAS,OAAO,SAAS,gBAAgB,OAAO,eAAe;AAAA,OACpF;AAAA,KACF;AAAA;AAAA,OAGG,cAAa,CAAC,OAAwD;AAAA,IAC1E,MAAM,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MACzC,iBAAiB,KAAK;AAAA,MACtB,gBAAgB,MAAM,aAAa,6BAA6B;AAAA,MAChE,MAAM,MAAM,iBAAiB,MAAM,GAAG;AAAA,MACtC,IAAI,IAAI,WAAW;AAAA,QAAG;AAAA,MACtB,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA,+BAGM,MAAM;AAAA,2BACV,IAAI,MAAM,GAAG;AAAA,6BACX,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,kDAKe,IAAI;AAAA;AAAA;AAAA,6BAGzB,MAAM;AAAA;AAAA,oCAEC,MAAM;AAAA;AAAA;AAAA,MAGpC,IAAI,KAAK,WAAW,IAAI;AAAA,QAAQ,MAAM,cAAc;AAAA,KACrD;AAAA;AAAA,OAGG,WAAU,CAAC,OAA0D;AAAA,IACzE,MAAM,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MACzC,iBAAiB,KAAK;AAAA,MACtB,gBAAgB,MAAM,aAAa,6BAA6B;AAAA,MAChE,MAAM,MAAM,iBAAiB,MAAM,GAAG;AAAA,MACtC,IAAI,IAAI,WAAW;AAAA,QAAG;AAAA,MACtB,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA,+BAGM,MAAM;AAAA,2BACV,IAAI,MAAM,GAAG;AAAA,6BACX,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,kDAKe,IAAI;AAAA;AAAA;AAAA,6BAGzB,MAAM,6BAA6B,MAAM;AAAA;AAAA;AAAA,oCAGlC,MAAM;AAAA;AAAA;AAAA,MAGpC,IAAI,KAAK,WAAW,IAAI;AAAA,QAAQ,MAAM,cAAc;AAAA,KACrD;AAAA;AAAA,OAGG,eAAc,CAAC,OAA2D;AAAA,IAC9E,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,4BAA4B;AAAA,MAC5D,sBAAsB,MAAM,OAAO,uBAAuB;AAAA,MAC1D,gBAAgB,MAAM,iBAAiB,8BAA8B;AAAA,MACrE,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA,+BAIM,MAAM;AAAA;AAAA,iCAEJ,MAAM;AAAA;AAAA,kBAErB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQlB,OAAO,KAAK;AAAA,KACb;AAAA;AAAA,OAGG,UAAS,CAAC,OAAqE;AAAA,IACnF,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,4BAA4B;AAAA,MAC5D,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAaD,MAAM;AAAA;AAAA,MAE7B,OAAO;AAAA,QACL,cAAc,SAAS,iBAAiB;AAAA,QACxC,iBAAiB,oBAAoB,SAAS,iBAAiB;AAAA,QAC/D,eAAe,SAAS,kBAAkB;AAAA,QAC1C,aAAa,SAAS,gBAAgB;AAAA,MACxC;AAAA,KACD;AAAA;AAEL;AAEA,SAAS,mBAAmB,CAAC,OAAwD;AAAA,EACnF,IAAI,UAAU,QAAQ,UAAU;AAAA,IAAW,OAAO;AAAA,EAClD,OAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI,IAAI,KAAK,KAAK,EAAE,YAAY;AAAA;AAGnF,SAAS,gBAAgB,CAAC,KAAkC;AAAA,EAC1D,MAAM,OAAO,IAAI;AAAA,EACjB,WAAW,MAAM,KAAK;AAAA,IACpB,eAAe,IAAI,0BAA0B;AAAA,IAC7C,IAAI,KAAK,IAAI,EAAE,GAAG;AAAA,MAChB,MAAM,IAAI,+BAA+B,8CAA8C,MAAM;AAAA,IAC/F;AAAA,IACA,KAAK,IAAI,EAAE;AAAA,EACb;AAAA,EACA,OAAO,CAAC,GAAG,IAAI;AAAA;AAGjB,SAAS,gBAAgB,CAAC,OAIjB;AAAA,EACP,eAAe,MAAM,WAAW,4BAA4B;AAAA,EAC5D,eAAe,MAAM,SAAS,0BAA0B;AAAA;AAG1D,SAAS,aAAa,GAAiC;AAAA,EACrD,OAAO,IAAI,8BAA6B,gBAAgB,uCAAuC;AAAA;;;ACtNjG,2CAAS;AACT;AAAA,4BACE;AAAA,mCACA;AAAA,yBACA;AAAA;AAAA,+BAEA;AAAA,yBACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CK,MAAM,wBAAyD;AAAA,EACvC;AAAA,EAA7B,WAAW,CAAkB,kBAAmC;AAAA,IAAnC;AAAA;AAAA,OAEvB,qBAAoB,CACxB,OAC+B;AAAA,IAC/B,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,iBAAiB,KAAK;AAAA,MACtB,MAAM,KAAK,gBAAgB,KAAK,OAAO,8BAA8B,KAAK,CAAC;AAAA,MAC3E,MAAM,iBAAiB,KAAK;AAAA,QAC1B,gBAAgB,oBAAoB,MAAM,WAAW,MAAM,UAAU,eAAe;AAAA,QACpF,gBACE,0BACA,MAAM,WACN,MAAM,OAAO,cACb,MAAM,iBACR;AAAA,MACF,CAAC;AAAA,MAED,MAAM,WAAW,MAAM,KAAK,YAC1B,KACA,MAAM,WACN,MAAM,OAAO,cACb,MAAM,mBACN,IACF;AAAA,MACA,IAAI,UAAU;AAAA,QACZ,IAAI,uBAAuB,aAAa,QAAQ,GAAG,KAAK;AAAA,UAAG,OAAO,aAAa,QAAQ;AAAA,QACvF,MAAM,eACJ,2BAA2B,MAAM,qEACnC;AAAA,MACF;AAAA,MAEA,MAAM,YAAY,MAAM,KAAK,gBAAgB,KAAK,KAAK;AAAA,MACvD,IAAI,WAAW;AAAA,QACb,MAAM,eACJ,mBAAmB,MAAM,UAAU,yGACrC;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YASb,MAAM,cAAc,MAAM,OAAO,iBAAiB,MAAM;AAAA,YACxD,MAAM,UAAU,oBAAoB,MAAM;AAAA,uBAC/B,MAAM,UAAU,mBAAmB,MAAM,eAAe;AAAA,YACnE,MAAM,eAAe,cAAc,MAAM,eAAe;AAAA,YACxD,MAAM,uBAAuB,MAAM,kBAAkB,MAAM;AAAA,wBAC/C,MAAM,sCAAsC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,MAKpE,IAAI,KAAK;AAAA,QAAI,OAAO,aAAa,KAAK,EAAE;AAAA,MAExC,MAAM,gBAAgB,MAAM,KAAK,YAC/B,KACA,MAAM,WACN,MAAM,OAAO,cACb,MAAM,mBACN,IACF;AAAA,MACA,IAAI,iBAAiB,uBAAuB,aAAa,aAAa,GAAG,KAAK,GAAG;AAAA,QAC/E,OAAO,aAAa,aAAa;AAAA,MACnC;AAAA,MACA,IAAI,MAAM,KAAK,gBAAgB,KAAK,KAAK,GAAG;AAAA,QAC1C,MAAM,eACJ,mBAAmB,MAAM,UAAU,yGACrC;AAAA,MACF;AAAA,MACA,MAAM,eACJ,2BAA2B,MAAM,qEACnC;AAAA,KACD;AAAA;AAAA,OAGG,UAAS,CAAC,OAA6D;AAAA,IAC3E,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,oBAAoB,KAAK;AAAA,MACzB,MAAM,KAAK,gBAAgB,KAAK,KAAK;AAAA,MACrC,MAAM,WAAW,MAAM,KAAK,gBAC1B,KACA,MAAM,WACN,MAAM,OAAO,cACb,MAAM,mBACN,IACF;AAAA,MACA,2BAA2B,aAAa,QAAQ,GAAG,MAAM,SAAS;AAAA,MAClE,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,eACJ,2BAA2B,MAAM,0BAA0B,SAAS,iCACtE;AAAA,MACF;AAAA,MAEA,MAAM,OAAO,gBAAgB,SAAS,iBAAiB,MAAM,IAAI;AAAA,MACjE,MAAM,WAAW,MAAM,KAAK,cAAc,KAAK,OAAO,IAAI;AAAA,MAC1D,QAAQ,SAAS,cAAc,yBAAyB,MAAM,QAAQ;AAAA,MACtE,MAAM,KAAK,gBAAgB,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,EAAE,UAAU,QAAQ,QAAQ,UAAU;AAAA,KAC9C;AAAA;AAAA,OAGG,UAAS,CAAC,OAA2E;AAAA,IACzF,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,oBAAoB,KAAK;AAAA,MACzB,gBAAgB,MAAM,SAAS,kBAAkB,IAAI;AAAA,MACrD,yBAAyB,MAAM,WAAW,mBAAmB;AAAA,MAC7D,yBAAyB,MAAM,gBAAgB,wBAAwB;AAAA,MACvE,MAAM,KAAK,gBAAgB,KAAK,KAAK;AAAA,MACrC,MAAM,WAAW,MAAM,KAAK,gBAC1B,KACA,MAAM,WACN,MAAM,OAAO,cACb,MAAM,mBACN,IACF;AAAA,MACA,2BAA2B,aAAa,QAAQ,GAAG,MAAM,SAAS;AAAA,MAClE,IAAI,SAAS,WAAW,SAAS;AAAA,QAC/B,IACE,aAAa,SAAS,UAAU,MAAM,MAAM,aAC5C,aAAa,SAAS,eAAe,MAAM,MAAM,kBACjD,aAAY,SAAS,QAAS,MAAM,MAAM,SAC1C;AAAA,UACA,OAAO,aAAa,QAAQ;AAAA,QAC9B;AAAA,QACA,MAAM,eACJ,2BAA2B,MAAM,oEACnC;AAAA,MACF;AAAA,MACA,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,eACJ,2BAA2B,MAAM,8CAA8C,SAAS,qBAC1F;AAAA,MACF;AAAA,MACA,IAAI,MAAM,UAAU,aAAY,SAAS,UAAU,GAAG;AAAA,QACpD,MAAM,IAAI,gCAA+B,iDAAiD;AAAA,MAC5F;AAAA,MACA,MAAM,KAAK,iBAAiB,KAAK,UAAU,MAAM,WAAW,MAAM,cAAc;AAAA,MAChF,MAAM,OAAO,MAAM;AAAA;AAAA,6CAEoB,MAAM;AAAA,8BACrB,MAAM,8BAA8B,MAAM;AAAA,yBAC/C,MAAM;AAAA,6BACF,MAAM;AAAA,4BACP,MAAM,OAAO;AAAA,qCACJ,MAAM;AAAA;AAAA,kCAET,MAAM,UAAU;AAAA;AAAA;AAAA,MAG5C,IAAI,CAAC,KAAK,IAAI;AAAA,QACZ,MAAM,eAAe,2BAA2B,MAAM,6BAA6B;AAAA,MACrF;AAAA,MACA,OAAO,aAAa,KAAK,EAAE;AAAA,KAC5B;AAAA;AAAA,OAGG,UAAS,CAAC,OAA2E;AAAA,IACzF,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,uBAAuB,KAAK;AAAA,MAC5B,OAAO,OAAO,MAAM;AAAA;AAAA,6BAEG,MAAM;AAAA,4BACP,MAAM,OAAO;AAAA;AAAA;AAAA,MAGnC,OAAO,MAAM,aAAa,GAAG,IAAI;AAAA,KAClC;AAAA;AAAA,OAKG,QAAO,CAAC,OAAgF;AAAA,IAC5F,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,uBAAuB,KAAK;AAAA,MAC5B,wBAAwB,MAAM,UAAU,iBAAiB,MAAM,UAAU,cAAc;AAAA,MACvF,gBAAgB,MAAM,aAAa,sBAAsB,IAAI;AAAA,MAC7D,MAAM,KAAK,gBAAgB,KAAK,KAAK;AAAA,MACrC,OAAO,MAAM,SAAS,cAClB,KAAK,iBAAiB,KAAK,KAAK,IAChC,KAAK,kBAAkB,KAAK,KAAK;AAAA,KACtC;AAAA;AAAA,OAGG,gBAAe,CACnB,OACsD;AAAA,IACtD,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,oCAAoC;AAAA,MACpE,gBAAgB,MAAM,gBAAgB,kCAAkC,IAAI;AAAA,MAC5E,sBAAsB,MAAM,OAAO,+BAA+B;AAAA,MAClE,MAAM,YAAY,MAAM;AAAA;AAAA,6BAED,MAAM;AAAA;AAAA,8BAEL,MAAM;AAAA;AAAA,gBAEpB,MAAM;AAAA;AAAA;AAAA,MAGhB,IAAI,YAAY,MAAM;AAAA,MACtB,IAAI,cAAc;AAAA,MAClB,IAAI,0BAA0B;AAAA,MAC9B,WAAW,YAAY,WAAW;AAAA,QAChC,IAAI,cAAc;AAAA,UAAG;AAAA,QACrB,MAAM,cAAc,MAAM;AAAA;AAAA;AAAA;AAAA,sCAII,SAAS;AAAA,qCACV,SAAS;AAAA,8CACA,SAAS;AAAA;AAAA,oBAEnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQZ,eAAe,YAAY;AAAA,QAC3B,aAAa,YAAY;AAAA,QACzB,IAAI,cAAc;AAAA,UAAG;AAAA,QACrB,MAAM,UAAU,MAAM;AAAA;AAAA,uCAES,SAAS;AAAA,sCACV,SAAS;AAAA,+CACA,SAAS;AAAA;AAAA,wCAEhB,SAAS;AAAA,wCACT,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAStC,2BAA2B,QAAQ;AAAA,QACnC,aAAa,QAAQ;AAAA,MACvB;AAAA,MACA,OAAO,EAAE,aAAa,wBAAwB;AAAA,KAC/C;AAAA;AAAA,OAGG,kBAAiB,CACrB,OAC+C;AAAA,IAC/C,OAAO,KAAK,iBAAiB,OAAO,QAAQ;AAAA,MAC1C,eAAe,MAAM,WAAW,oCAAoC;AAAA,MACpE,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,6BAQD,MAAM;AAAA;AAAA;AAAA,MAG7B,OAAO;AAAA,QACL,OAAO,SAAS,kBAAkB;AAAA,QAClC,kBAAkB,qBAAoB,SAAS,kBAAkB;AAAA,MACnE;AAAA,KACD;AAAA;AAAA,OAGW,iBAAgB,CAC5B,KACA,OAC+B;AAAA,IAC/B,MAAM,WAAW,MAAM,KAAK,gBAC1B,KACA,MAAM,WACN,MAAM,OAAO,cACb,MAAM,mBACN,IACF;AAAA,IACA,IAAI,SAAS,WAAW,aAAa;AAAA,MACnC,IACE,SAAS,sBAAsB,MAAM,UAAU,mBAC/C,SAAS,gBAAgB,QACzB,aAAY,SAAS,WAAW,MAAM,MAAM,aAC5C;AAAA,QACA,OAAO,aAAa,QAAQ;AAAA,MAC9B;AAAA,MACA,MAAM,eACJ,2BAA2B,MAAM,2EACnC;AAAA,IACF;AAAA,IACA,2BAA2B,aAAa,QAAQ,GAAG,MAAM,SAAS;AAAA,IAClE,OAAO,KAAK,sBAAsB,KAAK,UAAU,MAAM,WAAW;AAAA;AAAA,OAGtD,kBAAiB,CAC7B,KACA,OACsC;AAAA,IACtC,MAAM,aAAa,MAAM;AAAA;AAAA,2BAEF,MAAM;AAAA,0BACP,MAAM,OAAO;AAAA,kCACL,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA,IAI9C,IACE,WAAW,KAAK,CAAC,cAAc,UAAU,oBAAoB,MAAM,UAAU,cAAc,GAC3F;AAAA,MACA,MAAM,eACJ,mBAAmB,MAAM,UAAU,uFACrC;AAAA,IACF;AAAA,IACA,IAAI,WAAW,SAAS,GAAG;AAAA,MACzB,MAAM,eACJ,mBAAmB,MAAM,UAAU,oEACrC;AAAA,IACF;AAAA,IACA,OAAO,WAAW,KAAK,KAAK,sBAAsB,KAAK,WAAW,IAAI,MAAM,WAAW,IAAI;AAAA;AAAA,OAG/E,sBAAqB,CACjC,KACA,UACA,aAC+B;AAAA,IAC/B,IACE,cAAc,aAAY,SAAS,UAAU,KAC5C,SAAS,aAAa,QAAQ,cAAc,aAAY,SAAS,QAAQ,GAC1E;AAAA,MACA,MAAM,IAAI,gCACR,iEACF;AAAA,IACF;AAAA,IACA,MAAM,OAAO,MAAM;AAAA;AAAA;AAAA,wBAGC,6BAA6B;AAAA,2BAC1B,SAAS;AAAA,0BACV,SAAS;AAAA,mCACA,SAAS;AAAA;AAAA;AAAA;AAAA,IAIxC,IAAI,CAAC,KAAK,IAAI;AAAA,MACZ,MAAM,eACJ,2BAA2B,SAAS,uDACtC;AAAA,IACF;AAAA,IACA,OAAO,aAAa,KAAK,EAAE;AAAA;AAAA,OAGf,iBAAgB,CAC5B,KACA,UACA,WACA,gBACe;AAAA,IACf,OAAO,UAAU,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,2BAaA,SAAS;AAAA,0BACV,SAAS;AAAA,mCACA,SAAS;AAAA;AAAA,IAExC,MAAM,aAAa,OAAO,QAAQ,cAAc,CAAC;AAAA,IACjD,MAAM,QAAQ,OAAO,QAAQ,SAAS,CAAC;AAAA,IACvC,MAAM,WAAW,OAAO,QAAQ,YAAY,CAAC;AAAA,IAC7C,MAAM,UAAU,QAAQ,gBAAgB,OAAO,OAAO,OAAO,QAAQ,WAAW;AAAA,IAChF,MAAM,UAAU,QAAQ,gBAAgB,OAAO,OAAO,OAAO,QAAQ,WAAW;AAAA,IAChF,IACE,eAAe,kBACf,UAAU,aACV,aAAa,aACZ,YAAY,MAAM,YAAY,KAAK,YAAY,YAAY,IAC5D;AAAA,MACA,MAAM,IAAI,gCACR,mEACF;AAAA,IACF;AAAA,IAEA,OAAO,WACL,SAAS,oBAAoB,SACzB,MAAM;AAAA;AAAA;AAAA,iCAGiB,SAAS;AAAA,gCACV,SAAS;AAAA,yCACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAQxC,MAAM;AAAA;AAAA;AAAA,iCAGiB,SAAS;AAAA,gCACV,SAAS;AAAA,yCACA,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAe9C,IAAI,SAAS;AAAA,MACX,MAAM,IAAI,gCACR,SAAS,oBAAoB,SACzB,8EACA,iHACN;AAAA,IACF;AAAA;AAAA,OAGY,cAAa,CACzB,KACA,OACA,MACoC;AAAA,IACpC,IAAI,KAAK,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IAC/B,MAAM,eAAe,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,YAAY,IAAI,OAAO,CAAC,CAAC,CAAC;AAAA,IAC7E,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,cAAc,CAAC,CAAC;AAAA,IACvE,MAAM,iBAAiB,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,YAAY,IAAI,SAAS,CAAC,CAAC,CAAC;AAAA,IACjF,MAAM,WAAW,MAAM;AAAA;AAAA,2BAEA,MAAM;AAAA,0BACP,MAAM,OAAO;AAAA,mCACJ,MAAM;AAAA;AAAA,gCAET,IAAI,MAAM,YAAY;AAAA,qCACjB,IAAI,MAAM,QAAQ;AAAA,qCAClB,IAAI,MAAM,cAAc;AAAA;AAAA;AAAA,IAGzD,OAAO,SAAS,IAAI,CAAC,QAAQ,eAAe,gBAAgB,GAAG,CAAC,CAAC;AAAA;AAAA,OAGrD,gBAAe,CAC3B,KACA,OACA,MACe;AAAA,IACf,IAAI,KAAK,WAAW;AAAA,MAAG;AAAA,IACvB,MAAM,UAAU,KAAK,IAAI,GAAG,WAAW,SAAS,UAAU;AAAA,MACxD,MAAM,SAAS,cAAc,IAAI,SAAS;AAAA,MAC1C,MAAM,OAAO,cAAc,IAAI,IAAI;AAAA,MACnC,OAAO;AAAA,QACL,YAAY,IAAI,UAAU;AAAA,QAC1B,WAAW,KAAK,MAAM,SAAS;AAAA,QAC/B,eAAe,YAAY,SAAS;AAAA,QACpC,UAAU,IAAI,KAAK;AAAA,QACnB,SAAS,KAAK,MAAM,OAAO;AAAA,QAC3B,aAAa,YAAY,OAAO;AAAA,QAChC,gBAAgB,IAAI;AAAA,QACpB,MAAM,IAAI;AAAA,QACV,WAAW,IAAI;AAAA,QACf,cAAc,OAAO;AAAA,QACrB,WAAW,OAAO;AAAA,QAClB,cAAc,OAAO;AAAA,QACrB,iBAAiB,OAAO;AAAA,QACxB,QAAQ,OAAO;AAAA,QACf,cAAc,OAAO;AAAA,QACrB,iBAAiB,OAAO;AAAA,QACxB,kBAAkB,KAAK;AAAA,QACvB,eAAe,KAAK;AAAA,QACpB,kBAAkB,KAAK;AAAA,QACvB,qBAAqB,KAAK;AAAA,QAC1B,YAAY,KAAK;AAAA,QACjB,kBAAkB,KAAK;AAAA,QACvB,qBAAqB,KAAK;AAAA,MAC5B;AAAA,KACD;AAAA,IACD,MAAM;AAAA;AAAA;AAAA,oCAG0B,cAAc,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAcpD,MAAM,cAAc,MAAM,OAAO,iBAAiB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAexD,eAAe,CACrB,KACA,OAKA,UACe;AAAA,IACf,OAAO,0BAA0B,KAAK;AAAA,MACpC,WAAW,MAAM;AAAA,MACjB,UAAU,MAAM,OAAO;AAAA,MACvB,iBAAiB,MAAM,UAAU;AAAA,MACjC,gBAAgB,MAAM,UAAU;AAAA,SAC5B,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IACjC,CAAC;AAAA;AAAA,OAGW,gBAAe,CAC3B,KACA,OACqC;AAAA,IACrC,OAAO,OAAO,MAAM;AAAA;AAAA,2BAEG,MAAM;AAAA,kCACC,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,IAK9C,OAAO,OAAO;AAAA;AAAA,OAGF,YAAW,CACvB,KACA,WACA,UACA,mBACA,OAAO,OAC8B;AAAA,IACrC,MAAM,eAAe,OAAO,kBAAkB;AAAA,IAC9C,OAAO,OAAO,MAAM;AAAA;AAAA,2BAEG;AAAA,0BACD;AAAA,mCACS;AAAA,QAC3B;AAAA;AAAA,IAEJ,OAAO,OAAO;AAAA;AAAA,OAGF,gBAAe,CAC3B,KACA,WACA,UACA,mBACA,OAAO,OACuB;AAAA,IAC9B,MAAM,MAAM,MAAM,KAAK,YAAY,KAAK,WAAW,UAAU,mBAAmB,IAAI;AAAA,IACpF,IAAI,CAAC;AAAA,MAAK,MAAM,eAAe,2BAA2B,oCAAoC;AAAA,IAC9F,OAAO;AAAA;AAEX;AAEA,SAAS,oBAAmB,CAAC,OAAwD;AAAA,EACnF,IAAI,UAAU,QAAQ,UAAU;AAAA,IAAW,OAAO;AAAA,EAClD,OAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI,IAAI,KAAK,KAAK,EAAE,YAAY;AAAA;AAGnF,SAAS,YAAY,CAAC,OAA8C;AAAA,EAClE,OAAO,UAAU,OAAO,OAAO,OAAO,KAAK;AAAA;;;ACvoBtC,MAAM,kBAA6C;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,WAAW,CAAC,OAIT;AAAA,IACD,KAAK,UAAU,IAAI,wBAAwB,MAAM,gBAAgB;AAAA,IACjE,KAAK,UAAU,IAAI,wBAAwB,MAAM,gBAAgB;AAAA,IACjE,KAAK,mBAAmB,IAAI,iCAC1B,MAAM,KACN,MAAM,kBACR;AAAA,IACA,KAAK,SAAS,IAAI,wBAAwB,MAAM,gBAAgB;AAAA;AAAA,EAGlE,kBAAkB,GAAS;AAAA,IACzB,KAAK,iBAAiB,mBAAmB;AAAA;AAE7C;;;ACbA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWO,MAAM,mBAA+C;AAAA,EAC7B;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,uBAAsB,CAAC,OAAoE;AAAA,IAC/F,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,2BAGF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,IAGzD,IAAI,CAAC,KAAK;AAAA,MACR,MAAM,IAAI,eACR,wBAAwB,MAAM,iCAAiC,MAAM,aACvE;AAAA,IACF;AAAA,IACA,IAAI,IAAI,cAAc,MAAM,UAAU;AAAA,MACpC,MAAM,IAAI,eACR,wBAAwB,MAAM,qCAAqC,MAAM,YAC3E;AAAA,IACF;AAAA,IACA,IAAI,IAAI,WAAW,WAAW;AAAA,MAC5B,MAAM,IAAI,eACR,wBAAwB,MAAM,0CAA0C,IAAI,UAC9E;AAAA,IACF;AAAA,IACA,OAAO,qBAAqB,GAAG;AAAA;AAAA,OAG3B,MAAK,CAAC,OAAsD;AAAA,IAChE,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YA8BnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM,QAAQ;AAAA,YACd,MAAM,QAAQ,SAAS,WAAW,MAAM,QAAQ,eAAe;AAAA,YAC/D,MAAM,QAAQ,SAAS,WAAW,MAAM,QAAQ,YAAY;AAAA,YAC5D;AAAA,YACA;AAAA,YACA,MAAM,YAAY,IAAI;AAAA,YACtB;AAAA,YACA;AAAA,YACA,KAAK,UAAU,MAAM,MAAM;AAAA,YAC3B,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA;AAAA;AAAA;AAAA,MAKN,OAAO,qBAAqB,GAAG;AAAA,MAC/B,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,OAAO,KAAK,2BAA2B,KAAK;AAAA,MAC9C;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAII,2BAA0B,CAAC,OAAsD;AAAA,IAC7F,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IACE,CAAC,YACD,CAAC,uCAAuC,qBAAqB,QAAQ,GAAG,KAAK,GAC7E;AAAA,QACA,MAAM,IAAI,eACR,wBAAwB,MAAM,mCAAmC,MAAM,aACzE;AAAA,MACF;AAAA,MAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT;AAAA,oBACD;AAAA,wBACI,MAAM,YAAY,IAAI;AAAA,yBACrB;AAAA,0BACC;AAAA,+BACK;AAAA,qCACM;AAAA,+BACN;AAAA,mCACI;AAAA,sCACG;AAAA,oCACF;AAAA,6BACP;AAAA,mCACM;AAAA,iCACF;AAAA,oCACG;AAAA,kCACF;AAAA,yBACT;AAAA,4BACG;AAAA,0BACF;AAAA,6BACG,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,qBAAqB,OAAO;AAAA,KACpC;AAAA;AAAA,OAGG,MAAK,CAAC,OAAsD;AAAA,IAChE,OAAO,WAAW,MAAM,KAAK;AAAA;AAAA;AAAA,mBAGd;AAAA,kBACD,MAAM,SAAS;AAAA,uBACV,MAAM,aAAa,IAAI;AAAA,uBACvB;AAAA,0BACG;AAAA,wBACF;AAAA,2BACG,MAAM;AAAA,mBACd,MAAM;AAAA,uBACF;AAAA;AAAA;AAAA,IAInB,IAAI,SAAS;AAAA,MACX,OAAO,qBAAqB,OAAO;AAAA,IACrC;AAAA,IAEA,MAAM,WAAW,MAAM,KAAK,QAAQ,EAAE,WAAW,MAAM,WAAW,IAAI,MAAM,GAAG,CAAC;AAAA,IAChF,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,eACR,wBAAwB,MAAM,8BAA8B,MAAM,aACpE;AAAA,IACF;AAAA,IAEA,MAAM,IAAI,eACR,wBAAwB,MAAM,iCAAiC,SAAS,UAC1E;AAAA;AAAA,OAGI,WAAU,CAAC,OAA2D;AAAA,IAC1E,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,KAAK,kBAAkB,IAAI,MAAM,WAAW,MAAM,IAAI,kBAAkB;AAAA,MAE9E,OAAO,WAAW,MAAM;AAAA;AAAA,sBAER,MAAM;AAAA,6BACC,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,qBAAqB,OAAO;AAAA,KACpC;AAAA;AAAA,OAGG,gBAAe,CAAC,OAA6D;AAAA,IACjF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,WAAW,MAAM,KAAK,kBAC1B,IACA,MAAM,WACN,MAAM,IACN,kBACF;AAAA,MACA,MAAM,gBAAgB,kBAAkB,OAAO,IAAI,KAAK,MAAM,eAAe,IAAI,IAAM,CAAC;AAAA,MACxF,MAAM,mBAAmB,2BAA2B,QAAQ;AAAA,MAE5D,IAAI,kBAAkB;AAAA,QACpB,IAAI,2BAA2B,kBAAkB,aAAa,GAAG;AAAA,UAC/D,OAAO,qBAAqB,QAAQ;AAAA,QACtC;AAAA,QAEA,MAAM,IAAI,eACR,wBAAwB,MAAM,+CAChC;AAAA,MACF;AAAA,MAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,oBAGV;AAAA,+BACW,MAAM;AAAA,qCACA,cAAc;AAAA,+BACpB,MAAM,WAAW,cAAc,KAAK,UAAU,MAAM,MAAM,IAAI;AAAA,mCAC1D,MAAM,WAAW,WAAY,MAAM,MAAM,QAAQ,OAAQ;AAAA,sCACtD,MAAM,WAAW,WAAW,MAAM,MAAM,UAAU;AAAA,oCACpD,MAAM,WAAW,WAAY,MAAM,MAAM,SAAS,cAAe;AAAA,6BACxE,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,qBAAqB,OAAO;AAAA,KACpC;AAAA;AAAA,OAGG,cAAa,CAAC,OAA2D;AAAA,IAC7E,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,WAAW,MAAM,KAAK,kBAAkB,IAAI,MAAM,WAAW,MAAM,IAAI,gBAAgB;AAAA,MAC7F,MAAM,cAAc,gBAAgB,OAAO,IAAI,KAAK,MAAM,eAAe,IAAI,IAAM,CAAC;AAAA,MACpF,MAAM,iBAAiB,yBAAyB,QAAQ;AAAA,MAExD,IAAI,gBAAgB;AAAA,QAClB,IAAI,2BAA2B,gBAAgB,WAAW,GAAG;AAAA,UAC3D,OAAO,qBAAqB,QAAQ;AAAA,QACtC;AAAA,QAEA,MAAM,IAAI,eACR,wBAAwB,MAAM,6CAChC;AAAA,MACF;AAAA,MAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,oBAGV;AAAA,6BACS,MAAM;AAAA,mCACA,YAAY;AAAA,iCACd,MAAM,WAAW,WAAY,MAAM,MAAM,QAAQ,OAAQ;AAAA,oCACtD,MAAM,WAAW,WAAW,MAAM,MAAM,UAAU;AAAA,kCACpD,MAAM,WAAW,WAAY,MAAM,MAAM,SAAS,YAAa;AAAA,6BACpE,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,qBAAqB,OAAO;AAAA,KACpC;AAAA;AAAA,OAGG,OAAM,CAAC,OAAuD;AAAA,IAClE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,eACR,wBAAwB,MAAM,8BAA8B,MAAM,aACpE;AAAA,MACF;AAAA,MAEA,IAAI,oBAAoB,EAAE,QAAQ,SAAS,OAAO,CAAC,GAAG;AAAA,QACpD,MAAM,IAAI,eACR,wBAAwB,MAAM,2CAA2C,SAAS,UACpF;AAAA,MACF;AAAA,MAEA,MAAM,QAAQ,qBAAqB,OAAO,SAAS,KAAK;AAAA,MAExD,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT,MAAM;AAAA,oBACP;AAAA,0BACM,MAAM,cAAc,IAAI;AAAA,yBACzB,MAAM,WAAW,cAAc,OAAQ,MAAM,OAAO,QAAQ;AAAA,4BACzD,MAAM,WAAW,cAAc,OAAQ,MAAM,OAAO,WAAW;AAAA,0BACjE,MAAM,WAAW,cAAc,OAAQ,MAAM,OAAO,SAAS;AAAA,6BAC1D,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,qBAAqB,OAAO;AAAA,KACpC;AAAA;AAAA,OAGG,QAAO,CAAC,QAA4E;AAAA,IACxF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,qBAAqB,GAAG,IAAI;AAAA;AAAA,OAGrC,KAAI,CAAC,OAA2D;AAAA,IACpE,IAAK,MAAM,YAAY,MAAM,SAAS,WAAW,KAAM,MAAM,WAAW,WAAW,GAAG;AAAA,MACpF,OAAO;AAAA,QACL,MAAM,CAAC;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,UAAU;AAAA,MAClB,aAAa,KAAK,gBAAgB,SAAS;AAAA,MAC3C,OAAO,KAAK,MAAM,QAAQ;AAAA,IAC5B;AAAA,IAEA,IAAI,MAAM,WAAW;AAAA,MACnB,MAAM,gBAAe,MAAM,UAAU,IAAI,MAAM,IAAI,SAAS;AAAA,MAC5D,aAAa,KAAK,iBAAiB,cAAa,KAAK,IAAI,IAAI;AAAA,MAC7D,OAAO,KAAK,GAAG,MAAM,SAAS;AAAA,IAChC;AAAA,IAEA,IAAI,MAAM,eAAe;AAAA,MACvB,IAAI,MAAM,cAAc,WAAW,GAAG;AAAA,QACpC,aAAa,KAAK,oBAAoB,SAAS;AAAA,QAC/C,OAAO,KAAK,QAAQ;AAAA,MACtB,EAAO;AAAA,QACL,MAAM,mBAAmB;AAAA,QACzB,MAAM,gBAAe,MAAM,cAAc,IAAI,MAAM,IAAI,SAAS;AAAA,QAChE,aAAa,KACX,qBAAqB,0CAA0C,cAAa,KAAK,IAAI,KACvF;AAAA,QACA,OAAO,KAAK,UAAU,GAAG,MAAM,aAAa;AAAA;AAAA,IAEhD;AAAA,IAEA,IAAI,MAAM,cAAc;AAAA,MACtB,aAAa,KAAK,mBAAmB,SAAS;AAAA,MAC9C,OAAO,KAAK,QAAQ;AAAA,MACpB,aAAa,KAAK,qBAAqB,SAAS;AAAA,MAChD,OAAO,KAAK,MAAM,YAAY;AAAA,IAChC;AAAA,IAEA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,mBAAmB,SAAS;AAAA,MAC9C,OAAO,KAAK,QAAQ;AAAA,MACpB,aAAa,KAAK,iBAAiB,SAAS;AAAA,MAC5C,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IAEA,IAAI,MAAM,SAAS;AAAA,MACjB,aAAa,KAAK,mBAAmB,SAAS;AAAA,MAC9C,OAAO,KAAK,MAAM,QAAQ,IAAI;AAAA,MAC9B,IAAI,MAAM,QAAQ,SAAS,UAAU;AAAA,QACnC,aAAa,KAAK,qBAAqB,SAAS;AAAA,QAChD,OAAO,KAAK,MAAM,QAAQ,YAAY;AAAA,QACtC,aAAa,KAAK,iBAAiB,SAAS;AAAA,QAC5C,OAAO,KAAK,MAAM,QAAQ,SAAS;AAAA,MACrC;AAAA,IACF;AAAA,IAEA,IAAI,MAAM,UAAU;AAAA,MAClB,MAAM,gBAAe,MAAM,SAAS,IAAI,MAAM,IAAI,SAAS;AAAA,MAC3D,aAAa,KAAK,cAAc,cAAa,KAAK,IAAI,IAAI;AAAA,MAC1D,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IAEA,IAAI,MAAM,cAAc;AAAA,MACtB,aAAa,KAAK,uCAAuC,SAAS;AAAA,MAClE,OAAO,KAAK,MAAM,YAAY;AAAA,IAChC;AAAA,IAEA,IAAI,MAAM,eAAe;AAAA,MACvB,aAAa,KAAK,uCAAuC,SAAS;AAAA,MAClE,OAAO,KAAK,MAAM,aAAa;AAAA,IACjC;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,IAC9C,MAAM,SAAS,MAAM,UAAU;AAAA,IAE/B,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,qDAAqD,SACrD,MACF;AAAA,IAEA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,IAAI,QAAQ;AAAA;AAAA,QAER;AAAA,iDACyC,aAAa;AAAA;AAAA,IAG1D,IAAI,MAAM,UAAU,WAAW;AAAA,MAC7B,SAAS,WAAW,mBAAmB;AAAA,MACvC,YAAY,KAAK,MAAM,OAAO,MAAM;AAAA,IACtC,EAAO,SAAI,SAAS,GAAG;AAAA,MACrB,SAAS,YAAY;AAAA,MACrB,YAAY,KAAK,MAAM;AAAA,IACzB;AAAA,IAEA,MAAM,OAAO,MAAM,KAAK,IAAI,OAAsB,OAAO,WAAW;AAAA,IACpE,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IACzC,MAAM,OAAO,KAAK,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC;AAAA,IAExD,OAAO;AAAA,MACL;AAAA,MACA,SAAS,SAAS,KAAK,SAAS;AAAA,MAChC;AAAA,IACF;AAAA;AAAA,OAGY,kBAAiB,CAC7B,QACA,WACA,IACA,WACsB;AAAA,IACtB,OAAO,YAAY,MAAM;AAAA;AAAA,2BAEF,sBAAsB;AAAA;AAAA;AAAA,IAI7C,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,eAAe,wBAAwB,8BAA8B,aAAa;AAAA,IAC9F;AAAA,IAEA,IAAI,SAAS,WAAW,WAAW;AAAA,MACjC,MAAM,IAAI,eACR,wBAAwB,cAAc,0BAA0B,SAAS,UAC3E;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAEX;AAEA,SAAS,kBAAkB,CAAC,KAAgD;AAAA,EAC1E,OAAO,UAAU,IAAI,YAAY,IAAI,eAAe,IAAI,WAAW;AAAA;AAGrE,SAAS,SAAS,CAChB,MACA,SACA,OAC8B;AAAA,EAC9B,IAAI,CAAC,SAAS;AAAA,IACZ;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd;AAAA,IACA,OAAO,SAAS;AAAA,EAClB;AAAA;AAGF,SAAS,0BAA0B,CAAC,KAAwD;AAAA,EAC1F,IAAI,CAAC,IAAI,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,IAAI,yBACpB,IAAI,KAAK,IAAI,sBAAsB,IACnC,IAAI,KAAK,IAAI,SAAS;AAAA,EAE1B,IAAI,IAAI,qBAAqB,aAAa;AAAA,IACxC,OAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA,QAAS,IAAI,oBAAoB;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,OAAO,UACL,IAAI,sBACJ,IAAI,yBACJ,IAAI,qBACN;AAAA,EACF;AAAA;AAGF,SAAS,wBAAwB,CAAC,KAAsD;AAAA,EACtF,IAAI,CAAC,IAAI,gBAAgB;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,MAAM,cAAc,IAAI,uBACpB,IAAI,KAAK,IAAI,oBAAoB,IACjC,IAAI,KAAK,IAAI,SAAS;AAAA,EAE1B,IAAI,IAAI,mBAAmB,aAAa;AAAA,IACtC,OAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,OAAO,UAAU,IAAI,oBAAoB,IAAI,uBAAuB,IAAI,mBAAmB;AAAA,EAC7F;AAAA;AAGF,SAAS,iBAAiB,CACxB,OACA,aAC0B;AAAA,EAC1B,IAAI,MAAM,WAAW,aAAa;AAAA,IAChC,OAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ,MAAM;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AAAA;AAGF,SAAS,eAAe,CACtB,OACA,aACwB;AAAA,EACxB,IAAI,MAAM,WAAW,aAAa;AAAA,IAChC,OAAO;AAAA,MACL,QAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AAAA;AAGF,SAAS,oBAAoB,CAAC,KAAmC;AAAA,EAC/D,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,UAAU,IAAI;AAAA,IACd,SAAS,mBAAmB,GAAG;AAAA,IAC/B,QAAQ,IAAI;AAAA,IACZ,OAAO,IAAI,SAAS;AAAA,IACpB,UAAU,IAAI,KAAK,IAAI,SAAS;AAAA,IAChC,WAAW,IAAI,aAAa,IAAI,KAAK,IAAI,UAAU,IAAI;AAAA,IACvD,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,QAAQ,IAAI;AAAA,IACZ,gBAAgB,IAAI;AAAA,IACpB,WAAW,2BAA2B,GAAG;AAAA,IACzC,SAAS,yBAAyB,GAAG;AAAA,IACrC,OAAO,mBAAmB,GAAG;AAAA,EAC/B;AAAA;AAGF,SAAS,kBAAkB,CAAC,KAAiC;AAAA,EAC3D,IAAI,IAAI,iBAAiB,QAAQ;AAAA,IAC/B,OAAO,EAAE,MAAM,OAAO;AAAA,EACxB;AAAA,EAEA,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,YAAY;AAAA,IAC1C,MAAM,IAAI,eAAe,wBAAwB,IAAI,oCAAoC;AAAA,EAC3F;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,cAAc,IAAI;AAAA,IAClB,WAAW,IAAI;AAAA,EACjB;AAAA;;;ACjnBF;AAqEA,IAAM,+BAA+B;AACrC,IAAM,kCAAkC;AAGjC,SAAS,cAAc,CAAC,SAAqC;AAAA,EAElE,MAAM,aAAwD;AAAA,IAC5D,aAAa,QAAQ;AAAA,EACvB;AAAA,EACA,IAAI,QAAQ,2BAA2B,WAAW;AAAA,IAChD,WAAW,oBAAoB,QAAQ;AAAA,EACzC;AAAA,EACA,IAAI,QAAQ,0CAA0C,WAAW;AAAA,IAC/D,WAAW,sCAAsC,QAAQ;AAAA,EAC3D;AAAA,EAEA,MAAM,cACJ,QAAQ,sBAAsB,YAC1B,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,oBAAoB,IAAI,CAAC,IACxD;AAAA,EAEN,MAAM,iBACJ,QAAQ,yBAAyB,YAC7B,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,uBAAuB,IAAI,CAAC,IAC3D;AAAA,EAEN,MAAM,OAAO;AAAA,IACX,KAAK,QAAQ;AAAA,IAGb,cAAc;AAAA,IACd,iBAAiB;AAAA,IAIjB;AAAA,IAEA,UAAU,MAAM;AAAA,OACZ,QAAQ,YAAY,YAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,OAChE,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,EAC5C;AAAA,EAEA,IAAI,QAAQ,kBAAkB;AAAA,IAC5B,OAAO,SAAS,QAAQ,kBAAkB,IAAI;AAAA,EAChD;AAAA,EAEA,OAAO,SAAS;AAAA,OACX;AAAA,IACH,MAAM,QAAQ,QAAQ;AAAA,IACtB,MAAM,QAAQ,QAAQ;AAAA,OAClB,QAAQ,aAAa,YAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,OACnE,QAAQ,SAAS,YAAY,EAAE,UAAU,QAAQ,KAAK,IAAI,CAAC;AAAA,OAC3D,QAAQ,aAAa,YAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,EACzE,CAAC;AAAA;;;AC1HH;AAAA;AAAA;AA0FA,IAAM,oBAAoB;AAC1B,IAAM,eAA+B,EAAE,YAAY,MAAM;AAGzD,IAAM,2BAA2B;AAE1B,SAAS,oBAAoB,CAClC,WACA,OACA,UAAsC,CAAC,GAChB;AAAA,EACvB,MAAM,WAAW,2BAA2B,WAAW,OAAO;AAAA,IAC5D,YAAY,QAAQ,iBAAiB;AAAA,EACvC,CAAC;AAAA,EACD,OAAO;AAAA,OACF;AAAA,IACH,KAAK,mBAAmB,SAAS,GAAG;AAAA,IACpC,UAAU,mBAAmB,SAAS,QAAQ;AAAA,IAC9C,cAAc,SAAS,eACnB;AAAA,SACK,SAAS;AAAA,MACZ,KAAK,mBAAmB,SAAS,aAAa,GAAG;AAAA,IACnD,IACA;AAAA,EACN;AAAA;AAGK,SAAS,yBAAyB,CACvC,WACA,OACuB;AAAA,EACvB,MAAM,SAAS,uBAAuB,WAAW,KAAK;AAAA,EACtD,OAAO,oBAAoB;AAAA,IACzB,KAAK;AAAA;AAAA,cAEK,OAAO;AAAA;AAAA,IAEjB,MAAM,OAAO;AAAA,EACf,CAAC;AAAA;AAGI,SAAS,0BAA0B,CACxC,WACA,OACuB;AAAA,EACvB,MAAM,SAAS,uBAAuB,WAAW,KAAK;AAAA,EACtD,OAAO,oBAAoB;AAAA,IACzB,KAAK;AAAA;AAAA,cAEK,OAAO;AAAA;AAAA;AAAA,IAGjB,MAAM,OAAO;AAAA,EACf,CAAC;AAAA;AAGI,SAAS,yBAAyB,CACvC,WACA,OACA,YACA,OACsB;AAAA,EACtB,MAAM,SAAS,uBAAuB,WAAW,KAAK;AAAA,EACtD,OAAO,oBAAoB;AAAA,IACzB,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAMO,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOnB,MAAM,CAAC,YAAY,YAAY,GAAG,OAAO,MAAM,YAAY,KAAK;AAAA,EAClE,CAAC;AAAA;AAGH,SAAS,0BAA0B,CACjC,WACA,OACA,KACuB;AAAA,EACvB,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,aAAa,WAAW,KAAK;AAAA,SACjC;AAAA,MACH,OAAO,cAAc,WAAW,MAAM,OAAO,MAAM,SAAS;AAAA,SACzD;AAAA,MACH,OAAO,YAAY,WAAW,MAAM,OAAO,MAAM,QAAQ,GAAG;AAAA,SACzD;AAAA,MACH,OAAO,aAAa,WAAW,MAAM,OAAO,MAAM,OAAO,GAAG;AAAA,SACzD;AAAA,MACH,OAAO,YAAY,WAAW,MAAM,OAAO,MAAM,UAAU,MAAM,SAAS;AAAA,SACvE;AAAA,MACH,OAAO,iBACL,WACA,MAAM,OACN,MAAM,QACN,MAAM,WACN,MAAM,kBACR;AAAA,SACG;AAAA,MACH,OAAO,WAAW,WAAW,MAAM,IAAI,MAAM,MAAM;AAAA,SAChD;AAAA,MACH,OAAO,eAAe,WAAW,MAAM,OAAO,MAAM,YAAY,GAAG;AAAA,SAChE;AAAA,MACH,OAAO,YACL,WACA,MAAM,OACN,MAAM,OACN,MAAM,QACN,MAAM,kBACR;AAAA,SACG;AAAA,MACH,OAAO,cAAc,WAAW,MAAM,OAAO,MAAM,UAAU;AAAA,SAC1D;AAAA,MACH,MAAM,IAAI,MACR,mEAAmE,MAAM,OAC3E;AAAA;AAAA;AAIN,SAAS,YAAY,CACnB,WACA,OACuB;AAAA,EACvB,IAAI,MAAM,oBAAoB,MAAM;AAAA,IAClC,MAAM,IAAI,MAAM,2EAA2E;AAAA,EAC7F;AAAA,EAEA,MAAM,QAAQ,aAAa,oBAAoB,CAAC;AAAA,EAChD,MAAM,MAAM;AAAA;AAAA;AAAA;AAAA,eAIC,MAAM;AAAA;AAAA,EAGnB,OAAO;AAAA,IACL;AAAA,IACA,MAAM,CAAC,WAAW,MAAM,cAAc,GAAG,MAAM,IAAI;AAAA,IACnD,UACE;AAAA,IACF,WAAW,CAAC,WAAW,MAAM,YAAY;AAAA,IACzC;AAAA,IACA,SAAS,MAAM;AAAA,IACf,UAAU;AAAA,IACV,eAAe,MAAG;AAAA,MAAG;AAAA;AAAA,EACvB;AAAA;AAGF,SAAS,aAAa,CACpB,WACA,YACA,eACuB;AAAA,EACvB,OAAO,aAAa,WAAW,YAAY,iBAAiB,aAAa,CAAC;AAAA;AAG5E,SAAS,YAAY,CACnB,WACA,YACA,WACuB;AAAA,EACvB,MAAM,QAAQ,2BAA2B,WAAW,YAAY,YAAY;AAAA,EAC5E,MAAM,MAAM;AAAA;AAAA,YAEF,MAAM;AAAA,YACN,UAAU;AAAA,eACP,MAAM,MAAM;AAAA;AAAA,EAGzB,OAAO;AAAA,IACL;AAAA,IACA,MAAM,CAAC,GAAG,MAAM,MAAM,GAAG,UAAU,MAAM,GAAG,MAAM,MAAM,IAAI;AAAA,IAC5D,UAAU;AAAA;AAAA,cAEA,MAAM;AAAA,cACN,UAAU;AAAA;AAAA,IAEpB,WAAW,CAAC,GAAG,MAAM,MAAM,GAAG,UAAU,IAAI;AAAA,IAC5C,OAAO,MAAM;AAAA,IACb,SAAS,MAAM;AAAA,IACf,UAAU;AAAA,IACV,eAAe,MAAG;AAAA,MAAG;AAAA;AAAA,EACvB;AAAA;AAGF,SAAS,WAAW,CAClB,WACA,YACA,OACA,QACA,oBACuB;AAAA,EACvB,OAAO,aACL,WACA,YACA,2BAA2B,OAAO,QAAQ,kBAAkB,CAC9D;AAAA;AAGF,SAAS,WAAW,CAClB,WACA,YACA,QACA,KACuB;AAAA,EACvB,MAAM,QAAQ,2BAA2B,WAAW,YAAY,YAAY;AAAA,EAC5E,MAAM,aACJ,IAAI,cAAc,gBAAgB,UAAU,IACxC,2BAA2B,WAAW,YAAY,GAAG,IACrD;AAAA,EACN,MAAM,QAAQ,aAAa,gBAAgB,MAAM,CAAC;AAAA,EAElD,OAAO;AAAA,IACL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAWK,MAAM;AAAA,iBACH,MAAM;AAAA;AAAA,IAEnB,MAAM,CAAC,GAAG,MAAM,MAAM,GAAG,MAAM,IAAI;AAAA,IACnC,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB;AAAA,IACA,cAAc,aAAa,gBAAgB,UAAU,IAAI,MAAM;AAAA,IAC/D,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,eAAe,MAAM;AAAA,EACvB;AAAA;AAGF,SAAS,YAAY,CACnB,WACA,YACA,UACA,KACuB;AAAA,EACvB,MAAM,QAAQ,2BAA2B,WAAW,YAAY,YAAY;AAAA,EAC5E,MAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ;AAAA,EAClC,MAAM,WAAW,IAAI,aAAa,QAAQ,IAAI;AAAA,EAE9C,OAAO;AAAA,IACL,KAAK;AAAA;AAAA,cAEK,MAAM;AAAA,iBACH,MAAM,MAAM;AAAA;AAAA;AAAA,IAGzB,MAAM,CAAC,GAAG,MAAM,MAAM,GAAG,MAAM,MAAM,MAAM,QAAQ;AAAA,IACnD,UAAU;AAAA;AAAA,cAEA,MAAM;AAAA;AAAA,IAEhB,WAAW,MAAM;AAAA,IACjB,OAAO,MAAM;AAAA,IACb,SAAS,CAAC,UAAU,UAClB,UAAU,YAAY,IAAI,cAAc,WAAW,QAAQ,QAAQ;AAAA,IACrE,UAAU,IAAI,aAAa,CAAC,SAAS,KAAK,MAAM,GAAG,KAAK,IAAI;AAAA,IAC5D,eAAe,MAAG;AAAA,MAAG;AAAA;AAAA,EACvB;AAAA;AAGF,SAAS,WAAW,CAClB,WACA,YACA,aACA,WACuB;AAAA,EACvB,MAAM,QAAQ,2BAA2B,WAAW,YAAY,YAAY;AAAA,EAC5E,MAAM,WAAW,KAAK,IAAI,GAAG,WAAW;AAAA,EACxC,MAAM,SAAS,YAAY,gBAAgB,WAAW,MAAM,MAAM,MAAM,IAAI;AAAA,EAC5E,MAAM,kBAAkB,SACpB,uBAAuB,MAAM,MAAM,QAAQ,QAAQ,MAAM,MAAM,cAAc,IAC7E;AAAA,EACJ,MAAM,WAAW,kBAAkB,SAAS,gBAAgB,QAAQ;AAAA,EAEpE,OAAO;AAAA,IACL,KAAK;AAAA;AAAA,cAEK,MAAM;AAAA,QACZ;AAAA,iBACS,MAAM,MAAM;AAAA;AAAA;AAAA,IAGzB,MAAM,CAAC,GAAG,MAAM,MAAM,GAAI,iBAAiB,QAAQ,CAAC,GAAI,GAAG,MAAM,MAAM,MAAM,WAAW,CAAC;AAAA,IACzF,UAAU;AAAA;AAAA,cAEA,MAAM;AAAA;AAAA,IAEhB,WAAW,MAAM;AAAA,IACjB,OAAO,MAAM;AAAA,IACb,SAAS,CAAC,aAAa,WAAW;AAAA,IAClC,UAAU,CAAC,SAAS,KAAK,MAAM,GAAG,QAAQ;AAAA,IAC1C,eAAe,CAAC,MAAM,aAAa;AAAA,MACjC,IAAI,YAAY,YAAY,KAAK,WAAW;AAAA,QAAG;AAAA,MAC/C,OAAO,gBAAgB,KAAK,KAAK,SAAS,IAAI,MAAM,MAAM,MAAM;AAAA;AAAA,EAEpE;AAAA;AAGF,SAAS,gBAAgB,CACvB,WACA,YACA,QACA,WACA,oBACuB;AAAA,EACvB,MAAM,QAAQ,2BAA2B,WAAW,YAAY,YAAY;AAAA,EAC5E,MAAM,cAAc,cAAc,aAAa,kBAAkB;AAAA,EACjE,MAAM,UACJ,cAAc,aACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAWA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAKuB,uBAAuB,YAAY,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrE,MAAM,QAAQ,aAAa,oBAAoB,CAAC;AAAA,EAChD,MAAM,iBAAiB,aAAa,oBAAoB,GAAG,WAAW;AAAA,EACtE,MAAM,MAAM;AAAA,sBACQ,kBAAkB;AAAA,YAC5B,MAAM;AAAA,MACZ;AAAA,eACS,eAAe;AAAA;AAAA,EAE5B,MAAM,OAAO;AAAA,IACX,GAAG,MAAM;AAAA,IACT;AAAA,IACA,GAAI,uBAAuB,YAAY,CAAC,IAAI,CAAC,kBAAkB;AAAA,IAC/D,GAAG,eAAe;AAAA,EACpB;AAAA,EAEA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,0CAA0C;AAAA,IACpD,WAAW;AAAA,IACX;AAAA,IACA,SAAS,MAAM;AAAA,IACf,UAAU;AAAA,IACV,eAAe,MAAG;AAAA,MAAG;AAAA;AAAA,EACvB;AAAA;AAeF,SAAS,aAAa,CACpB,WACA,YACA,YACuB;AAAA,EACvB,MAAM,QAAQ,2BAA2B,WAAW,YAAY,YAAY;AAAA,EAC5E,MAAM,SAAS,wBACb,YACA,EAAE,SAAS,oBAAoB,MAAM,wBAAwB,IAAI,mBAAmB,GACpF,EACF;AAAA,EACA,MAAM,aAAa,aAAa,MAAM,MAAM,QAAQ,SAAS,0BAA0B;AAAA,EACvF,MAAM,MAAM;AAAA,sBACQ,OAAO;AAAA,YACjB,MAAM;AAAA,eACH,WAAW;AAAA;AAAA,EAGxB,OAAO;AAAA,IACL;AAAA,IACA,MAAM,CAAC,GAAG,OAAO,MAAM,GAAG,MAAM,MAAM,GAAG,WAAW,IAAI;AAAA,IACxD,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,OAAO,MAAM;AAAA,IACb,cAAc,MAAM;AAAA,IACpB,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,eAAe,MAAM;AAAA,EACvB;AAAA;AAMF,SAAS,uBAAuB,CAC9B,YACA,QACA,YACmB;AAAA,EACnB,MAAM,QAAkB,CAAC;AAAA,EACzB,MAAM,OAAkB,CAAC;AAAA,EACzB,WAAW,QAAQ,CAAC,WAAW,UAAU;AAAA,IACvC,MAAM,OAAO,eAAe,KAAK,GAAG,UAAU,GAAG,cAAc;AAAA,IAC/D,MAAM,QAAQ,sBAAsB,WAAW,QAAQ,IAAI;AAAA,IAC3D,MAAM,KAAK,WAAW,MAAM,GAAG;AAAA,IAC/B,KAAK,KAAK,UAAU,QAAQ,GAAG,MAAM,IAAI;AAAA,GAC1C;AAAA,EACD,OAAO,EAAE,KAAK,sBAAsB,MAAM,KAAK,IAAI,MAAM,KAAK;AAAA;AAShE,SAAS,qBAAqB,CAC5B,WACA,QACA,MACmB;AAAA,EACnB,MAAM,OAAO,QAAQ;AAAA,EACrB,MAAM,SAAS,OAAO;AAAA,EACtB,MAAM,SAAS,UAAU;AAAA,EACzB,MAAM,WAAW,UAAU,cAAc;AAAA,EAGzC,MAAM,eAAe,WAAW,GAAG,wBAAwB,GAAG;AAAA,EAC9D,MAAM,aAAa,WAAW,GAAG,mBAAmB,GAAG;AAAA,EACvD,MAAM,aAAa,WAAW,GAAG,wBAAwB,GAAG;AAAA,EAC5D,MAAM,WAAW,WAAW,GAAG,mBAAmB,GAAG;AAAA,EAErD,MAAM,QAAQ,0BAA0B,WAAW,MAAM,QAAQ,IAAI;AAAA,EACrE,MAAM,QAAQ,sBAAsB,WAAW,QAAQ,cAAc,UAAU;AAAA,EAE/E,MAAM,aAAa;AAAA,IACjB,GAAG,qBAAqB,OAAO;AAAA,IAC/B,GAAG,gBAAgB,OAAO;AAAA,IAC1B,GAAG,cAAc,OAAO;AAAA,IACxB,GAAG;AAAA,EACL;AAAA,EACA,MAAM,YAAuB,CAAC,UAAU,MAAM;AAAA,EAC9C,IAAI,YAAY,UAAU,uBAAuB,WAAW;AAAA,IAC1D,WAAW,KAAK,GAAG,+BAA+B;AAAA,IAClD,UAAU,KAAK,UAAU,kBAAkB;AAAA,EAC7C;AAAA,EAEA,MAAM,QAAQ;AAAA,aACH,MAAM,4CAA4C,MAAM;AAAA,oBACjD;AAAA,sBACE;AAAA,WACX,uBAAuB;AAAA,WACvB,2BAA2B;AAAA,WAC3B,uBAAuB;AAAA,YACtB,WAAW,KAAK,OAAO;AAAA;AAAA,EAEjC,MAAM,YAAY,CAAC,GAAG,MAAM,MAAM,GAAG,MAAM,MAAM,GAAG,SAAS;AAAA,EAE7D,IAAI,UAAU,gBAAgB,OAAO;AAAA,IACnC,OAAO;AAAA,MACL,KAAK,WAAW,qBAAqB,aAAa,gBAAgB;AAAA,MAClE,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAGA,MAAM,QAAQ,UAAU,SAAS;AAAA,EACjC,OAAO;AAAA,IACL,KAAK,8BAA8B,wBAAwB,sBAAsB,aAAa,gBAAgB;AAAA,IAC9G,MAAM,CAAC,GAAG,WAAW,KAAK;AAAA,EAC5B;AAAA;AAMF,SAAS,yBAAyB,CAChC,WACA,MACA,QACA,MACmB;AAAA,EACnB,MAAM,SAAS;AAAA,IACb,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,qBAAqB;AAAA,EACvB;AAAA,EACA,MAAM,OAAkB,CAAC;AAAA,EAEzB,IAAI,UAAU,UAAU,UAAU,OAAO,SAAS,GAAG;AAAA,IACnD,MAAM,SAAS,wBACb,UAAU,QACV;AAAA,MACE,SAAS,GAAG;AAAA,MACZ,MAAM,GAAG;AAAA,MACT,IAAI,GAAG;AAAA,IACT,GACA,IACF;AAAA,IACA,OAAO,KAAK,YAAY,OAAO,KAAK;AAAA,IACpC,KAAK,KAAK,GAAG,OAAO,IAAI;AAAA,EAC1B;AAAA,EAEA,OAAO,EAAE,KAAK,sBAAsB,OAAO,KAAK,IAAI,MAAM,KAAK;AAAA;AAMjE,SAAS,qBAAqB,CAC5B,WACA,QACA,cACA,YACmB;AAAA,EACnB,MAAM,iBAAiB,GAAG;AAAA,EAC1B,MAAM,UAAoB,CAAC;AAAA,EAC3B,MAAM,OAAkB,CAAC;AAAA,EAEzB,WAAW,SAAS,UAAU,WAAW,CAAC,GAAG;AAAA,IAE3C,IAAI,MAAM,SAAS;AAAA,MAAY;AAAA,IAC/B,MAAM,YAAY,MAAM,cAAc,SAAS,SAAS;AAAA,IACxD,QAAQ,KACN,aAAa,mBAAmB,cAAc,gBAAgB,mBAAmB,cAAc,oCAC/F,GACE,MAAM,eAAe,YACjB,IAAI,mBAAmB,cAAc,gBACrC,oBAAoB,cAAc,KACpC,WACN;AAAA,IACA,KAAK,KAAK,MAAM,YAAY,MAAM,YAAY,MAAM,UAAU;AAAA,EAChE;AAAA,EAEA,QAAQ,KAAK,GAAG,oBAAoB,GAAG,gBAAgB;AAAA,EACvD,OAAO,EAAE,KAAK,QAAQ,KAAK,IAAI,GAAG,KAAK;AAAA;AAGzC,SAAS,UAAU,CACjB,WACA,IACA,QACuB;AAAA,EACvB,IAAI,OAAO,WAAW,GAAG;AAAA,IACvB,MAAM,SAAQ,aAAa,oBAAoB,CAAC;AAAA,IAChD,OAAO;AAAA,MACL,KAAK;AAAA;AAAA;AAAA;AAAA,mBAIQ,OAAM;AAAA;AAAA,MAEnB,MAAM,OAAM;AAAA,MACZ,UAAU;AAAA,MACV,WAAW,CAAC;AAAA,MACZ;AAAA,MACA,SAAS,MAAM;AAAA,MACf,UAAU;AAAA,MACV,eAAe,MAAG;AAAA,QAAG;AAAA;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAAO,IAAI,CAAC,UACjC,2BAA2B,WAAW,OAAO,YAAY,CAC3D;AAAA,EACA,MAAM,aAAa,qBAAqB,IAAI,cAAc;AAAA,EAC1D,MAAM,QAAQ,aAAa,oBAAoB,CAAC;AAAA,EAChD,MAAM,gBAAgB,aAAa,oBAAoB,GAAG,UAAU;AAAA,EACpE,MAAM,MAAM;AAAA;AAAA,YAEF,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,eAKR,cAAc;AAAA;AAAA,EAG3B,OAAO;AAAA,IACL;AAAA,IACA,MAAM,CAAC,GAAG,WAAW,MAAM,WAAW,GAAG,cAAc,IAAI;AAAA,IAC3D,UAAU,0CAA0C,WAAW;AAAA,IAC/D,WAAW,WAAW;AAAA,IACtB;AAAA,IACA,SAAS,MAAM;AAAA,IACf,UAAU;AAAA,IACV,eAAe,MAAG;AAAA,MAAG;AAAA;AAAA,EACvB;AAAA;AAGF,SAAS,cAAc,CACrB,WACA,YACA,YACA,KACuB;AAAA,EACvB,MAAM,QAAQ,2BAA2B,WAAW,YAAY,GAAG;AAAA,EACnE,IAAI,CAAC;AAAA,IAAY,OAAO;AAAA,EAExB,MAAM,aAAa,4BAA4B,UAAU;AAAA,EACzD,MAAM,aAAa,aAAa,MAAM,MAAM,QAAQ,SAAS,0BAA0B;AAAA,EACvF,MAAM,cAAc,aAAa,MAAM,MAAM,QAAQ,WAAW,oBAAoB;AAAA,EAEpF,OAAO;AAAA,IACL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,UAKC,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAMP,MAAM;AAAA,iBACH,WAAW;AAAA;AAAA,IAExB,MAAM,CAAC,GAAG,WAAW,MAAM,GAAG,MAAM,MAAM,GAAG,WAAW,IAAI;AAAA,IAC5D,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,OAAO;AAAA,IACP,cAAc,MAAM;AAAA,IACpB,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,eAAe,MAAM;AAAA,EACvB;AAAA;AAGF,SAAS,sBAAsB,CAAC,WAAmB,OAA6C;AAAA,EAC9F,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,sBAAsB,WAAW,KAAK;AAAA,SAC1C;AAAA,MACH,OAAO,sBAAsB,WAAW,MAAM,OAAO,iBAAiB,MAAM,SAAS,CAAC;AAAA,SACnF,QAAQ;AAAA,MACX,OAAO,sBACL,WACA,MAAM,OACN,2BAA2B,MAAM,OAAO,MAAM,QAAQ,MAAM,kBAAkB,CAChF;AAAA,IACF;AAAA,SACK;AAAA,MACH,OAAO,0BACL,WACA,MAAM,OACN,MAAM,QACN,MAAM,WACN,MAAM,kBACR;AAAA,SACG;AAAA,MACH,OAAO,oBAAoB,WAAW,MAAM,IAAI,MAAM,MAAM;AAAA,SACzD;AAAA,SACA;AAAA,SAEA;AAAA,MACH,OAAO,uBAAuB,WAAW,MAAM,KAAK;AAAA,SACjD;AAAA,SACA;AAAA,MACH,OAAO,+BAA+B,WAAW,KAAK;AAAA,SACnD;AAAA,MACH,MAAM,IAAI,MAAM,yEAAyE;AAAA;AAAA;AAI/F,SAAS,qBAAqB,CAC5B,WACA,OACyB;AAAA,EACzB,IAAI,MAAM,oBAAoB,MAAM;AAAA,IAClC,MAAM,IAAI,MAAM,2EAA2E;AAAA,EAC7F;AAAA,EAEA,OAAO;AAAA,IACL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,IAKL,MAAM,CAAC,WAAW,MAAM,YAAY;AAAA,EACtC;AAAA;AAGF,SAAS,qBAAqB,CAC5B,WACA,YACA,WACyB;AAAA,EACzB,MAAM,QAAQ,uBAAuB,WAAW,UAAU;AAAA,EAC1D,OAAO;AAAA,IACL,KAAK;AAAA;AAAA,cAEK,MAAM;AAAA,cACN,UAAU;AAAA;AAAA,IAEpB,MAAM,CAAC,GAAG,MAAM,MAAM,GAAG,UAAU,IAAI;AAAA,EACzC;AAAA;AAGF,SAAS,yBAAyB,CAChC,WACA,YACA,QACA,WACA,oBACyB;AAAA,EACzB,MAAM,QAAQ,uBAAuB,WAAW,UAAU;AAAA,EAC1D,MAAM,cAAc,cAAc,aAAa,kBAAkB;AAAA,EACjE,MAAM,UACJ,cAAc,aACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAWA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAKuB,uBAAuB,YAAY,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOrE,OAAO;AAAA,IACL,KAAK;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,cACI,MAAM;AAAA,QACZ;AAAA;AAAA,IAEJ,MAAM;AAAA,MACJ,GAAG,MAAM;AAAA,MACT;AAAA,MACA,GAAI,uBAAuB,YAAY,CAAC,IAAI,CAAC,kBAAkB;AAAA,IACjE;AAAA,EACF;AAAA;AAGF,SAAS,mBAAmB,CAC1B,WACA,IACA,QACyB;AAAA,EACzB,IAAI,OAAO,WAAW,GAAG;AAAA,IACvB,OAAO;AAAA,MACL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,MAAM,CAAC;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,iBAAiB,OAAO,IAAI,CAAC,UAAU,uBAAuB,WAAW,KAAK,CAAC;AAAA,EACrF,MAAM,aAAa,qBAAqB,IAAI,cAAc;AAAA,EAC1D,OAAO;AAAA,IACL,KAAK;AAAA;AAAA,cAEK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMrB,MAAM,CAAC,GAAG,WAAW,MAAM,SAAS;AAAA,EACtC;AAAA;AAGF,SAAS,8BAA8B,CACrC,WACA,OACyB;AAAA,EACzB,MAAM,WAAW,2BAA2B,WAAW,OAAO,YAAY;AAAA,EAC1E,OAAO;AAAA,IACL,KAAK;AAAA;AAAA,cAEK,SAAS;AAAA;AAAA,IAEnB,MAAM,SAAS;AAAA,EACjB;AAAA;AAGF,SAAS,eAAe,CAAC,OAA6B;AAAA,EACpD,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,SACA;AAAA,MACH,OAAO,gBAAgB,MAAM,KAAK;AAAA;AAAA,MAElC,OAAO;AAAA;AAAA;AAIb,SAAS,eAAe,CAAC,UAAuD;AAAA,EAC9E,OACE,SAAS,gBAAgB;AAAA,IACvB,KAAK,SAAS;AAAA,IACd,MAAM,SAAS;AAAA,IACf,SAAS,CAAC,aAAa,SAAS,QAAQ,UAAU,SAAS;AAAA,EAC7D;AAAA;AAIJ,SAAS,oBAAoB,CAC3B,IACA,QACmB;AAAA,EACnB,MAAM,WAAW,OAAO,UAAU,UAAU,OAAO,cAAc,cAAc;AAAA,EAC/E,MAAM,eAAe,OAAO,IAC1B,CAAC,UAAU,2CAA2C,MAAM,eAC9D;AAAA,EAEA,OAAO;AAAA,IACL,KAAK,aAAa,KAAK,IAAI,WAAW;AAAA,IACtC,MAAM,OAAO,QAAQ,CAAC,UAAU,MAAM,IAAI;AAAA,EAC5C;AAAA;AAGF,SAAS,2BAA2B,CAAC,YAAkD;AAAA,EACrF,IAAI,WAAW,WAAW;AAAA,IAAG,OAAO,EAAE,KAAK,eAAe,MAAM,CAAC,EAAE;AAAA,EAEnE,OAAO;AAAA,IACL,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,oCAK2B,WAAW,IAAI,MAAM,SAAS,EAAE,KAAK,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,IAKzE,MAAM,CAAC,GAAG,UAAU;AAAA,EACtB;AAAA;AAGF,SAAS,gBAAgB,CAAC,WAAoD;AAAA,EAC5E,QAAQ,UAAU;AAAA,SACX;AAAA,SACA,MAAM;AAAA,MACT,MAAM,QAAQ,UAAU,MAAM,IAAI,gBAAgB;AAAA,MAClD,MAAM,SAAS,UAAU,OAAO,QAAQ,UAAU;AAAA,MAClD,OAAO;AAAA,QACL,KAAK,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,GAAG,EAAE,KAAK,MAAM;AAAA,QAClD,MAAM,MAAM,QAAQ,CAAC,SAAS,KAAK,IAAI;AAAA,MACzC;AAAA,IACF;AAAA,SACK,OAAO;AAAA,MACV,MAAM,OAAO,iBAAiB,UAAU,IAAI;AAAA,MAC5C,OAAO,gBAAgB,IAAI;AAAA,IAC7B;AAAA,SACK;AAAA,MACH,OAAO,UAAU,eAAe,YAC5B,gCAAgC,UAAU,YAAY,MAAM,UAAU,KAAK,IAC3E,yBAAyB,UAAU,YAAY,MAAM,UAAU,KAAK;AAAA,SACrE;AAAA,MACH,OAAO,UAAU,eAAe,YAC5B,gCAAgC,UAAU,YAAY,OAAO,UAAU,KAAK,IAC5E,yBAAyB,UAAU,YAAY,OAAO,UAAU,KAAK;AAAA,SACtE;AAAA,SACA;AAAA,SACA;AAAA,SACA,OAAO;AAAA,MACV,MAAM,KAAK,sBAAsB,UAAU,EAAE;AAAA,MAC7C,IAAI,UAAU,eAAe,WAAW;AAAA,QACtC,OAAO;AAAA,UACL,KAAK,IAAI,mBAAmB,qBAAqB,mBAAmB,eAAe;AAAA,UACnF,MAAM,CAAC,UAAU,YAAY,UAAU,YAAY,UAAU,KAAK;AAAA,QACpE;AAAA,MACF;AAAA,MACA,OAAO;AAAA,QACL,KAAK,GAAG,oBAAoB,KAAK;AAAA,QACjC,MAAM,CAAC,UAAU,YAAY,WAAW,UAAU,KAAK,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,SACK;AAAA,MACH,OAAO,UAAU,eAAe,YAC5B,0BAA0B,UAAU,YAAY,UAAU,MAAM,IAChE,mBAAmB,UAAU,YAAY,UAAU,MAAM;AAAA,SAC1D,UAAU;AAAA,MACb,MAAM,MAAM;AAAA,MACZ,MAAM,OAA0B,EAAE,KAAK,MAAM,CAAC,UAAU,UAAU,EAAE;AAAA,MACpE,OAAO,UAAU,QAAQ,OAAO,gBAAgB,IAAI;AAAA,IACtD;AAAA,SACK;AAAA,MACH,OAAO,yBAAyB,UAAU,YAAY,UAAU,KAAK;AAAA;AAAA;AAI3E,SAAS,+BAA+B,CACtC,YACA,IACA,OACmB;AAAA,EACnB,IAAI,UAAU,MAAM;AAAA,IAClB,MAAM,MAAM,GAAG,mBAAmB;AAAA,IAClC,MAAM,OAA0B,EAAE,KAAK,MAAM,CAAC,UAAU,EAAE;AAAA,IAC1D,OAAO,OAAO,OAAO,OAAO,gBAAgB,IAAI;AAAA,EAClD;AAAA,EAEA,IAAI,OAAO,MAAM;AAAA,IACf,OAAO;AAAA,MACL,KAAK,IAAI,mBAAmB,qBAAqB,mBAAmB;AAAA,MACpE,MAAM,CAAC,YAAY,YAAY,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,KAAK,IAAI,mBAAmB,gBAAgB,mBAAmB,iBAAiB,mBAAmB,qBAAqB,mBAAmB;AAAA,IAC3I,MAAM,CAAC,YAAY,YAAY,YAAY,YAAY,KAAK;AAAA,EAC9D;AAAA;AAGF,SAAS,yBAAyB,CAChC,YACA,QACmB;AAAA,EACnB,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO,EAAE,KAAK,SAAS,MAAM,CAAC,EAAE;AAAA,EACzD,MAAM,gBAAgB,OAAO,OAAO,CAAC,UAAU,UAAU,IAAI;AAAA,EAC7D,MAAM,UAAoB,CAAC;AAAA,EAC3B,MAAM,OAAkB,CAAC;AAAA,EAEzB,IAAI,cAAc,WAAW,OAAO,QAAQ;AAAA,IAC1C,QAAQ,KAAK,GAAG,mBAAmB,YAAY;AAAA,IAC/C,KAAK,KAAK,UAAU;AAAA,EACtB;AAAA,EAEA,IAAI,cAAc,SAAS,GAAG;AAAA,IAC5B,QAAQ,KACN,IAAI,mBAAmB,qBAAqB,mBAAmB,mBAAmB,cAC/E,IAAI,MAAM,YAAY,EACtB,KAAK,IAAI,KACd;AAAA,IACA,KAAK,KAAK,YAAY,YAAY,GAAG,aAAa;AAAA,EACpD;AAAA,EAEA,OAAO;AAAA,IACL,KAAK,IAAI,QAAQ,KAAK,MAAM;AAAA,IAC5B;AAAA,EACF;AAAA;AAGF,SAAS,eAAe,CAAC,WAAiD;AAAA,EACxE,OAAO;AAAA,IACL,KAAK,kBAAkB,UAAU;AAAA,IACjC,MAAM,UAAU;AAAA,EAClB;AAAA;AAGF,SAAS,wBAAwB,CAC/B,YACA,IACA,OACmB;AAAA,EACnB,IAAI,UAAU,MAAM;AAAA,IAClB,MAAM,MAAM,GAAG,mBAAmB;AAAA,IAClC,MAAM,OAA0B,EAAE,KAAK,MAAM,CAAC,UAAU,EAAE;AAAA,IAC1D,OAAO,OAAO,OAAO,OAAO,gBAAgB,IAAI;AAAA,EAClD;AAAA,EAEA,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,IAAI,OAAO,MAAM;AAAA,MACf,OAAO;AAAA,QACL,KAAK,IAAI,mBAAmB,oBAAoB,mBAAmB;AAAA,QACnE,MAAM,CAAC,YAAY,YAAY,KAAK;AAAA,MACtC;AAAA,IACF;AAAA,IAEA,OAAO;AAAA,MACL,KAAK,IAAI,mBAAmB,gBAAgB,mBAAmB,iBAAiB,mBAAmB,oBAAoB,mBAAmB;AAAA,MAC1I,MAAM,CAAC,YAAY,YAAY,YAAY,YAAY,KAAK;AAAA,IAC9D;AAAA,EACF;AAAA,EAEA,IAAI,OAAO,MAAM;AAAA,IACf,OAAO;AAAA,MACL,KAAK,GAAG,oBAAoB;AAAA,MAC5B,MAAM,CAAC,YAAY,WAAW,KAAK,CAAC;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,KAAK,IAAI,mBAAmB,gBAAgB,mBAAmB,iBAAiB,oBAAoB;AAAA,IACpG,MAAM,CAAC,YAAY,YAAY,YAAY,WAAW,KAAK,CAAC;AAAA,EAC9D;AAAA;AAGF,SAAS,kBAAkB,CAAC,YAAoB,QAA+C;AAAA,EAC7F,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO,EAAE,KAAK,SAAS,MAAM,CAAC,EAAE;AAAA,EAEzD,MAAM,gBAAgB,OAAO,OAAO,CAAC,UAAU,UAAU,IAAI;AAAA,EAC7D,MAAM,eAAe,cAAc,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ;AAAA,EAC/F,MAAM,cAAc,cAAc,OAAO,CAAC,UAAU,OAAO,UAAU,QAAQ;AAAA,EAC7E,MAAM,UAAoB,CAAC;AAAA,EAC3B,MAAM,OAAkB,CAAC;AAAA,EAEzB,IAAI,OAAO,WAAW,cAAc,QAAQ;AAAA,IAC1C,QAAQ,KAAK,GAAG,mBAAmB,YAAY;AAAA,IAC/C,KAAK,KAAK,UAAU;AAAA,EACtB;AAAA,EAEA,IAAI,aAAa,SAAS,GAAG;AAAA,IAC3B,QAAQ,KACN,IAAI,mBAAmB,oBAAoB,mBAAmB,SAAS,aACpE,IAAI,MAAM,SAAS,EACnB,KAAK,IAAI,KACd;AAAA,IACA,KAAK,KAAK,YAAY,YAAY,GAAG,YAAY;AAAA,EACnD;AAAA,EAEA,IAAI,YAAY,SAAS,GAAG;AAAA,IAC1B,QAAQ,KACN,GAAG,oBAAoB,SAAS,YAAY,IAAI,MAAM,gBAAgB,EAAE,KAAK,IAAI,IACnF;AAAA,IACA,KAAK,KAAK,YAAY,GAAG,YAAY,IAAI,UAAU,CAAC;AAAA,EACtD;AAAA,EAEA,OAAO;AAAA,IACL,KAAK,IAAI,QAAQ,KAAK,MAAM;AAAA,IAC5B;AAAA,EACF;AAAA;AAGF,SAAS,wBAAwB,CAAC,YAAoB,OAAmC;AAAA,EACvF,MAAM,UAAoB,CAAC;AAAA,EAC3B,MAAM,OAAkB,CAAC;AAAA,EAEzB,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,QAAQ,KACN,IAAI,mBAAmB,wCAAwC,mBAAmB,SACpF;AAAA,IACA,KAAK,KAAK,YAAY,OAAO,UAAU;AAAA,EACzC;AAAA,EAEA,QAAQ,KACN,IAAI,mBAAmB,mBAAmB,oBAAoB,yCAChE;AAAA,EACA,KAAK,KAAK,YAAY,YAAY,WAAW,KAAK,CAAC;AAAA,EAEnD,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,QAAQ,KACN,IAAI,mBAAmB,iCAAiC,oBAAoB,cAC9E;AAAA,IACA,KAAK,KAAK,YAAY,YAAY,KAAK;AAAA,EACzC;AAAA,EAEA,OAAO,EAAE,KAAK,IAAI,QAAQ,KAAK,MAAM,MAAM,KAAK;AAAA;AAGlD,SAAS,oBAAoB,CAAC,OAAe,QAA8C;AAAA,EACzF,MAAM,QAAQ,SAAS,KAAK;AAAA,EAC5B,IAAI,MAAM,WAAW;AAAA,IAAG,OAAO,EAAE,KAAK,SAAS,MAAM,CAAC,EAAE;AAAA,EAExD,MAAM,UAAU,MAAM,IAAI,MAAM;AAAA,IAC9B,MAAM,eAAe,OAAO,IAC1B,MAAM,sCAAsC,mBAAmB,cACjE;AAAA,IACA,OAAO,IAAI,aAAa,KAAK,MAAM;AAAA,GACpC;AAAA,EACD,MAAM,OAAO,MAAM,QAAQ,CAAC,SAAS,OAAO,QAAQ,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC;AAAA,EAE7E,OAAO,EAAE,KAAK,IAAI,QAAQ,KAAK,OAAO,MAAM,KAAK;AAAA;AAGnD,SAAS,0BAA0B,CACjC,OACA,QACA,oBACmB;AAAA,EACnB,MAAM,YACJ,UAAU,OAAO,SAAS,IACtB,qBAAqB,OAAO,MAAM,IAClC,2BAA2B,OAAO,kBAAkB;AAAA,EAE1D,IAAI,CAAC,WAAW;AAAA,IACd,MAAM,IAAI,MACR,kFACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,0BAA0B,CACjC,OACA,oBAC0B;AAAA,EAC1B,MAAM,mBAAwC,CAAC;AAAA,EAE/C,YAAY,cAAc,WAAW,OAAO,QAAQ,sBAAsB,CAAC,CAAC,GAAG;AAAA,IAC7E,IAAI,OAAO,WAAW;AAAA,MAAG;AAAA,IACzB,MAAM,YAAY,qBAAqB,OAAO,MAAM;AAAA,IACpD,iBAAiB,KAAK;AAAA,MACpB,KAAK,2BAA2B,UAAU;AAAA,MAC1C,MAAM,CAAC,cAAc,GAAG,UAAU,IAAI;AAAA,IACxC,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,iBAAiB,WAAW;AAAA,IAAG,OAAO;AAAA,EAE1C,OAAO;AAAA,IACL,KAAK,IAAI,iBAAiB,IAAI,CAAC,cAAc,UAAU,GAAG,EAAE,KAAK,MAAM;AAAA,IACvE,MAAM,iBAAiB,QAAQ,CAAC,cAAc,UAAU,IAAI;AAAA,EAC9D;AAAA;AAGF,SAAS,YAAY,CACnB,QACA,WACA,iBAAiB,cACF;AAAA,EACf,MAAM,UAAoB,CAAC;AAAA,EAC3B,MAAM,OAAkB,CAAC;AAAA,EAEzB,WAAW,SAAS,QAAQ;AAAA,IAC1B,IAAI,MAAM,SAAS,UAAU;AAAA,MAC3B,QAAQ,KAAK,GAAG,iBAAiB,MAAM,QAAQ,SAAS,KAAK,MAAM,UAAU,YAAY,GAAG;AAAA,MAC5F;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,MAAM,cAAc,SAAS,SAAS;AAAA,IACxD,QAAQ,KACN,aAAa,mBAAmB,cAAc,gBAAgB,mBAAmB,cAAc,oCAC/F,GAAG,gCAAgC,OAAO,cAAc,KAAK,WAC/D;AAAA,IACA,KAAK,KAAK,MAAM,YAAY,MAAM,YAAY,MAAM,UAAU;AAAA,EAChE;AAAA,EAEA,OAAO,EAAE,KAAK,QAAQ,KAAK,IAAI,GAAG,MAAM,QAAQ,eAAe;AAAA;AAGjE,SAAS,eAAe,CAAC,QAAwE;AAAA,EAC/F,MAAM,cAAoC,CAAC;AAAA,EAC3C,WAAW,SAAS,QAAQ;AAAA,IAC1B,IAAI,MAAM,SAAS,YAAY;AAAA,MAC7B,MAAM,IAAI,MAAM,uEAAuE;AAAA,IACzF;AAAA,IAEA,YAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN,YAAY,MAAM;AAAA,MAClB,WAAW,MAAM,cAAc,SAAS,SAAS;AAAA,MACjD,YAAY,MAAM;AAAA,IACpB,CAAC;AAAA,EACH;AAAA,EACA,YAAY,KAAK,GAAG,oBAAoB,CAAC;AAAA,EACzC,OAAO;AAAA;AAGT,SAAS,mBAAmB,GAAkC;AAAA,EAC5D,OAAO;AAAA,IACL,EAAE,MAAM,UAAU,QAAQ,kBAAkB,WAAW,MAAM;AAAA,IAC7D,EAAE,MAAM,UAAU,QAAQ,cAAc,WAAW,MAAM;AAAA,EAC3D;AAAA;AAGF,SAAS,sBAAsB,CAC7B,QACA,QACA,iBAAiB,cACE;AAAA,EACnB,MAAM,YAAiC,CAAC;AAAA,EAExC,SAAS,QAAQ,EAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AAAA,IACrD,MAAM,qBAAqB,OACxB,MAAM,GAAG,KAAK,EACd,IAAI,CAAC,OAAO,kBACX,qBAAqB,OAAO,OAAO,gBAAgB,cAAc,CACnE;AAAA,IACF,MAAM,mBAAmB,kBAAkB,OAAO,QAAQ,OAAO,QAAQ,cAAc;AAAA,IACvF,IAAI,CAAC;AAAA,MAAkB;AAAA,IAEvB,MAAM,QAAQ,CAAC,GAAG,oBAAoB,gBAAgB;AAAA,IACtD,UAAU,KAAK;AAAA,MACb,KAAK,IAAI,MAAM,IAAI,CAAC,SAAS,KAAK,GAAG,EAAE,KAAK,OAAO;AAAA,MACnD,MAAM,MAAM,QAAQ,CAAC,SAAS,KAAK,IAAI;AAAA,IACzC,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,UAAU,WAAW;AAAA,IAAG,OAAO,EAAE,KAAK,SAAS,MAAM,CAAC,EAAE;AAAA,EAE5D,OAAO;AAAA,IACL,KAAK,IAAI,UAAU,IAAI,CAAC,SAAS,KAAK,GAAG,EAAE,KAAK,MAAM;AAAA,IACtD,MAAM,UAAU,QAAQ,CAAC,SAAS,KAAK,IAAI;AAAA,EAC7C;AAAA;AAGF,SAAS,oBAAoB,CAC3B,OACA,QACA,iBAAiB,cACE;AAAA,EACnB,IAAI,MAAM,SAAS,UAAU;AAAA,IAC3B,OAAO;AAAA,MACL,KAAK,GAAG,iBAAiB,MAAM,MAAM;AAAA,MACrC,MAAM,CAAC,OAAO,KAAK;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,IAAI,OAAO,SAAS;AAAA,IAClB,OAAO;AAAA,MACL,KAAK,IAAI,mBAAmB,cAAc,gBAAgB,mBAAmB,cAAc;AAAA,MAC3F,MAAM,CAAC,MAAM,YAAY,MAAM,UAAU;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,KAAK,IAAI,mBAAmB,cAAc,qBAAqB,mBAAmB,cAAc,mBAAmB,gCAAgC,OAAO,cAAc,OAAO,MAAM,eAAe,YAAY,eAAe;AAAA,IAC/N,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,eAAe,YAAY,OAAO,QAAQ,WAAW,OAAO,KAAK;AAAA,IACzE;AAAA,EACF;AAAA;AAGF,SAAS,iBAAiB,CACxB,OACA,QACA,iBAAiB,cACS;AAAA,EAC1B,IAAI,MAAM,SAAS,UAAU;AAAA,IAC3B,OAAO;AAAA,MACL,KAAK,GAAG,iBAAiB,MAAM,MAAM,KAAK,MAAM,cAAc,SAAS,MAAM;AAAA,MAC7E,MAAM,CAAC,OAAO,KAAK;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,IAAI,OAAO;AAAA,IAAS,OAAO;AAAA,EAE3B,MAAM,UAAU,aAAa,mBAAmB,cAAc,gBAAgB,mBAAmB,cAAc;AAAA,EAC/G,MAAM,gBAAgB,MAAM,cAAc,SAAS,MAAM;AAAA,EAEzD,OAAO;AAAA,IACL,KAAK,IAAI,mBAAmB,mBAAmB,gCAAgC,OAAO,cAAc,KAAK,iBAAiB,MAAM,eAAe,YAAY,eAAe;AAAA,IAC1K,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,eAAe,YAAY,OAAO,QAAQ,WAAW,OAAO,KAAK;AAAA,IACzE;AAAA,EACF;AAAA;AAGF,SAAS,eAAe,CAAC,KAA2B,QAA+C;AAAA,EACjG,MAAM,aAAa,iBAAiB,IAAI,sBAAsB,IAAI,UAAU;AAAA,EAC5E,MAAM,QAA0B;AAAA,IAC9B,SAAS;AAAA,IACT,OAAO,OAAO,IAAI,aAAa;AAAA,IAC/B,QAAQ,OAAO,IAAI,CAAC,UAAU,oBAAoB,KAAK,YAAY,KAAK,CAAC;AAAA,EAC3E;AAAA,EACA,OAAO,GAAG,oBAAoB,OAAO,KAAK,KAAK,UAAU,KAAK,CAAC,EAAE,SAAS,WAAW;AAAA;AAGvF,SAAS,eAAe,CACtB,OACA,QAC+B;AAAA,EAC/B,IAAI,CAAC,MAAM,WAAW,iBAAiB,GAAG;AAAA,IACxC,sBAAsB,4CAA4C;AAAA,EACpE;AAAA,EAEA,MAAM,MAAM,MAAM,MAAM,kBAAkB,MAAM;AAAA,EAChD,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,UAAU,KAAK,MAAM,OAAO,KAAK,KAAK,WAAW,EAAE,SAAS,MAAM,CAAC;AAAA,IACnE,MAAM;AAAA,IACN,sBAAsB,4CAA4C;AAAA;AAAA,EAGpE,IAAI,CAAC,mBAAmB,OAAO,GAAG;AAAA,IAChC,sBAAsB,4CAA4C;AAAA,EACpE;AAAA,EAEA,MAAM,gBAAgB,OAAO,IAAI,aAAa;AAAA,EAC9C,IACE,QAAQ,MAAM,WAAW,cAAc,UACvC,QAAQ,MAAM,KAAK,CAAC,OAAO,UAAU,UAAU,cAAc,MAAM,GACnE;AAAA,IACA,sBAAsB,+DAA+D;AAAA,EACvF;AAAA,EAEA,OAAO,QAAQ;AAAA;AAGjB,SAAS,qBAAqB,CAAC,SAAwB;AAAA,EACrD,MAAM,IAAI,0BAA0B,sBAAsB,SAAS,aAAa;AAAA;AAGlF,SAAS,kBAAkB,CAAC,OAA2C;AAAA,EACrE,IAAI,CAAC,cAAc,KAAK;AAAA,IAAG,OAAO;AAAA,EAClC,IAAI,MAAM,YAAY;AAAA,IAAG,OAAO;AAAA,EAChC,IAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM,KAAK,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AAAA,IACvF,OAAO;AAAA,EACT;AAAA,EACA,IAAI,CAAC,MAAM,QAAQ,MAAM,MAAM;AAAA,IAAG,OAAO;AAAA,EACzC,OAAO,MAAM,OAAO,MAClB,CAAC,SACC,cAAc,IAAI,KAClB,OAAO,KAAK,YAAY,cACvB,KAAK,WAAW,OAAO,OAAO,MAAM,OAAO,EAChD;AAAA;AAGF,SAAS,mBAAmB,CAC1B,KACA,YACA,OACoB;AAAA,EACpB,MAAM,QACJ,MAAM,SAAS,WACX,MAAM,WAAW,mBACf,IAAI,iBACJ,IAAI,aACN,WAAW,MAAM;AAAA,EAEvB,OAAO,UAAU,QAAQ,UAAU,YAAY,EAAE,SAAS,KAAK,IAAI,EAAE,SAAS,OAAO,MAAM;AAAA;AAG7F,SAAS,aAAa,CAAC,OAAmC;AAAA,EACxD,OAAO,MAAM,SAAS,WAClB,UAAU,MAAM,UAAU,MAAM,cAChC,YAAY,MAAM,cAAc,MAAM,cAAc,UAAU,MAAM;AAAA;AAG1E,SAAS,+BAA+B,CACtC,OACA,iBAAiB,cACT;AAAA,EACR,OAAO,MAAM,eAAe,YACxB,IAAI,mBAAmB,cAAc,gBACrC,oBAAoB,cAAc;AAAA;AAGxC,SAAS,gBAAgB,CAAC,QAAyC,WAA4B;AAAA,EAC7F,OAAO,YAAY,GAAG,aAAa,WAAW;AAAA;AAGhD,SAAS,mBAAmB,CAAC,SAAS,cAAsB;AAAA,EAC1D,OAAO,GAAG;AAAA;AAGZ,SAAS,kBAAkB,CAAC,SAAS,cAAsB;AAAA,EACzD,OAAO,GAAG;AAAA;AAGZ,SAAS,kBAAkB,CAAC,SAAS,cAAsB;AAAA,EACzD,OAAO,gBAAgB,oBAAoB,MAAM;AAAA;AAGnD,SAAS,UAAU,CAAC,OAAwB;AAAA,EAC1C,IAAI,iBAAiB;AAAA,IAAM,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AAAA,EACpE,MAAM,OAAO,KAAK,UAAU,KAAK;AAAA,EACjC,OAAO,SAAS,YAAY,SAAS;AAAA;AAGvC,SAAS,QAAQ,CAAC,OAAyB;AAAA,EACzC,OAAO,MACJ,KAAK,EACL,YAAY,EACZ,MAAM,KAAK,EACX,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AAAA;AAGrC,SAAS,qBAAqB,CAAC,IAA0D;AAAA,EACvF,QAAQ;AAAA,SACD;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,MACH,OAAO;AAAA;AAAA;AAIb,SAAS,kBAAkB,CAAC,KAAqB;AAAA,EAC/C,IAAI,QAAQ;AAAA,EACZ,OAAO,IAAI,QAAQ,OAAO,MAAM,IAAI,EAAE,OAAO;AAAA;AAG/C,SAAS,mBAA+D,CAAC,UAAgB;AAAA,EACvF,OAAO;AAAA,OACF;AAAA,IACH,KAAK,mBAAmB,SAAS,GAAG;AAAA,EACtC;AAAA;AAGF,SAAS,gBAAgB,CAAC,OAAyC;AAAA,EACjE,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,MAAM,SAAS,KAAK,MAAM,KAAK;AAAA,IAC/B,OAAO,cAAc,MAAM,IAAI,SAAS,CAAC;AAAA,EAC3C;AAAA,EAEA,OAAO,cAAc,KAAK,IAAI,QAAQ,CAAC;AAAA;AAGzC,SAAS,YAAe,CAAC,MAAkC;AAAA,EACzD,OAAO;AAAA;AAGT,SAAS,aAAa,CAAC,OAAkD;AAAA,EACvE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;;;AC1+C5E,IAAM,+BAAwD;AAAA,EAC5D,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AAAA,EACf,cAAc;AAAA,EACd,OAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,UAAU;AAAA,IACV,KAAK;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;AAAA,EACA,cAAc;AAAA,IACZ,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,IAAI;AAAA,IACJ,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,qBAAqB;AAAA,IACnB,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,EACZ;AAAA,EACA,kBAAkB;AAAA,IAChB,QAAQ,EAAE,UAAU,MAAM,UAAU,KAAK;AAAA,IACzC,MAAM,EAAE,UAAU,MAAM,UAAU,KAAK;AAAA,IACvC,SAAS,EAAE,UAAU,KAAK;AAAA,IAC1B,SAAS,EAAE,UAAU,MAAM,UAAU,KAAK;AAAA,IAC1C,QAAQ,EAAE,UAAU,MAAM,UAAU,KAAK;AAAA,IACzC,SAAS,EAAE,UAAU,MAAM,UAAU,KAAK;AAAA,IAC1C,MAAM,EAAE,UAAU,MAAM,UAAU,KAAK;AAAA,IACvC,WAAW,EAAE,UAAU,MAAM,UAAU,KAAK;AAAA,EAC9C;AAAA,EACA,QAAQ;AAAA,IACN,YAAY;AAAA,IACZ,kBAAkB;AAAA,EACpB;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAQA,SAAS,UAAyB,CAChC,KACA,QACA,SACA,QACA,OACA,aACgB;AAAA,EAChB,MAAM,QAAQ;AAAA,EACd,MAAM,WAAW,QAAQ;AAAA,EAGzB,MAAM,OAAO,YAAY;AAAA,EACzB,MAAM,oBAAoB,OACvB,IAAI,CAAC,GAAG,MAAM;AAAA,IACb,MAAM,OAAO,QAAQ,IAAI,CAAC,IAAG,MAAM,IAAI,OAAO,IAAI,WAAW,IAAI,GAAG;AAAA,IACpE,OAAO,IAAI,KAAK,KAAK,GAAG;AAAA,GACzB,EACA,KAAK,GAAG;AAAA,EAEX,MAAM,WAAW,QACd,IAAI,CAAC,MAAM;AAAA,IAEV,MAAM,WAAW,OAAO,MAAM,qBAAqB,IAAI,MAAM,OAAO,MAAM,GAAG,EAAE,IAAI;AAAA,IACnF,OAAO,GAAG,YAAY,OAAO,SAAS;AAAA,GACvC,EACA,KAAK,OAAO;AAAA,EAEf,MAAM,QAAQ,GAAG,uBAAuB,yBAAyB,SAAS,QAAQ,KAAK,GAAG,SAAS,YAAY;AAAA,EAC/G,MAAM,SAAS,CAAC,GAAG,aAAa,GAAG,OAAO,KAAK,CAAC;AAAA,EAEhD,OAAO,IAAI,OAAO,OAAO,MAAwB;AAAA;AAAA;AAoB5C,MAAM,gBAAyC;AAAA,EACvB;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,EAE7B,iBAAiB,GAA4B;AAAA,IAC3C,OAAO;AAAA;AAAA,OAGH,aAAY,CAAC,QAAwD;AAAA,IACzE,MAAM,WAAW,qBAAqB,OAAO,WAAW,OAAO,OAAO;AAAA,MACpE,cAAc,OAAO;AAAA,IACvB,CAAC;AAAA,IACD,MAAM,QAAQ,OAAO,iBAAiB,QAAQ,YAAY,MAAM,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5F,MAAM,UAAU,MAAM,KAAK,IAAI,OAC7B,SAAS,KACT,SAAS,IACX;AAAA,IACA,MAAM,OAAO,SAAS,SAAS,OAAO;AAAA,IACtC,MAAM,UACJ,UAAU,aAAa,SAAS,eAC5B,SAAS,aAAa,SAElB,MAAM,KAAK,IAAI,OACb,SAAS,aAAa,KACtB,SAAS,aAAa,IACxB,GACA,MACJ,IACA,SAAS,QAAQ,QAAQ,QAAQ,KAAK;AAAA,IAE5C,OAAO;AAAA,MACL,SAAS,KAAK,IAAI,CAAC,QAAQ,iBAAiB,GAAG,CAAC;AAAA,MAChD;AAAA,MACA,eAAe,SAAS,cAAc,MAAM,QAAQ,MAAM;AAAA,SACtD,UAAU,YAAY,CAAC,IAAI,EAAE,MAAM;AAAA,IACzC;AAAA;AAAA,OAGI,aAAY,CAAC,QAAwD;AAAA,IACzE,MAAM,WAAW,0BAA0B,OAAO,WAAW,mBAAmB,OAAO,KAAK,CAAC;AAAA,IAC7F,OAAO,OAAO,MAAM,KAAK,IAAI,OAC3B,SAAS,KACT,SAAS,IACX;AAAA,IACA,OAAO,EAAE,OAAO,OAAO,KAAK,SAAS,CAAC,EAAE;AAAA;AAAA,OAGpC,cAAa,CAAC,QAA0D;AAAA,IAC5E,MAAM,WAAW,2BAA2B,OAAO,WAAW,mBAAmB,OAAO,KAAK,CAAC;AAAA,IAC9F,OAAO,OAAO,MAAM,KAAK,IAAI,OAAkB,SAAS,KAAK,SAAS,IAAsB;AAAA,IAC5F,OAAO,EAAE,QAAQ,QAAQ,UAAU;AAAA;AAAA,OAG/B,aAAY,CAAC,QAAwD;AAAA,IACzE,OAAO;AAAA,MACL,QAAQ,MAAM,QAAQ,IACpB,OAAO,OAAO,IAAI,OAAO,WAAW;AAAA,QAClC,YAAY,MAAM;AAAA,QAClB,SAAS,MAAM,iBACb,KAAK,KACL,0BACE,OAAO,WACP,mBAAmB,OAAO,KAAK,GAC/B,MAAM,YACN,MAAM,KACR,CACF;AAAA,MACF,EAAE,CACJ;AAAA,IACF;AAAA;AAAA,OAGI,eAAc,CAAC,QAIS;AAAA,IAC5B,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO;AAAA,+BACH,OAAO;AAAA,2BACX,OAAO;AAAA;AAAA,IAG9B,OAAO,MAAM,YAAY,GAAG,IAAI;AAAA;AAAA,OAG5B,UAAS,CAAC,QAMsB;AAAA,IACpC,MAAM,YAAY,OAAO,aAAa;AAAA,IACtC,MAAM,iBACJ,cAAc,aACV,2CACA,cAAc,SACZ,2FACA;AAAA,IACR,MAAM,QAAQ,iDAAiD,iBAC7D,OAAO,SAAS,sBAAsB;AAAA,IAExC,MAAM,OAAO,OAAO,SAChB,CAAC,OAAO,WAAW,OAAO,cAAc,OAAO,UAAU,OAAO,MAAM,IACtE,CAAC,OAAO,WAAW,OAAO,cAAc,OAAO,QAAQ;AAAA,IAC3D,MAAM,OAAO,MAAM,KAAK,IAAI,OAA0B,OAAO,IAAI;AAAA,IAEjE,OAAO,KAAK,IAAI,CAAC,QAAQ,UAAU,GAAG,CAAC;AAAA;AAAA,OAGnC,oBAAmB,CAAC,QAGU;AAAA,IAClC,MAAM,SAAS,IAAI;AAAA,IACnB,IAAI,OAAO,MAAM,WAAW;AAAA,MAAG,OAAO;AAAA,IACtC,MAAM,OAAO,MAAM,WACjB,KAAK,KACL,6BACA,CAAC,kBAAkB,YAAY,GAC/B,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,SAAS,CAAC,GACrD,2BACA,CAAC,OAAO,SAAS,CACnB;AAAA,IAEA,WAAW,OAAO,MAAM;AAAA,MACtB,OAAO,IAAI,GAAG,IAAI,kBAAkB,IAAI,cAAc,YAAY,GAAG,CAAC;AAAA,IACxE;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,eAAc,CAAC,QAGqB;AAAA,IACxC,MAAM,SAAS,IAAI;AAAA,IACnB,IAAI,OAAO,MAAM,WAAW;AAAA,MAAG,OAAO;AAAA,IACtC,MAAM,OAAO,MAAM,WACjB,KAAK,KACL,2BACA,CAAC,kBAAkB,aAAa,SAAS,GACzC,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,CAAC,GAC9D,2BACA,CAAC,OAAO,SAAS,CACnB;AAAA,IAEA,WAAW,OAAO,MAAM;AAAA,MACtB,MAAM,MAAM,GAAG,IAAI,kBAAkB,IAAI,aAAa,IAAI;AAAA,MAC1D,MAAM,WAAW,OAAO,IAAI,GAAG,KAAK,CAAC;AAAA,MACrC,SAAS,KAAK,UAAU,GAAG,CAAC;AAAA,MAC5B,OAAO,IAAI,KAAK,QAAQ;AAAA,IAC1B;AAAA,IACA,OAAO;AAAA;AAAA,OAGH,uBAAsB,CAAC,QAGS;AAAA,IACpC,IAAI,OAAO,MAAM,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IACvC,MAAM,SAAS,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,cAAc,KAAK,QAAQ,CAAC;AAAA,IAO5E,MAAM,aAAa,MAAM,WACvB,KAAK,KACL,2BACA,CAAC,kBAAkB,WAAW,GAC9B,QACA,2BACA,CAAC,OAAO,SAAS,CACnB;AAAA,IACA,MAAM,aAAa,MAAM,WACvB,KAAK,KACL,2BACA,CAAC,kBAAkB,WAAW,GAC9B,QACA,2BACA,CAAC,OAAO,SAAS,CACnB;AAAA,IAEA,MAAM,UAAU,IAAI;AAAA,IACpB,WAAW,OAAO,CAAC,GAAG,YAAY,GAAG,UAAU,GAAG;AAAA,MAChD,MAAM,OAAO,UAAU,GAAG;AAAA,MAC1B,QAAQ,IACN,GAAG,KAAK,gBAAgB,KAAK,YAAY,KAAK,UAAU,KAAK,gBAAgB,KAAK,YAClF,IACF;AAAA,IACF;AAAA,IACA,OAAO,CAAC,GAAG,QAAQ,OAAO,CAAC;AAAA;AAAA,OAGvB,oBAAmB,CAAC,QAK6C;AAAA,IACrE,8BAA8B,OAAO,KAAK;AAAA,IAC1C,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,2BAED,OAAO;AAAA,+BACH,OAAO;AAAA,UAC5B,OAAO,iBAAiB,KAAK,uBAAuB,OAAO,mBAAmB,KAAK;AAAA;AAAA,cAE/E,OAAO,QAAQ;AAAA;AAAA,IAEzB,MAAM,UAAU,KAAK,SAAS,OAAO;AAAA,IACrC,MAAM,UAAU,KAAK,MAAM,GAAG,OAAO,KAAK,EAAE,IAAI,CAAC,QAAQ,YAAY,GAAG,CAAC;AAAA,IACzE,MAAM,OAAO,QAAQ,GAAG,EAAE;AAAA,IAC1B,OAAO;AAAA,MACL;AAAA,SACI,WAAW,OAAO,EAAE,eAAe,KAAK,UAAU,IAAI,CAAC;AAAA,IAC7D;AAAA;AAAA,OAGI,KAAI,CAAC,QAaqE;AAAA,IAC9E,MAAM,cAAc,OAAO,UAAU;AAAA,IACrC,MAAM,QAAQ,OAAO,SAAS;AAAA,IAC9B,MAAM,UAAU,OAAO,WAAW;AAAA,IAClC,MAAM,QAAQ,OAAO,SAAS;AAAA,IAC9B,MAAM,cACJ,YAAY,cAAc,eAAe,YAAY,cAAc,eAAe;AAAA,IAGpF,MAAM,aACJ,OAAO,iBAAiB,YACpB,KAAK,QACL,OAAO,OAAO,iBAAiB,WAC7B,KAAK,2BAA2B,OAAO,iBACvC,KAAK,4BAA4B,KAAK,IAAI,OAAO,YAAwB;AAAA,IAEjF,MAAM,wBAAwB,OAAO,kBACjC,KAAK,0BAA0B,GAAG,OAAO,uBACzC,KAAK;AAAA,IAET,MAAM,wBAAwB,OAAO,kBACjC,KAAK,0BAA0B,IAAI,OAAO,sBAC1C,KAAK;AAAA,IAET,MAAM,qBAAqB,OAAO,eAC9B,KAAK,wBAAwB,OAAO,iBACpC,KAAK;AAAA,IAET,MAAM,sBAAsB,OAAO,gBAC/B,KAAK,wBAAwB,OAAO,kBACpC,KAAK;AAAA,IAET,MAAM,qBAAqB,OAAO,eAC9B,KAAK,wBAAwB,OAAO,iBACpC,KAAK;AAAA,IAET,MAAM,sBAAsB,OAAO,gBAC/B,KAAK,wBAAwB,OAAO,kBACpC,KAAK;AAAA,IAET,MAAM,UAAU,KAAK;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IAIJ,OAAO,eAAe,MAAM,KAAK;AAAA;AAAA,2BAEV,OAAO;AAAA,QAC1B;AAAA;AAAA,IAEJ,MAAM,QAAQ,YAAY;AAAA,IAE1B,IAAI,UAAU;AAAA,MAAG,OAAO,EAAE,SAAS,CAAC,GAAG,SAAS,cAAc,OAAO,MAAM;AAAA,IAI3E,MAAM,aAAa,QAAQ;AAAA,IAC3B,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,2BAED,OAAO;AAAA,QAC1B;AAAA,iBACS,KAAK,IAAI,WAAW,KAAK,UAAU,QAAQ,KAAK,WAAW,KAAK;AAAA,cACnE;AAAA,eACC;AAAA;AAAA,IAGX,MAAM,UAAU,KAAK,SAAS;AAAA,IAC9B,MAAM,UAAU,KAAK,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,QAAQ,YAAY,GAAG,CAAC;AAAA,IAElE,OAAO,EAAE,SAAS,SAAS,MAAM;AAAA;AAErC;AAEA,SAAS,6BAA6B,CAAC,OAAqB;AAAA,EAC1D,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,GAAG;AAAA,IAC9C,MAAM,IAAI,MAAM,mEAAmE;AAAA,EACrF;AAAA;AAGF,eAAe,SAAS,CAAC,KAAgB,UAAkD;AAAA,EACzF,OAAO,OAAO,MAAM,IAAI,OAItB,SAAS,UAAU,SAAS,SAA2B;AAAA,EACzD,OAAO,OAAO,KAAK,SAAS,CAAC;AAAA;AAG/B,eAAe,gBAAgB,CAC7B,KACA,UAC8C;AAAA,EAC9C,MAAM,OAAO,MAAM,IAAI,OAA2B,SAAS,KAAK;AAAA,IAC9D,GAAG,SAAS;AAAA,EACd,CAAmB;AAAA,EAEnB,OAAO,KAAK,IAAI,CAAC,SAAS;AAAA,IACxB,OAAO,aAAa,IAAI,YAAY,IAAI,UAAU;AAAA,IAClD,OAAO,OAAO,IAAI,KAAK;AAAA,EACzB,EAAE;AAAA;AAGJ,SAAS,YAAY,CAAC,WAA0B,WAAmC;AAAA,EACjF,QAAQ;AAAA,SACD;AAAA,MACH,OAAO,aAAa;AAAA,SACjB;AAAA,MACH,OAAO,cAAc,OAAO,OAAO,OAAO,SAAS;AAAA,SAChD;AAAA,MACH,OAAO,cAAc;AAAA,SAClB;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,SACA;AAAA,MACH,OAAO,cAAc,OAAO,OAAO,KAAK,MAAM,SAAS;AAAA;AAAA,MAEvD,OAAO;AAAA;AAAA;AAIb,SAAS,kBAAkB,CAAC,OAAiC;AAAA,EAC3D,QAAQ,MAAM;AAAA,SACP;AAAA,SACA;AAAA,SACA;AAAA,SACA;AAAA,MACH,OAAO,mBAAmB,MAAM,KAAK;AAAA;AAAA,MAErC,OAAO;AAAA;AAAA;AAIb,SAAS,WAAW,CAAC,KAAmC;AAAA,EACtD,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,cAAc,IAAI;AAAA,IAClB,WAAW,IAAI;AAAA,IACf,YAAY,IAAI;AAAA,IAChB,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,SAAS,IAAI;AAAA,IACb,cAAc,IAAI;AAAA,EACpB;AAAA;AAMF,SAAS,gBAAgB,CAAC,KAAwC;AAAA,EAChE,MAAM,OAAO,YAAY,GAAG;AAAA,EAC5B,MAAM,QAAQ,oBAAoB,IAAI,OAAO;AAAA,EAC7C,OAAO,QAAQ,KAAK,MAAM,MAAM,IAAI;AAAA;AAGtC,SAAS,mBAAmB,CAAC,OAA4C;AAAA,EACvE,IAAI,CAAC,cAAc,KAAK;AAAA,IAAG;AAAA,EAC3B,MAAM,QAAwB,CAAC;AAAA,EAC/B,YAAY,QAAQ,QAAQ,OAAO,QAAQ,KAAK,GAAG;AAAA,IACjD,MAAM,UAAU,wBAAwB,GAAG;AAAA,EAC7C;AAAA,EACA,OAAO;AAAA;AAKT,SAAS,uBAAuB,CAAC,OAAmC;AAAA,EAClE,IAAI,UAAU,QAAQ,UAAU;AAAA,IAAW,OAAO;AAAA,EAClD,IAAI,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO,MAAM,IAAI,iBAAiB;AAAA,EAC5D,OAAO,kBAAkB,KAAK;AAAA;AAMhC,SAAS,iBAAiB,CAAC,OAAmC;AAAA,EAC5D,MAAM,MAAM,cAAc,KAAK,IAAI,QAAQ,CAAC;AAAA,EAC5C,MAAM,WAA8B;AAAA,IAClC,WAAW,OAAO,IAAI,SAAS;AAAA,IAC/B,cAAc,OAAO,IAAI,YAAY;AAAA,IACrC,WAAW,OAAO,IAAI,SAAS;AAAA,IAC/B,YAAY,cAAc,IAAI,UAAU,IAAI,IAAI,aAAa,CAAC;AAAA,IAC9D,WAAW,IAAI,KAAK,IAAI,SAAmB;AAAA,IAC3C,WAAW,IAAI,KAAK,IAAI,SAAmB;AAAA,IAC3C,SAAS,OAAO,IAAI,OAAO;AAAA,IAC3B,cAAc,OAAO,IAAI,YAAY;AAAA,EACvC;AAAA,EACA,IAAI,cAAc,IAAI,cAAc,KAAK,OAAO,KAAK,IAAI,cAAc,EAAE,SAAS,GAAG;AAAA,IACnF,SAAS,iBAAiB,IAAI;AAAA,EAChC;AAAA,EACA,MAAM,QAAQ,oBAAoB,IAAI,KAAK;AAAA,EAC3C,IAAI;AAAA,IAAO,SAAS,QAAQ;AAAA,EAC5B,OAAO;AAAA;AAGT,SAAS,aAAa,CAAC,OAAkD;AAAA,EACvE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;AAG5E,SAAS,SAAS,CAAC,KAAqC;AAAA,EACtD,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,cAAc,IAAI;AAAA,IAClB,UAAU,IAAI;AAAA,IACd,QAAQ,IAAI;AAAA,IACZ,cAAc,IAAI;AAAA,IAClB,UAAU,IAAI;AAAA,IACd,YAAY,IAAI,aAAc,IAAI,aAAyC;AAAA,IAC3E,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,cAAc,IAAI;AAAA,EACpB;AAAA;;;ACvkBF;;;ACPA,eAAsB,wBAA8B,CAClD,OAO0B;AAAA,EAC1B,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,CAAC;AAAA,EAC5C,IAAI,SAAS,WAAW,GAAG;AAAA,IACzB,OAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,gBAAe,SAAS,IAAI,CAAC,GAAG,UAAU,IAAI,QAAQ,GAAG,EAAE,KAAK,IAAI;AAAA,EAC1E,MAAM,OAAO,MAAM,MAAM,IAAI,OAC3B;AAAA,4BACwB,MAAM,gBAAgB,MAAM,cAAc;AAAA,aACzD,MAAM;AAAA,kCACe,MAAM,mBAAmB;AAAA,iBAC1C,MAAM;AAAA,OAEnB,CAAC,MAAM,WAAW,GAAG,QAAQ,CAC/B;AAAA,EAEA,MAAM,kBAAkB,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,EAE/E,OAAO,SAAS,QAAQ,CAAC,YAAY;AAAA,IACnC,MAAM,MAAM,gBAAgB,IAAI,OAAO;AAAA,IACvC,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC;AAAA,GACvB;AAAA;;;ADhBI,MAAM,qBAAmD;AAAA,EACjC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,MAAK,CAAC,OAA0D;AAAA,IACpE,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAQnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN;AAAA,YACA,MAAM,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA,MAK7B,OAAO,uBAAuB,GAAG;AAAA,MACjC,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,iBACR,0BAA0B,MAAM,mCAAmC,MAAM,aAC3E;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,OAAM,CAAC,OAA2D;AAAA,IACtE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA,MAGzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,iBACR,0BAA0B,MAAM,8BAA8B,MAAM,aACtE;AAAA,MACF;AAAA,MAEA,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,IAAI,iBACR,0BAA0B,MAAM,oBAAoB,MAAM,iCAC5D;AAAA,MACF;AAAA,MAEA,OAAO,WACL,MAAM,WAAW,cACb,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,sCAClB,MAAM,QAAQ,aAAa;AAAA,sCAC3B,MAAM,QAAQ,aAAa;AAAA,+BAClC;AAAA,kCACG;AAAA,mCACC,MAAM,sBAAsB,MAAM;AAAA;AAAA,gBAGzD,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,sCAClB;AAAA,sCACA;AAAA,+BACP,MAAM,OAAO,QAAQ;AAAA,kCAClB,MAAM,OAAO,WAAW;AAAA,mCACvB,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAI/D,OAAO,uBAAuB,OAAO;AAAA,KACtC;AAAA;AAAA,OAGG,UAAS,CAAC,OAAkE;AAAA,IAChF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,eAAe,MAAM;AAAA;AAAA,6BAEL,MAAM,sBAAsB,MAAM;AAAA;AAAA,MAGzD,IAAI,CAAC,aAAa;AAAA,QAChB,MAAM,IAAI,iBACR,0BAA0B,MAAM,yCAAyC,MAAM,aACjF;AAAA,MACF;AAAA,MAEA,IAAI,YAAY,WAAW,WAAW;AAAA,QACpC,MAAM,IAAI,iBACR,0BAA0B,MAAM,+BAA+B,MAAM,iCACvE;AAAA,MACF;AAAA,MAEA,IAAI,YAAY,gBAAgB,MAAM,YAAY;AAAA,QAChD,MAAM,IAAI,iBACR,+BAA+B,MAAM,iBAAiB,MAAM,4CAA4C,MAAM,4BAA4B,YAAY,eACxJ;AAAA,MACF;AAAA,MAEA,IAAI;AAAA,QACF,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAad,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN;AAAA,cACA,MAAM,aAAa,IAAI;AAAA,cACvB,KAAK,UAAU,MAAM,MAAM;AAAA;AAAA;AAAA;AAAA,QAKjC,OAAO,2BAA2B,GAAG;AAAA,QACrC,OAAO,OAAO;AAAA,QACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,UAC5B,MAAM,IAAI,iBACR,+BAA+B,MAAM,mCAAmC,MAAM,aAChF;AAAA,QACF;AAAA,QAEA,MAAM;AAAA;AAAA,KAET;AAAA;AAAA,OAGG,WAAU,CAAC,OAAmE;AAAA,IAClF,iCAAiC,MAAM,aAAa,aAAa;AAAA,IAEjE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA,MAGzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,iBACR,+BAA+B,MAAM,8BAA8B,MAAM,aAC3E;AAAA,MACF;AAAA,MAEA,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,IAAI,iBACR,+BAA+B,MAAM,oBAAoB,MAAM,iCACjE;AAAA,MACF;AAAA,MAEA,IAAI,MAAM,WAAW,eAAe,MAAM,OAAO,cAAc,SAAS,YAAY;AAAA,QAClF,MAAM,IAAI,iBACR,+BAA+B,MAAM,uBAAuB,MAAM,OAAO,8BAA8B,SAAS,cAClH;AAAA,MACF;AAAA,MAEA,OAAO,WACL,MAAM,WAAW,cACb,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,sCAClB,MAAM,OAAO;AAAA,iCAClB,MAAM,eAAe,SAAS,gBAAgB;AAAA,+BAChD;AAAA,kCACG;AAAA,mCACC,MAAM,sBAAsB,MAAM;AAAA;AAAA,gBAGzD,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,sCAClB;AAAA,iCACL,MAAM,eAAe,SAAS,gBAAgB;AAAA,+BAChD,MAAM,OAAO,QAAQ;AAAA,kCAClB,MAAM,OAAO,WAAW;AAAA,mCACvB,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAI/D,OAAO,2BAA2B,OAAO;AAAA,KAC1C;AAAA;AAAA,OAGG,QAAO,CAAC,QAA8E;AAAA,IAC1F,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,uBAAuB,GAAG,IAAI;AAAA;AAAA,OAGvC,KAAI,CAAC,OAA+D;AAAA,IACxE,IAAI,iBAAiB,KAAK,KAAK,MAAM,aAAa,WAAW,GAAG;AAAA,MAC9D,OAAO;AAAA,QACL,MAAM,CAAC;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,YAAY;AAAA,MACpB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,UAAU;AAAA,IAC9B;AAAA,IAEA,IAAI,MAAM,aAAa;AAAA,MACrB,MAAM,gBAAe,MAAM,YAAY,IAAI,MAAM,IAAI,SAAS,EAAE,KAAK,IAAI;AAAA,MACzE,aAAa,KAAK,mBAAmB,gBAAe;AAAA,MACpD,OAAO,KAAK,GAAG,MAAM,WAAW;AAAA,IAClC;AAAA,IAEA,QAAQ,qBAAqB,cAAc,QAAQ,OAAO,KAAK;AAAA,IAE/D,QAAQ,MAAM,OAAO,YAAY,MAAM,aAAqC;AAAA,MAC1E,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IACD,MAAM,OAAO,KAAK,IAAI,sBAAsB;AAAA,IAE5C,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAAA,OAGI,wBAAuB,CAC3B,OACuC;AAAA,IACvC,MAAM,OAAO,MAAM,yBAAiD;AAAA,MAClE,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,YAAY,CAAC,QAAQ,IAAI;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO;AAAA,MACL,MAAM,KAAK,IAAI,sBAAsB;AAAA,IACvC;AAAA;AAAA,OAGI,UAAS,CAAC,OAAuE;AAAA,IACrF,IAAI,iBAAiB,KAAK,GAAG;AAAA,MAC3B,OAAO;AAAA,QACL,OAAO,CAAC;AAAA,QACR,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,eAAe;AAAA,MACvB,aAAa,KAAK,sBAAsB,SAAS;AAAA,MACjD,OAAO,KAAK,MAAM,aAAa;AAAA,IACjC;AAAA,IAEA,IAAI,MAAM,YAAY;AAAA,MACpB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,UAAU;AAAA,IAC9B;AAAA,IAEA,IAAI,MAAM,QAAQ;AAAA,MAChB,aAAa,KAAK,cAAc,SAAS;AAAA,MACzC,OAAO,KAAK,MAAM,MAAM;AAAA,IAC1B;AAAA,IAEA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,iBAAiB,SAAS;AAAA,MAC5C,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IAEA,QAAQ,qBAAqB,cAAc,QAAQ,OAAO,KAAK;AAAA,IAE/D,QAAQ,MAAM,OAAO,YAAY,MAAM,aAAyC;AAAA,MAC9E,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IACD,MAAM,QAAQ,KAAK,IAAI,0BAA0B;AAAA,IAEjD,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAEJ;AAEA,SAAS,UAAS,CAAC,KAGgB;AAAA,EACjC,IAAI,CAAC,IAAI,eAAe;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM,IAAI,cAAc;AAAA,IACxB,SAAS,IAAI;AAAA,EACf;AAAA;AAGF,SAAS,sBAAsB,CAAC,KAAgD;AAAA,EAC9E,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,YAAY,IAAI;AAAA,IAChB,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,QACE,IAAI,qBAAqB,IAAI,oBACzB;AAAA,MACE,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,IACjB,IACA;AAAA,IACN,OAAO,WAAU,GAAG;AAAA,EACtB;AAAA;AAGF,SAAS,0BAA0B,CAAC,KAAwD;AAAA,EAC1F,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,eAAe,IAAI;AAAA,IACnB,YAAY,IAAI;AAAA,IAChB,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI;AAAA,IACf,MAAM,IAAI;AAAA,IACV,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,QAAQ,wBAAwB,IAAI,MAAM;AAAA,IAC1C,QAAQ,IAAI,oBACR;AAAA,MACE,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,IACjB,IACA;AAAA,IACJ,aAAa,IAAI,gBAAgB,OAAO,OAAO,IAAI,YAAY,IAAI;AAAA,IACnE,OAAO,WAAU,GAAG;AAAA,EACtB;AAAA;AAGF,SAAS,uBAAuB,CAC9B,OAC8B;AAAA,EAC9B,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAAqC;AAAA;AAG3F,SAAS,gCAAgC,CAAC,OAA2B,WAAyB;AAAA,EAC5F,IAAI,UAAU,cAAc,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,IAAI;AAAA,IAClE,MAAM,IAAI,iBAAiB,yBAAyB,2CAA2C;AAAA,EACjG;AAAA;;;AExaF;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCA;AAKO,MAAM,uBAAuD;AAAA,EACrC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,eAAc,CAAC,OAAsE;AAAA,IACzF,8BAA8B,KAAK;AAAA,IAEnC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,iBAAiB,IAAI;AAAA,QACzB,qBAAqB,MAAM,WAAW,MAAM,EAAE;AAAA,QAC9C,sBACE,MAAM,WACN,MAAM,SAAS,eAAe,WAC9B,MAAM,SAAS,eAAe,SAChC;AAAA,MACF,CAAC;AAAA,MACD,OAAO,oBAAoB,MAAM;AAAA;AAAA,6BAEV,MAAM;AAAA,sBACb,MAAM;AAAA,6BACC,MAAM,SAAS,eAAe;AAAA,qCACtB,MAAM,SAAS,eAAe;AAAA;AAAA,8CAErB,MAAM,SAAS,eAAe;AAAA;AAAA;AAAA,MAGtE,IAAI,kBAAkB;AAAA,QACpB,MAAM,gCAAgC,MAAM,QAAQ;AAAA,MACtD;AAAA,MAEA,OAAO,eAAe,MAAM;AAAA;AAAA,6BAEL,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,MAAM,WAAW,cAAc,wBAAwB,WAAW,IAAI;AAAA,MACtE,MAAM,iBAAiB,0BAA0B,UAAU,cAAc;AAAA,MAEzE,IAAI,eAAe,UAAU;AAAA,QAC3B,QAAQ,YAAY,yBAAyB,UAAU,KAAK;AAAA,QAC5D,MAAM,yBAAyB,mCAAmC,QAAQ;AAAA,QAE1E,OAAO,WAAW,MAAM;AAAA;AAAA,0BAEN,8BAA8B;AAAA,+BACzB,MAAM;AAAA,uBACd,MAAM;AAAA,2BACF;AAAA,oCACS;AAAA;AAAA;AAAA,QAG5B,IAAI,CAAC;AAAA,UAAS,MAAM,4BAA4B,MAAM,EAAE;AAAA,QACxD,OAAO,mBAAmB,OAAO;AAAA,MACnC;AAAA,MAEA,OAAO,YAAY,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAyBnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM,SAAS;AAAA,YACf,MAAM,SAAS;AAAA,YACf,MAAM,SAAS,eAAe;AAAA,YAC9B,MAAM,SAAS,eAAe;AAAA,YAC9B,kBAAkB,MAAM,SAAS,MAAM,OAAO,eAAe;AAAA,YAC7D,wBAAwB,MAAM,SAAS,MAAM,OAAO,qBAAqB;AAAA,YACzE,wBAAwB,MAAM,SAAS,MAAM,OAAO,qBAAqB;AAAA,YACzE;AAAA,YACA,MAAM,aAAa,IAAI;AAAA,YACvB;AAAA,YACA;AAAA,YACA,MAAM,SAAS;AAAA,YACf,MAAM,SAAS,eAAe;AAAA,YAC9B,MAAM,SAAS;AAAA,YACf,MAAM,SAAS;AAAA,YACf,MAAM,SAAS;AAAA,YACf,MAAM,kBAAkB;AAAA,YACxB,MAAM,mBAAmB,YAAY,OAAO;AAAA,YAC5C,MAAM,mBAAmB,YAAY,OAAO;AAAA,YAC5C,MAAM,mBAAmB,YAAY,OAAO;AAAA;AAAA;AAAA;AAAA,MAKlD,OAAO,mBAAmB,QAAQ;AAAA,KACnC;AAAA;AAAA,OAGG,uBAAsB,CAC1B,OAC8B;AAAA,IAC9B,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,gCAAgC,IAAI,KAAK;AAAA,MAC3D,OAAO,yBAAyB,GAAG;AAAA,KACpC;AAAA;AAAA,OAGG,OAAM,CAAC,OAA+D;AAAA,IAC1E,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,cAAc,MAAM,gCAAgC,IAAI,KAAK;AAAA,MACnE,MAAM,WAAW,wBAAwB,WAAW;AAAA,MACpD,6CAA6C,UAAU,MAAM,QAAQ;AAAA,MACrE,MAAM,WAAW,2BAA2B,SAAS,UAAU,MAAM,QAAQ;AAAA,MAC7E,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,+BAGC,SAAS;AAAA,kCACN,SAAS;AAAA,6BACd,MAAM;AAAA,qBACd,MAAM;AAAA,yBACF;AAAA,kCACS,MAAM;AAAA;AAAA;AAAA,MAGlC,IAAI,CAAC;AAAA,QAAS,MAAM,4BAA4B,MAAM,EAAE;AAAA,MACxD,OAAO,yBAAyB,OAAO;AAAA,KACxC;AAAA;AAAA,OAGG,OAAM,CAAC,OAA+D;AAAA,IAC1E,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,cAAc,MAAM,gCAAgC,IAAI,KAAK;AAAA,MACnE,MAAM,WAAW,wBAAwB,WAAW;AAAA,MACpD,MAAM,OAAO,wBAAwB,UAAU,KAAK;AAAA,MACpD,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT,MAAM;AAAA,0BACD,KAAK;AAAA,8BACD;AAAA,+BACC,KAAK,SAAS;AAAA,kCACX,KAAK,SAAS;AAAA,8BAClB,KAAK,kBAAkB,YAAY;AAAA,4BACrC,KAAK,gBAAgB;AAAA,6BACpB,MAAM;AAAA,qBACd,MAAM;AAAA,yBACF;AAAA,kCACS,MAAM;AAAA;AAAA;AAAA,MAGlC,IAAI,CAAC;AAAA,QAAS,MAAM,4BAA4B,MAAM,EAAE;AAAA,MACxD,OAAO,yBAAyB,OAAO;AAAA,KACxC;AAAA;AAAA,OAGG,2BAA0B,CAC9B,OACuC;AAAA,IACvC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,cAAc,MAAM,gCAAgC,IAAI,KAAK;AAAA,MACnE,MAAM,UAAU,2BAA2B,wBAAwB,WAAW,GAAG,KAAK;AAAA,MACtF,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,iCAGG,QAAQ,WAAW;AAAA,8BACtB,QAAQ,WAAW;AAAA,8BACnB,QAAQ,WAAW;AAAA,+BAClB,QAAQ,SAAS;AAAA,kCACd,QAAQ,SAAS;AAAA,4CACP;AAAA,uCACL;AAAA,2CACI;AAAA,2CACA;AAAA,6BACd,MAAM;AAAA,qBACd,MAAM;AAAA,yBACF;AAAA,kCACS,MAAM;AAAA,qCACH,MAAM;AAAA,kCACT;AAAA;AAAA;AAAA,MAG5B,IAAI,CAAC;AAAA,QAAS,MAAM,4BAA4B,MAAM,EAAE;AAAA,MACxD,OAAO,kCAAkC,OAAO;AAAA,KACjD;AAAA;AAAA,OAGG,oBAAmB,CACvB,OACuC;AAAA,IACvC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,cAAc,MAAM,gCAAgC,IAAI,KAAK;AAAA,MACnE,MAAM,WAAW,8BAA8B,wBAAwB,WAAW,CAAC;AAAA,MACnF,MAAM,gBAAgB,8BAA8B,UAAU,MAAM,aAAa;AAAA,MACjF,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,4CAGc,cAAc;AAAA,uCACnB,cAAc;AAAA,2CACV,cAAc;AAAA,2CACd,cAAc;AAAA,6BAC5B,MAAM;AAAA,qBACd,MAAM;AAAA,yBACF;AAAA,kCACS,MAAM;AAAA,qCACH,cAAc;AAAA;AAAA;AAAA,MAG7C,IAAI,CAAC;AAAA,QAAS,MAAM,4BAA4B,MAAM,EAAE;AAAA,MACxD,OAAO,kCAAkC,OAAO;AAAA,KACjD;AAAA;AAAA,OAGG,QAAO,CAAC,QAAgF;AAAA,IAC5F,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,yBAAyB,GAAG,IAAI;AAAA;AAAA,OAGzC,KAAI,CAAC,OAAmE;AAAA,IAC5E,4BAA4B,MAAM,WAAW,WAAW;AAAA,IAExD,IAAI,MAAM,YAAY,MAAM,SAAS,WAAW,GAAG;AAAA,MACjD,OAAO,EAAE,MAAM,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IAC9C;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,cAAc;AAAA,MACtB,aAAa,KAAK,oBAAoB,SAAS;AAAA,MAC/C,OAAO,KAAK,MAAM,YAAY;AAAA,IAChC;AAAA,IACA,IAAI,MAAM,gBAAgB;AAAA,MACxB,aAAa,KAAK,sBAAsB,SAAS;AAAA,MACjD,OAAO,KAAK,MAAM,cAAc;AAAA,IAClC;AAAA,IACA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,iBAAiB,SAAS;AAAA,MAC5C,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IACA,IAAI,MAAM,kBAAkB;AAAA,MAC1B,aAAa,KAAK,yBAAyB,SAAS;AAAA,MACpD,OAAO,KAAK,MAAM,gBAAgB;AAAA,IACpC;AAAA,IAEA,IAAI,MAAM,eAAe;AAAA,MACvB,IAAI,MAAM,cAAc,WAAW,GAAG;AAAA,QACpC,OAAO,EAAE,MAAM,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,MAC9C;AAAA,MACA,MAAM,gBAAe,MAAM,cAAc,IAAI,MAAM,IAAI,SAAS;AAAA,MAChE,MAAM,OAAO,cAAa,KAAK,IAAI;AAAA,MACnC,MAAM,aAAa,MAAM,cAAc,IAAI,MAAM,IAAI,SAAS,EAAE,KAAK,IAAI;AAAA,MACzE,MAAM,aAAa,MAAM,cAAc,IAAI,MAAM,IAAI,SAAS,EAAE,KAAK,IAAI;AAAA,MACzE,aAAa,KACX,uBAAuB,UACrB,kCAAkC,gBAClC,kCAAkC,eACtC;AAAA,MACA,OAAO,KAAK,GAAG,MAAM,eAAe,GAAG,MAAM,eAAe,GAAG,MAAM,aAAa;AAAA,IACpF;AAAA,IAEA,IAAI,MAAM,UAAU;AAAA,MAClB,MAAM,gBAAe,MAAM,SAAS,IAAI,MAAM,IAAI,SAAS;AAAA,MAC3D,aAAa,KAAK,cAAc,cAAa,KAAK,IAAI,IAAI;AAAA,MAC1D,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IACA,IAAI,MAAM,cAAc;AAAA,MACtB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,YAAY;AAAA,IAChC;AAAA,IACA,IAAI,MAAM,eAAe;AAAA,MACvB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,aAAa;AAAA,IACjC;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,IAC9C,MAAM,SAAS,MAAM,UAAU;AAAA,IAC/B,8BAA8B,MAAM,OAAO,OAAO;AAAA,IAClD,8BAA8B,QAAQ,QAAQ;AAAA,IAE9C,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,yDAAyD,SACzD,MACF;AAAA,IAEA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,IAAI,QAAQ;AAAA;AAAA,QAER;AAAA,4BACoB,aAAa;AAAA;AAAA,IAErC,IAAI,MAAM,UAAU,WAAW;AAAA,MAC7B,SAAS,WAAW,mBAAmB;AAAA,MACvC,YAAY,KAAK,MAAM,OAAO,MAAM;AAAA,IACtC,EAAO,SAAI,SAAS,GAAG;AAAA,MACrB,SAAS,YAAY;AAAA,MACrB,YAAY,KAAK,MAAM;AAAA,IACzB;AAAA,IAEA,MAAM,OAAO,MAAM,KAAK,IAAI,OAAsB,OAAO,WAAW;AAAA,IACpE,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IACzC,MAAM,OAAO,KAAK,IAAI,wBAAwB;AAAA,IAC9C,OAAO,EAAE,MAAM,SAAS,SAAS,KAAK,SAAS,OAAO,MAAM;AAAA;AAAA,OAGxD,0BAAyB,CAC7B,OACyC;AAAA,IACzC,MAAM,OAAO,MAAM,yBAAsC;AAAA,MACvD,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,YAAY,CAAC,QAAQ,IAAI;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO,EAAE,MAAM,KAAK,IAAI,wBAAwB,EAAE;AAAA;AAEtD;AAEA,eAAe,+BAA+B,CAC5C,KACA,OACsB;AAAA,EACtB,MAAM,MAAM,MAAM,eAAe,KAAK,MAAM,WAAW,MAAM,EAAE;AAAA,EAC/D,6BAA6B,wBAAwB,GAAG,GAAG,KAAK;AAAA,EAChE,OAAO;AAAA;AAGT,eAAe,cAAc,CAAC,KAAgB,WAAmB,IAAkC;AAAA,EACjG,4BAA4B,WAAW,WAAW;AAAA,EAClD,4BAA4B,IAAI,IAAI;AAAA,EAEpC,OAAO,OAAO,MAAM;AAAA;AAAA,yBAEG,sBAAsB;AAAA;AAAA;AAAA,EAG7C,IAAI,CAAC;AAAA,IAAK,MAAM,sBAAsB,WAAW,EAAE;AAAA,EACnD,2BAA2B,wBAAwB,GAAG,CAAC;AAAA,EACvD,OAAO;AAAA;AAGT,SAAS,yBAAyB,CAAC,UAAsC;AAAA,EACvE,IAAI,QAAQ,WAAW;AAAA,EACvB,OAAO,UAAU;AAAA,IAAU,QAAQ,WAAW;AAAA,EAC9C,OAAO;AAAA;AAGT,SAAS,oBAAoB,CAAC,WAAmB,IAAoB;AAAA,EACnE,OAAO,kBAAkB,KAAK,UAAU,CAAC,WAAW,EAAE,CAAC;AAAA;AAGzD,SAAS,qBAAqB,CAAC,WAAmB,WAAmB,WAA2B;AAAA,EAC9F,OAAO,8BAA8B,KAAK,UAAU,CAAC,WAAW,WAAW,SAAS,CAAC;AAAA;AAGvF,SAAS,wBAAwB,CAAC,KAAuC;AAAA,EACvE,OAAO,0BAA0B,wBAAwB,GAAG,CAAC;AAAA;AAG/D,SAAS,kBAAkB,CAAC,KAAsC;AAAA,EAChE,OAAO,yBAAyB,wBAAwB,GAAG,CAAC;AAAA;AAG9D,SAAS,iCAAiC,CAAC,KAAgD;AAAA,EACzF,OAAO,8BAA8B,yBAAyB,GAAG,CAAC;AAAA;AAGpE,SAAS,uBAAuB,CAAC,KAA6C;AAAA,EAC5E,MAAM,YAA0C;AAAA,IAC9C,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,cAAc,IAAI;AAAA,IAClB,gBAAgB,IAAI;AAAA,IACpB,UAAU,IAAI,4BAA4B;AAAA,IAC1C,WAAW,IAAI;AAAA,IACf,kBAAkB,IAAI;AAAA,IACtB,yBAAyB,IAAI,8BAA8B;AAAA,IAC3D,kBAAkB,IAAI,qBAAqB;AAAA,IAC3C,oBAAoB,IAAI,uBAAuB;AAAA,IAC/C,eAAe,IAAI,kBAAkB;AAAA,IACrC,cAAc,IAAI,kBAAkB;AAAA,IACpC,oBAAoB,IAAI,yBAAyB;AAAA,IACjD,oBAAoB,IAAI,yBAAyB;AAAA,IACjD,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,SAAS,qBAAoB,IAAI,SAAS,SAAS;AAAA,IACnD,gBAAgB,IAAI,mBAAmB;AAAA,IACvC,gBAAgB,4BAA4B,IAAI,kBAAkB,gBAAgB;AAAA,IAClF,kBAAkB,4BAA4B,IAAI,oBAAoB,kBAAkB;AAAA,IACxF,eAAe,4BAA4B,IAAI,iBAAiB,eAAe;AAAA,IAC/E,gBAAgB,IAAI,mBAAmB;AAAA,IACvC,2BAA2B,IAAI,iCAAiC;AAAA,IAChE,uBAAuB,IAAI,4BAA4B;AAAA,IACvD,2BAA2B,4BACzB,IAAI,8BACJ,2BACF;AAAA,IACA,0BAA0B,IAAI,+BAC1B,IAAI,KAAK,IAAI,4BAA4B,IACzC;AAAA,IACJ,UAAU;AAAA,MACR,gBAAgB,qBAAoB,IAAI,kBAAkB,gBAAgB;AAAA,MAC1E,mBAAmB,qBAAoB,IAAI,qBAAqB,mBAAmB;AAAA,IACrF;AAAA,IACA,cAAc,IAAI,iBAAiB;AAAA,EACrC;AAAA,EACA,OAAO,qBAAqB,SAAS;AAAA;AAGvC,SAAS,2BAA2B,CAClC,OACA,WACoB;AAAA,EACpB,OAAO,UAAU,OAAO,YAAY,qBAAoB,OAAO,SAAS;AAAA;AAG1E,SAAS,oBAAmB,CAAC,OAA+B,WAA2B;AAAA,EACrF,MAAM,SAAS,OAAO,KAAK;AAAA,EAC3B,IAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,GAAG;AAAA,IAC/C,MAAM,IAAI,mBACR,qCAAqC,+CACvC;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;;AC5dF,MAAM,eAAuC;AAAA,EACrB;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,UAAS,CAAC,QAIoB;AAAA,IAClC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BASF,OAAO;AAAA,wBACV,OAAO;AAAA,6BACF,OAAO,QAAQ;AAAA,+BACb,OAAO,QAAQ;AAAA,2BACnB,OAAO,QAAQ;AAAA;AAAA,IAGtC,OAAO,MAAM,qBAAqB,GAAG,IAAI;AAAA;AAAA,OAGrC,eAAc,CAAC,QAMmB;AAAA,IACtC,IAAI,OAAO,MAAM,WAAW;AAAA,MAAG,OAAO,CAAC;AAAA,IACvC,MAAM,YAAY,KAAK,UACrB,OAAO,MAAM,IAAI,CAAC,UAAU;AAAA,MAC1B,SAAS,KAAK;AAAA,MACd,cAAc,KAAK,QAAQ;AAAA,MAC3B,gBAAgB,KAAK,QAAQ;AAAA,MAC7B,YAAY,KAAK,QAAQ;AAAA,IAC3B,EAAE,CACJ;AAAA,IACA,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA,kCAGM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAUE,OAAO;AAAA;AAAA,IAEvC,OAAO,KAAK,IAAI,oBAAoB;AAAA;AAAA,OAGhC,WAAU,CAAC,OAAuE;AAAA,IACtF,IAAI,MAAM,eAAe,WAAW,GAAG;AAAA,MACrC,OAAO,EAAE,QAAQ,CAAC,GAAG,SAAS,OAAO,OAAO,EAAE;AAAA,IAChD;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,QAAQ;AAAA,MAChB,aAAa,KAAK,cAAc,SAAS;AAAA,MACzC,OAAO,KAAK,MAAM,MAAM;AAAA,IAC1B;AAAA,IAEA,IAAI,MAAM,cAAc;AAAA,MACtB,aAAa,KAAK,qBAAqB,SAAS;AAAA,MAChD,OAAO,KAAK,MAAM,YAAY;AAAA,IAChC;AAAA,IAEA,IAAI,MAAM,eAAe;AAAA,MACvB,MAAM,gBAAe,MAAM,cAAc,IAAI,MAAM,IAAI,SAAS;AAAA,MAChE,aAAa,KAAK,sBAAsB,cAAa,KAAK,IAAI,IAAI;AAAA,MAClE,OAAO,KAAK,GAAG,MAAM,aAAa;AAAA,IACpC;AAAA,IAEA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,iBAAiB,SAAS;AAAA,MAC5C,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,IAC9C,MAAM,SAAS,MAAM,UAAU;AAAA,IAE/B,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,qDAAqD,SACrD,MACF;AAAA,IAEA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,IAAI,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QASR;AAAA,8BACsB,kBAAkB,yBAAyB,qBAAqB;AAAA;AAAA,IAG1F,IAAI,MAAM,UAAU,WAAW;AAAA,MAC7B,SAAS,WAAW,mBAAmB;AAAA,MACvC,YAAY,KAAK,MAAM,OAAO,MAAM;AAAA,IACtC,EAAO,SAAI,SAAS,GAAG;AAAA,MACrB,SAAS,YAAY;AAAA,MACrB,YAAY,KAAK,MAAM;AAAA,IACzB;AAAA,IAEA,MAAM,OAAO,MAAM,KAAK,IAAI,OAAuB,OAAO,WAAW;AAAA,IACrE,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IACzC,MAAM,SAAS,KAAK,IAAI,oBAAoB;AAAA,IAE5C,OAAO;AAAA,MACL;AAAA,MACA,SAAS,SAAS,OAAO,SAAS;AAAA,MAClC;AAAA,IACF;AAAA;AAAA,OAGI,uBAAsB,CAC1B,OACiD;AAAA,IACjD,oBAAoB,MAAM,KAAK;AAAA,IAC/B,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,MAAM,SAAS,MAAM,QAAQ,6DAA6D;AAAA,IAC1F,IAAI,MAAM,OAAO;AAAA,MACf,OAAO,KAAK,MAAM,MAAM,QAAQ,MAAM,MAAM,cAAc,MAAM,MAAM,SAAS;AAAA,IACjF;AAAA,IACA,OAAO,KAAK,MAAM,QAAQ,CAAC;AAAA,IAC3B,MAAM,iBAAiB,IAAI,OAAO;AAAA,IAClC,MAAM,OAAO,MAAM,KAAK,IAAI,OAC1B;AAAA;AAAA;AAAA,4DAGsD;AAAA;AAAA,gBAE5C;AAAA,SAEV,MACF;AAAA,IACA,OAAO,mBAAmB,MAAM,MAAM,KAAK;AAAA;AAAA,OAGvC,eAAc,CAAC,OAAgD;AAAA,IACnE,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UASL,MAAM;AAAA,UACN,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ,QAAQ;AAAA,UACtB,MAAM,QAAQ,QAAQ;AAAA,UACtB,MAAM,QAAQ,QAAQ;AAAA,UACtB,MAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAOhB,cAAa,CAAC,OAA+C;AAAA,IACjE,MAAM,KAAK;AAAA;AAAA,2BAEY,MAAM;AAAA,wBACT,MAAM,QAAQ;AAAA,6BACT,MAAM,QAAQ,QAAQ;AAAA,+BACpB,MAAM,QAAQ,QAAQ;AAAA,2BAC1B,MAAM,QAAQ,QAAQ;AAAA;AAAA;AAAA,OAIzC,iBAAgB,CAAC,QAA4D;AAAA,IACjF,IAAI,OAAO,WAAW;AAAA,MAAG;AAAA,IACzB,MAAM,OAAO,KAAK,UAAU,OAAO,IAAI,aAAa,CAAC;AAAA,IACrD,MAAM,KAAK;AAAA;AAAA;AAAA,kCAGmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BlC;AAEA,SAAS,aAAa,CAAC,OAAiC;AAAA,EACtD,OAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM,QAAQ;AAAA,IACvB,cAAc,MAAM,QAAQ,QAAQ;AAAA,IACpC,gBAAgB,MAAM,QAAQ,QAAQ;AAAA,IACtC,YAAY,MAAM,QAAQ,QAAQ;AAAA,IAClC,eACE,MAAM,SAAS,mBAAmB,MAAM,QAAQ,cAAc,MAAM,QAAQ;AAAA,EAChF;AAAA;AAGF,SAAS,kBAAkB,CACzB,MACA,OACwC;AAAA,EACxC,MAAM,UAAU,KAAK,SAAS;AAAA,EAC9B,MAAM,SAAS,KAAK,MAAM,GAAG,KAAK,EAAE,IAAI,oBAAoB;AAAA,EAC5D,MAAM,OAAO,OAAO,GAAG,EAAE;AAAA,EACzB,OAAO;AAAA,IACL;AAAA,OACI,WAAW,OACX;AAAA,MACE,MAAM;AAAA,QACJ,QAAQ,KAAK;AAAA,QACb,cAAc,KAAK,QAAQ;AAAA,QAC3B,WAAW,KAAK,QAAQ;AAAA,MAC1B;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAAA;AAGF,SAAS,mBAAmB,CAAC,OAAqB;AAAA,EAChD,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,GAAG;AAAA,IAC9C,MAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AAAA;AAYF,SAAS,oBAAoB,CAAC,KAAoC;AAAA,EAChE,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,QAAQ,IAAI;AAAA,IACZ,SAAS;AAAA,MACP,MAAM,IAAI;AAAA,MACV,cAAc,IAAI;AAAA,MAClB,WAAW,IAAI;AAAA,IACjB;AAAA,IACA,aAAa,aAAY,IAAI,YAAY;AAAA,EAC3C;AAAA;AAGF,SAAS,YAAW,CAAC,OAA8B;AAAA,EACjD,OAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI,IAAI,KAAK,KAAK,EAAE,YAAY;AAAA;;;ACtSnF;AAOO,MAAM,iBAA2C;AAAA,EACzB;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,MAAK,CAAC,OAAkD;AAAA,IAC5D,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAYnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN;AAAA,YACA,MAAM,aAAa,IAAI;AAAA,YACvB,MAAM,2BAA2B;AAAA,YACjC,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA,MAK7B,OAAO,mBAAmB,GAAG;AAAA,MAC7B,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,aACR,sBAAsB,MAAM,mCAAmC,MAAM,aACvE;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,OAAM,CAAC,OAAmD;AAAA,IAC9D,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA,MAGzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,aACR,sBAAsB,MAAM,8BAA8B,MAAM,aAClE;AAAA,MACF;AAAA,MAEA,IAAI,MAAM,WAAW,aAAa;AAAA,QAChC,IAAI,MAAM,UAAU,MAAM,OAAO,cAAc,SAAS,YAAY;AAAA,UAClE,MAAM,IAAI,aACR,sBAAsB,MAAM,uBAAuB,MAAM,OAAO,8BAA8B,SAAS,cACzG;AAAA,QACF;AAAA,QACA,IAAI,CAAC,MAAM,WAAW,SAAS,SAAS,YAAY,MAAM,aAAa,IAAI;AAAA,UACzE,MAAM,IAAI,aACR,sBAAsB,MAAM,mDAC9B;AAAA,QACF;AAAA,MACF;AAAA,MAEA,OAAO,WACL,MAAM,WAAW,cACb,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,8BAC1B,MAAM;AAAA,sCACE,MAAM,QAAQ,aAAa;AAAA,+BAClC;AAAA,kCACG;AAAA,+BACH,oBAAoB,MAAM,UAAU;AAAA,mCAChC,MAAM,sBAAsB,MAAM;AAAA;AAAA,gBAGzD,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,8BAC1B,MAAM,YAAY,SAAS,aAAa;AAAA,sCAChC;AAAA,+BACP,MAAM,OAAO,QAAQ;AAAA,kCAClB,MAAM,OAAO,WAAW;AAAA,+BAC3B;AAAA,mCACI,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAI/D,OAAO,mBAAmB,OAAO;AAAA,KAClC;AAAA;AAAA,OAGG,QAAO,CAAC,QAA0E;AAAA,IACtF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,mBAAmB,GAAG,IAAI;AAAA;AAAA,OAGnC,KAAI,CAAC,OAAuD;AAAA,IAChE,IAAI,iBAAiB,KAAK,KAAK,MAAM,SAAS,WAAW,GAAG;AAAA,MAC1D,OAAO;AAAA,QACL,MAAM,CAAC;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,QAAQ;AAAA,MAChB,aAAa,KAAK,cAAc,SAAS;AAAA,MACzC,OAAO,KAAK,MAAM,MAAM;AAAA,IAC1B;AAAA,IAEA,IAAI,MAAM,SAAS;AAAA,MACjB,MAAM,gBAAe,MAAM,QAAQ,IAAI,MAAM,IAAI,SAAS;AAAA,MAC1D,aAAa,KAAK,eAAe,cAAa,KAAK,IAAI,IAAI;AAAA,MAC3D,OAAO,KAAK,GAAG,MAAM,OAAO;AAAA,IAC9B;AAAA,IAEA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,iBAAiB,SAAS;AAAA,MAC5C,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IAEA,QAAQ,qBAAqB,cAAc,QAAQ,OAAO,KAAK;AAAA,IAE/D,QAAQ,MAAM,OAAO,YAAY,MAAM,aAA0B;AAAA,MAC/D,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IAED,OAAO;AAAA,MACL,MAAM,KAAK,IAAI,kBAAkB;AAAA,MACjC;AAAA,MACA;AAAA,IACF;AAAA;AAAA,OAGI,oBAAmB,CAAC,OAAmE;AAAA,IAC3F,MAAM,OAAO,MAAM,yBAAsC;AAAA,MACvD,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,YAAY,CAAC,QAAQ,IAAI;AAAA,MACzB,YAAY;AAAA,IACd,CAAC;AAAA,IAED,OAAO;AAAA,MACL,MAAM,KAAK,IAAI,kBAAkB;AAAA,IACnC;AAAA;AAEJ;AAEA,SAAS,mBAAmB,CAAC,YAAkD;AAAA,EAC7E,OAAO,eAAe,YAAY,KAAK,UAAU,UAAU,IAAI;AAAA;AAGjE,SAAS,gBAAgB,CAAC,KAA8C;AAAA,EACtE,IAAI,CAAC,IAAI,eAAe;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM,IAAI,cAAc;AAAA,IACxB,SAAS,IAAI;AAAA,EACf;AAAA;AAGF,SAAS,kBAAkB,CAAC,KAAiC;AAAA,EAC3D,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI;AAAA,IACf,MAAM,IAAI;AAAA,IACV,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,UAAU,IAAI,aAAa,OAAO,OAAO,IAAI,SAAS,IAAI;AAAA,IAC1D,QAAQ,IAAI,oBACR;AAAA,MACE,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,IACjB,IACA;AAAA,IACJ,yBAAyB,IAAI,8BAA8B;AAAA,IAC3D,eAAe,IAAI,kBAAkB;AAAA,IACrC,OAAO,iBAAiB,GAAG;AAAA,IAC3B,YAAY,cAAc,GAAG,IAAI,IAAI,aAAa;AAAA,EACpD;AAAA;AAGF,SAAS,aAAa,CAAC,KAA2B;AAAA,EAChD,OACE,IAAI,uBAAuB,QAC3B,IAAI,uBAAuB,KAC3B,IAAI,uBAAuB,OAC3B,IAAI,uBAAuB,OAC3B,IAAI,uBAAuB;AAAA;;;AChOxB,MAAM,oBAAiD;AAAA,EAC/B;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,WAAU,CAAC,QASuB;AAAA,IACtC,MAAM,QAAQ,OAAO,SAAS;AAAA,IAG9B,MAAM,aAAa,OAAO,OAAO,KAAK,gBAAgB,OAAO,SAAS,KAAK;AAAA,IAC3E,MAAM,WAAW,OAAO,KAAK,KAAK,gBAAgB,OAAO,OAAO,KAAK;AAAA,IACrE,MAAM,cAAc,OAAO,UAAU,YAAY,KAAK,YAAY,OAAO,UAAU,KAAK;AAAA,IAExF,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA,2BAED,OAAO;AAAA,+BACH,OAAO;AAAA,0BACZ,OAAO;AAAA,4BACL,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,oBACU,UAAU,QAAQ,KAAK,WAAW,KAAK;AAAA,QACnD;AAAA;AAAA,IAGJ,OAAO,KAAK,IAAI,CAAC,QAAQ,WAAW,GAAG,CAAC;AAAA;AAAA,OAGpC,gBAAe,CACnB,OACkD;AAAA,IAClD,IAAI,MAAM,OAAO,WAAW,GAAG;AAAA,MAC7B,OAAO,CAAC;AAAA,IACV;AAAA,IAEA,MAAM,QAAQ,MAAM,UAAU,SAAS,SAAS;AAAA,IAChD,MAAM,SAAoB,CAAC;AAAA,IAC3B,IAAI,YAAY;AAAA,IAChB,MAAM,SAAS,MAAM,OAClB,IAAI,CAAC,QAAQ,gBAAgB;AAAA,MAC5B,MAAM,gBAAe;AAAA,QACnB,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,MACA,OAAO,KAAK,aAAa,OAAO,cAAc,OAAO,UAAU,OAAO,UAAU;AAAA,MAChF,OAAO,IAAI,cAAa,KAAK,IAAI;AAAA,KAClC,EACA,KAAK,IAAI;AAAA,IAEZ,MAAM,uBAAuB,IAAI;AAAA,IACjC,OAAO,KAAK,MAAM,SAAS;AAAA,IAE3B,MAAM,eAAe,CAAC,OAAO;AAAA,IAC7B,IAAI,MAAM,MAAM;AAAA,MACd,aAAa,KAAK,qBAAqB,aAAa;AAAA,MACpD,OAAO,KAAK,MAAM,IAAI;AAAA,IACxB;AAAA,IACA,IAAI,MAAM,IAAI;AAAA,MACZ,aAAa,KAAK,qBAAqB,aAAa;AAAA,MACpD,OAAO,KAAK,MAAM,EAAE;AAAA,IACtB;AAAA,IAEA,IAAI,QAAQ;AAAA;AAAA,iBAEC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAQoB;AAAA;AAAA;AAAA;AAAA,uCAIE;AAAA;AAAA;AAAA;AAAA,gBAIvB,aAAa,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA,IAKrC,IAAI,MAAM,mBAAmB,WAAW;AAAA,MACtC,SAAS,gCAAgC;AAAA,MACzC,OAAO,KAAK,KAAK,IAAI,GAAG,MAAM,cAAc,CAAC;AAAA,IAC/C;AAAA,IAEA,SAAS,kCAAkC;AAAA,IAE3C,MAAM,OAAO,MAAM,KAAK,IAAI,OAK1B,OAAO,MAAwB;AAAA,IACjC,MAAM,UAAU,MAAM,OAAO,IAAI,CAAC,YAAY;AAAA,SACzC;AAAA,MACH,QAAQ,CAAC;AAAA,IACX,EAAE;AAAA,IAEF,WAAW,OAAO,MAAM;AAAA,MACtB,MAAM,SAAS,QAAQ,OAAO,IAAI,YAAY;AAAA,MAC9C,IAAI,QAAQ;AAAA,QACV,OAAO,OAAO,KAAK,WAAW,GAAG,CAAC;AAAA,MACpC;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAAA,OAGH,UAAS,CAAC,QAKoB;AAAA,IAClC,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO;AAAA,+BACH,OAAO;AAAA,0BACZ,OAAO;AAAA,4BACL,OAAO;AAAA;AAAA,IAG/B,OAAO,MAAM,WAAW,GAAG,IAAI;AAAA;AAEnC;AAEA,SAAS,UAAU,CAAC,KAA6C;AAAA,EAC/D,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,cAAc,IAAI;AAAA,IAClB,UAAU,IAAI;AAAA,IACd,YAAY,IAAI;AAAA,IAChB,OAAO,IAAI;AAAA,IACX,MAAM,IAAI,QAAQ;AAAA,IAClB,IAAI,IAAI,KAAK,IAAI,EAAE;AAAA,IACnB,cAAc,IAAI;AAAA,EACpB;AAAA;;;AC9JK,MAAM,yBAA2D;AAAA,EACzC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,MAAK,CACT,OACqC;AAAA,IACrC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAE9C,OAAO,YAAY,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YASnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN;AAAA,YACA,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,MAMZ,IAAI,UAAU;AAAA,QACZ,OAAO,6BAA6B,UAAU,SAAS;AAAA,MACzD;AAAA,MAEA,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM;AAAA,+BACJ,MAAM;AAAA,6BACR,MAAM;AAAA,kCACD,MAAM;AAAA;AAAA;AAAA,MAIlC,IAAI,UAAU,WAAW,aAAa;AAAA,QACpC,OAAO,6BAA6B,UAAU,WAAW;AAAA,MAC3D;AAAA,MAEA,IAAI,UAAU,WAAW,eAAe;AAAA,QACtC,OAAO,6BAA6B,UAAU,aAAa;AAAA,MAC7D;AAAA,MAEA,IAAI,UAAU,WAAW,UAAU;AAAA,QACjC,MAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AAAA,MAGA,OAAO,WAAW,MAAM;AAAA;AAAA,uBAEP;AAAA,4BACK,MAAM;AAAA,6BACL;AAAA,0BACH;AAAA,sBACJ;AAAA,6BACO,MAAM;AAAA,+BACJ,MAAM;AAAA,6BACR,MAAM;AAAA,kCACD,MAAM;AAAA;AAAA;AAAA,MAIlC,IAAI,CAAC,SAAS;AAAA,QACZ,MAAM,IAAI,MACR,yDAAyD,aAAa,KAAK,IAC7E;AAAA,MACF;AAAA,MAEA,OAAO,6BAA6B,SAAS,SAAS;AAAA,KACvD;AAAA;AAAA,OAGG,SAAQ,CACZ,OACgC;AAAA,IAChC,OAAO,WAAW,MAAM,KAAK;AAAA;AAAA,qBAEZ;AAAA,2BACM,MAAM;AAAA,wBACT;AAAA,oBACJ;AAAA,2BACO,MAAM;AAAA,6BACJ,MAAM;AAAA,2BACR,MAAM;AAAA,gCACD,MAAM;AAAA;AAAA;AAAA,IAIlC,IAAI,CAAC,SAAS;AAAA,MACZ,MAAM,IAAI,MACR,4DAA4D,aAAa,KAAK,IAChF;AAAA,IACF;AAAA,IAEA,OAAO,wBAAwB,OAAO;AAAA;AAAA,OAGlC,KAAI,CACR,OACgC;AAAA,IAChC,OAAO,WAAW,MAAM,KAAK;AAAA;AAAA,qBAEZ;AAAA,wBACG,MAAM;AAAA,oBACV,MAAM;AAAA,2BACC,MAAM;AAAA,6BACJ,MAAM;AAAA,2BACR,MAAM;AAAA,gCACD,MAAM;AAAA;AAAA;AAAA,IAIlC,IAAI,CAAC,SAAS;AAAA,MACZ,MAAM,IAAI,MACR,wDAAwD,aAAa,KAAK,IAC5E;AAAA,IACF;AAAA,IAEA,OAAO,wBAAwB,OAAO;AAAA;AAE1C;AAEA,SAAS,4BAA4B,CACnC,KACA,aAC4B;AAAA,EAC5B,OAAO;AAAA,OACF,wBAAwB,GAAG;AAAA,IAC9B;AAAA,EACF;AAAA;AAGF,SAAS,uBAAuB,CAAC,KAAgD;AAAA,EAC/E,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,aAAa,IAAI;AAAA,IACjB,WAAW,IAAI;AAAA,IACf,gBAAgB,IAAI;AAAA,IACpB,QAAQ,IAAI;AAAA,IACZ,YAAY,aAAY,IAAI,WAAW;AAAA,IACvC,aAAa,IAAI,eAAe,aAAY,IAAI,YAAY,IAAI;AAAA,IAChE,UAAU,IAAI,YAAY,aAAY,IAAI,SAAS,IAAI;AAAA,IACvD,OAAO,IAAI,SAAS;AAAA,EACtB;AAAA;AAGF,SAAS,YAAW,CAAC,OAA8B;AAAA,EACjD,OAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI,IAAI,KAAK,KAAK,EAAE,YAAY;AAAA;AAGnF,SAAS,YAAY,CAAC,KAAiC;AAAA,EACrD,OAAO,KAAK,UAAU,CAAC,IAAI,WAAW,IAAI,aAAa,IAAI,WAAW,IAAI,cAAc,CAAC;AAAA;;;AC9J3F;AAMO,MAAM,oBAAiD;AAAA,EAC/B;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,MAAK,CAAC,OAAwD;AAAA,IAClE,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAWnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN;AAAA,YACA,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA,MAK7B,OAAO,sBAAsB,GAAG;AAAA,MAChC,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,gBACR,yBAAyB,MAAM,mCAAmC,MAAM,aAC1E;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,OAAM,CAAC,OAAyD;AAAA,IACpE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,gBACR,yBAAyB,MAAM,8BAA8B,MAAM,aACrE;AAAA,MACF;AAAA,MAEA,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,IAAI,gBACR,yBAAyB,MAAM,oBAAoB,MAAM,iCAC3D;AAAA,MACF;AAAA,MAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT,MAAM;AAAA,0BACD,MAAM,cAAc,IAAI;AAAA,iCACjB,MAAM,oBAAoB;AAAA,8BAC7B,MAAM,kBAAkB;AAAA,8BACxB,MAAM,kBAAkB;AAAA,oCAClB,MAAM,uBAAuB;AAAA,oBAC7C,MAAM,WAAW,cAAc,OAAQ,MAAM,SAAS;AAAA,6BAC7C,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,sBAAsB,OAAO;AAAA,KACrC;AAAA;AAAA,OAGG,QAAO,CAAC,QAA6E;AAAA,IACzF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,sBAAsB,GAAG,IAAI;AAAA;AAAA,OAGtC,KAAI,CAAC,OAA6D;AAAA,IACtE,IAAI,iBAAiB,KAAK,GAAG;AAAA,MAC3B,OAAO;AAAA,QACL,MAAM,CAAC;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,aAAa;AAAA,MACrB,aAAa,KAAK,mBAAmB,SAAS;AAAA,MAC9C,OAAO,KAAK,MAAM,WAAW;AAAA,IAC/B;AAAA,IAEA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,iBAAiB,SAAS;AAAA,MAC5C,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IAEA,IAAI,MAAM,gBAAgB;AAAA,MACxB,aAAa,KAAK,sBAAsB,SAAS;AAAA,MACjD,OAAO,KAAK,MAAM,cAAc;AAAA,IAClC;AAAA,IAEA,QAAQ,qBAAqB,cAAc,QAAQ,OAAO,KAAK;AAAA,IAE/D,QAAQ,MAAM,OAAO,YAAY,MAAM,aAAoC;AAAA,MACzE,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IAED,OAAO;AAAA,MACL,MAAM,KAAK,IAAI,qBAAqB;AAAA,MACpC;AAAA,MACA;AAAA,IACF;AAAA;AAEJ;AAEA,SAAS,qBAAqB,CAAC,KAA8C;AAAA,EAC3E,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,aAAa,IAAI;AAAA,IACjB,WAAW,IAAI;AAAA,IACf,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA,IACZ,OAAO,IAAI;AAAA,IACX,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,kBAAkB,IAAI,sBAAsB,OAAO,OAAO,IAAI,kBAAkB,IAAI;AAAA,IACpF,gBAAgB,IAAI,mBAAmB,OAAO,OAAO,IAAI,eAAe,IAAI;AAAA,IAC5E,gBAAgB,IAAI,mBAAmB;AAAA,IACvC,qBAAqB,IAAI,yBAAyB;AAAA,IAClD,OAAO,IAAI,SAAS;AAAA,EACtB;AAAA;;;AC1JF;AAKO,MAAM,8BAAqE;AAAA,EACnD;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAA6E;AAAA,IACxF,yBAAyB,MAAM,WAAW,WAAW;AAAA,IAErD,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAiBnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN,gBAAgB,MAAM,KAAK;AAAA,YAC3B,gBAAgB,MAAM,eAAe;AAAA,YACrC;AAAA,YACA,MAAM,eAAe,IAAI;AAAA,YACzB,MAAM,aAAa;AAAA;AAAA;AAAA;AAAA,MAKzB,OAAO,gCAAgC,GAAG;AAAA,MAC1C,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,0BACR,mCAAmC,MAAM,mCAAmC,MAAM,aACpF;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,OAAM,CAAC,OAA6E;AAAA,IACxF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,2BAA2B,IAAI,MAAM,WAAW,MAAM,EAAE;AAAA,MAE9D,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT;AAAA,2BACM,MAAM,eAAe,IAAI;AAAA,2BACzB,eAAe,MAAM,WAAW;AAAA,uBACpC,gBAAgB,MAAM,QAAQ;AAAA,6BACxB,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,OAAM,CAAC,OAA6E;AAAA,IACxF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,2BAA2B,IAAI,MAAM,WAAW,MAAM,EAAE;AAAA,MAE9D,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT;AAAA,2BACM,MAAM,eAAe,IAAI;AAAA,2BACzB,eAAe,MAAM,WAAW;AAAA,6BAC9B,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,OAAM,CAAC,OAA6E;AAAA,IACxF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,2BAA2B,IAAI,MAAM,WAAW,MAAM,EAAE;AAAA,MAE9D,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT;AAAA,yBACI,MAAM,aAAa,IAAI;AAAA,6BACnB,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,QAAO,CAAC,QAGiC;AAAA,IAC7C,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,gCAAgC,GAAG,IAAI;AAAA;AAAA,OAGhD,KAAI,CAAC,OAAiF;AAAA,IAC1F,IAAK,MAAM,YAAY,MAAM,SAAS,WAAW,KAAM,MAAM,aAAa,WAAW,GAAG;AAAA,MACtF,OAAO;AAAA,QACL,eAAe,CAAC;AAAA,QAChB,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,UAAU;AAAA,MAClB,MAAM,gBAAe,MAAM,SAAS,IAAI,MAAM,IAAI,SAAS;AAAA,MAC3D,aAAa,KAAK,cAAc,cAAa,KAAK,IAAI,IAAI;AAAA,MAC1D,OAAO,KAAK,GAAG,MAAM,QAAQ;AAAA,IAC/B;AAAA,IAEA,IAAI,MAAM,YAAY;AAAA,MACpB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,UAAU;AAAA,IAC9B;AAAA,IAEA,IAAI,MAAM,aAAa;AAAA,MACrB,MAAM,gBAAe,MAAM,YAAY,IAAI,MAAM,IAAI,SAAS;AAAA,MAC9D,aAAa,KAAK,mBAAmB,cAAa,KAAK,IAAI,IAAI;AAAA,MAC/D,OAAO,KAAK,GAAG,MAAM,WAAW;AAAA,IAClC;AAAA,IAEA,IAAI,MAAM,eAAe;AAAA,MACvB,aAAa,KAAK,sBAAsB,SAAS;AAAA,MACjD,OAAO,KAAK,MAAM,aAAa;AAAA,IACjC;AAAA,IAEA,IAAI,MAAM,WAAW;AAAA,MACnB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,SAAS;AAAA,IAC7B;AAAA,IAEA,IAAI,MAAM,QAAQ;AAAA,MAChB,aAAa,KAAK,cAAc,SAAS;AAAA,MACzC,OAAO,KAAK,MAAM,MAAM;AAAA,IAC1B;AAAA,IAEA,IAAI,MAAM,SAAS;AAAA,MACjB,aAAa,KAAK,eAAe,SAAS;AAAA,MAC1C,OAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,IAEA,IAAI,MAAM,gBAAgB;AAAA,MACxB,aAAa,KAAK,sBAAsB,SAAS;AAAA,MACjD,OAAO,KAAK,MAAM,cAAc;AAAA,IAClC;AAAA,IAEA,IAAI,MAAM,gBAAgB;AAAA,MACxB,aAAa,KAAK,oBAAoB,SAAS;AAAA,MAC/C,OAAO,KAAK,MAAM,cAAc;AAAA,IAClC;AAAA,IAEA,IAAI,MAAM,iBAAiB;AAAA,MACzB,aAAa,KAAK,oBAAoB,SAAS;AAAA,MAC/C,OAAO,KAAK,MAAM,eAAe;AAAA,IACnC;AAAA,IAEA,MAAM,QAAQ,SAAS,aAAa,KAAK,OAAO;AAAA,IAChD,MAAM,QAAQ,MAAM,UAAU,QAAQ,QAAQ;AAAA,IAC9C,MAAM,SAAS,MAAM,UAAU;AAAA,IAC/B,OAAO,YAAY,MAAM,KAAK,IAAI,OAChC,gEAAgE,SAChE,MACF;AAAA,IAEA,MAAM,cAAc,CAAC,GAAG,MAAM;AAAA,IAC9B,IAAI,QAAQ;AAAA;AAAA,QAER;AAAA,8BACsB,aAAa;AAAA;AAAA,IAGvC,IAAI,MAAM,UAAU,WAAW;AAAA,MAC7B,SAAS,WAAW,mBAAmB;AAAA,MACvC,YAAY,KAAK,MAAM,OAAO,MAAM;AAAA,IACtC,EAAO,SAAI,SAAS,GAAG;AAAA,MACrB,SAAS,YAAY;AAAA,MACrB,YAAY,KAAK,MAAM;AAAA,IACzB;AAAA,IAEA,MAAM,OAAO,MAAM,KAAK,IAAI,OAA0C,OAAO,WAAW;AAAA,IACxF,MAAM,QAAQ,OAAO,UAAU,SAAS,CAAC;AAAA,IAEzC,OAAO;AAAA,MACL,eAAe,KAAK,IAAI,+BAA+B;AAAA,MACvD,SAAS,SAAS,KAAK,SAAS;AAAA,MAChC;AAAA,IACF;AAAA;AAEJ;AAEA,eAAe,0BAA0B,CACvC,KACA,WACA,IAC0C;AAAA,EAC1C,OAAO,OAAO,MAAM;AAAA;AAAA,yBAEG,sBAAsB;AAAA;AAAA;AAAA,EAI7C,IAAI,CAAC,KAAK;AAAA,IACR,MAAM,IAAI,0BACR,mCAAmC,8BAA8B,aACnE;AAAA,EACF;AAAA,EAEA,IAAI,IAAI,WAAW,WAAW;AAAA,IAC5B,MAAM,IAAI,0BACR,mCAAmC,oBAAoB,4BACzD;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,eAAe,CAAC,OAAmC;AAAA,EAC1D,OAAO,KAAK,UAAU,KAAK;AAAA;AAG7B,SAAS,WAAW,CAAC,OAAwD;AAAA,EAC3E,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAA2B;AAAA;AAGjF,SAAS,cAAc,CAAC,OAA6D;AAAA,EACnF,OAAO,QAAQ,KAAK,UAAU,KAAK,IAAI;AAAA;AAGzC,SAAS,UAAU,CACjB,OACuC;AAAA,EACvC,OAAO,OAAO,UAAU,WACnB,KAAK,MAAM,KAAK,IAChB,SAAS;AAAA;AAGhB,SAAS,+BAA+B,CACtC,KAC4B;AAAA,EAC5B,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,YAAY,IAAI;AAAA,IAChB,eAAe,IAAI;AAAA,IACnB,WAAW,IAAI;AAAA,IACf,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,QAAQ,IAAI;AAAA,IACZ,SAAS,IAAI;AAAA,IACb,gBAAgB,IAAI;AAAA,IACpB,OAAO,YAAY,IAAI,KAAK;AAAA,IAC5B,iBAAiB,YAAY,IAAI,gBAAgB;AAAA,IACjD,QAAQ,IAAI;AAAA,IACZ,aAAa,IAAI,KAAK,IAAI,YAAY;AAAA,IACtC,WAAW,IAAI,aAAa,IAAI,KAAK,IAAI,UAAU,IAAI;AAAA,IACvD,aAAa,IAAI,eAAe,IAAI,KAAK,IAAI,YAAY,IAAI;AAAA,IAC7D,aAAa,WAAW,IAAI,YAAY;AAAA,IACxC,UAAU,IAAI,WAAW,YAAY,IAAI,QAAQ,IAAI;AAAA,IACrD,aAAa,IAAI,eAAe,IAAI,KAAK,IAAI,YAAY,IAAI;AAAA,IAC7D,aAAa,WAAW,IAAI,YAAY;AAAA,IACxC,WAAW,IAAI,aAAa,IAAI,KAAK,IAAI,UAAU,IAAI;AAAA,EACzD;AAAA;AAGF,SAAS,wBAAwB,CAAC,OAAe,WAAyB;AAAA,EACxE,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AAAA,IACzC,MAAM,IAAI,0BACR,kCAAkC,2CACpC;AAAA,EACF;AAAA;;;ACxRF;AAOO,MAAM,qBAAmD;AAAA,EAIjC;AAAA,EAHpB;AAAA,EACA;AAAA,EAET,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA,IAC3B,KAAK,QAAQ,IAAI,yBAAyB,GAAG;AAAA,IAC7C,KAAK,aAAa,IAAI,8BAA8B,GAAG;AAAA;AAAA,OAGnD,MAAK,CAAC,OAA0D;AAAA,IACpE,MAAM,WAAW,MAAM,YAAY,IAAI;AAAA,IAEvC,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAcnB,MAAM;AAAA,YACN,MAAM;AAAA,YACN,MAAM;AAAA,YACN;AAAA,YACA,iBAAgB,MAAM,KAAK;AAAA,YAC3B;AAAA,YACA;AAAA,YACA,MAAM,SAAS,KAAK,UAAU,MAAM,MAAM,IAAI;AAAA,YAC9C,MAAM,sBAAsB,QAAQ;AAAA,YACpC,MAAM,sBAAsB,MAAM;AAAA,YAClC;AAAA;AAAA;AAAA;AAAA,MAKN,OAAO,uBAAuB,GAAG;AAAA,MACjC,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,iBACR,0BAA0B,MAAM,mCAAmC,MAAM,aAC3E;AAAA,MACF;AAAA,MAEA,MAAM;AAAA;AAAA;AAAA,OAIJ,MAAK,CAAC,OAA0D;AAAA,IACpE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,YAAY,MAAM,aAAa,IAAI;AAAA,MACzC,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,UAAU;AAAA,QACZ,IAAI,SAAS,WAAW,UAAU;AAAA,UAChC,MAAM,IAAI,iBACR,0BAA0B,MAAM,mCAAmC,MAAM,aAC3E;AAAA,QACF;AAAA,QAEA,IAAI,SAAS,gBAAgB,MAAM,YAAY;AAAA,UAC7C,MAAM,IAAI,iBACR,0BAA0B,MAAM,iBAAiB,MAAM,iDAAiD,SAAS,eACnH;AAAA,QACF;AAAA,QAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,uBAGT;AAAA,sBACD,iBAAgB,MAAM,KAAK;AAAA,2BACtB;AAAA,4BACC;AAAA,sBACN;AAAA;AAAA;AAAA,gBAGN,MAAM,SAAS,KAAK,UAAU,MAAM,MAAM,IAAI;AAAA;AAAA;AAAA,gCAG9B,MAAM,WAAW,SAAS;AAAA,iDACT,MAAM,WAAW,uBAAuB;AAAA,+BAC1D,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,QAIzD,OAAO,uBAAuB,OAAO;AAAA,MACvC;AAAA,MAEA,IAAI;AAAA,QACF,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAed,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN;AAAA,cACA,iBAAgB,MAAM,KAAK;AAAA,cAC3B;AAAA,cACA,MAAM,SAAS,KAAK,UAAU,MAAM,MAAM,IAAI;AAAA,cAC9C,MAAM,sBAAsB,QAAQ;AAAA,cACpC,MAAM,sBAAsB,MAAM;AAAA,cAClC;AAAA,cACA,MAAM,WAAW,SAAS;AAAA,cAC1B,MAAM,WAAW,uBAAuB;AAAA;AAAA;AAAA;AAAA,QAK9C,OAAO,uBAAuB,GAAG;AAAA,QACjC,OAAO,OAAO;AAAA,QACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,UAC5B,MAAM,IAAI,iBACR,0BAA0B,MAAM,mCAAmC,MAAM,aAC3E;AAAA,QACF;AAAA,QAEA,MAAM;AAAA;AAAA,KAET;AAAA;AAAA,OAGG,QAAO,CAAC,OAA4D;AAAA,IACxE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,WAAW,MAAM,gBAAgB,IAAI,MAAM,WAAW,MAAM,IAAI,SAAS;AAAA,MAC/E,OAAO,WAAW,MAAM;AAAA;AAAA,sBAER,OAAO,SAAS,OAAO,IAAI;AAAA,8BACnB,MAAM,UAAU;AAAA,+CACC,MAAM,UAAU;AAAA,6BAClC,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAGzD,OAAO,uBAAuB,OAAO;AAAA,KACtC;AAAA;AAAA,OAGG,0BAAyB,CAC7B,OAC4B;AAAA,IAC5B,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,WAAW,MAAM,gBAAgB,IAAI,MAAM,WAAW,MAAM,IAAI,SAAS;AAAA,MAC/E,oCAAoC,UAAU,MAAM,cAAc;AAAA,MAClE,MAAM,UAAU,SAAS,mCACrB,IAAI,KAAK,SAAS,gCAAgC,IAClD,MAAM;AAAA,MACV,OAAO,WAAW,MAAM;AAAA,sEACwC,IAAI,KAChE,KAAK,IAAI,QAAQ,QAAQ,GAAG,MAAM,oBAAoB,QAAQ,CAAC,CACjE;AAAA,6BACqB,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAGzD,OAAO,uBAAuB,OAAO;AAAA,KACtC;AAAA;AAAA,OAGG,OAAM,CAAC,OAA2D;AAAA,IACtE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,iBACR,0BAA0B,MAAM,8BAA8B,MAAM,aACtE;AAAA,MACF;AAAA,MAEA,IAAI,CAAC,qBAAqB,SAAS,QAAQ,MAAM,MAAM,GAAG;AAAA,QACxD,MAAM,IAAI,iBACR,0BAA0B,MAAM,oBAAoB,MAAM,8CAA8C,SAAS,UACnH;AAAA,MACF;AAAA,MACA,oCAAoC,UAAU,MAAM,cAAc;AAAA,MAElE,OAAO,WACL,MAAM,WAAW,cACb,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,0BAC9B;AAAA,oCACU;AAAA,qDACiB;AAAA,mCAClB,MAAM,sBAAsB,MAAM;AAAA;AAAA,gBAGzD,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,0BAC9B,MAAM,SAAS;AAAA,oCACL;AAAA,qDACiB;AAAA,mCAClB,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAI/D,OAAO,uBAAuB,OAAO;AAAA,KACtC;AAAA;AAAA,OAGG,KAAI,CAAC,OAAyD;AAAA,IAClE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,iBACR,0BAA0B,MAAM,8BAA8B,MAAM,aACtE;AAAA,MACF;AAAA,MAEA,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,IAAI,iBACR,0BAA0B,MAAM,oBAAoB,MAAM,6BAC5D;AAAA,MACF;AAAA,MACA,oCAAoC,UAAU,MAAM,cAAc;AAAA,MAElE,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT;AAAA,0BACK;AAAA,oBACN;AAAA,8BACU;AAAA,+CACiB;AAAA,6BAClB,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,uBAAuB,OAAO;AAAA,KACtC;AAAA;AAAA,OAGG,OAAM,CAAC,OAA2D;AAAA,IACtE,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,iBACR,0BAA0B,MAAM,8BAA8B,MAAM,aACtE;AAAA,MACF;AAAA,MAEA,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,IAAI,iBACR,0BAA0B,MAAM,oBAAoB,MAAM,6BAC5D;AAAA,MACF;AAAA,MAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT;AAAA,0BACK;AAAA,oBACN;AAAA;AAAA,8BAEU,MAAM,WAAW,SAAS;AAAA,+CACT,MAAM,WAAW,uBAAuB;AAAA,6BAC1D,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,uBAAuB,OAAO;AAAA,KACtC;AAAA;AAAA,OAGG,QAAO,CAAC,QAA8E;AAAA,IAC1F,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,uBAAuB,GAAG,IAAI;AAAA;AAAA,OAGvC,KAAI,CAAC,OAA+D;AAAA,IACxE,IAAI,iBAAiB,KAAK,KAAK,MAAM,aAAa,WAAW,GAAG;AAAA,MAC9D,OAAO;AAAA,QACL,MAAM,CAAC;AAAA,QACP,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,YAAY;AAAA,MACpB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,UAAU;AAAA,IAC9B;AAAA,IAEA,IAAI,MAAM,aAAa;AAAA,MACrB,MAAM,gBAAe,MAAM,YAAY,IAAI,MAAM,IAAI,SAAS;AAAA,MAC9D,aAAa,KAAK,mBAAmB,cAAa,KAAK,IAAI,IAAI;AAAA,MAC/D,OAAO,KAAK,GAAG,MAAM,WAAW;AAAA,IAClC;AAAA,IAEA,QAAQ,qBAAqB,cAAc,QAAQ,OAAO,KAAK;AAAA,IAE/D,QAAQ,MAAM,OAAO,YAAY,MAAM,aAAqC;AAAA,MAC1E,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IACD,MAAM,OAAO,KAAK,IAAI,sBAAsB;AAAA,IAE5C,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAAA,OAGI,wBAAuB,CAC3B,OACuC;AAAA,IACvC,MAAM,OAAO,MAAM,yBAAiD;AAAA,MAClE,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX,aAAa;AAAA,MACb,UAAU,MAAM;AAAA,MAChB,WAAW,MAAM;AAAA,MACjB,YAAY,CAAC,QAAQ,IAAI;AAAA,IAC3B,CAAC;AAAA,IAED,OAAO;AAAA,MACL,MAAM,KAAK,IAAI,sBAAsB;AAAA,IACvC;AAAA;AAEJ;AAAA;AAEO,MAAM,8BAAqE;AAAA,EACnD;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,OAAM,CAAC,OAA6E;AAAA,IACxF,IAAI;AAAA,MACF,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA;AAAA;AAAA,YAInB,MAAM,cAAc,MAAM,cAAc,MAAM,YAAY;AAAA,YAC1D,MAAM,WAAW,MAAM,MAAM,aAAa,IAAI;AAAA;AAAA;AAAA,MAGpD,OAAO,gCAAgC,GAAG;AAAA,MAC1C,OAAO,OAAO;AAAA,MACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,QAC5B,MAAM,IAAI,iBACR,kEAAkE,MAAM,aAC1E;AAAA,MACF;AAAA,MACA,MAAM;AAAA;AAAA;AAAA,OAIJ,MAAK,CAAC,OAA4E;AAAA,IACtF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,yBAAyB,IAAI,MAAM,WAAW,MAAM,WAAW,QAAQ;AAAA,MACzF,OAAO,WAAW,MAAM;AAAA;AAAA,qBAET;AAAA,uCACkB,MAAM,oBAAoB,QAAQ;AAAA,qCACpC,MAAM,oBAAoB,MAAM;AAAA,uBAC9C,MAAM,WAAW;AAAA,sBAClB;AAAA,8BACQ,MAAM,UAAU;AAAA,+CACC,MAAM,UAAU;AAAA,yBACtC,MAAM,aAAa,IAAI;AAAA,6BACnB,IAAI,gCAAgC,IAAI;AAAA;AAAA;AAAA,MAG/D,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,QAAO,CAAC,OAA8E;AAAA,IAC1F,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,yBAAyB,IAAI,MAAM,WAAW,MAAM,WAAW,SAAS;AAAA,MAC1F,OAAO,WAAW,MAAM;AAAA;AAAA,sBAER,OAAO,IAAI,OAAO,IAAI;AAAA,8BACd,MAAM,UAAU;AAAA,+CACC,MAAM,UAAU;AAAA,6BAClC,MAAM,+BAA+B,MAAM;AAAA;AAAA;AAAA,MAGlE,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,0BAAyB,CAC7B,OACqC;AAAA,IACrC,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,yBAAyB,IAAI,MAAM,WAAW,MAAM,WAAW,SAAS;AAAA,MAC1F,iCAAiC,KAAK,MAAM,cAAc;AAAA,MAC1D,MAAM,eAAe,IAAI,mCACrB,IAAI,KAAK,IAAI,gCAAgC,IAC7C,MAAM;AAAA,MACV,OAAO,WAAW,MAAM;AAAA;AAAA,+CAEiB,IAAI,KACvC,KAAK,IAAI,aAAa,QAAQ,GAAG,MAAM,oBAAoB,QAAQ,CAAC,CACtE;AAAA,6BACmB,MAAM,+BAA+B,MAAM;AAAA;AAAA;AAAA,MAGlE,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,OAAM,CAAC,OAA6E;AAAA,IACxF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,MAAM,MAAM,MAAM,yBAAyB,IAAI,MAAM,WAAW,MAAM,WAAW,SAAS;AAAA,MAC1F,iCAAiC,KAAK,MAAM,cAAc;AAAA,MAC1D,OAAO,WAAW,MAAM;AAAA;AAAA,qBAET,MAAM;AAAA,gCACK,MAAM,WAAW;AAAA,4BACrB,MAAM,gBAAgB;AAAA,oBAC9B,MAAM,QAAQ,KAAK,UAAU,MAAM,KAAK,IAAI;AAAA,oBAC5C,MAAM,QAAQ,KAAK,UAAU,MAAM,KAAK,IAAI;AAAA,0BACtC,MAAM,cAAc,KAAK,UAAU,MAAM,WAAW,IAAI;AAAA,oBAC9D,MAAM,WAAW,cAAc,OAAQ,MAAM,SAAS;AAAA,8BAC5C;AAAA,+CACiB;AAAA,2BACpB,MAAM,eAAe,IAAI;AAAA,6BACvB,MAAM,+BAA+B,MAAM;AAAA;AAAA;AAAA,MAGlE,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,OAAM,CAAC,OAA6E;AAAA,IACxF,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,OAAO,MAAM;AAAA;AAAA,6BAEG,MAAM,+BAA+B,MAAM;AAAA;AAAA;AAAA,MAGlE,IAAI,CAAC,KAAK;AAAA,QACR,MAAM,IAAI,iBACR,qCAAqC,MAAM,uBAC7C;AAAA,MACF;AAAA,MACA,IAAI,IAAI,WAAW,YAAY,IAAI,WAAW,WAAW;AAAA,QACvD,MAAM,IAAI,iBACR,qCAAqC,MAAM,+CAA+C,IAAI,UAChG;AAAA,MACF;AAAA,MACA,OAAO,WAAW,MAAM;AAAA;AAAA,qBAET;AAAA,oBACD,MAAM,SAAS;AAAA,8BACL;AAAA,+CACiB;AAAA,2BACpB,MAAM,eAAe,IAAI;AAAA,6BACvB,MAAM,+BAA+B,MAAM;AAAA;AAAA;AAAA,MAGlE,OAAO,gCAAgC,OAAO;AAAA,KAC/C;AAAA;AAAA,OAGG,eAAc,CAAC,QAG0B;AAAA,IAC7C,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,+BAA+B,OAAO;AAAA;AAAA,IAEpE,OAAO,MAAM,gCAAgC,GAAG,IAAI;AAAA;AAAA,OAGhD,KAAI,CAAC,OAAiF;AAAA,IAC1F,IAAI,iBAAiB,KAAK;AAAA,MAAG,OAAO,EAAE,MAAM,CAAC,GAAG,OAAO,GAAG,SAAS,MAAM;AAAA,IACzE,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IACZ,IAAI,MAAM,SAAS;AAAA,MACjB,aAAa,KAAK,eAAe,SAAS;AAAA,MAC1C,OAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,IACA,QAAQ,qBAAqB,cAAc,QAAQ,OAAO,KAAK;AAAA,IAC/D,MAAM,SAAS,MAAM,aAA8C;AAAA,MACjE,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IACD,OAAO,KAAK,QAAQ,MAAM,OAAO,KAAK,IAAI,+BAA+B,EAAE;AAAA;AAE/E;AAAA;AAEO,MAAM,yBAA2D;AAAA,EACzC;AAAA,EAA7B,WAAW,CAAkB,KAAoB;AAAA,IAApB;AAAA;AAAA,OAEvB,MAAK,CAAC,OAAkE;AAAA,IAC5E,0BAAyB,MAAM,WAAW,WAAW;AAAA,IAErD,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,eAAe,MAAM;AAAA;AAAA,6BAEL,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,aAAa;AAAA,QAChB,MAAM,IAAI,iBACR,0BAA0B,MAAM,yCAAyC,MAAM,aACjF;AAAA,MACF;AAAA,MAEA,IAAI,YAAY,WAAW,WAAW;AAAA,QACpC,MAAM,IAAI,iBACR,0BAA0B,MAAM,+BAA+B,MAAM,6BACvE;AAAA,MACF;AAAA,MACA,oCAAoC,aAAa,MAAM,cAAc;AAAA,MAErE,IAAI,YAAY,gBAAgB,MAAM,YAAY;AAAA,QAChD,MAAM,IAAI,iBACR,+BAA+B,MAAM,iBAAiB,MAAM,4CAA4C,MAAM,4BAA4B,YAAY,eACxJ;AAAA,MACF;AAAA,MAEA,IAAI;AAAA,QACF,OAAO,OAAO,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAcd,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN,MAAM;AAAA,cACN;AAAA,cACA,iBAAgB,MAAM,KAAK;AAAA,cAC3B,MAAM,aAAa,IAAI;AAAA;AAAA;AAAA;AAAA,QAK7B,OAAO,2BAA2B,GAAG;AAAA,QACrC,OAAO,OAAO;AAAA,QACd,IAAI,kBAAkB,KAAK,GAAG;AAAA,UAC5B,MAAM,IAAI,iBACR,+BAA+B,MAAM,mCAAmC,MAAM,aAChF;AAAA,QACF;AAAA,QAEA,MAAM;AAAA;AAAA,KAET;AAAA;AAAA,OAGG,OAAM,CAAC,OAAmE;AAAA,IAC9E,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,iBACR,+BAA+B,MAAM,8BAA8B,MAAM,aAC3E;AAAA,MACF;AAAA,MACA,MAAM,2CAA2C,IAAI,UAAU,MAAM,cAAc;AAAA,MAEnF,IAAI,SAAS,WAAW,aAAa,SAAS,WAAW,WAAW;AAAA,QAClE,MAAM,IAAI,iBACR,+BAA+B,MAAM,oBAAoB,MAAM,iCACjE;AAAA,MACF;AAAA,MAEA,OAAO,WACL,MAAM,WAAW,cACb,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,2BAC7B,MAAM,SAAS,iBAAgB,MAAM,MAAM,IAAI;AAAA,0BAChD;AAAA,mCACS,MAAM,sBAAsB,MAAM;AAAA;AAAA,gBAGzD,MAAM;AAAA;AAAA;AAAA,2BAGS,MAAM;AAAA,gCACD,MAAM,cAAc,IAAI;AAAA,2BAC7B;AAAA,0BACD,MAAM,SAAS;AAAA,mCACN,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAI/D,OAAO,2BAA2B,OAAO;AAAA,KAC1C;AAAA;AAAA,OAGG,KAAI,CAAC,OAAiE;AAAA,IAC1E,OAAO,iBAAiB,KAAK,KAAK,OAAO,OAAO;AAAA,MAC9C,OAAO,YAAY,MAAM;AAAA;AAAA,6BAEF,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,IAAI,CAAC,UAAU;AAAA,QACb,MAAM,IAAI,iBACR,+BAA+B,MAAM,8BAA8B,MAAM,aAC3E;AAAA,MACF;AAAA,MACA,MAAM,2CAA2C,IAAI,UAAU,MAAM,cAAc;AAAA,MAEnF,IAAI,SAAS,WAAW,WAAW;AAAA,QACjC,MAAM,IAAI,iBACR,+BAA+B,MAAM,oBAAoB,MAAM,6BACjE;AAAA,MACF;AAAA,MAEA,OAAO,WAAW,MAAM;AAAA;AAAA;AAAA,qBAGT;AAAA,0BACK;AAAA,qBACL;AAAA,oBACD;AAAA,6BACS,MAAM,sBAAsB,MAAM;AAAA;AAAA;AAAA,MAIzD,OAAO,2BAA2B,OAAO;AAAA,KAC1C;AAAA;AAAA,OAGG,QAAO,CAAC,QAAkF;AAAA,IAC9F,OAAO,OAAO,MAAM,KAAK;AAAA;AAAA,2BAEF,OAAO,sBAAsB,OAAO;AAAA;AAAA,IAG3D,OAAO,MAAM,2BAA2B,GAAG,IAAI;AAAA;AAAA,OAG3C,KAAI,CAAC,OAAuE;AAAA,IAChF,IAAI,iBAAiB,KAAK,GAAG;AAAA,MAC3B,OAAO;AAAA,QACL,OAAO,CAAC;AAAA,QACR,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IAEA,MAAM,eAAe,CAAC,iBAAiB;AAAA,IACvC,MAAM,SAAyB,CAAC,MAAM,SAAS;AAAA,IAC/C,IAAI,QAAQ;AAAA,IAEZ,IAAI,MAAM,eAAe;AAAA,MACvB,aAAa,KAAK,sBAAsB,SAAS;AAAA,MACjD,OAAO,KAAK,MAAM,aAAa;AAAA,IACjC;AAAA,IAEA,IAAI,MAAM,YAAY;AAAA,MACpB,aAAa,KAAK,kBAAkB,SAAS;AAAA,MAC7C,OAAO,KAAK,MAAM,UAAU;AAAA,IAC9B;AAAA,IAEA,IAAI,MAAM,UAAU;AAAA,MAClB,aAAa,KAAK,gBAAgB,SAAS;AAAA,MAC3C,OAAO,KAAK,MAAM,QAAQ;AAAA,IAC5B;AAAA,IAEA,IAAI,MAAM,QAAQ;AAAA,MAChB,aAAa,KAAK,cAAc,SAAS;AAAA,MACzC,OAAO,KAAK,MAAM,MAAM;AAAA,IAC1B;AAAA,IAEA,IAAI,MAAM,SAAS;AAAA,MACjB,aAAa,KAAK,eAAe,SAAS;AAAA,MAC1C,OAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,IAEA,QAAQ,qBAAqB,cAAc,QAAQ,OAAO,KAAK;AAAA,IAE/D,QAAQ,MAAM,OAAO,YAAY,MAAM,aAAyC;AAAA,MAC9E,KAAK,KAAK;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,QAAQ,MAAM;AAAA,IAChB,CAAC;AAAA,IACD,MAAM,QAAQ,KAAK,IAAI,0BAA0B;AAAA,IAEjD,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAEJ;AAEA,SAAS,gBAAe,CAAC,OAAmC;AAAA,EAC1D,OAAO,KAAK,UAAU,KAAK;AAAA;AAG7B,SAAS,YAAW,CAAC,OAAwD;AAAA,EAC3E,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAA2B;AAAA;AAGjF,SAAS,sBAAsB,CAAC,KAAgD;AAAA,EAC9E,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,YAAY,IAAI;AAAA,IAChB,QAAQ,IAAI;AAAA,IACZ,OAAO,aAAY,IAAI,KAAK;AAAA,IAC5B,UAAU,IAAI,YAAY,IAAI,KAAK,IAAI,SAAS,IAAI;AAAA,IACpD,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,OAAO,IAAI,SAAS;AAAA,IACpB,QAAQ,YAAY,IAAI,MAAM;AAAA,IAC9B,sBAAsB;AAAA,MACpB,MAAM,IAAI;AAAA,MACV,IAAI,IAAI;AAAA,IACV;AAAA,IACA,SAAS,OAAO,IAAI,OAAO;AAAA,OACvB,IAAI,mBAAmB,IAAI,mCAC3B;AAAA,MACE,WAAW;AAAA,QACT,OAAO,IAAI;AAAA,QACX,qBAAqB,IAAI,KAAK,IAAI,gCAAgC;AAAA,MACpE;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAAA;AAGF,SAAS,WAAW,CAAC,OAAyE;AAAA,EAC5F,IAAI,UAAU,QAAQ,UAAU,WAAW;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAA0B;AAAA;AAGhF,SAAS,0BAA0B,CAAC,KAAwD;AAAA,EAC1F,OAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR,WAAW,IAAI;AAAA,IACf,eAAe,IAAI;AAAA,IACnB,YAAY,IAAI;AAAA,IAChB,WAAW,OAAO,IAAI,UAAU;AAAA,IAChC,UAAU,IAAI;AAAA,IACd,QAAQ,IAAI;AAAA,IACZ,SAAS,IAAI;AAAA,IACb,QAAQ,IAAI;AAAA,IACZ,OAAO,aAAY,IAAI,KAAK;AAAA,IAC5B,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,IAClC,YAAY,IAAI,cAAc,IAAI,KAAK,IAAI,WAAW,IAAI;AAAA,IAC1D,QAAQ,IAAI,SAAS,aAAY,IAAI,MAAM,IAAI;AAAA,IAC/C,OAAO,IAAI,SAAS;AAAA,EACtB;AAAA;AAGF,SAAS,yBAAwB,CAAC,OAAe,WAAyB;AAAA,EACxE,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AAAA,IACzC,MAAM,IAAI,iBAAiB,yBAAyB,2CAA2C;AAAA,EACjG;AAAA;AAGF,SAAS,oBAAoB,CAC3B,SACA,MACS;AAAA,EACT,OACE,YAAY,aACX,YAAY,aAAa,SAAS,eAClC,YAAY,YAAY,SAAS;AAAA;AA6DtC,eAAe,wBAAwB,CACrC,KACA,WACA,WACA,QAC0C;AAAA,EAC1C,OAAO,OAAO,MAAM;AAAA;AAAA,yBAEG,+BAA+B;AAAA;AAAA;AAAA,EAGtD,IAAI,CAAC,KAAK;AAAA,IACR,MAAM,IAAI,iBACR,qCAAqC,qCAAqC,aAC5E;AAAA,EACF;AAAA,EACA,IAAI,IAAI,WAAW,QAAQ;AAAA,IACzB,MAAM,IAAI,iBACR,qCAAqC,sBAAsB,mBAAmB,IAAI,WACpF;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,gCAAgC,CACvC,KACA,OACM;AAAA,EACN,IAAI,IAAI,oBAAoB,OAAO;AAAA,IACjC,MAAM,IAAI,iBACR,6EAA6E,IAAI,eACnF;AAAA,EACF;AAAA;AAGF,SAAS,+BAA+B,CACtC,KAC4B;AAAA,EAC5B,OAAO;AAAA,IACL,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,IACf,SAAS,IAAI;AAAA,IACb,QAAQ,IAAI;AAAA,IACZ,QAAQ,IAAI;AAAA,OACR,IAAI,4BAA4B,IAAI,yBACpC;AAAA,MACE,oBAAoB;AAAA,QAClB,MAAM,IAAI;AAAA,QACV,IAAI,IAAI;AAAA,MACV;AAAA,IACF,IACA,CAAC;AAAA,OACD,IAAI,WAAW,EAAE,SAAS,IAAI,SAAS,IAAI,CAAC;AAAA,OAC5C,IAAI,gBAAgB,EAAE,cAAc,IAAI,cAAc,IAAI,CAAC;AAAA,OAC3D,IAAI,QAAQ,EAAE,OAAO,UAAU,IAAI,KAAK,EAAE,IAAI,CAAC;AAAA,OAC/C,IAAI,QAAQ,EAAE,OAAO,UAAU,IAAI,KAAK,EAAE,IAAI,CAAC;AAAA,OAC/C,IAAI,cAAc,EAAE,aAAa,UAAU,IAAI,WAAW,EAAE,IAAI,CAAC;AAAA,OACjE,IAAI,QAAQ,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,IACxC,SAAS,OAAO,IAAI,OAAO;AAAA,OACvB,IAAI,mBAAmB,IAAI,mCAC3B;AAAA,MACE,WAAW;AAAA,QACT,OAAO,IAAI;AAAA,QACX,qBAAqB,IAAI,KAAK,IAAI,gCAAgC;AAAA,MACpE;AAAA,IACF,IACA,CAAC;AAAA,IACL,WAAW,IAAI,KAAK,IAAI,UAAU;AAAA,OAC9B,IAAI,aAAa,EAAE,WAAW,IAAI,KAAK,IAAI,UAAU,EAAE,IAAI,CAAC;AAAA,OAC5D,IAAI,eAAe,EAAE,aAAa,IAAI,KAAK,IAAI,YAAY,EAAE,IAAI,CAAC;AAAA,EACxE;AAAA;AAGF,SAAS,SAAY,CAAC,OAAsB;AAAA,EAC1C,OAAO,OAAO,UAAU,WAAY,KAAK,MAAM,KAAK,IAAU;AAAA;AAGhE,eAAe,eAAe,CAC5B,KACA,WACA,IACA,QACiC;AAAA,EACjC,OAAO,OAAO,MAAM;AAAA,qDAC+B,sBAAsB;AAAA;AAAA,EAEzE,IAAI,CAAC;AAAA,IAAK,MAAM,IAAI,iBAAiB,0BAA0B,gBAAgB;AAAA,EAC/E,IAAI,IAAI,WAAW,QAAQ;AAAA,IACzB,MAAM,IAAI,iBACR,0BAA0B,eAAe,mBAAmB,IAAI,WAClE;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,mCAAmC,CAAC,KAA6B,OAAsB;AAAA,EAC9F,IAAI,IAAI,qBAAqB,SAAS,OAAO;AAAA,IAC3C,MAAM,IAAI,iBACR,kEAAkE,IAAI,MACxE;AAAA,EACF;AAAA;AAGF,eAAe,0CAA0C,CACvD,KACA,MACA,OACe;AAAA,EACf,OAAO,OAAO,MAAM;AAAA;AAAA,yBAEG,KAAK,uBAAuB,KAAK;AAAA;AAAA;AAAA,EAGxD,IAAI,CAAC;AAAA,IAAK,MAAM,IAAI,iBAAiB,6CAA6C;AAAA,EAClF,oCAAoC,KAAK,KAAK;AAAA;;;A7Cz6BzC,MAAM,gBAAmD;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB,IAAI;AAAA,EAExC,WAAW,CAAC,SAAiC;AAAA,IAC3C,KAAK,aAAa,QAAQ,cAAc;AAAA,IACxC,KAAK,yBAAyB,KAAK,IACjC,GACA,KAAK,OAAO,QAAQ,yBAAyB,QAAQ,IAAI,CAC3D;AAAA,IAEA,KAAK,MAAM,eAAe;AAAA,SACpB,QAAQ,qBAAqB,YAC7B,EAAE,kBAAkB,QAAQ,iBAAiB,IAC7C,CAAC;AAAA,SACD,QAAQ,SAAS,YAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,SACvD,QAAQ,SAAS,YAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,SACvD,QAAQ,aAAa,YAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,SACnE,QAAQ,SAAS,YAAY,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,SACvD,QAAQ,aAAa,YAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACvE,KAAK,QAAQ,OAAO;AAAA,MACpB,YAAY,KAAK;AAAA,SACb,QAAQ,sBAAsB,YAC9B,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,CAAC;AAAA,SACD,qBAAqB,QAAQ,wBAAwB,wBAAwB,MACjF,YACI,EAAE,wBAAwB,QAAQ,uBAAuB,IACzD,CAAC;AAAA,SACD,qBACF,QAAQ,uCACR,uCACF,MAAM,YACF,EAAE,uCAAuC,QAAQ,sCAAsC,IACvF,CAAC;AAAA,SACD,qBAAqB,QAAQ,sBAAsB,sBAAsB,MAAM,YAC/E,EAAE,sBAAsB,QAAQ,qBAAqB,IACrD,CAAC;AAAA,SACD,QAAQ,YAAY,YAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,SAChE,QAAQ,QAAQ,YAAY,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC1D,CAAC;AAAA,IAED,KAAK,YAAY,+BAA+B,KAAK,KAAK,KAAK,UAAU;AAAA,IACzE,MAAM,SAAS,qBAAqB,KAAK,KAAK;AAAA,MAC5C,sBAAsB,CAAC,QAAQ,iBAAiB,KAAK,KAAK,GAAG;AAAA,MAC7D,oBAAoB;AAAA,IACtB,CAAC;AAAA,IACD,MAAM,QAAQ,4BACZ,OAAO,QAAQ;AAAA,MACb,KAAK,6BAA6B;AAAA,MAClC,OAAO,IAAI;AAAA,OAEb,MAAM,KAAK,6BAA6B,CAC1C;AAAA,IACA,KAAK,UAAU,4BAA4B,OAAO,SAAS,KAAK;AAAA,IAChE,KAAK,WAAW,6BAA6B,OAAO,UAAU,KAAK;AAAA,IACnE,KAAK,OAAO,yBAAyB,OAAO,MAAM,KAAK;AAAA,IACvD,KAAK,SAAS,0BAA0B,OAAO,QAAQ,KAAK;AAAA,IAC5D,KAAK,aAAa,4BAA4B,OAAO,YAAY,KAAK;AAAA,IACtE,KAAK,eAAe,4BAA4B,OAAO,cAAc,KAAK;AAAA,IAC1E,KAAK,eAAe,gCAAgC,OAAO,cAAc,KAAK;AAAA,IAC9E,KAAK,wBAAwB,4BAA4B,OAAO,uBAAuB,KAAK;AAAA,IAC5F,KAAK,WAAW,4BAA4B,OAAO,UAAU,KAAK;AAAA,IAClE,KAAK,iBAAiB,4BAA4B,OAAO,gBAAgB,KAAK;AAAA,IAC9E,KAAK,aAAa,4BAA4B,OAAO,YAAY,KAAK;AAAA,IACtE,KAAK,oBAAoB,4BAA4B,OAAO,mBAAmB,KAAK;AAAA,IACpF,KAAK,cAAc,4BAA4B,OAAO,aAAa,KAAK;AAAA,IACxE,KAAK,QAAQ,4BAA4B,OAAO,OAAO,KAAK;AAAA;AAAA,OAGxD,KAAI,GAAkB;AAAA,IAC1B,KAAK,6BAA6B;AAAA,IAClC,MAAM,KAAK;AAAA;AAAA,OAGP,YAAc,CAClB,KACA,UAAqC,CAAC,GAC1B;AAAA,IACZ,IAAI,KAAK,iBAAiB,SAAS,GAAG;AAAA,MACpC,8BAA8B;AAAA,IAChC;AAAA,IAEA,IAAI;AAAA,MACF,OAAO,MAAM,iBACX,KAAK,KACL,OAAO,WAAW;AAAA,QAChB,IAAI,SAAS;AAAA,QACb,MAAM,qBAAmD;AAAA,UACvD,IAAI,CAAC;AAAA,UACL,kBAAkB,IAAI;AAAA,UACtB,QAAQ;AAAA,QACV;AAAA,QACA,MAAM,YAAY,KAAK,yBAAyB,QAAQ,kBAAkB;AAAA,QAC1E,MAAM,KAAK,8BAA8B,WAAW,MAAM,MAAM;AAAA,QAEhE,IAAI;AAAA,UACF,MAAM,SAAS,MAAM,KAAK,iBAAiB,IAAI,MAAM,MAAM,IAAI,EAAE,CAAC;AAAA,UAClE,mBAAmB,iBAAiB,kBAAkB;AAAA,UACtD,OAAO;AAAA,kBACP;AAAA,UACA,mBAAmB,SAAS;AAAA,UAC5B,UAAU,SAAS,mBAAmB;AAAA,UACtC,mBAAmB,iBAAiB,WAAW;AAAA,UAC/C,SAAS;AAAA;AAAA,SAGb,EAAE,WAAW,QAAQ,cAAc,iBAAiB,iBAAiB,UAAU,CACjF;AAAA,MACA,OAAO,OAAO;AAAA,MACd,IAAI,+BAA+B,KAAK,GAAG;AAAA,QACzC,MAAM,IAAI,wBACR,uGACA,EAAE,OAAO,OAAO,MAAM,wBAAwB,CAChD;AAAA,MACF;AAAA,MACA,MAAM;AAAA;AAAA;AAAA,EAIF,4BAA4B,GAAS;AAAA,IAC3C,IAAI,CAAC,KAAK,iBAAiB,SAAS;AAAA,MAAG;AAAA,IACvC,MAAM,IAAI,wBACR,kGACF;AAAA;AAAA,OASI,MAAK,GAAkB;AAAA,IAC3B,MAAM,KAAK,IAAI,IAAI,EAAE,SAAS,KAAK,uBAAuB,CAAC;AAAA;AAAA,OAOvD,WAAU,GAAkB;AAAA,IAChC,MAAM,WAAW,KAAK,KAAK,KAAK,UAAU;AAAA;AAAA,EAGpC,wBAAwB,CAC9B,QACA,oBACoD;AAAA,IACpD,OAAO;AAAA,SACF,qBAAqB,QAAQ;AAAA,QAC9B,sBAAsB,OAAO,QAAQ,IAAI,MAAM;AAAA,QAC/C;AAAA,MACF,CAAC;AAAA,MACD,MAAM,YAAY;AAAA,QAChB,MAAM;AAAA;AAAA,MAER,aAAa,YAA2B;AAAA,QACtC,8BAA8B;AAAA;AAAA,IAElC;AAAA;AAEJ;AAEA,SAAS,oBAAoB,CAC3B,KACA,SAIkB;AAAA,EAClB,OAAO;AAAA,IACL,SAAS,IAAI,gBAAgB,GAAG;AAAA,IAChC,UAAU,IAAI,kBAAkB;AAAA,MAC9B;AAAA,MACA,kBAAkB,QAAQ;AAAA,MAC1B,oBAAoB,QAAQ;AAAA,IAC9B,CAAC;AAAA,IACD,MAAM,IAAI,cAAc,EAAE,IAAI,CAAC;AAAA,IAC/B,QAAQ,IAAI,eAAe,EAAE,IAAI,CAAC;AAAA,IAClC,YAAY,IAAI,mBAAmB,GAAG;AAAA,IACtC,cAAc,IAAI,qBAAqB,GAAG;AAAA,IAC1C,cAAc,IAAI,qBAAqB,GAAG;AAAA,IAC1C,uBAAuB,IAAI,8BAA8B,GAAG;AAAA,IAC5D,UAAU,IAAI,iBAAiB,GAAG;AAAA,IAClC,gBAAgB,IAAI,uBAAuB,GAAG;AAAA,IAC9C,YAAY,IAAI,oBAAoB,GAAG;AAAA,IACvC,mBAAmB,IAAI,yBAAyB,GAAG;AAAA,IACnD,aAAa,IAAI,oBAAoB,GAAG;AAAA,IACxC,OAAO,IAAI,eAAe,GAAG;AAAA,EAC/B;AAAA;AAoBF,SAAS,oBAAoB,CAAC,OAA2B,OAAmC;AAAA,EAC1F,IAAI,UAAU,WAAW;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GAAG;AAAA,IACxC,MAAM,IAAI,MAAM,0BAA0B,6CAA6C;AAAA,EACzF;AAAA,EAEA,OAAO,KAAK,MAAM,KAAK;AAAA;",
53
+ "debugId": "843969ACD3B756C464756E2164756E21",
54
+ "names": []
55
+ }