{"version":3,"file":"ImportExecutor.cjs","sources":["../../../../../packages/engine-http/src/transfer/ImportExecutor.ts"],"sourcesContent":["import { Client, Connection, ConstraintHelper, DatabaseMetadataResolver, wrapIdentifier } from '@contember/database'\nimport { Model, Schema } from '@contember/schema'\nimport * as Typesafe from '@contember/typesafe'\nimport { ParseError } from '@contember/typesafe'\nimport { Command, CommandArgsMap, CommandName } from './Command'\nimport { DatabaseContext, StageBySlugQuery } from '@contember/engine-system-api'\nimport { DbColumnSchema, TransferMapping, TransferTableMapping } from './TransferMapping'\nimport { ContentSchemaTransferMappingFactory } from './ContentSchemaTransferMappingFactory'\nimport { SystemSchemaTransferMappingFactory } from './SystemSchemaTransferMappingFactory'\nimport { AuthResult, HttpErrorResponse } from '../common'\nimport { ProjectGroupContainer } from '../projectGroup/ProjectGroupContainer'\n\ntype Cell = boolean | number | string | null\ntype Row = readonly Cell[]\n\ntype InsertContext = {\n\ttableName: string\n\tinsertStartFragment: string\n\trowFragment: string\n\trowParser: Typesafe.Type<Row>\n\trows: Array<Row>\n\tinsertedRowCount: number\n}\n\nexport class ImportError extends Error {\n}\n\ntype CommandProcessor<T extends CommandName> = (it: CommandIterator<T>) => Promise<CommandIterator | null>\ntype CommandProcessorMap<T extends CommandName> = { [N in CommandName]?: N extends T ? CommandProcessor<N> : undefined }\n\nclass CommandIterator<T extends CommandName = CommandName> {\n\tprivate constructor(\n\t\tpublic readonly commandName: T,\n\t\tpublic readonly commandArgs: CommandArgsMap[T],\n\t\tprivate readonly commandIterator: AsyncIterator<Command>,\n\t) {\n\t}\n\n\tpublic static async create(commands: AsyncIterable<Command>): Promise<CommandIterator | null> {\n\t\tconst commandIterator = commands[Symbol.asyncIterator]()\n\t\tconst result = await commandIterator.next()\n\n\t\tif (result.done) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst [name, ...args] = result.value\n\t\treturn new CommandIterator(name, args, commandIterator)\n\t}\n\n\tasync next(): Promise<CommandIterator | null> {\n\t\tconst result = await this.commandIterator.next()\n\n\t\tif (result.done) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst [name, ...args] = result.value\n\t\treturn new CommandIterator(name, args, this.commandIterator)\n\t}\n}\n\nexport class ImportExecutor {\n\tconstructor(\n\t\tprivate readonly contentSchemaTransferMappingFactory: ContentSchemaTransferMappingFactory,\n\t\tprivate readonly systemSchemaTransferMappingFactory: SystemSchemaTransferMappingFactory,\n\t\tprivate readonly databaseMetadataResolver: DatabaseMetadataResolver,\n\t) {\n\t}\n\n\tasync import(groupContainer: ProjectGroupContainer, authResult: AuthResult, commands: AsyncIterable<Command>) {\n\t\tconst it = await CommandIterator.create(commands)\n\n\t\tconst final = await this.match(it, {\n\t\t\timportContentSchemaBegin: it => this.importContentSchemaBegin(groupContainer, authResult, it),\n\t\t\timportSystemSchemaBegin: it => this.importSystemSchemaBegin(groupContainer, authResult, it),\n\t\t})\n\n\t\tif (final !== null) {\n\t\t\tthrow new ImportError(`Unexpected ${final.commandName}`)\n\t\t}\n\t}\n\n\tprivate async match<T extends CommandName>(it: CommandIterator<T> | null, processors: CommandProcessorMap<T>) {\n\t\tlet next: CommandIterator | null = it\n\n\t\twhile (next !== null) {\n\t\t\tconst processor = processors[next.commandName]\n\n\t\t\tif (processor) {\n\t\t\t\tnext = await processor(next as any)\n\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn next\n\t}\n\n\tprivate async importContentSchemaBegin(groupContainer: ProjectGroupContainer, authResult: AuthResult, it: CommandIterator<'importContentSchemaBegin'>) {\n\t\tconst [options] = it.commandArgs\n\t\tconst projectContainer = await this.createProjectContainer(groupContainer, options.project)\n\t\tconst systemDatabaseContext = projectContainer.systemDatabaseContext\n\t\tconst stage = await this.fetchStageBySlug(systemDatabaseContext, options.project, options.stage)\n\n\t\tconst contentSchema = await projectContainer.contentSchemaResolver.getSchema({ db: systemDatabaseContext, stage: stage.slug, normalize: true })\n\n\t\tif (contentSchema.meta.version !== options.schemaVersion) {\n\t\t\tthrow new ImportError(`Incompatible schema version (import version ${options.schemaVersion} does not match server version ${contentSchema.meta.version})`)\n\t\t}\n\n\t\tawait this.requireImportAccess(groupContainer, contentSchema.schema, authResult, options.project, 'content')\n\t\tconst contentDatabaseClient = projectContainer.connection.createClient(stage.schema, {})\n\t\tconst mapping = this.contentSchemaTransferMappingFactory.createContentSchemaMapping(contentSchema.schema)\n\n\t\treturn await contentDatabaseClient.transaction(async db => {\n\t\t\tawait this.disableTriggers(db, options.tables)\n\t\t\tawait this.lockTables(db, options.tables)\n\t\t\tawait this.truncateTables(db, options.tables)\n\n\t\t\tconst metadata = await this.databaseMetadataResolver.resolveMetadata(db, db.schema)\n\t\t\tconst constraintHelper = new ConstraintHelper(db, metadata)\n\t\t\tawait constraintHelper.setConstraintsDeferred('foreignKey')\n\n\t\t\tconst result = await this.match(await it.next(), {\n\t\t\t\timportSequence: it => this.importSequence(db, mapping, it),\n\t\t\t\tinsertBegin: it => this.insertBegin(db, mapping, it),\n\t\t\t})\n\n\t\t\tawait constraintHelper.setConstraintsImmediate('foreignKey')\n\t\t\tawait this.enableTriggers(db, options.tables)\n\n\t\t\treturn result\n\t\t})\n\t}\n\n\tprivate async importSystemSchemaBegin(groupContainer: ProjectGroupContainer, authResult: AuthResult, it: CommandIterator<'importSystemSchemaBegin'>) {\n\t\tconst [options] = it.commandArgs\n\t\tconst projectContainer = await this.createProjectContainer(groupContainer, options.project)\n\t\tconst schema = await groupContainer.projectSchemaResolver.getSchema(options.project)\n\n\t\tif (schema === undefined) {\n\t\t\tthrow new ImportError(`Project ${options.project} does not have schema`)\n\t\t}\n\n\t\tawait this.requireImportAccess(groupContainer, schema, authResult, options.project, 'system')\n\t\tconst systemDatabaseContext = projectContainer.systemDatabaseContext\n\t\tconst mapping = this.systemSchemaTransferMappingFactory.build()\n\n\t\treturn await systemDatabaseContext.client.transaction(async db => {\n\t\t\tawait this.truncateTables(db, options.tables)\n\n\t\t\tconst metadata = await this.databaseMetadataResolver.resolveMetadata(db, db.schema)\n\t\t\tconst constraintHelper = new ConstraintHelper(db, metadata)\n\t\t\tawait constraintHelper.setConstraintsDeferred('foreignKey')\n\n\t\t\treturn await this.match(await it.next(), {\n\t\t\t\tinsertBegin: it => this.insertBegin(db, mapping, it),\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate async importSequence(db: Client<Connection.TransactionLike>, mapping: TransferMapping, it: CommandIterator<'importSequence'>): Promise<CommandIterator | null> {\n\t\tconst [options] = it.commandArgs\n\n\t\tawait db.query(\n\t\t\t'SELECT setval(pg_get_serial_sequence(?, ?), ?)',\n\t\t\t[`${db.schema}.${options.table}`, options.column, options.value],\n\t\t)\n\n\t\treturn it.next()\n\t}\n\n\tprivate async insertBegin(db: Client<Connection.TransactionLike>, mapping: TransferMapping, it: CommandIterator<'insertBegin'>): Promise<CommandIterator | null> {\n\t\tconst [options] = it.commandArgs\n\t\tconst insertContext = await this.buildInsertContext(db, mapping, db.schema, options.table, options.columns)\n\t\tlet insertRowsPromise: Promise<Connection.Result> | null = null\n\n\t\t// postgresql has a limit of 65535 parameters per query\n\t\tconst batchSize = Math.max(1, Math.min(1000, Math.floor(65500 / options.columns.length)))\n\n\t\tconst result = await this.match(await it.next(), {\n\t\t\tinsertRow: async it => {\n\t\t\t\tconst [values] = it.commandArgs\n\n\t\t\t\ttry {\n\t\t\t\t\tinsertContext.rows.push(insertContext.rowParser(values))\n\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (e instanceof ParseError) {\n\t\t\t\t\t\tthrow new ImportError(`Invalid row ${JSON.stringify(values)} for table ${options.table}: ${e.message}`)\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow e\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (insertContext.rows.length === batchSize) {\n\t\t\t\t\tawait insertRowsPromise\n\t\t\t\t\tinsertRowsPromise = this.insertRows(db, insertContext)\n\t\t\t\t\tinsertContext.insertedRowCount += insertContext.rows.length\n\t\t\t\t\tinsertContext.rows = []\n\t\t\t\t}\n\n\t\t\t\treturn await it.next()\n\t\t\t},\n\t\t})\n\n\t\tif (insertContext.rows.length > 0) {\n\t\t\tawait insertRowsPromise\n\t\t\tawait this.insertRows(db, insertContext)\n\t\t\tinsertContext.insertedRowCount += insertContext.rows.length\n\t\t\tinsertContext.rows = []\n\t\t}\n\n\t\tif (result === null || result.commandName !== 'insertEnd') {\n\t\t\tthrow new ImportError(`Missing insertEnd command`)\n\t\t}\n\n\t\treturn await result.next()\n\t}\n\n\tprivate async createProjectContainer(groupContainer: ProjectGroupContainer, projectSlug: string) {\n\t\tconst projectContainerResolver = groupContainer.projectContainerResolver\n\t\tconst projectContainer = await projectContainerResolver.getProjectContainer(projectSlug, { alias: true })\n\n\t\tif (projectContainer === undefined) {\n\t\t\tthrow new ImportError(`Project ${projectSlug} does not exists.`)\n\t\t}\n\n\t\treturn projectContainer\n\t}\n\n\tprivate async requireImportAccess(groupContainer: ProjectGroupContainer, schema: Schema, authResult: AuthResult, projectSlug: string, kind: 'content' | 'system') {\n\t\tconst { effective: memberships } = await groupContainer.projectMembershipResolver.resolveMemberships({\n\t\t\trequest: { get: () => '' },\n\t\t\tacl: schema.acl,\n\t\t\tprojectSlug: projectSlug,\n\t\t\tidentity: {\n\t\t\t\tidentityId: authResult.identityId,\n\t\t\t\troles: authResult.roles,\n\t\t\t},\n\t\t})\n\n\t\tconst projectRoles = memberships.map(it => it.role)\n\n\t\tif (!projectRoles.some(role => schema.acl.roles[role]?.[kind]?.import)) {\n\t\t\tthrow new HttpErrorResponse(403, `You are not allowed to import ${kind} in ${projectSlug}`)\n\t\t}\n\t}\n\n\tprivate async fetchStageBySlug(systemDatabaseContext: DatabaseContext, projectSlug: string, stageSlug: string) {\n\t\tconst stage = await systemDatabaseContext.queryHandler.fetch(new StageBySlugQuery(stageSlug))\n\n\t\tif (stage === null) {\n\t\t\tthrow new ImportError(`Project ${projectSlug} does not have stage ${stageSlug}.`)\n\t\t}\n\n\t\treturn stage\n\t}\n\n\tprivate async disableTriggers(db: Client, tableNames: readonly string[]) {\n\t\tfor (const tableName of tableNames) {\n\t\t\tconst tableNameQuoted = `${wrapIdentifier(db.schema)}.${wrapIdentifier(tableName)}`\n\t\t\tawait db.query(`ALTER TABLE ${tableNameQuoted} DISABLE TRIGGER USER`)\n\t\t}\n\t}\n\n\tprivate async enableTriggers(db: Client, tableNames: readonly string[]) {\n\t\tfor (const tableName of tableNames) {\n\t\t\tconst tableNameQuoted = `${wrapIdentifier(db.schema)}.${wrapIdentifier(tableName)}`\n\t\t\tawait db.query(`ALTER TABLE ${tableNameQuoted} ENABLE TRIGGER USER`)\n\t\t}\n\t}\n\n\tprivate async lockTables(db: Client, tableNames: readonly string[]) {\n\t\tconst tableNamesQuoted = tableNames.map(it => `${wrapIdentifier(db.schema)}.${wrapIdentifier(it)}`)\n\t\tawait db.query(`LOCK ${tableNamesQuoted.join(', ')} IN EXCLUSIVE MODE`)\n\t}\n\n\tprivate async truncateTables(db: Client, tableNames: readonly string[]) {\n\t\tconst tableNamesQuoted = tableNames.map(it => `${wrapIdentifier(db.schema)}.${wrapIdentifier(it)}`)\n\t\tawait db.query(`TRUNCATE ${tableNamesQuoted.join(', ')}`)\n\t}\n\n\tprivate async insertRows(db: Client, context: InsertContext) {\n\t\tconst rowsFragment = context.rows.map(_ => context.rowFragment).join(',\\n')\n\t\tconst sql = context.insertStartFragment + rowsFragment\n\t\tconst parameters: Cell[] = []\n\n\t\tfor (const row of context.rows) {\n\t\t\tfor (const cell of row) {\n\t\t\t\tparameters.push(cell)\n\t\t\t}\n\t\t}\n\n\t\treturn await db.query(sql, parameters)\n\t}\n\n\tprivate async buildInsertContext(db: Client, mapping: TransferMapping, schema: string, tableName: string, columnNames: readonly string[]): Promise<InsertContext> {\n\t\tconst tableMapping = mapping.tables[tableName]\n\t\tconst columns = []\n\n\t\tif (tableMapping === undefined) {\n\t\t\tthrow new ImportError(`Unknown table ${tableName}`)\n\t\t}\n\n\t\tfor (const columnName of columnNames) {\n\t\t\tconst column = tableMapping.columns[columnName]\n\n\t\t\tif (column === undefined) {\n\t\t\t\tthrow new ImportError(`Unknown column ${tableName}.${columnName}`)\n\t\t\t}\n\n\t\t\tcolumns.push(column)\n\t\t}\n\n\t\tconst insertStartFragment = (tableMapping.createInsertStartFragment ?? this.createInsertStartFragment)(schema, tableName, columnNames)\n\t\tconst rowFragment = '(' + columns.map(_ => '?').join(', ') + ')'\n\t\tconst rowParser = await this.buildRowParser(db, tableMapping, columns)\n\n\t\treturn {\n\t\t\ttableName,\n\t\t\tinsertStartFragment,\n\t\t\trowFragment,\n\t\t\trowParser,\n\t\t\trows: [],\n\t\t\tinsertedRowCount: 0,\n\t\t}\n\t}\n\n\tprivate createInsertStartFragment(schema: string, tableName: string, columnNames: readonly string[]): string {\n\t\tconst tableQuoted = `${wrapIdentifier(schema)}.${wrapIdentifier(tableName)}`\n\t\tconst columnsQuoted = '(' + columnNames.map(it => wrapIdentifier(it)).join(', ') + ')'\n\t\treturn `INSERT INTO ${tableQuoted} ${columnsQuoted} VALUES\\n`\n\t}\n\n\tprivate async buildRowParser(db: Client, tableMapping: TransferTableMapping, columns: DbColumnSchema[]): Promise<Typesafe.Type<readonly Cell[]>> {\n\t\tconst baseType = Typesafe.tuple(...columns.map(it => {\n\t\t\tconst base = this.buildColumnRuntimeType(it.type)\n\t\t\treturn it.nullable ? Typesafe.nullable(base) : base\n\t\t}))\n\n\t\tif (tableMapping.createRowParser === undefined) {\n\t\t\treturn baseType\n\t\t}\n\n\t\treturn await tableMapping.createRowParser(db, columns.map(it => it.name), baseType)\n\t}\n\n\tprivate buildColumnRuntimeType(columnType: Model.ColumnType): Typesafe.Type<Exclude<Cell, null>> {\n\t\tswitch (columnType) {\n\t\t\tcase Model.ColumnType.Uuid: return Typesafe.string // TODO\n\t\t\tcase Model.ColumnType.String: return Typesafe.string\n\t\t\tcase Model.ColumnType.Int: return Typesafe.number // TODO\n\t\t\tcase Model.ColumnType.Double: return Typesafe.number\n\t\t\tcase Model.ColumnType.Bool: return Typesafe.boolean\n\t\t\tcase Model.ColumnType.Enum: return Typesafe.string // TODO\n\t\t\tcase Model.ColumnType.DateTime: return Typesafe.string // TODO\n\t\t\tcase Model.ColumnType.Date: return Typesafe.string // TODO\n\t\t\tcase Model.ColumnType.Json: return Typesafe.string\n\t\t}\n\t}\n}\n"],"names":["it","ConstraintHelper","schema","ParseError","HttpErrorResponse","StageBySlugQuery","wrapIdentifier","Typesafe","Model"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBO,MAAM,oBAAoB,MAAM;AACvC;AAKA,MAAM,gBAAqD;AAAA,EAClD,YACS,aACA,aACC,iBAChB;AAHe,SAAA,cAAA;AACA,SAAA,cAAA;AACC,SAAA,kBAAA;AAAA,EAAA;AAAA,EAIlB,aAAoB,OAAO,UAAmE;AAC7F,UAAM,kBAAkB,SAAS,OAAO,aAAa,EAAE;AACjD,UAAA,SAAS,MAAM,gBAAgB,KAAK;AAE1C,QAAI,OAAO,MAAM;AACT,aAAA;AAAA,IAAA;AAGR,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,OAAO;AAC/B,WAAO,IAAI,gBAAgB,MAAM,MAAM,eAAe;AAAA,EAAA;AAAA,EAGvD,MAAM,OAAwC;AAC7C,UAAM,SAAS,MAAM,KAAK,gBAAgB,KAAK;AAE/C,QAAI,OAAO,MAAM;AACT,aAAA;AAAA,IAAA;AAGR,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,OAAO;AAC/B,WAAO,IAAI,gBAAgB,MAAM,MAAM,KAAK,eAAe;AAAA,EAAA;AAE7D;AAEO,MAAM,eAAe;AAAA,EAC3B,YACkB,qCACA,oCACA,0BAChB;AAHgB,SAAA,sCAAA;AACA,SAAA,qCAAA;AACA,SAAA,2BAAA;AAAA,EAAA;AAAA,EAIlB,MAAM,OAAO,gBAAuC,YAAwB,UAAkC;AAC7G,UAAM,KAAK,MAAM,gBAAgB,OAAO,QAAQ;AAEhD,UAAM,QAAQ,MAAM,KAAK,MAAM,IAAI;AAAA,MAClC,0BAA0B,CAAAA,QAAM,KAAK,yBAAyB,gBAAgB,YAAYA,GAAE;AAAA,MAC5F,yBAAyB,CAAAA,QAAM,KAAK,wBAAwB,gBAAgB,YAAYA,GAAE;AAAA,IAAA,CAC1F;AAED,QAAI,UAAU,MAAM;AACnB,YAAM,IAAI,YAAY,cAAc,MAAM,WAAW,EAAE;AAAA,IAAA;AAAA,EACxD;AAAA,EAGD,MAAc,MAA6B,IAA+B,YAAoC;AAC7G,QAAI,OAA+B;AAEnC,WAAO,SAAS,MAAM;AACf,YAAA,YAAY,WAAW,KAAK,WAAW;AAE7C,UAAI,WAAW;AACP,eAAA,MAAM,UAAU,IAAW;AAAA,MAAA,OAE5B;AACN;AAAA,MAAA;AAAA,IACD;AAGM,WAAA;AAAA,EAAA;AAAA,EAGR,MAAc,yBAAyB,gBAAuC,YAAwB,IAAiD;AAChJ,UAAA,CAAC,OAAO,IAAI,GAAG;AACrB,UAAM,mBAAmB,MAAM,KAAK,uBAAuB,gBAAgB,QAAQ,OAAO;AAC1F,UAAM,wBAAwB,iBAAiB;AACzC,UAAA,QAAQ,MAAM,KAAK,iBAAiB,uBAAuB,QAAQ,SAAS,QAAQ,KAAK;AAE/F,UAAM,gBAAgB,MAAM,iBAAiB,sBAAsB,UAAU,EAAE,IAAI,uBAAuB,OAAO,MAAM,MAAM,WAAW,MAAM;AAE9I,QAAI,cAAc,KAAK,YAAY,QAAQ,eAAe;AACnD,YAAA,IAAI,YAAY,+CAA+C,QAAQ,aAAa,kCAAkC,cAAc,KAAK,OAAO,GAAG;AAAA,IAAA;AAGpJ,UAAA,KAAK,oBAAoB,gBAAgB,cAAc,QAAQ,YAAY,QAAQ,SAAS,SAAS;AAC3G,UAAM,wBAAwB,iBAAiB,WAAW,aAAa,MAAM,QAAQ,EAAE;AACvF,UAAM,UAAU,KAAK,oCAAoC,2BAA2B,cAAc,MAAM;AAExG,WAAO,MAAM,sBAAsB,YAAY,OAAM,OAAM;AAC1D,YAAM,KAAK,gBAAgB,IAAI,QAAQ,MAAM;AAC7C,YAAM,KAAK,WAAW,IAAI,QAAQ,MAAM;AACxC,YAAM,KAAK,eAAe,IAAI,QAAQ,MAAM;AAE5C,YAAM,WAAW,MAAM,KAAK,yBAAyB,gBAAgB,IAAI,GAAG,MAAM;AAClF,YAAM,mBAAmB,IAAIC,0BAAiB,IAAI,QAAQ;AACpD,YAAA,iBAAiB,uBAAuB,YAAY;AAE1D,YAAM,SAAS,MAAM,KAAK,MAAM,MAAM,GAAG,QAAQ;AAAA,QAChD,gBAAgB,CAAAD,QAAM,KAAK,eAAe,IAAI,SAASA,GAAE;AAAA,QACzD,aAAa,CAAAA,QAAM,KAAK,YAAY,IAAI,SAASA,GAAE;AAAA,MAAA,CACnD;AAEK,YAAA,iBAAiB,wBAAwB,YAAY;AAC3D,YAAM,KAAK,eAAe,IAAI,QAAQ,MAAM;AAErC,aAAA;AAAA,IAAA,CACP;AAAA,EAAA;AAAA,EAGF,MAAc,wBAAwB,gBAAuC,YAAwB,IAAgD;AAC9I,UAAA,CAAC,OAAO,IAAI,GAAG;AACrB,UAAM,mBAAmB,MAAM,KAAK,uBAAuB,gBAAgB,QAAQ,OAAO;AAC1F,UAAME,UAAS,MAAM,eAAe,sBAAsB,UAAU,QAAQ,OAAO;AAEnF,QAAIA,YAAW,QAAW;AACzB,YAAM,IAAI,YAAY,WAAW,QAAQ,OAAO,uBAAuB;AAAA,IAAA;AAGxE,UAAM,KAAK,oBAAoB,gBAAgBA,SAAQ,YAAY,QAAQ,SAAS,QAAQ;AAC5F,UAAM,wBAAwB,iBAAiB;AACzC,UAAA,UAAU,KAAK,mCAAmC,MAAM;AAE9D,WAAO,MAAM,sBAAsB,OAAO,YAAY,OAAM,OAAM;AACjE,YAAM,KAAK,eAAe,IAAI,QAAQ,MAAM;AAE5C,YAAM,WAAW,MAAM,KAAK,yBAAyB,gBAAgB,IAAI,GAAG,MAAM;AAClF,YAAM,mBAAmB,IAAID,0BAAiB,IAAI,QAAQ;AACpD,YAAA,iBAAiB,uBAAuB,YAAY;AAE1D,aAAO,MAAM,KAAK,MAAM,MAAM,GAAG,QAAQ;AAAA,QACxC,aAAa,CAAAD,QAAM,KAAK,YAAY,IAAI,SAASA,GAAE;AAAA,MAAA,CACnD;AAAA,IAAA,CACD;AAAA,EAAA;AAAA,EAGF,MAAc,eAAe,IAAwC,SAA0B,IAAwE;AAChK,UAAA,CAAC,OAAO,IAAI,GAAG;AAErB,UAAM,GAAG;AAAA,MACR;AAAA,MACA,CAAC,GAAG,GAAG,MAAM,IAAI,QAAQ,KAAK,IAAI,QAAQ,QAAQ,QAAQ,KAAK;AAAA,IAChE;AAEA,WAAO,GAAG,KAAK;AAAA,EAAA;AAAA,EAGhB,MAAc,YAAY,IAAwC,SAA0B,IAAqE;AAC1J,UAAA,CAAC,OAAO,IAAI,GAAG;AACf,UAAA,gBAAgB,MAAM,KAAK,mBAAmB,IAAI,SAAS,GAAG,QAAQ,QAAQ,OAAO,QAAQ,OAAO;AAC1G,QAAI,oBAAuD;AAG3D,UAAM,YAAY,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,KAAK,MAAM,QAAQ,QAAQ,QAAQ,MAAM,CAAC,CAAC;AAExF,UAAM,SAAS,MAAM,KAAK,MAAM,MAAM,GAAG,QAAQ;AAAA,MAChD,WAAW,OAAMA,QAAM;AAChB,cAAA,CAAC,MAAM,IAAIA,IAAG;AAEhB,YAAA;AACH,wBAAc,KAAK,KAAK,cAAc,UAAU,MAAM,CAAC;AAAA,iBAE/C,GAAG;AACX,cAAI,aAAaG,SAAAA,YAAY;AAC5B,kBAAM,IAAI,YAAY,eAAe,KAAK,UAAU,MAAM,CAAC,cAAc,QAAQ,KAAK,KAAK,EAAE,OAAO,EAAE;AAAA,UAAA,OAEhG;AACA,kBAAA;AAAA,UAAA;AAAA,QACP;AAGG,YAAA,cAAc,KAAK,WAAW,WAAW;AACtC,gBAAA;AACc,8BAAA,KAAK,WAAW,IAAI,aAAa;AACvC,wBAAA,oBAAoB,cAAc,KAAK;AACrD,wBAAc,OAAO,CAAC;AAAA,QAAA;AAGhB,eAAA,MAAMH,IAAG,KAAK;AAAA,MAAA;AAAA,IACtB,CACA;AAEG,QAAA,cAAc,KAAK,SAAS,GAAG;AAC5B,YAAA;AACA,YAAA,KAAK,WAAW,IAAI,aAAa;AACzB,oBAAA,oBAAoB,cAAc,KAAK;AACrD,oBAAc,OAAO,CAAC;AAAA,IAAA;AAGvB,QAAI,WAAW,QAAQ,OAAO,gBAAgB,aAAa;AACpD,YAAA,IAAI,YAAY,2BAA2B;AAAA,IAAA;AAG3C,WAAA,MAAM,OAAO,KAAK;AAAA,EAAA;AAAA,EAG1B,MAAc,uBAAuB,gBAAuC,aAAqB;AAChG,UAAM,2BAA2B,eAAe;AAC1C,UAAA,mBAAmB,MAAM,yBAAyB,oBAAoB,aAAa,EAAE,OAAO,MAAM;AAExG,QAAI,qBAAqB,QAAW;AACnC,YAAM,IAAI,YAAY,WAAW,WAAW,mBAAmB;AAAA,IAAA;AAGzD,WAAA;AAAA,EAAA;AAAA,EAGR,MAAc,oBAAoB,gBAAuCE,SAAgB,YAAwB,aAAqB,MAA4B;AACjK,UAAM,EAAE,WAAW,YAAA,IAAgB,MAAM,eAAe,0BAA0B,mBAAmB;AAAA,MACpG,SAAS,EAAE,KAAK,MAAM,GAAG;AAAA,MACzB,KAAKA,QAAO;AAAA,MACZ;AAAA,MACA,UAAU;AAAA,QACT,YAAY,WAAW;AAAA,QACvB,OAAO,WAAW;AAAA,MAAA;AAAA,IACnB,CACA;AAED,UAAM,eAAe,YAAY,IAAI,CAAA,OAAM,GAAG,IAAI;AAElD,QAAI,CAAC,aAAa,KAAK,CAAA,SAAQA,QAAO,IAAI,MAAM,IAAI,IAAI,IAAI,GAAG,MAAM,GAAG;AACvE,YAAM,IAAIE,aAAAA,kBAAkB,KAAK,iCAAiC,IAAI,OAAO,WAAW,EAAE;AAAA,IAAA;AAAA,EAC3F;AAAA,EAGD,MAAc,iBAAiB,uBAAwC,aAAqB,WAAmB;AACxG,UAAA,QAAQ,MAAM,sBAAsB,aAAa,MAAM,IAAIC,gBAAAA,iBAAiB,SAAS,CAAC;AAE5F,QAAI,UAAU,MAAM;AACnB,YAAM,IAAI,YAAY,WAAW,WAAW,wBAAwB,SAAS,GAAG;AAAA,IAAA;AAG1E,WAAA;AAAA,EAAA;AAAA,EAGR,MAAc,gBAAgB,IAAY,YAA+B;AACxE,eAAW,aAAa,YAAY;AAC7B,YAAA,kBAAkB,GAAGC,SAAAA,eAAe,GAAG,MAAM,CAAC,IAAIA,SAAAA,eAAe,SAAS,CAAC;AACjF,YAAM,GAAG,MAAM,eAAe,eAAe,uBAAuB;AAAA,IAAA;AAAA,EACrE;AAAA,EAGD,MAAc,eAAe,IAAY,YAA+B;AACvE,eAAW,aAAa,YAAY;AAC7B,YAAA,kBAAkB,GAAGA,SAAAA,eAAe,GAAG,MAAM,CAAC,IAAIA,SAAAA,eAAe,SAAS,CAAC;AACjF,YAAM,GAAG,MAAM,eAAe,eAAe,sBAAsB;AAAA,IAAA;AAAA,EACpE;AAAA,EAGD,MAAc,WAAW,IAAY,YAA+B;AACnE,UAAM,mBAAmB,WAAW,IAAI,CAAA,OAAM,GAAGA,SAAAA,eAAe,GAAG,MAAM,CAAC,IAAIA,SAAe,eAAA,EAAE,CAAC,EAAE;AAClG,UAAM,GAAG,MAAM,QAAQ,iBAAiB,KAAK,IAAI,CAAC,oBAAoB;AAAA,EAAA;AAAA,EAGvE,MAAc,eAAe,IAAY,YAA+B;AACvE,UAAM,mBAAmB,WAAW,IAAI,CAAA,OAAM,GAAGA,SAAAA,eAAe,GAAG,MAAM,CAAC,IAAIA,SAAe,eAAA,EAAE,CAAC,EAAE;AAClG,UAAM,GAAG,MAAM,YAAY,iBAAiB,KAAK,IAAI,CAAC,EAAE;AAAA,EAAA;AAAA,EAGzD,MAAc,WAAW,IAAY,SAAwB;AACtD,UAAA,eAAe,QAAQ,KAAK,IAAI,OAAK,QAAQ,WAAW,EAAE,KAAK,KAAK;AACpE,UAAA,MAAM,QAAQ,sBAAsB;AAC1C,UAAM,aAAqB,CAAC;AAEjB,eAAA,OAAO,QAAQ,MAAM;AAC/B,iBAAW,QAAQ,KAAK;AACvB,mBAAW,KAAK,IAAI;AAAA,MAAA;AAAA,IACrB;AAGD,WAAO,MAAM,GAAG,MAAM,KAAK,UAAU;AAAA,EAAA;AAAA,EAGtC,MAAc,mBAAmB,IAAY,SAA0BJ,SAAgB,WAAmB,aAAwD;AAC3J,UAAA,eAAe,QAAQ,OAAO,SAAS;AAC7C,UAAM,UAAU,CAAC;AAEjB,QAAI,iBAAiB,QAAW;AAC/B,YAAM,IAAI,YAAY,iBAAiB,SAAS,EAAE;AAAA,IAAA;AAGnD,eAAW,cAAc,aAAa;AAC/B,YAAA,SAAS,aAAa,QAAQ,UAAU;AAE9C,UAAI,WAAW,QAAW;AACzB,cAAM,IAAI,YAAY,kBAAkB,SAAS,IAAI,UAAU,EAAE;AAAA,MAAA;AAGlE,cAAQ,KAAK,MAAM;AAAA,IAAA;AAGpB,UAAM,uBAAuB,aAAa,6BAA6B,KAAK,2BAA2BA,SAAQ,WAAW,WAAW;AAC/H,UAAA,cAAc,MAAM,QAAQ,IAAI,OAAK,GAAG,EAAE,KAAK,IAAI,IAAI;AAC7D,UAAM,YAAY,MAAM,KAAK,eAAe,IAAI,cAAc,OAAO;AAE9D,WAAA;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,CAAC;AAAA,MACP,kBAAkB;AAAA,IACnB;AAAA,EAAA;AAAA,EAGO,0BAA0BA,SAAgB,WAAmB,aAAwC;AACtG,UAAA,cAAc,GAAGI,wBAAeJ,OAAM,CAAC,IAAII,SAAAA,eAAe,SAAS,CAAC;AACpE,UAAA,gBAAgB,MAAM,YAAY,IAAI,CAAA,OAAMA,SAAe,eAAA,EAAE,CAAC,EAAE,KAAK,IAAI,IAAI;AAC5E,WAAA,eAAe,WAAW,IAAI,aAAa;AAAA;AAAA,EAAA;AAAA,EAGnD,MAAc,eAAe,IAAY,cAAoC,SAAoE;AAChJ,UAAM,WAAWC,oBAAS,MAAM,GAAG,QAAQ,IAAI,CAAM,OAAA;AACpD,YAAM,OAAO,KAAK,uBAAuB,GAAG,IAAI;AAChD,aAAO,GAAG,WAAWA,oBAAS,SAAS,IAAI,IAAI;AAAA,IAAA,CAC/C,CAAC;AAEE,QAAA,aAAa,oBAAoB,QAAW;AACxC,aAAA;AAAA,IAAA;AAGD,WAAA,MAAM,aAAa,gBAAgB,IAAI,QAAQ,IAAI,CAAM,OAAA,GAAG,IAAI,GAAG,QAAQ;AAAA,EAAA;AAAA,EAG3E,uBAAuB,YAAkE;AAChG,YAAQ,YAAY;AAAA,MACnB,KAAKC,OAAAA,MAAM,WAAW;AAAM,eAAOD,oBAAS;AAAA,MAC5C,KAAKC,OAAAA,MAAM,WAAW;AAAQ,eAAOD,oBAAS;AAAA,MAC9C,KAAKC,OAAAA,MAAM,WAAW;AAAK,eAAOD,oBAAS;AAAA,MAC3C,KAAKC,OAAAA,MAAM,WAAW;AAAQ,eAAOD,oBAAS;AAAA,MAC9C,KAAKC,OAAAA,MAAM,WAAW;AAAM,eAAOD,oBAAS;AAAA,MAC5C,KAAKC,OAAAA,MAAM,WAAW;AAAM,eAAOD,oBAAS;AAAA,MAC5C,KAAKC,OAAAA,MAAM,WAAW;AAAU,eAAOD,oBAAS;AAAA,MAChD,KAAKC,OAAAA,MAAM,WAAW;AAAM,eAAOD,oBAAS;AAAA,MAC5C,KAAKC,OAAAA,MAAM,WAAW;AAAM,eAAOD,oBAAS;AAAA,IAAA;AAAA,EAC7C;AAEF;;;"}