@things-factory/ops-master 10.1.206 → 10.1.208
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/bootstrap.js +1 -1
- package/dist-client/bootstrap.js.map +1 -1
- package/dist-client/pages/master/reference-targets.d.ts +1 -1
- package/dist-client/pages/master/reference-targets.js +2 -2
- package/dist-client/pages/master/reference-targets.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/master-axis.d.ts +1 -1
- package/dist-server/service/master-axis.js.map +1 -1
- package/dist-server/service/master-change-policy.d.ts +1 -1
- package/dist-server/service/master-change-policy.js +1 -1
- package/dist-server/service/master-change-policy.js.map +1 -1
- package/dist-server/service/material/material-revision-service.js +11 -15
- package/dist-server/service/material/material-revision-service.js.map +1 -1
- package/dist-server/service/recipe/recipe-revision-service.js +12 -16
- package/dist-server/service/recipe/recipe-revision-service.js.map +1 -1
- package/dist-server/service/row-lock.d.ts +22 -0
- package/dist-server/service/row-lock.js +31 -0
- package/dist-server/service/row-lock.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-revision-service.js +11 -15
- package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/translations/ko.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipe-revision-service.js","sourceRoot":"","sources":["../../../server/service/recipe/recipe-revision-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport { EntityManager, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'\nimport { Refusal, writeLockSupported } from '@things-factory/shell'\nimport { masterChangePolicy } from '../master-change-policy'\nimport { RecipeDefinition } from './recipe-definition'\nimport { RecipeRevisionInput, RecipeRevisionOutput } from './recipe-revision-line'\nimport { MaterialDefinition } from '../material/material-definition'\nimport { OperationDefinition } from '../operation/operation-definition'\nimport { RouteDefinition } from './route-definition'\nimport { readRecipeContent, recipeContentValues, RecipeDraftContent } from './recipe-revision-content'\nimport {\n RecipeBasis,\n RecipePlan,\n RecipeRevision,\n RecipeSegment\n} from './recipe-revision'\nimport { approvalInputMatches, releaseKinds } from '../master-change-approval/approval-input'\n\nasync function saveLines(\n manager: EntityManager, domainId: string, recipeId: string, revisionId: string,\n inputs: RecipeDraftContent['inputs'], outputs: RecipeDraftContent['outputs']\n) {\n const header = await manager.findOneByOrFail(RecipeRevision, { id: revisionId, domain: { id: domainId } })\n const route = header.route ? await manager.findOneBy(RouteDefinition, { domain: { id: domainId }, name: header.route }) : null\n if (header.route && !route) refuse('INVALID_RECIPE_REFERENCE', 'Route not found in this domain.')\n for (const [entity, lines] of [[RecipeRevisionInput, inputs], [RecipeRevisionOutput, outputs]] as const) {\n for (const [position, line] of lines.entries()) {\n const material = await manager.findOneBy(MaterialDefinition, { domain: { id: domainId }, name: line.material })\n if (!material) refuse('INVALID_RECIPE_REFERENCE', `Material not found: ${line.material}`)\n const operation = line.operation ? await manager.findOneBy(OperationDefinition, { domain: { id: domainId }, name: line.operation }) : null\n if (line.operation && (!operation || !route?.steps.includes(line.operation)))\n refuse('INVALID_RECIPE_REFERENCE', 'Input operation must exist in the selected route.')\n const values = {\n domain: { id: domainId }, recipe: { id: recipeId }, revision: { id: revisionId },\n materialDefinition: { id: material.id }, material: material.name,\n lineKey: line.lineKey, position, qty: line.qty\n }\n if (entity === RecipeRevisionInput) {\n await manager.save(RecipeRevisionInput, manager.create(RecipeRevisionInput, {\n ...values, operationDefinition: operation ? { id: operation.id } : null, operation: operation?.name ?? null\n }))\n } else {\n await manager.save(RecipeRevisionOutput, manager.create(RecipeRevisionOutput, values))\n }\n }\n }\n}\n\nasync function headerReferences(manager: EntityManager, domainId: string, content: RecipeDraftContent) {\n const primaryMaterial = await manager.findOneBy(MaterialDefinition, { domain: { id: domainId }, name: content.materialDefinitionName })\n const routeDefinition = content.route ? await manager.findOneBy(RouteDefinition, { domain: { id: domainId }, name: content.route }) : null\n if (!primaryMaterial || (content.route && !routeDefinition)) refuse('INVALID_RECIPE_REFERENCE')\n return { primaryMaterial: { id: primaryMaterial.id }, routeDefinition: routeDefinition ? { id: routeDefinition.id } : null }\n}\n\nexport class RecipeRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? RECIPE_REFUSALS[code] ?? 'The recipe change could not be applied.'\n )\n }\n}\nconst RECIPE_REFUSALS: Record<string, string> = {\n TRANSACTION_REQUIRED: 'This change requires a transaction.',\n INVALID_INSTANT: 'Enter a valid date and time including its time zone.',\n INVALID_CONTENT: 'The proposed recipe content is invalid.',\n INVALID_RECIPE_REFERENCE: 'A recipe material, operation or route is invalid in this domain.',\n RECIPE_NOT_FOUND: 'The recipe does not exist in this domain.',\n REVISION_NOT_FOUND: 'The revision does not exist in this domain.',\n INVALID_BASE_REVISION: 'The proposed change is based on a different revision.',\n DRAFT_NOT_OWNED: 'Only the draft author can edit or submit it.',\n REVISION_FROZEN: 'This submitted revision cannot be edited. Create another draft.',\n DRAFT_CONFLICT: 'The draft changed. Reload it before saving.',\n PLAN_CONFLICT: 'The approved schedule changed. Review and submit a new draft.',\n INVALID_SUBMISSION: 'The submitted content does not match the frozen revision.',\n AUTHOR_CANNOT_APPROVE: 'The author cannot approve their own change.',\n RETROACTIVE_IMPACT: 'This change would alter a recipe already used by a recorded execution.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the execution time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the execution time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This execution already has a different recipe or execution time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the recipe through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new RecipeRefusal(code, detail)\n}\nfunction transaction(manager: EntityManager) {\n if (!manager.queryRunner?.isTransactionActive) refuse('TRANSACTION_REQUIRED')\n}\n/** Current reads are required after waiting for the subject lock, including MySQL REPEATABLE READ. */\nfunction currentLock(manager: EntityManager) {\n return writeLockSupported(manager) ? { lock: { mode: 'pessimistic_write' as const } } : {}\n}\nfunction instant(value: Date | string): Date {\n if (!(value instanceof Date) && (typeof value !== 'string' || !/(Z|[+-]\\d{2}:\\d{2})$/.test(value)))\n refuse('INVALID_INSTANT')\n const result = new Date(value)\n if (!Number.isFinite(result.getTime())) refuse('INVALID_INSTANT')\n return result\n}\nfunction text(value: unknown, field: string): string {\n if (typeof value !== 'string' || !value.trim()) refuse('INVALID_CONTENT', field)\n return value.trim()\n}\n/** Sorted object keys, ordered arrays, ISO instants. This is the v1 submission encoding. */\nfunction canonical(value: any): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map(canonical).join(',') + ']'\n return (\n '{' +\n Object.keys(value)\n .sort()\n .map(key => JSON.stringify(key) + ':' + canonical(value[key]))\n .join(',') +\n '}'\n )\n}\nexport function recipeSubmissionHash(revision: RecipeRevision): string {\n return createHash('sha256')\n .update(\n canonical({\n schemaVersion: 1,\n revisionNumber: revision.revisionNumber,\n policyId: revision.policyId,\n domainId: revision.domainId,\n recipeId: revision.recipeId,\n primaryMaterialId: revision.primaryMaterialId,\n routeDefinitionId: revision.routeDefinitionId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n ...recipeContentValues(revision),\n inputReferences: revision.inputs.map(line => [line.lineKey, line.materialDefinitionId, line.operationDefinitionId]),\n outputReferences: revision.outputs.map(line => [line.lineKey, line.materialDefinitionId]),\n effectiveFrom: revision.effectiveFrom.toISOString(),\n reason: revision.reason\n })\n )\n .digest('hex')\n}\n\n/** Display values are a checked projection of the frozen revision, never a second editable source. */\nexport async function recipeApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== recipeSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const recipe = await subject(manager, domainId, draft.recipeId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(RecipePlan, {\n domain: { id: domainId }, recipe: { id: draft.recipeId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(RecipeSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n /*\n * How the base was published (2026-10-20) — the approval screen names a baseline base in plain words. Only the\n * base carries it: it was published before this draft existed and never changes, so the snapshot stays pinned.\n * The proposal is unpublished here and would read differently once published.\n */\n const basePlan = base ? await manager.findOneBy(RecipePlan, { domain: { id: domainId }, publishedRevision: { id: base.id } }) : null\n const values = (row: RecipeRevision) => ({\n revisionNumber: row.revisionNumber, ...recipeContentValues(row),\n detail: {\n revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),\n effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,\n ...(row.id === base?.id ? { releaseKind: basePlan?.releaseKind ?? null } : {}),\n ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})\n }\n })\n return {\n headline: recipe.name,\n reason: draft.reason,\n effectiveFrom: draft.effectiveFrom.toISOString(),\n before: base ? values(base) : null,\n after: values(draft),\n revision: {\n revisionId: draft.id,\n hash: draft.contentHash,\n recipeId: draft.recipeId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertRecipeApprovalInput(\n manager: EntityManager,\n domainId: string,\n input: Record<string, unknown>\n) {\n const reference = input?.revision as { revisionId?: string }\n if (typeof reference?.revisionId !== 'string') refuse('INVALID_SUBMISSION')\n const expected = await recipeApprovalInput(manager, domainId, reference.revisionId)\n if (!approvalInputMatches(input, expected)) refuse('INVALID_SUBMISSION')\n}\n\nasync function subject(manager: EntityManager, domainId: string, recipeId: string) {\n const recipe = await manager.findOne(RecipeDefinition, {\n where: { id: recipeId, domain: { id: domainId } },\n ...currentLock(manager)\n })\n if (!recipe) refuse('RECIPE_NOT_FOUND')\n // Compare the current head and latest persisted plan in one SQL snapshot. A historical\n // knownAt query must not compare its selected old plan with the current head.\n const head = await manager.createQueryBuilder(RecipeDefinition, 'head')\n .leftJoin(RecipePlan, 'plan', 'plan.recipe = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: recipeId, domain: { id: domainId } })\n .groupBy('head.id').addGroupBy('head.planGeneration')\n .getRawOne()\n if (!head || Number(head.generation) !== Number(head.latest ?? 0)) {\n throw new Refusal('PLAN_INTEGRITY_FAILURE', {}, 'The current plan generation does not match the latest published plan. Contact an administrator.')\n }\n return recipe\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(RecipeRevision, {\n where: { id: revisionId, domain: { id: domainId } },\n relations: { inputs: true, outputs: true },\n ...(locked ? currentLock(manager) : {})\n })\n if (!found) refuse('REVISION_NOT_FOUND')\n found.inputs.sort((a, b) => a.position - b.position)\n found.outputs.sort((a, b) => a.position - b.position)\n return found\n}\n/** A write lock valid on every supported SQL backend, including SQLite (no SELECT FOR UPDATE). */\nasync function lockSubject(manager: EntityManager, domainId: string, recipeId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(RecipeDefinition)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: recipeId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('RECIPE_NOT_FOUND')\n return subject(manager, domainId, recipeId)\n}\n\nexport async function createRecipeDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { recipeId?: string; name?: string; baseRevisionId?: string; content: RecipeDraftContent }\n) {\n transaction(manager)\n const accepted = readRecipeContent(asked.content)\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n let recipe: RecipeDefinition\n if (asked.recipeId) {\n recipe = await lockSubject(manager, domainId, asked.recipeId)\n } else {\n recipe = await manager.save(\n RecipeDefinition,\n manager.create(RecipeDefinition, {\n domain: { id: domainId },\n name: text(asked.name, 'name'),\n materialDefinitionName: accepted.materialDefinitionName,\n inputs: [],\n outputs: [],\n planGeneration: 0,\n revisionLock: 0,\n creator: { id: creatorId },\n updater: { id: creatorId }\n })\n )\n }\n const previous = await manager.findOne(RecipeRevision, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id } }, order: { revisionNumber: 'DESC' },\n ...currentLock(manager)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (recipe.planGeneration > 0) {\n baseRevisionId = (await resolveRecipe(manager, domainId, recipe.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const { inputs, outputs, ...header } = accepted\n const saved = await manager.save(\n RecipeRevision,\n manager.create(RecipeRevision, {\n ...header,\n ...await headerReferences(manager, domainId, accepted),\n policy: { id: policy.id },\n domain: { id: domainId },\n recipe: { id: recipe.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: recipe.planGeneration,\n revisionNumber,\n editGeneration: 0,\n creator: { id: creatorId },\n createdAt: new Date(),\n frozenAt: null,\n contentHash: null,\n activityInstanceId: null\n })\n )\n await saveLines(manager, domainId, recipe.id, saved.id, inputs, outputs)\n return revision(manager, domainId, saved.id)\n}\n\nexport async function editRecipeDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: RecipeDraftContent\n) {\n transaction(manager)\n const accepted = readRecipeContent(input)\n const initial = await revision(manager, domainId, revisionId, false)\n const recipe = await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.baseGeneration !== recipe.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n recipe.planGeneration > 0\n ? (await resolveRecipe(manager, domainId, recipe.id, accepted.effectiveFrom)).revision.id\n : null\n const { inputs, outputs, ...header } = accepted\n const updated = await manager\n .createQueryBuilder()\n .update(RecipeRevision)\n .set({\n ...header,\n ...await headerReferences(manager, domainId, accepted),\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n editGeneration: expectedEditGeneration + 1\n })\n .where({\n id: revisionId,\n domain: { id: domainId },\n creator: { id: actorId },\n editGeneration: expectedEditGeneration\n })\n .andWhere('frozen_at IS NULL')\n .execute()\n if (updated.affected !== 1) refuse('DRAFT_CONFLICT')\n await manager.delete(RecipeRevisionInput, { revision: { id: revisionId }, domain: { id: domainId } })\n await manager.delete(RecipeRevisionOutput, { revision: { id: revisionId }, domain: { id: domainId } })\n await saveLines(manager, domainId, recipe.id, revisionId, inputs, outputs)\n return revision(manager, domainId, revisionId)\n}\n\n/** Product calls this in the same transaction as issuing its worklist approval. */\nexport async function freezeRecipeDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const recipe = await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.editGeneration !== expectedEditGeneration) refuse('DRAFT_CONFLICT')\n if (draft.baseGeneration !== recipe.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n readRecipeContent(draft)\n const contentHash = recipeSubmissionHash(draft)\n await manager.update(\n RecipeRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindRecipeApproval(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n activityInstanceId: string\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n RecipeRevision,\n { id: revisionId, domain: { id: domainId } },\n { activityInstanceId: text(activityInstanceId, 'activityInstanceId') }\n )\n}\n\n/** Internal completion callback only. Never expose this as an approved=true mutation. */\nexport async function publishRecipeRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { activityInstanceId: string; approverId: string; submissionHash: string }\n) {\n return publishRevision(manager, domainId, revisionId, {\n kind: 'approved',\n activityInstanceId: decision.activityInstanceId,\n actorId: decision.approverId,\n submissionHash: decision.submissionHash\n })\n}\n\nexport async function publishUnregulatedRecipe(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n editGeneration: number\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.recipeId)\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(RecipePlan, {\n domain: { id: domainId },\n publishedRevision: { id: revisionId },\n releaseKind: 'policy'\n })\n if (prior) {\n if (prior.publisherId !== actorId) refuse('DRAFT_NOT_OWNED')\n return prior\n }\n const frozen = await freezeRecipeDraft(manager, domainId, actorId, revisionId, editGeneration)\n return publishRevision(manager, domainId, revisionId, { kind: 'policy', actorId, submissionHash: frozen.contentHash })\n}\n\nasync function publishRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { kind: 'approved' | 'policy'; activityInstanceId?: string; actorId: string; submissionHash: string }\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const recipe = await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (\n !draft.frozenAt ||\n (decision.kind === 'approved'\n ? draft.activityInstanceId !== decision.activityInstanceId\n : !!draft.activityInstanceId) ||\n draft.contentHash !== decision.submissionHash ||\n recipeSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n if (policy.approvalRequired !== (decision.kind === 'approved'))\n throw new Refusal('MASTER_APPROVAL_POLICY_MISMATCH', {}, 'Use the publication path required by the domain policy.')\n if (decision.kind === 'approved' && draft.creatorId === decision.actorId) refuse('AUTHOR_CANNOT_APPROVE')\n text(decision.actorId, 'publisher')\n const previousDecision = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...currentLock(manager)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== recipe.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n if (\n await manager.findOne(RecipeBasis, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...currentLock(manager)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id }, generation: recipe.planGeneration },\n ...currentLock(manager)\n })\n if (recipe.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(RecipeSegment, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id }, plan: { id: oldPlan.id } },\n order: { validFrom: 'ASC' },\n ...currentLock(manager)\n })\n : []\n // Do not silently erase an already approved future appointment.\n if (oldSegments.some(segment => segment.validFrom >= draft.effectiveFrom)) refuse('FUTURE_PLAN_CONFLICT')\n const recordedAt = new Date()\n const plan = await manager.save(\n RecipePlan,\n manager.create(RecipePlan, {\n domain: { id: domainId },\n recipe: { id: recipe.id },\n generation: recipe.planGeneration + 1,\n recordedAt,\n activityInstanceId: decision.activityInstanceId ?? null,\n submissionHash: decision.submissionHash,\n approver: decision.kind === 'approved' ? { id: decision.actorId } : null,\n publisher: { id: decision.actorId },\n releaseKind: decision.kind,\n publishedRevision: { id: revisionId },\n policy: { id: policy.id }\n })\n )\n for (const old of oldSegments) {\n await manager.save(\n RecipeSegment,\n manager.create(RecipeSegment, {\n domain: { id: domainId },\n recipe: { id: recipe.id },\n plan: { id: plan.id },\n revision: { id: old.revisionId },\n validFrom: old.validFrom,\n validTo: !old.validTo || old.validTo > draft.effectiveFrom ? draft.effectiveFrom : old.validTo\n })\n )\n }\n await manager.save(\n RecipeSegment,\n manager.create(RecipeSegment, {\n domain: { id: domainId },\n recipe: { id: recipe.id },\n plan: { id: plan.id },\n revision: { id: revisionId },\n validFrom: draft.effectiveFrom,\n validTo: null\n })\n )\n const advanced = await manager.update(\n RecipeDefinition,\n { id: recipe.id, domain: { id: domainId }, planGeneration: recipe.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveRecipe(\n manager: EntityManager,\n domainId: string,\n recipeId: string,\n businessTime: Date | string,\n knownAt: Date | string = new Date()\n) {\n const at = instant(businessTime)\n const known = instant(knownAt)\n const plan = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, recipe: { id: recipeId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...currentLock(manager)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n await subject(manager, domainId, recipeId)\n const query = manager\n .createQueryBuilder(RecipeSegment, 'segment')\n .where({ domain: { id: domainId }, recipe: { id: recipeId }, plan: { id: plan.id } })\n .andWhere('segment.validFrom <= :at', { at })\n .andWhere('(segment.validTo IS NULL OR segment.validTo > :at)', { at })\n if (currentLock(manager).lock) query.setLock('pessimistic_write')\n const segments = await query.getMany()\n if (!segments.length) await refuseBeforeBaseline(manager, domainId, recipeId, at)\n if (segments.length !== 1) refuse(segments.length ? 'AMBIGUOUS_EFFECTIVITY' : 'NO_EFFECTIVE_REVISION')\n const selected = await revision(manager, domainId, segments[0].revisionId)\n if (!selected.frozenAt || selected.contentHash !== recipeSubmissionHash(selected))\n refuse('REVISION_INTEGRITY_FAILURE')\n return { revision: selected, plan, segment: segments[0] }\n}\n\n/** 기준선보다 앞선 시각은 모른다고 말한다 — 검사 명세의 같은 자리를 보라(2026-09-24). */\nasync function refuseBeforeBaseline(manager: EntityManager, domainId: string, recipeId: string, at: Date) {\n const first = await manager.findOneBy(RecipePlan, {\n domain: { id: domainId }, recipe: { id: recipeId }, generation: 1, releaseKind: 'baseline'\n })\n if (!first) return\n const recorded = await manager.findOneBy(RecipeRevision, { domain: { id: domainId }, id: first.publishedRevisionId })\n if (recorded && at < recorded.effectiveFrom)\n throw new Refusal(\n 'BEFORE_BASELINE',\n { baselineAt: recorded.effectiveFrom.toISOString() },\n `This master was first recorded at ${recorded.effectiveFrom.toISOString()}; nothing is known about it before then.`\n )\n}\n\n/**\n * **개정본이 하나도 없는 제조법**마다 지금 서 있는 행을 첫 개정본으로 적는다 — 기준선(2026-09-24).\n * 규칙은 검사 명세의 `standTestSpecificationBaselines` 와 같다. 제조법만의 것 둘:\n *\n * - 옛 행의 줄에는 `lineKey` 가 없다. **자리로 붙인다** — `input-1` · `output-1`. plant 시드가 쓰는 규칙과\n * 같고, 줄의 차례가 뜻을 가지는 모델이라 자리에서 온 키는 내용을 바꾸지 않는다.\n * - 품목 · 공정 · 경로는 이름으로 가리킨다. **쓰기 전에 전부 대조한다** — 줄을 쓰다가 거절되면 반쯤 쓴\n * 개정본이 트랜잭션에 남는다. 없는 것을 가리키는 행은 세우지 않고 까닭을 남긴다.\n */\nexport async function standRecipeBaselines(manager: EntityManager, domainId: string, at: Date, edition: string) {\n transaction(manager)\n const roots = await manager\n .createQueryBuilder(RecipeDefinition, 'recipe')\n .leftJoin(RecipeRevision, 'rev', 'rev.recipe_id = recipe.id AND rev.domain_id = recipe.domain_id')\n .where('recipe.domain_id = :domainId', { domainId })\n .andWhere('rev.id IS NULL')\n .getMany()\n const outcome = { stood: 0, unreadable: [] as { name: string; problem: string }[] }\n if (!roots.length) return outcome\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n const where = { where: { domain: { id: domainId } } }\n const materials = new Set((await manager.find(MaterialDefinition, where)).map(one => one.name))\n const operations = new Set((await manager.find(OperationDefinition, where)).map(one => one.name))\n const routes = new Map((await manager.find(RouteDefinition, where)).map(one => [one.name, one] as const))\n const keyed = (rows: any, side: 'input' | 'output') =>\n Array.isArray(rows) ? rows.map((row, index) => ({ ...row, lineKey: row?.lineKey ?? `${side}-${index + 1}` })) : rows\n for (const root of roots) {\n if (root.planGeneration !== 0) {\n outcome.unreadable.push({ name: root.name, problem: 'plan without revision' })\n continue\n }\n let read: ReturnType<typeof recipeContentValues>\n try {\n read = recipeContentValues({\n materialDefinitionName: root.materialDefinitionName,\n description: root.description ?? null,\n route: root.route ?? null,\n inputs: keyed(root.inputs, 'input'),\n outputs: keyed(root.outputs, 'output')\n } as any)\n } catch (error: any) {\n outcome.unreadable.push({ name: root.name, problem: error?.message ?? String(error) })\n continue\n }\n const route = read.route ? routes.get(read.route) : null\n const missing = [\n ...(materials.has(read.materialDefinitionName) ? [] : [`material ${read.materialDefinitionName}`]),\n ...(read.route && !route ? [`route ${read.route}`] : []),\n ...[...read.inputs, ...read.outputs].filter(line => !materials.has(line.material)).map(line => `material ${line.material}`),\n ...read.inputs\n .filter(line => line.operation && (!operations.has(line.operation) || !route?.steps.includes(line.operation)))\n .map(line => `operation ${line.operation} in route ${read.route ?? '(none)'}`)\n ]\n if (missing.length) {\n outcome.unreadable.push({ name: root.name, problem: 'points at what this domain does not have: ' + [...new Set(missing)].join(', ') })\n continue\n }\n const validFrom = root.effectiveStart && root.effectiveStart > at ? root.effectiveStart : at\n const validTo = root.effectiveEnd ?? null\n const { inputs, outputs, ...header } = read\n const saved = await manager.save(\n RecipeRevision,\n manager.create(RecipeRevision, {\n ...header,\n effectiveFrom: validFrom,\n reason: `baseline: the row as it stood, recorded by ${edition}`,\n ...await headerReferences(manager, domainId, read as any),\n policy: { id: policy.id },\n domain: { id: domainId },\n recipe: { id: root.id },\n baseRevision: null,\n baseGeneration: 0,\n revisionNumber: 1,\n editGeneration: 0,\n creator: null,\n createdAt: at,\n frozenAt: at,\n contentHash: null,\n activityInstanceId: null\n })\n )\n await saveLines(manager, domainId, root.id, saved.id, inputs, outputs)\n const stood = await revision(manager, domainId, saved.id)\n const contentHash = recipeSubmissionHash(stood)\n await manager.update(RecipeRevision, { id: stood.id, domain: { id: domainId } }, { contentHash })\n const plan = await manager.save(\n RecipePlan,\n manager.create(RecipePlan, {\n domain: { id: domainId },\n recipe: { id: root.id },\n generation: 1,\n recordedAt: at,\n activityInstanceId: null,\n submissionHash: contentHash,\n approver: null,\n publisher: null,\n releaseKind: 'baseline',\n publishedRevision: { id: stood.id },\n policy: { id: policy.id }\n })\n )\n if (!validTo || validTo > validFrom) {\n await manager.save(\n RecipeSegment,\n manager.create(RecipeSegment, {\n domain: { id: domainId },\n recipe: { id: root.id },\n plan: { id: plan.id },\n revision: { id: stood.id },\n validFrom,\n validTo\n })\n )\n }\n const advanced = await manager.update(\n RecipeDefinition,\n { id: root.id, domain: { id: domainId }, planGeneration: 0 },\n { planGeneration: 1 }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n outcome.stood++\n }\n return outcome\n}\n\n/** Replay reads verify the captured digest too, not only the currently effective schedule. */\nexport async function recipeRevisionForBasis(manager: EntityManager, domainId: string, basis: RecipeBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.recipeId !== basis.recipeId || !selected.frozenAt || selected.contentHash !== basis.contentHash || recipeSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n if (selected.routeDefinitionId ? (\n basis.routeSnapshot?.id !== selected.routeDefinitionId ||\n basis.routeHash !== createHash('sha256').update(canonical(basis.routeSnapshot)).digest('hex')\n ) : (basis.routeSnapshot !== null || basis.routeHash !== null)) refuse('REVISION_INTEGRITY_FAILURE')\n return selected\n}\n\n/** Must run inside the transaction that writes the execution result. */\nexport async function captureRecipeBasis(\n manager: EntityManager,\n domainId: string,\n recipeId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, recipeId)\n const existing = await manager.findOne(RecipeBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...currentLock(manager)\n })\n if (existing) {\n if (existing.recipeId !== recipeId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await recipeRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveRecipe(manager, domainId, recipeId, at, resolvedAt)\n const route = selected.revision.routeDefinitionId ? await manager.findOne(RouteDefinition, {\n where: { id: selected.revision.routeDefinitionId, domain: { id: domainId } }, ...currentLock(manager)\n }) : null\n if (selected.revision.routeDefinitionId && (!route ||\n (route.effectiveStart && route.effectiveStart > at) || (route.effectiveEnd && route.effectiveEnd <= at)))\n refuse('INVALID_RECIPE_REFERENCE', 'The referenced route is not effective at execution time.')\n if (selected.revision.inputs.some(line => line.operation && !route?.steps.includes(line.operation)))\n refuse('INVALID_RECIPE_REFERENCE', 'The current route no longer contains a required input operation.')\n const routeSnapshot = route ? {\n id: route.id, name: route.name, steps: route.steps, procedure: route.procedure ?? null\n } : null\n const saved = await manager.save(\n RecipeBasis,\n manager.create(RecipeBasis, {\n domain: { id: domainId },\n recipe: { id: recipeId },\n recordKey: text(recordKey, 'recordKey'),\n businessTime: at,\n resolvedAt,\n routeSnapshot,\n routeHash: routeSnapshot ? createHash('sha256').update(canonical(routeSnapshot)).digest('hex') : null,\n revision: { id: selected.revision.id },\n contentHash: selected.revision.contentHash,\n plan: { id: selected.plan.id }\n })\n )\n return manager.findOneByOrFail(RecipeBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function recipeRevisionOverview(\n manager: EntityManager,\n domainId: string,\n recipeId: string,\n at = new Date()\n) {\n const recipe = await subject(manager, domainId, recipeId)\n const revisions = await manager.find(RecipeRevision, {\n where: { domain: { id: domainId }, recipe: { id: recipeId } },\n relations: { inputs: true, outputs: true },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, recipe: { id: recipeId }, generation: recipe.planGeneration }\n })\n const schedule = plan\n ? await manager.find(RecipeSegment, {\n where: { domain: { id: domainId }, recipe: { id: recipeId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n /*\n * 개정본마다 **어떻게 발행됐는지**(`releaseKind`)를 함께 싣는다 — 발행한 적용계획의 값 그대로(2026-10-20).\n * 화면은 이것으로 기준선을 알아보고 사람의 말(「최초 기록」)로 적는다. 기준선의 사유는 서버가 쓴 기록\n * 문장인데 해시에 들어가 바꿀 수 없고, 문구로 알아보면 깨지기 쉽다. 발행 전 개정본은 null.\n */\n const kindOf = releaseKinds(await manager.findBy(RecipePlan, { domain: { id: domainId }, recipe: { id: recipeId } }))\n return {\n recipeId,\n name: recipe.name,\n generation: recipe.planGeneration,\n at: at.toISOString(),\n schedule: schedule.map(segment => ({\n ...segment,\n state: segment.validFrom > at ? 'scheduled' : segment.validTo && segment.validTo <= at ? 'expired' : 'current'\n })),\n revisions: revisions.map(item => ({ ...item,\n inputs: item.inputs.sort((a, b) => a.position - b.position),\n outputs: item.outputs.sort((a, b) => a.position - b.position),\n state: item.frozenAt ? 'frozen' : 'draft',\n releaseKind: kindOf(item.id) }))\n }\n}\n\n/** Read-time projection, never a clock-driven rewrite of the identity row. */\nexport async function effectiveRecipe(\n manager: EntityManager,\n domainId: string,\n recipe: RecipeDefinition,\n at = new Date()\n) {\n const selected = await resolveRecipe(manager, domainId, recipe.id, at)\n return Object.assign(new RecipeDefinition(), recipe, {\n description: selected.revision.description,\n ...recipeContentValues(selected.revision),\n effectiveStart: selected.segment.validFrom,\n effectiveEnd: selected.segment.validTo ?? undefined\n })\n}\n\n/**\n * **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).\n * 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.\n * 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —\n * 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.\n */\nexport async function saveAndPublishRecipe(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n asked: { recipeId?: string; name?: string; baseRevisionId?: string; content: RecipeDraftContent; revisionId?: string; editGeneration?: number }\n) {\n // Reuse the owned draft and its concurrency guard; publishing failure rolls back the edit too.\n if (asked.revisionId && !Number.isInteger(asked.editGeneration)) refuse('DRAFT_CONFLICT')\n const draft = asked.revisionId\n ? await editRecipeDraft(manager, domainId, actorId, asked.revisionId, asked.editGeneration!, asked.content)\n : await createRecipeDraft(manager, domainId, actorId, asked)\n const plan = await publishUnregulatedRecipe(manager, domainId, actorId, draft.id, draft.editGeneration)\n return { revision: await revision(manager, domainId, draft.id, false), plan }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"recipe-revision-service.js","sourceRoot":"","sources":["../../../server/service/recipe/recipe-revision-service.ts"],"names":[],"mappings":";;;AAsHA,oDAqBC;AAGD,kDAuCC;AAED,8DASC;AA8CD,8CA4DC;AAED,0CA4CC;AAGD,8CAwBC;AAED,gDAgBC;AAGD,sDAYC;AAED,4DAwBC;AAwGD,sCA6BC;AA0BD,oDAkHC;AAGD,wDAWC;AAGD,gDA+CC;AAED,wDA0CC;AAGD,0CAaC;AAQD,oDAaC;AAh1BD,6CAAwC;AACxC,qCAAyE;AACzE,iDAA+C;AAC/C,kEAA4D;AAC5D,2DAAsD;AACtD,iEAAkF;AAClF,yEAAoE;AACpE,4EAAuE;AACvE,yDAAoD;AACpD,uEAAsG;AACtG,uDAK0B;AAC1B,6EAA6F;AAC7F,0CAAqD;AAErD,KAAK,UAAU,SAAS,CACtB,OAAsB,EAAE,QAAgB,EAAE,QAAgB,EAAE,UAAkB,EAC9E,MAAoC,EAAE,OAAsC;IAE5E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,gCAAc,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC1G,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,kCAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9H,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK;QAAE,MAAM,CAAC,0BAA0B,EAAE,iCAAiC,CAAC,CAAA;IACjG,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,0CAAmB,EAAE,MAAM,CAAC,EAAE,CAAC,2CAAoB,EAAE,OAAO,CAAC,CAAU,EAAE,CAAC;QACxG,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,wCAAkB,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;YAC/G,IAAI,CAAC,QAAQ;gBAAE,MAAM,CAAC,0BAA0B,EAAE,uBAAuB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;YACzF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,0CAAmB,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YAC1I,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC1E,MAAM,CAAC,0BAA0B,EAAE,mDAAmD,CAAC,CAAA;YACzF,MAAM,MAAM,GAAG;gBACb,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;gBAChF,kBAAkB,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI;gBAChE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG;aAC/C,CAAA;YACD,IAAI,MAAM,KAAK,0CAAmB,EAAE,CAAC;gBACnC,MAAM,OAAO,CAAC,IAAI,CAAC,0CAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,0CAAmB,EAAE;oBAC1E,GAAG,MAAM,EAAE,mBAAmB,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,IAAI,IAAI;iBAC5G,CAAC,CAAC,CAAA;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,CAAC,IAAI,CAAC,2CAAoB,EAAE,OAAO,CAAC,MAAM,CAAC,2CAAoB,EAAE,MAAM,CAAC,CAAC,CAAA;YACxF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAsB,EAAE,QAAgB,EAAE,OAA2B;IACnG,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,wCAAkB,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAA;IACvI,MAAM,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,kCAAe,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC1I,IAAI,CAAC,eAAe,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC;QAAE,MAAM,CAAC,0BAA0B,CAAC,CAAA;IAC/F,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AAC9H,CAAC;AAED,MAAa,aAAc,SAAQ,eAAO;IACxC,YAAY,IAAY,EAAE,MAAe;QACvC,KAAK,CACH,IAAI,EACJ,EAAE,EACF,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,yCAAyC,CAC7E,CAAA;IACH,CAAC;CACF;AARD,sCAQC;AACD,MAAM,eAAe,GAA2B;IAC9C,oBAAoB,EAAE,qCAAqC;IAC3D,eAAe,EAAE,sDAAsD;IACvE,eAAe,EAAE,yCAAyC;IAC1D,wBAAwB,EAAE,kEAAkE;IAC5F,gBAAgB,EAAE,2CAA2C;IAC7D,kBAAkB,EAAE,6CAA6C;IACjE,qBAAqB,EAAE,uDAAuD;IAC9E,eAAe,EAAE,8CAA8C;IAC/D,eAAe,EAAE,iEAAiE;IAClF,cAAc,EAAE,6CAA6C;IAC7D,aAAa,EAAE,+DAA+D;IAC9E,kBAAkB,EAAE,2DAA2D;IAC/E,qBAAqB,EAAE,6CAA6C;IACpE,kBAAkB,EAAE,wEAAwE;IAC5F,oBAAoB,EAAE,yDAAyD;IAC/E,qBAAqB,EAAE,iEAAiE;IACxF,qBAAqB,EAAE,4DAA4D;IACnF,0BAA0B,EAAE,wDAAwD;IACpF,cAAc,EAAE,kEAAkE;IAClF,sBAAsB,EAAE,2DAA2D;IACnF,iBAAiB,EAAE,6CAA6C;CACjE,CAAA;AACD,SAAS,MAAM,CAAC,IAAY,EAAE,MAAe;IAC3C,MAAM,IAAI,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC;AACD,SAAS,WAAW,CAAC,OAAsB;IACzC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,mBAAmB;QAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;AAC/E,CAAC;AACD,SAAS,OAAO,CAAC,KAAoB;IACnC,IAAI,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChG,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC3B,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAA;IAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;IACjE,OAAO,MAAM,CAAA;AACf,CAAC;AACD,SAAS,IAAI,CAAC,KAAc,EAAE,KAAa;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;QAAE,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAA;IAChF,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;AACrB,CAAC;AACD,4FAA4F;AAC5F,SAAS,SAAS,CAAC,KAAU;IAC3B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7E,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAA;IAC3E,OAAO,CACL,GAAG;QACH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aACf,IAAI,EAAE;aACN,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;aAC7D,IAAI,CAAC,GAAG,CAAC;QACZ,GAAG,CACJ,CAAA;AACH,CAAC;AACD,SAAgB,oBAAoB,CAAC,QAAwB;IAC3D,OAAO,IAAA,wBAAU,EAAC,QAAQ,CAAC;SACxB,MAAM,CACL,SAAS,CAAC;QACR,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;QAC7C,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;QAC7C,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,GAAG,IAAA,6CAAmB,EAAC,QAAQ,CAAC;QAChC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACnH,gBAAgB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACzF,aAAa,EAAE,QAAQ,CAAC,aAAa,CAAC,WAAW,EAAE;QACnD,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC,CACH;SACA,MAAM,CAAC,KAAK,CAAC,CAAA;AAClB,CAAC;AAED,sGAAsG;AAC/F,KAAK,UAAU,mBAAmB,CAAC,OAAsB,EAAE,QAAgB,EAAE,UAAkB;IACpG,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC3D,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,WAAW,KAAK,oBAAoB,CAAC,KAAK,CAAC;QAAE,MAAM,CAAC,oBAAoB,CAAC,CAAA;IACtG,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC/D,MAAM,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAClG,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,4BAAU,EAAE;QACtD,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,cAAc;KAC3F,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACT,MAAM,OAAO,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,+BAAa,EAAE;QACpE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;KAC3E,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACT;;;;OAIG;IACH,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,4BAAU,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACpI,MAAM,MAAM,GAAG,CAAC,GAAmB,EAAE,EAAE,CAAC,CAAC;QACvC,cAAc,EAAE,GAAG,CAAC,cAAc,EAAE,GAAG,IAAA,6CAAmB,EAAC,GAAG,CAAC;QAC/D,MAAM,EAAE;YACN,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE;YACjG,aAAa,EAAE,GAAG,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM;YAClE,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9E,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3I;KACF,CAAC,CAAA;IACF,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,IAAI;QACrB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE;QAChD,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QAClC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;QACpB,QAAQ,EAAE;YACR,UAAU,EAAE,KAAK,CAAC,EAAE;YACpB,IAAI,EAAE,KAAK,CAAC,WAAW;YACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC;KACF,CAAA;AACH,CAAC;AAEM,KAAK,UAAU,yBAAyB,CAC7C,OAAsB,EACtB,QAAgB,EAChB,KAA8B;IAE9B,MAAM,SAAS,GAAG,KAAK,EAAE,QAAmC,CAAA;IAC5D,IAAI,OAAO,SAAS,EAAE,UAAU,KAAK,QAAQ;QAAE,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC3E,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;IACnF,IAAI,CAAC,IAAA,qCAAoB,EAAC,KAAK,EAAE,QAAQ,CAAC;QAAE,MAAM,CAAC,oBAAoB,CAAC,CAAA;AAC1E,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,OAAsB,EAAE,QAAgB,EAAE,QAAgB;IAC/E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,oCAAgB,EAAE;QACrD,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;QACjD,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,oCAAgB,CAAC;KAC1C,CAAC,CAAA;IACF,IAAI,CAAC,MAAM;QAAE,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACvC,uFAAuF;IACvF,8EAA8E;IAC9E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC,oCAAgB,EAAE,MAAM,CAAC;SACpE,QAAQ,CAAC,4BAAU,EAAE,MAAM,EAAE,qDAAqD,CAAC;SACnF,MAAM,CAAC,qBAAqB,EAAE,YAAY,CAAC;SAC3C,SAAS,CAAC,sBAAsB,EAAE,QAAQ,CAAC;SAC3C,KAAK,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC;SACjD,OAAO,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,qBAAqB,CAAC;SACpD,SAAS,EAAE,CAAA;IACd,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,eAAO,CAAC,wBAAwB,EAAE,EAAE,EAAE,iGAAiG,CAAC,CAAA;IACpJ,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AACD,KAAK,UAAU,QAAQ,CAAC,OAAsB,EAAE,QAAgB,EAAE,UAAkB,EAAE,MAAM,GAAG,IAAI;IACjG,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,gCAAc,EAAE;QAClD,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;QACnD,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;QAC1C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,sBAAW,EAAC,OAAO,EAAE,gCAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACxD,CAAC,CAAA;IACF,IAAI,CAAC,KAAK;QAAE,MAAM,CAAC,oBAAoB,CAAC,CAAA;IACxC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IACpD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IACrD,OAAO,KAAK,CAAA;AACd,CAAC;AACD,kGAAkG;AAClG,KAAK,UAAU,WAAW,CAAC,OAAsB,EAAE,QAAgB,EAAE,QAAgB;IACnF,WAAW,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,MAAM,GAAG,MAAM,OAAO;SACzB,kBAAkB,EAAE;SACpB,MAAM,CAAC,oCAAgB,CAAC;SACxB,GAAG,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,mBAAmB,EAAE,CAAC;SAChD,KAAK,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC;SACjD,OAAO,EAAE,CAAA;IACZ,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;QAAE,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACrD,OAAO,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAC7C,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,OAAsB,EACtB,QAAgB,EAChB,SAAiB,EACjB,KAAiG;IAEjG,WAAW,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,QAAQ,GAAG,IAAA,2CAAiB,EAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACjD,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAA;IAC9E,IAAI,MAAwB,CAAA;IAC5B,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC/D,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CACzB,oCAAgB,EAChB,OAAO,CAAC,MAAM,CAAC,oCAAgB,EAAE;YAC/B,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACxB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;YAC9B,sBAAsB,EAAE,QAAQ,CAAC,sBAAsB;YACvD,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,EAAE;YACX,cAAc,EAAE,CAAC;YACjB,YAAY,EAAE,CAAC;YACf,OAAO,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;YAC1B,OAAO,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;SAC3B,CAAC,CACH,CAAA;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,gCAAc,EAAE;QACrD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE;QACjG,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,gCAAc,CAAC;KACxC,CAAC,CAAA;IACF,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,cAAc,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;IAC1D,IAAI,cAAc,GAAkB,IAAI,CAAA;IACxC,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;QAC9B,cAAc,GAAG,CAAC,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAA;IAC1G,CAAC;IACD,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,KAAK,cAAc;QAAE,MAAM,CAAC,uBAAuB,CAAC,CAAA;IACpG,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,QAAQ,CAAA;IAC/C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAC9B,gCAAc,EACd,OAAO,CAAC,MAAM,CAAC,gCAAc,EAAE;QAC7B,GAAG,MAAM;QACT,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACtD,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;QACzB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACxB,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;QACzB,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI;QAC5D,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,cAAc;QACd,cAAc,EAAE,CAAC;QACjB,OAAO,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;QAC1B,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,IAAI;QACjB,kBAAkB,EAAE,IAAI;KACzB,CAAC,CACH,CAAA;IACD,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACxE,OAAO,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;AAC9C,CAAC;AAEM,KAAK,UAAU,eAAe,CACnC,OAAsB,EACtB,QAAgB,EAChB,OAAe,EACf,UAAkB,EAClB,sBAA8B,EAC9B,KAAyB;IAEzB,WAAW,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,QAAQ,GAAG,IAAA,2CAAiB,EAAC,KAAK,CAAC,CAAA;IACzC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACrE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC3D,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO;QAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC1D,IAAI,KAAK,CAAC,QAAQ;QAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC7C,IAAI,KAAK,CAAC,cAAc,KAAK,MAAM,CAAC,cAAc;QAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IAC3E,kFAAkF;IAClF,MAAM,cAAc,GAClB,MAAM,CAAC,cAAc,GAAG,CAAC;QACvB,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;QACzF,CAAC,CAAC,IAAI,CAAA;IACV,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,QAAQ,CAAA;IAC/C,MAAM,OAAO,GAAG,MAAM,OAAO;SAC1B,kBAAkB,EAAE;SACpB,MAAM,CAAC,gCAAc,CAAC;SACtB,GAAG,CAAC;QACH,GAAG,MAAM;QACT,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACtD,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI;QAC5D,cAAc,EAAE,sBAAsB,GAAG,CAAC;KAC3C,CAAC;SACD,KAAK,CAAC;QACL,EAAE,EAAE,UAAU;QACd,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACxB,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;QACxB,cAAc,EAAE,sBAAsB;KACvC,CAAC;SACD,QAAQ,CAAC,mBAAmB,CAAC;SAC7B,OAAO,EAAE,CAAA;IACZ,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC;QAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACpD,MAAM,OAAO,CAAC,MAAM,CAAC,0CAAmB,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IACrG,MAAM,OAAO,CAAC,MAAM,CAAC,2CAAoB,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IACtG,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IAC1E,OAAO,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;AAChD,CAAC;AAED,mFAAmF;AAC5E,KAAK,UAAU,iBAAiB,CACrC,OAAsB,EACtB,QAAgB,EAChB,OAAe,EACf,UAAkB,EAClB,sBAA8B;IAE9B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACrE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC3D,IAAI,KAAK,CAAC,SAAS,KAAK,OAAO;QAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC1D,IAAI,KAAK,CAAC,QAAQ;QAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;IAC7C,IAAI,KAAK,CAAC,cAAc,KAAK,sBAAsB;QAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;IAC7E,IAAI,KAAK,CAAC,cAAc,KAAK,MAAM,CAAC,cAAc;QAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IAC3E,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAA;IAC9E,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IACzD,IAAA,2CAAiB,EAAC,KAAK,CAAC,CAAA;IACxB,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,OAAO,CAAC,MAAM,CAClB,gCAAc,EACd,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAC5C,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,WAAW,EAAE,CACtC,CAAA;IACD,OAAO,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;AAChD,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,OAAsB,EACtB,QAAgB,EAChB,UAAkB,EAClB,kBAA0B;IAE1B,WAAW,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC3D,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,kBAAkB;QAAE,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC7E,MAAM,OAAO,CAAC,MAAM,CAClB,gCAAc,EACd,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAC5C,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,EAAE,CACvE,CAAA;AACH,CAAC;AAED,yFAAyF;AAClF,KAAK,UAAU,qBAAqB,CACzC,OAAsB,EACtB,QAAgB,EAChB,UAAkB,EAClB,QAAoF;IAEpF,OAAO,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE;QACpD,IAAI,EAAE,UAAU;QAChB,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB;QAC/C,OAAO,EAAE,QAAQ,CAAC,UAAU;QAC5B,cAAc,EAAE,QAAQ,CAAC,cAAc;KACxC,CAAC,CAAA;AACJ,CAAC;AAEM,KAAK,UAAU,wBAAwB,CAC5C,OAAsB,EACtB,QAAgB,EAChB,OAAe,EACf,UAAkB,EAClB,cAAsB;IAEtB,WAAW,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAA;IAC9E,IAAI,MAAM,CAAC,gBAAgB;QACzB,MAAM,IAAI,eAAO,CAAC,0BAA0B,EAAE,EAAE,EAAE,wCAAwC,CAAC,CAAA;IAC7F,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,4BAAU,EAAE;QAChD,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACxB,iBAAiB,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;QACrC,WAAW,EAAE,QAAQ;KACtB,CAAC,CAAA;IACF,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO;YAAE,MAAM,CAAC,iBAAiB,CAAC,CAAA;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,CAAA;IAC9F,OAAO,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;AACxH,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,OAAsB,EACtB,QAAgB,EAChB,UAAkB,EAClB,QAA+G;IAE/G,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACrE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC3D,IACE,CAAC,KAAK,CAAC,QAAQ;QACf,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU;YAC3B,CAAC,CAAC,KAAK,CAAC,kBAAkB,KAAK,QAAQ,CAAC,kBAAkB;YAC1D,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;QAC/B,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC,cAAc;QAC7C,oBAAoB,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,cAAc;QAEvD,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC9B,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAA;IAC9E,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IACzD,IAAI,MAAM,CAAC,gBAAgB,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC;QAC5D,MAAM,IAAI,eAAO,CAAC,iCAAiC,EAAE,EAAE,EAAE,yDAAyD,CAAC,CAAA;IACrH,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,OAAO;QAAE,MAAM,CAAC,uBAAuB,CAAC,CAAA;IACzG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;IACnC,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,4BAAU,EAAE;QACzD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE;QAC1E,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,4BAAU,CAAC;KACpC,CAAC,CAAA;IACF,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAA;IAC7C,IAAI,KAAK,CAAC,cAAc,KAAK,MAAM,CAAC,cAAc;QAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IAC3E,qGAAqG;IACrG,IACE,MAAM,OAAO,CAAC,OAAO,CAAC,6BAAW,EAAE;QACjC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,IAAA,yBAAe,EAAC,KAAK,CAAC,aAAa,CAAC,EAAE;QAClH,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,6BAAW,CAAC;KACrC,CAAC;QAEF,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC9B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,4BAAU,EAAE;QAChD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE;QACjG,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,4BAAU,CAAC;KACpC,CAAC,CAAA;IACF,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,OAAO;QAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IAClE,MAAM,WAAW,GAAG,OAAO;QACzB,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,+BAAa,EAAE;YAChC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE;YACxF,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;YAC3B,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,+BAAa,CAAC;SACvC,CAAC;QACJ,CAAC,CAAC,EAAE,CAAA;IACN,gEAAgE;IAChE,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,aAAa,CAAC;QAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;IACzG,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAA;IAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAC7B,4BAAU,EACV,OAAO,CAAC,MAAM,CAAC,4BAAU,EAAE;QACzB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACxB,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;QACzB,UAAU,EAAE,MAAM,CAAC,cAAc,GAAG,CAAC;QACrC,UAAU;QACV,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,IAAI,IAAI;QACvD,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,QAAQ,EAAE,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;QACxE,SAAS,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,OAAO,EAAE;QACnC,WAAW,EAAE,QAAQ,CAAC,IAAI;QAC1B,iBAAiB,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;QACrC,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;KAC1B,CAAC,CACH,CAAA;IACD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,OAAO,CAAC,IAAI,CAChB,+BAAa,EACb,OAAO,CAAC,MAAM,CAAC,+BAAa,EAAE;YAC5B,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACxB,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;YACzB,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACrB,QAAQ,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,UAAU,EAAE;YAChC,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO;SAC/F,CAAC,CACH,CAAA;IACH,CAAC;IACD,MAAM,OAAO,CAAC,IAAI,CAChB,+BAAa,EACb,OAAO,CAAC,MAAM,CAAC,+BAAa,EAAE;QAC5B,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACxB,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;QACzB,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;QACrB,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;QAC5B,SAAS,EAAE,KAAK,CAAC,aAAa;QAC9B,OAAO,EAAE,IAAI;KACd,CAAC,CACH,CAAA;IACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CACnC,oCAAgB,EAChB,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,EAClF,EAAE,cAAc,EAAE,IAAI,CAAC,UAAU,EAAE,CACpC,CAAA;IACD,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC;QAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IACpD,OAAO,IAAI,CAAA;AACb,CAAC;AAEM,KAAK,UAAU,aAAa,CACjC,OAAsB,EACtB,QAAgB,EAChB,QAAgB,EAChB,YAA2B,EAC3B,UAAyB,IAAI,IAAI,EAAE;IAEnC,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,4BAAU,EAAE;QAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAA,yBAAe,EAAC,KAAK,CAAC,EAAE;QACjG,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;QAC7B,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,4BAAU,CAAC;KACpC,CAAC,CAAA;IACF,IAAI,CAAC,IAAI;QAAE,MAAM,CAAC,uBAAuB,CAAC,CAAA;IAC1C,MAAM,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC1C,MAAM,KAAK,GAAG,OAAO;SAClB,kBAAkB,CAAC,+BAAa,EAAE,SAAS,CAAC;SAC5C,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC;SACpF,QAAQ,CAAC,0BAA0B,EAAE,EAAE,EAAE,EAAE,CAAC;SAC5C,QAAQ,CAAC,oDAAoD,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;IACzE,IAAA,qBAAU,EAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC1B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAA;IACtC,IAAI,CAAC,QAAQ,CAAC,MAAM;QAAE,MAAM,oBAAoB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;IACjF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAA;IACtG,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;IAC1E,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,WAAW,KAAK,oBAAoB,CAAC,QAAQ,CAAC;QAC/E,MAAM,CAAC,4BAA4B,CAAC,CAAA;IACtC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;AAC3D,CAAC;AAED,4DAA4D;AAC5D,KAAK,UAAU,oBAAoB,CAAC,OAAsB,EAAE,QAAgB,EAAE,QAAgB,EAAE,EAAQ;IACtG,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,4BAAU,EAAE;QAChD,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU;KAC3F,CAAC,CAAA;IACF,IAAI,CAAC,KAAK;QAAE,OAAM;IAClB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,gCAAc,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,mBAAmB,EAAE,CAAC,CAAA;IACrH,IAAI,QAAQ,IAAI,EAAE,GAAG,QAAQ,CAAC,aAAa;QACzC,MAAM,IAAI,eAAO,CACf,iBAAiB,EACjB,EAAE,UAAU,EAAE,QAAQ,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,EACpD,qCAAqC,QAAQ,CAAC,aAAa,CAAC,WAAW,EAAE,0CAA0C,CACpH,CAAA;AACL,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,oBAAoB,CAAC,OAAsB,EAAE,QAAgB,EAAE,EAAQ,EAAE,OAAe;IAC5G,WAAW,CAAC,OAAO,CAAC,CAAA;IACpB,MAAM,KAAK,GAAG,MAAM,OAAO;SACxB,kBAAkB,CAAC,oCAAgB,EAAE,QAAQ,CAAC;SAC9C,QAAQ,CAAC,gCAAc,EAAE,KAAK,EAAE,gEAAgE,CAAC;SACjG,KAAK,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,CAAC;SACnD,QAAQ,CAAC,gBAAgB,CAAC;SAC1B,OAAO,EAAE,CAAA;IACZ,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,EAAyC,EAAE,CAAA;IACnF,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,OAAO,CAAA;IACjC,MAAM,MAAM,GAAG,MAAM,IAAA,yCAAkB,EAAC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAA;IAC9E,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;IACrD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,wCAAkB,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/F,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,0CAAmB,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IACjG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,kCAAe,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAU,CAAC,CAAC,CAAA;IACzG,MAAM,KAAK,GAAG,CAAC,IAAS,EAAE,IAAwB,EAAE,EAAE,CACpD,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACtH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAA;YAC9E,SAAQ;QACV,CAAC;QACD,IAAI,IAA4C,CAAA;QAChD,IAAI,CAAC;YACH,IAAI,GAAG,IAAA,6CAAmB,EAAC;gBACzB,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;gBACnD,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;gBACrC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI;gBACzB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;gBACnC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;aAChC,CAAC,CAAA;QACX,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACtF,SAAQ;QACV,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACxD,MAAM,OAAO,GAAG;YACd,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC;YAClG,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3H,GAAG,IAAI,CAAC,MAAM;iBACX,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;iBAC7G,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC,KAAK,IAAI,QAAQ,EAAE,CAAC;SACjF,CAAA;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,4CAA4C,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACtI,SAAQ;QACV,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAA;QAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAA;QACzC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;QAC3C,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAC9B,gCAAc,EACd,OAAO,CAAC,MAAM,CAAC,gCAAc,EAAE;YAC7B,GAAG,MAAM;YACT,aAAa,EAAE,SAAS;YACxB,MAAM,EAAE,8CAA8C,OAAO,EAAE;YAC/D,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAW,CAAC;YACzD,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;YACzB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACxB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACvB,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,CAAC;YACjB,cAAc,EAAE,CAAC;YACjB,cAAc,EAAE,CAAC;YACjB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,EAAE;YACb,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,IAAI;YACjB,kBAAkB,EAAE,IAAI;SACzB,CAAC,CACH,CAAA;QACD,MAAM,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;QACtE,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAA;QACzD,MAAM,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;QAC/C,MAAM,OAAO,CAAC,MAAM,CAAC,gCAAc,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAA;QACjG,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAC7B,4BAAU,EACV,OAAO,CAAC,MAAM,CAAC,4BAAU,EAAE;YACzB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;YACxB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;YACvB,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,EAAE;YACd,kBAAkB,EAAE,IAAI;YACxB,cAAc,EAAE,WAAW;YAC3B,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,UAAU;YACvB,iBAAiB,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;YACnC,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;SAC1B,CAAC,CACH,CAAA;QACD,IAAI,CAAC,OAAO,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;YACpC,MAAM,OAAO,CAAC,IAAI,CAChB,+BAAa,EACb,OAAO,CAAC,MAAM,CAAC,+BAAa,EAAE;gBAC5B,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;gBACxB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;gBACvB,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;gBACrB,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC1B,SAAS;gBACT,OAAO;aACR,CAAC,CACH,CAAA;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CACnC,oCAAgB,EAChB,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,EAC5D,EAAE,cAAc,EAAE,CAAC,EAAE,CACtB,CAAA;QACD,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC;YAAE,MAAM,CAAC,eAAe,CAAC,CAAA;QACpD,OAAO,CAAC,KAAK,EAAE,CAAA;IACjB,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,8FAA8F;AACvF,KAAK,UAAU,sBAAsB,CAAC,OAAsB,EAAE,QAAgB,EAAE,KAAkB;IACvG,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACzD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;IACpE,IAAI,QAAQ,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,IAAI,oBAAoB,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC;QACrK,MAAM,CAAC,4BAA4B,CAAC,CAAA;IACtC,CAAC;IACD,IAAI,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAC/B,KAAK,CAAC,aAAa,EAAE,EAAE,KAAK,QAAQ,CAAC,iBAAiB;QACtD,KAAK,CAAC,SAAS,KAAK,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAC9F,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,KAAK,IAAI,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;QAAE,MAAM,CAAC,4BAA4B,CAAC,CAAA;IACpG,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,wEAAwE;AACjE,KAAK,UAAU,kBAAkB,CACtC,OAAsB,EACtB,QAAgB,EAChB,QAAgB,EAChB,SAAiB,EACjB,YAA2B;IAE3B,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IAChC,MAAM,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC9C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,6BAAW,EAAE;QAClD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE;QAC9C,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,6BAAW,CAAC;KACrC,CAAC,CAAA;IACF,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE;YAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAChH,MAAM,sBAAsB,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;QACzD,OAAO,QAAQ,CAAA;IACjB,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAA;IAC7B,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,CAAC,CAAA;IACjF,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,kCAAe,EAAE;QACzF,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAG,IAAA,sBAAW,EAAC,OAAO,EAAE,kCAAe,CAAC;KACvH,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACT,IAAI,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,CAAC,KAAK;QAChD,CAAC,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QACxG,MAAM,CAAC,0BAA0B,EAAE,0DAA0D,CAAC,CAAA;IAChG,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjG,MAAM,CAAC,0BAA0B,EAAE,kEAAkE,CAAC,CAAA;IACxG,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,CAAC;QAC5B,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;KACvF,CAAC,CAAC,CAAC,IAAI,CAAA;IACR,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAC9B,6BAAW,EACX,OAAO,CAAC,MAAM,CAAC,6BAAW,EAAE;QAC1B,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACxB,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACxB,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC;QACvC,YAAY,EAAE,EAAE;QAChB,UAAU;QACV,aAAa;QACb,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,IAAA,wBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;QACrG,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE;QACtC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,WAAW;QAC1C,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE;KAC/B,CAAC,CACH,CAAA;IACD,OAAO,OAAO,CAAC,eAAe,CAAC,6BAAW,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;AACzF,CAAC;AAEM,KAAK,UAAU,sBAAsB,CAC1C,OAAsB,EACtB,QAAgB,EAChB,QAAgB,EAChB,EAAE,GAAG,IAAI,IAAI,EAAE;IAEf,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACzD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,gCAAc,EAAE;QACnD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;QAC7D,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE;QAC1C,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE;KACvC,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,4BAAU,EAAE;QAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE;KACjG,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,IAAI;QACnB,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,+BAAa,EAAE;YAChC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE;YACpF,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;SAC5B,CAAC;QACJ,CAAC,CAAC,EAAE,CAAA;IACN;;;;OAIG;IACH,MAAM,MAAM,GAAG,IAAA,6BAAY,EAAC,MAAM,OAAO,CAAC,MAAM,CAAC,4BAAU,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IACrH,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,UAAU,EAAE,MAAM,CAAC,cAAc;QACjC,EAAE,EAAE,EAAE,CAAC,WAAW,EAAE;QACpB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACjC,GAAG,OAAO;YACV,KAAK,EAAE,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;SAC/G,CAAC,CAAC;QACH,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI;YACzC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC3D,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC7D,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO;YACzC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;KACnC,CAAA;AACH,CAAC;AAED,8EAA8E;AACvE,KAAK,UAAU,eAAe,CACnC,OAAsB,EACtB,QAAgB,EAChB,MAAwB,EACxB,EAAE,GAAG,IAAI,IAAI,EAAE;IAEf,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACtE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,oCAAgB,EAAE,EAAE,MAAM,EAAE;QACnD,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,WAAW;QAC1C,GAAG,IAAA,6CAAmB,EAAC,QAAQ,CAAC,QAAQ,CAAC;QACzC,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,SAAS;QAC1C,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,SAAS;KACpD,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,oBAAoB,CACxC,OAAsB,EACtB,QAAgB,EAChB,OAAe,EACf,KAA+I;IAE/I,+FAA+F;IAC/F,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC;QAAE,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACzF,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU;QAC5B,CAAC,CAAC,MAAM,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,cAAe,EAAE,KAAK,CAAC,OAAO,CAAC;QAC3G,CAAC,CAAC,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IAC9D,MAAM,IAAI,GAAG,MAAM,wBAAwB,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,CAAA;IACvG,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;AAC/E,CAAC","sourcesContent":["import { createHash } from 'node:crypto'\nimport { EntityManager, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'\nimport { Refusal } from '@things-factory/shell'\nimport { masterChangePolicy } from '../master-change-policy'\nimport { RecipeDefinition } from './recipe-definition'\nimport { RecipeRevisionInput, RecipeRevisionOutput } from './recipe-revision-line'\nimport { MaterialDefinition } from '../material/material-definition'\nimport { OperationDefinition } from '../operation/operation-definition'\nimport { RouteDefinition } from './route-definition'\nimport { readRecipeContent, recipeContentValues, RecipeDraftContent } from './recipe-revision-content'\nimport {\n RecipeBasis,\n RecipePlan,\n RecipeRevision,\n RecipeSegment\n} from './recipe-revision'\nimport { approvalInputMatches, releaseKinds } from '../master-change-approval/approval-input'\nimport { lockRowsOf, writeLockOn } from '../row-lock'\n\nasync function saveLines(\n manager: EntityManager, domainId: string, recipeId: string, revisionId: string,\n inputs: RecipeDraftContent['inputs'], outputs: RecipeDraftContent['outputs']\n) {\n const header = await manager.findOneByOrFail(RecipeRevision, { id: revisionId, domain: { id: domainId } })\n const route = header.route ? await manager.findOneBy(RouteDefinition, { domain: { id: domainId }, name: header.route }) : null\n if (header.route && !route) refuse('INVALID_RECIPE_REFERENCE', 'Route not found in this domain.')\n for (const [entity, lines] of [[RecipeRevisionInput, inputs], [RecipeRevisionOutput, outputs]] as const) {\n for (const [position, line] of lines.entries()) {\n const material = await manager.findOneBy(MaterialDefinition, { domain: { id: domainId }, name: line.material })\n if (!material) refuse('INVALID_RECIPE_REFERENCE', `Material not found: ${line.material}`)\n const operation = line.operation ? await manager.findOneBy(OperationDefinition, { domain: { id: domainId }, name: line.operation }) : null\n if (line.operation && (!operation || !route?.steps.includes(line.operation)))\n refuse('INVALID_RECIPE_REFERENCE', 'Input operation must exist in the selected route.')\n const values = {\n domain: { id: domainId }, recipe: { id: recipeId }, revision: { id: revisionId },\n materialDefinition: { id: material.id }, material: material.name,\n lineKey: line.lineKey, position, qty: line.qty\n }\n if (entity === RecipeRevisionInput) {\n await manager.save(RecipeRevisionInput, manager.create(RecipeRevisionInput, {\n ...values, operationDefinition: operation ? { id: operation.id } : null, operation: operation?.name ?? null\n }))\n } else {\n await manager.save(RecipeRevisionOutput, manager.create(RecipeRevisionOutput, values))\n }\n }\n }\n}\n\nasync function headerReferences(manager: EntityManager, domainId: string, content: RecipeDraftContent) {\n const primaryMaterial = await manager.findOneBy(MaterialDefinition, { domain: { id: domainId }, name: content.materialDefinitionName })\n const routeDefinition = content.route ? await manager.findOneBy(RouteDefinition, { domain: { id: domainId }, name: content.route }) : null\n if (!primaryMaterial || (content.route && !routeDefinition)) refuse('INVALID_RECIPE_REFERENCE')\n return { primaryMaterial: { id: primaryMaterial.id }, routeDefinition: routeDefinition ? { id: routeDefinition.id } : null }\n}\n\nexport class RecipeRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? RECIPE_REFUSALS[code] ?? 'The recipe change could not be applied.'\n )\n }\n}\nconst RECIPE_REFUSALS: Record<string, string> = {\n TRANSACTION_REQUIRED: 'This change requires a transaction.',\n INVALID_INSTANT: 'Enter a valid date and time including its time zone.',\n INVALID_CONTENT: 'The proposed recipe content is invalid.',\n INVALID_RECIPE_REFERENCE: 'A recipe material, operation or route is invalid in this domain.',\n RECIPE_NOT_FOUND: 'The recipe does not exist in this domain.',\n REVISION_NOT_FOUND: 'The revision does not exist in this domain.',\n INVALID_BASE_REVISION: 'The proposed change is based on a different revision.',\n DRAFT_NOT_OWNED: 'Only the draft author can edit or submit it.',\n REVISION_FROZEN: 'This submitted revision cannot be edited. Create another draft.',\n DRAFT_CONFLICT: 'The draft changed. Reload it before saving.',\n PLAN_CONFLICT: 'The approved schedule changed. Review and submit a new draft.',\n INVALID_SUBMISSION: 'The submitted content does not match the frozen revision.',\n AUTHOR_CANNOT_APPROVE: 'The author cannot approve their own change.',\n RETROACTIVE_IMPACT: 'This change would alter a recipe already used by a recorded execution.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the execution time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the execution time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This execution already has a different recipe or execution time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the recipe through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new RecipeRefusal(code, detail)\n}\nfunction transaction(manager: EntityManager) {\n if (!manager.queryRunner?.isTransactionActive) refuse('TRANSACTION_REQUIRED')\n}\nfunction instant(value: Date | string): Date {\n if (!(value instanceof Date) && (typeof value !== 'string' || !/(Z|[+-]\\d{2}:\\d{2})$/.test(value)))\n refuse('INVALID_INSTANT')\n const result = new Date(value)\n if (!Number.isFinite(result.getTime())) refuse('INVALID_INSTANT')\n return result\n}\nfunction text(value: unknown, field: string): string {\n if (typeof value !== 'string' || !value.trim()) refuse('INVALID_CONTENT', field)\n return value.trim()\n}\n/** Sorted object keys, ordered arrays, ISO instants. This is the v1 submission encoding. */\nfunction canonical(value: any): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map(canonical).join(',') + ']'\n return (\n '{' +\n Object.keys(value)\n .sort()\n .map(key => JSON.stringify(key) + ':' + canonical(value[key]))\n .join(',') +\n '}'\n )\n}\nexport function recipeSubmissionHash(revision: RecipeRevision): string {\n return createHash('sha256')\n .update(\n canonical({\n schemaVersion: 1,\n revisionNumber: revision.revisionNumber,\n policyId: revision.policyId,\n domainId: revision.domainId,\n recipeId: revision.recipeId,\n primaryMaterialId: revision.primaryMaterialId,\n routeDefinitionId: revision.routeDefinitionId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n ...recipeContentValues(revision),\n inputReferences: revision.inputs.map(line => [line.lineKey, line.materialDefinitionId, line.operationDefinitionId]),\n outputReferences: revision.outputs.map(line => [line.lineKey, line.materialDefinitionId]),\n effectiveFrom: revision.effectiveFrom.toISOString(),\n reason: revision.reason\n })\n )\n .digest('hex')\n}\n\n/** Display values are a checked projection of the frozen revision, never a second editable source. */\nexport async function recipeApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== recipeSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const recipe = await subject(manager, domainId, draft.recipeId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(RecipePlan, {\n domain: { id: domainId }, recipe: { id: draft.recipeId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(RecipeSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n /*\n * How the base was published (2026-10-20) — the approval screen names a baseline base in plain words. Only the\n * base carries it: it was published before this draft existed and never changes, so the snapshot stays pinned.\n * The proposal is unpublished here and would read differently once published.\n */\n const basePlan = base ? await manager.findOneBy(RecipePlan, { domain: { id: domainId }, publishedRevision: { id: base.id } }) : null\n const values = (row: RecipeRevision) => ({\n revisionNumber: row.revisionNumber, ...recipeContentValues(row),\n detail: {\n revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),\n effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,\n ...(row.id === base?.id ? { releaseKind: basePlan?.releaseKind ?? null } : {}),\n ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})\n }\n })\n return {\n headline: recipe.name,\n reason: draft.reason,\n effectiveFrom: draft.effectiveFrom.toISOString(),\n before: base ? values(base) : null,\n after: values(draft),\n revision: {\n revisionId: draft.id,\n hash: draft.contentHash,\n recipeId: draft.recipeId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertRecipeApprovalInput(\n manager: EntityManager,\n domainId: string,\n input: Record<string, unknown>\n) {\n const reference = input?.revision as { revisionId?: string }\n if (typeof reference?.revisionId !== 'string') refuse('INVALID_SUBMISSION')\n const expected = await recipeApprovalInput(manager, domainId, reference.revisionId)\n if (!approvalInputMatches(input, expected)) refuse('INVALID_SUBMISSION')\n}\n\nasync function subject(manager: EntityManager, domainId: string, recipeId: string) {\n const recipe = await manager.findOne(RecipeDefinition, {\n where: { id: recipeId, domain: { id: domainId } },\n ...writeLockOn(manager, RecipeDefinition)\n })\n if (!recipe) refuse('RECIPE_NOT_FOUND')\n // Compare the current head and latest persisted plan in one SQL snapshot. A historical\n // knownAt query must not compare its selected old plan with the current head.\n const head = await manager.createQueryBuilder(RecipeDefinition, 'head')\n .leftJoin(RecipePlan, 'plan', 'plan.recipe = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: recipeId, domain: { id: domainId } })\n .groupBy('head.id').addGroupBy('head.planGeneration')\n .getRawOne()\n if (!head || Number(head.generation) !== Number(head.latest ?? 0)) {\n throw new Refusal('PLAN_INTEGRITY_FAILURE', {}, 'The current plan generation does not match the latest published plan. Contact an administrator.')\n }\n return recipe\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(RecipeRevision, {\n where: { id: revisionId, domain: { id: domainId } },\n relations: { inputs: true, outputs: true },\n ...(locked ? writeLockOn(manager, RecipeRevision) : {})\n })\n if (!found) refuse('REVISION_NOT_FOUND')\n found.inputs.sort((a, b) => a.position - b.position)\n found.outputs.sort((a, b) => a.position - b.position)\n return found\n}\n/** A write lock valid on every supported SQL backend, including SQLite (no SELECT FOR UPDATE). */\nasync function lockSubject(manager: EntityManager, domainId: string, recipeId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(RecipeDefinition)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: recipeId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('RECIPE_NOT_FOUND')\n return subject(manager, domainId, recipeId)\n}\n\nexport async function createRecipeDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { recipeId?: string; name?: string; baseRevisionId?: string; content: RecipeDraftContent }\n) {\n transaction(manager)\n const accepted = readRecipeContent(asked.content)\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n let recipe: RecipeDefinition\n if (asked.recipeId) {\n recipe = await lockSubject(manager, domainId, asked.recipeId)\n } else {\n recipe = await manager.save(\n RecipeDefinition,\n manager.create(RecipeDefinition, {\n domain: { id: domainId },\n name: text(asked.name, 'name'),\n materialDefinitionName: accepted.materialDefinitionName,\n inputs: [],\n outputs: [],\n planGeneration: 0,\n revisionLock: 0,\n creator: { id: creatorId },\n updater: { id: creatorId }\n })\n )\n }\n const previous = await manager.findOne(RecipeRevision, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id } }, order: { revisionNumber: 'DESC' },\n ...writeLockOn(manager, RecipeRevision)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (recipe.planGeneration > 0) {\n baseRevisionId = (await resolveRecipe(manager, domainId, recipe.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const { inputs, outputs, ...header } = accepted\n const saved = await manager.save(\n RecipeRevision,\n manager.create(RecipeRevision, {\n ...header,\n ...await headerReferences(manager, domainId, accepted),\n policy: { id: policy.id },\n domain: { id: domainId },\n recipe: { id: recipe.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: recipe.planGeneration,\n revisionNumber,\n editGeneration: 0,\n creator: { id: creatorId },\n createdAt: new Date(),\n frozenAt: null,\n contentHash: null,\n activityInstanceId: null\n })\n )\n await saveLines(manager, domainId, recipe.id, saved.id, inputs, outputs)\n return revision(manager, domainId, saved.id)\n}\n\nexport async function editRecipeDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: RecipeDraftContent\n) {\n transaction(manager)\n const accepted = readRecipeContent(input)\n const initial = await revision(manager, domainId, revisionId, false)\n const recipe = await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.baseGeneration !== recipe.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n recipe.planGeneration > 0\n ? (await resolveRecipe(manager, domainId, recipe.id, accepted.effectiveFrom)).revision.id\n : null\n const { inputs, outputs, ...header } = accepted\n const updated = await manager\n .createQueryBuilder()\n .update(RecipeRevision)\n .set({\n ...header,\n ...await headerReferences(manager, domainId, accepted),\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n editGeneration: expectedEditGeneration + 1\n })\n .where({\n id: revisionId,\n domain: { id: domainId },\n creator: { id: actorId },\n editGeneration: expectedEditGeneration\n })\n .andWhere('frozen_at IS NULL')\n .execute()\n if (updated.affected !== 1) refuse('DRAFT_CONFLICT')\n await manager.delete(RecipeRevisionInput, { revision: { id: revisionId }, domain: { id: domainId } })\n await manager.delete(RecipeRevisionOutput, { revision: { id: revisionId }, domain: { id: domainId } })\n await saveLines(manager, domainId, recipe.id, revisionId, inputs, outputs)\n return revision(manager, domainId, revisionId)\n}\n\n/** Product calls this in the same transaction as issuing its worklist approval. */\nexport async function freezeRecipeDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const recipe = await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.editGeneration !== expectedEditGeneration) refuse('DRAFT_CONFLICT')\n if (draft.baseGeneration !== recipe.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n readRecipeContent(draft)\n const contentHash = recipeSubmissionHash(draft)\n await manager.update(\n RecipeRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindRecipeApproval(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n activityInstanceId: string\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n RecipeRevision,\n { id: revisionId, domain: { id: domainId } },\n { activityInstanceId: text(activityInstanceId, 'activityInstanceId') }\n )\n}\n\n/** Internal completion callback only. Never expose this as an approved=true mutation. */\nexport async function publishRecipeRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { activityInstanceId: string; approverId: string; submissionHash: string }\n) {\n return publishRevision(manager, domainId, revisionId, {\n kind: 'approved',\n activityInstanceId: decision.activityInstanceId,\n actorId: decision.approverId,\n submissionHash: decision.submissionHash\n })\n}\n\nexport async function publishUnregulatedRecipe(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n editGeneration: number\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.recipeId)\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(RecipePlan, {\n domain: { id: domainId },\n publishedRevision: { id: revisionId },\n releaseKind: 'policy'\n })\n if (prior) {\n if (prior.publisherId !== actorId) refuse('DRAFT_NOT_OWNED')\n return prior\n }\n const frozen = await freezeRecipeDraft(manager, domainId, actorId, revisionId, editGeneration)\n return publishRevision(manager, domainId, revisionId, { kind: 'policy', actorId, submissionHash: frozen.contentHash })\n}\n\nasync function publishRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { kind: 'approved' | 'policy'; activityInstanceId?: string; actorId: string; submissionHash: string }\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const recipe = await lockSubject(manager, domainId, initial.recipeId)\n const draft = await revision(manager, domainId, revisionId)\n if (\n !draft.frozenAt ||\n (decision.kind === 'approved'\n ? draft.activityInstanceId !== decision.activityInstanceId\n : !!draft.activityInstanceId) ||\n draft.contentHash !== decision.submissionHash ||\n recipeSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n if (policy.approvalRequired !== (decision.kind === 'approved'))\n throw new Refusal('MASTER_APPROVAL_POLICY_MISMATCH', {}, 'Use the publication path required by the domain policy.')\n if (decision.kind === 'approved' && draft.creatorId === decision.actorId) refuse('AUTHOR_CANNOT_APPROVE')\n text(decision.actorId, 'publisher')\n const previousDecision = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...writeLockOn(manager, RecipePlan)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== recipe.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n if (\n await manager.findOne(RecipeBasis, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...writeLockOn(manager, RecipeBasis)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id }, generation: recipe.planGeneration },\n ...writeLockOn(manager, RecipePlan)\n })\n if (recipe.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(RecipeSegment, {\n where: { domain: { id: domainId }, recipe: { id: recipe.id }, plan: { id: oldPlan.id } },\n order: { validFrom: 'ASC' },\n ...writeLockOn(manager, RecipeSegment)\n })\n : []\n // Do not silently erase an already approved future appointment.\n if (oldSegments.some(segment => segment.validFrom >= draft.effectiveFrom)) refuse('FUTURE_PLAN_CONFLICT')\n const recordedAt = new Date()\n const plan = await manager.save(\n RecipePlan,\n manager.create(RecipePlan, {\n domain: { id: domainId },\n recipe: { id: recipe.id },\n generation: recipe.planGeneration + 1,\n recordedAt,\n activityInstanceId: decision.activityInstanceId ?? null,\n submissionHash: decision.submissionHash,\n approver: decision.kind === 'approved' ? { id: decision.actorId } : null,\n publisher: { id: decision.actorId },\n releaseKind: decision.kind,\n publishedRevision: { id: revisionId },\n policy: { id: policy.id }\n })\n )\n for (const old of oldSegments) {\n await manager.save(\n RecipeSegment,\n manager.create(RecipeSegment, {\n domain: { id: domainId },\n recipe: { id: recipe.id },\n plan: { id: plan.id },\n revision: { id: old.revisionId },\n validFrom: old.validFrom,\n validTo: !old.validTo || old.validTo > draft.effectiveFrom ? draft.effectiveFrom : old.validTo\n })\n )\n }\n await manager.save(\n RecipeSegment,\n manager.create(RecipeSegment, {\n domain: { id: domainId },\n recipe: { id: recipe.id },\n plan: { id: plan.id },\n revision: { id: revisionId },\n validFrom: draft.effectiveFrom,\n validTo: null\n })\n )\n const advanced = await manager.update(\n RecipeDefinition,\n { id: recipe.id, domain: { id: domainId }, planGeneration: recipe.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveRecipe(\n manager: EntityManager,\n domainId: string,\n recipeId: string,\n businessTime: Date | string,\n knownAt: Date | string = new Date()\n) {\n const at = instant(businessTime)\n const known = instant(knownAt)\n const plan = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, recipe: { id: recipeId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...writeLockOn(manager, RecipePlan)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n await subject(manager, domainId, recipeId)\n const query = manager\n .createQueryBuilder(RecipeSegment, 'segment')\n .where({ domain: { id: domainId }, recipe: { id: recipeId }, plan: { id: plan.id } })\n .andWhere('segment.validFrom <= :at', { at })\n .andWhere('(segment.validTo IS NULL OR segment.validTo > :at)', { at })\n lockRowsOf(manager, query)\n const segments = await query.getMany()\n if (!segments.length) await refuseBeforeBaseline(manager, domainId, recipeId, at)\n if (segments.length !== 1) refuse(segments.length ? 'AMBIGUOUS_EFFECTIVITY' : 'NO_EFFECTIVE_REVISION')\n const selected = await revision(manager, domainId, segments[0].revisionId)\n if (!selected.frozenAt || selected.contentHash !== recipeSubmissionHash(selected))\n refuse('REVISION_INTEGRITY_FAILURE')\n return { revision: selected, plan, segment: segments[0] }\n}\n\n/** 기준선보다 앞선 시각은 모른다고 말한다 — 검사 명세의 같은 자리를 보라(2026-09-24). */\nasync function refuseBeforeBaseline(manager: EntityManager, domainId: string, recipeId: string, at: Date) {\n const first = await manager.findOneBy(RecipePlan, {\n domain: { id: domainId }, recipe: { id: recipeId }, generation: 1, releaseKind: 'baseline'\n })\n if (!first) return\n const recorded = await manager.findOneBy(RecipeRevision, { domain: { id: domainId }, id: first.publishedRevisionId })\n if (recorded && at < recorded.effectiveFrom)\n throw new Refusal(\n 'BEFORE_BASELINE',\n { baselineAt: recorded.effectiveFrom.toISOString() },\n `This master was first recorded at ${recorded.effectiveFrom.toISOString()}; nothing is known about it before then.`\n )\n}\n\n/**\n * **개정본이 하나도 없는 제조법**마다 지금 서 있는 행을 첫 개정본으로 적는다 — 기준선(2026-09-24).\n * 규칙은 검사 명세의 `standTestSpecificationBaselines` 와 같다. 제조법만의 것 둘:\n *\n * - 옛 행의 줄에는 `lineKey` 가 없다. **자리로 붙인다** — `input-1` · `output-1`. plant 시드가 쓰는 규칙과\n * 같고, 줄의 차례가 뜻을 가지는 모델이라 자리에서 온 키는 내용을 바꾸지 않는다.\n * - 품목 · 공정 · 경로는 이름으로 가리킨다. **쓰기 전에 전부 대조한다** — 줄을 쓰다가 거절되면 반쯤 쓴\n * 개정본이 트랜잭션에 남는다. 없는 것을 가리키는 행은 세우지 않고 까닭을 남긴다.\n */\nexport async function standRecipeBaselines(manager: EntityManager, domainId: string, at: Date, edition: string) {\n transaction(manager)\n const roots = await manager\n .createQueryBuilder(RecipeDefinition, 'recipe')\n .leftJoin(RecipeRevision, 'rev', 'rev.recipe_id = recipe.id AND rev.domain_id = recipe.domain_id')\n .where('recipe.domain_id = :domainId', { domainId })\n .andWhere('rev.id IS NULL')\n .getMany()\n const outcome = { stood: 0, unreadable: [] as { name: string; problem: string }[] }\n if (!roots.length) return outcome\n const policy = await masterChangePolicy(manager, domainId, 'recipeDefinition')\n const where = { where: { domain: { id: domainId } } }\n const materials = new Set((await manager.find(MaterialDefinition, where)).map(one => one.name))\n const operations = new Set((await manager.find(OperationDefinition, where)).map(one => one.name))\n const routes = new Map((await manager.find(RouteDefinition, where)).map(one => [one.name, one] as const))\n const keyed = (rows: any, side: 'input' | 'output') =>\n Array.isArray(rows) ? rows.map((row, index) => ({ ...row, lineKey: row?.lineKey ?? `${side}-${index + 1}` })) : rows\n for (const root of roots) {\n if (root.planGeneration !== 0) {\n outcome.unreadable.push({ name: root.name, problem: 'plan without revision' })\n continue\n }\n let read: ReturnType<typeof recipeContentValues>\n try {\n read = recipeContentValues({\n materialDefinitionName: root.materialDefinitionName,\n description: root.description ?? null,\n route: root.route ?? null,\n inputs: keyed(root.inputs, 'input'),\n outputs: keyed(root.outputs, 'output')\n } as any)\n } catch (error: any) {\n outcome.unreadable.push({ name: root.name, problem: error?.message ?? String(error) })\n continue\n }\n const route = read.route ? routes.get(read.route) : null\n const missing = [\n ...(materials.has(read.materialDefinitionName) ? [] : [`material ${read.materialDefinitionName}`]),\n ...(read.route && !route ? [`route ${read.route}`] : []),\n ...[...read.inputs, ...read.outputs].filter(line => !materials.has(line.material)).map(line => `material ${line.material}`),\n ...read.inputs\n .filter(line => line.operation && (!operations.has(line.operation) || !route?.steps.includes(line.operation)))\n .map(line => `operation ${line.operation} in route ${read.route ?? '(none)'}`)\n ]\n if (missing.length) {\n outcome.unreadable.push({ name: root.name, problem: 'points at what this domain does not have: ' + [...new Set(missing)].join(', ') })\n continue\n }\n const validFrom = root.effectiveStart && root.effectiveStart > at ? root.effectiveStart : at\n const validTo = root.effectiveEnd ?? null\n const { inputs, outputs, ...header } = read\n const saved = await manager.save(\n RecipeRevision,\n manager.create(RecipeRevision, {\n ...header,\n effectiveFrom: validFrom,\n reason: `baseline: the row as it stood, recorded by ${edition}`,\n ...await headerReferences(manager, domainId, read as any),\n policy: { id: policy.id },\n domain: { id: domainId },\n recipe: { id: root.id },\n baseRevision: null,\n baseGeneration: 0,\n revisionNumber: 1,\n editGeneration: 0,\n creator: null,\n createdAt: at,\n frozenAt: at,\n contentHash: null,\n activityInstanceId: null\n })\n )\n await saveLines(manager, domainId, root.id, saved.id, inputs, outputs)\n const stood = await revision(manager, domainId, saved.id)\n const contentHash = recipeSubmissionHash(stood)\n await manager.update(RecipeRevision, { id: stood.id, domain: { id: domainId } }, { contentHash })\n const plan = await manager.save(\n RecipePlan,\n manager.create(RecipePlan, {\n domain: { id: domainId },\n recipe: { id: root.id },\n generation: 1,\n recordedAt: at,\n activityInstanceId: null,\n submissionHash: contentHash,\n approver: null,\n publisher: null,\n releaseKind: 'baseline',\n publishedRevision: { id: stood.id },\n policy: { id: policy.id }\n })\n )\n if (!validTo || validTo > validFrom) {\n await manager.save(\n RecipeSegment,\n manager.create(RecipeSegment, {\n domain: { id: domainId },\n recipe: { id: root.id },\n plan: { id: plan.id },\n revision: { id: stood.id },\n validFrom,\n validTo\n })\n )\n }\n const advanced = await manager.update(\n RecipeDefinition,\n { id: root.id, domain: { id: domainId }, planGeneration: 0 },\n { planGeneration: 1 }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n outcome.stood++\n }\n return outcome\n}\n\n/** Replay reads verify the captured digest too, not only the currently effective schedule. */\nexport async function recipeRevisionForBasis(manager: EntityManager, domainId: string, basis: RecipeBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.recipeId !== basis.recipeId || !selected.frozenAt || selected.contentHash !== basis.contentHash || recipeSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n if (selected.routeDefinitionId ? (\n basis.routeSnapshot?.id !== selected.routeDefinitionId ||\n basis.routeHash !== createHash('sha256').update(canonical(basis.routeSnapshot)).digest('hex')\n ) : (basis.routeSnapshot !== null || basis.routeHash !== null)) refuse('REVISION_INTEGRITY_FAILURE')\n return selected\n}\n\n/** Must run inside the transaction that writes the execution result. */\nexport async function captureRecipeBasis(\n manager: EntityManager,\n domainId: string,\n recipeId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, recipeId)\n const existing = await manager.findOne(RecipeBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...writeLockOn(manager, RecipeBasis)\n })\n if (existing) {\n if (existing.recipeId !== recipeId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await recipeRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveRecipe(manager, domainId, recipeId, at, resolvedAt)\n const route = selected.revision.routeDefinitionId ? await manager.findOne(RouteDefinition, {\n where: { id: selected.revision.routeDefinitionId, domain: { id: domainId } }, ...writeLockOn(manager, RouteDefinition)\n }) : null\n if (selected.revision.routeDefinitionId && (!route ||\n (route.effectiveStart && route.effectiveStart > at) || (route.effectiveEnd && route.effectiveEnd <= at)))\n refuse('INVALID_RECIPE_REFERENCE', 'The referenced route is not effective at execution time.')\n if (selected.revision.inputs.some(line => line.operation && !route?.steps.includes(line.operation)))\n refuse('INVALID_RECIPE_REFERENCE', 'The current route no longer contains a required input operation.')\n const routeSnapshot = route ? {\n id: route.id, name: route.name, steps: route.steps, procedure: route.procedure ?? null\n } : null\n const saved = await manager.save(\n RecipeBasis,\n manager.create(RecipeBasis, {\n domain: { id: domainId },\n recipe: { id: recipeId },\n recordKey: text(recordKey, 'recordKey'),\n businessTime: at,\n resolvedAt,\n routeSnapshot,\n routeHash: routeSnapshot ? createHash('sha256').update(canonical(routeSnapshot)).digest('hex') : null,\n revision: { id: selected.revision.id },\n contentHash: selected.revision.contentHash,\n plan: { id: selected.plan.id }\n })\n )\n return manager.findOneByOrFail(RecipeBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function recipeRevisionOverview(\n manager: EntityManager,\n domainId: string,\n recipeId: string,\n at = new Date()\n) {\n const recipe = await subject(manager, domainId, recipeId)\n const revisions = await manager.find(RecipeRevision, {\n where: { domain: { id: domainId }, recipe: { id: recipeId } },\n relations: { inputs: true, outputs: true },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(RecipePlan, {\n where: { domain: { id: domainId }, recipe: { id: recipeId }, generation: recipe.planGeneration }\n })\n const schedule = plan\n ? await manager.find(RecipeSegment, {\n where: { domain: { id: domainId }, recipe: { id: recipeId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n /*\n * 개정본마다 **어떻게 발행됐는지**(`releaseKind`)를 함께 싣는다 — 발행한 적용계획의 값 그대로(2026-10-20).\n * 화면은 이것으로 기준선을 알아보고 사람의 말(「최초 기록」)로 적는다. 기준선의 사유는 서버가 쓴 기록\n * 문장인데 해시에 들어가 바꿀 수 없고, 문구로 알아보면 깨지기 쉽다. 발행 전 개정본은 null.\n */\n const kindOf = releaseKinds(await manager.findBy(RecipePlan, { domain: { id: domainId }, recipe: { id: recipeId } }))\n return {\n recipeId,\n name: recipe.name,\n generation: recipe.planGeneration,\n at: at.toISOString(),\n schedule: schedule.map(segment => ({\n ...segment,\n state: segment.validFrom > at ? 'scheduled' : segment.validTo && segment.validTo <= at ? 'expired' : 'current'\n })),\n revisions: revisions.map(item => ({ ...item,\n inputs: item.inputs.sort((a, b) => a.position - b.position),\n outputs: item.outputs.sort((a, b) => a.position - b.position),\n state: item.frozenAt ? 'frozen' : 'draft',\n releaseKind: kindOf(item.id) }))\n }\n}\n\n/** Read-time projection, never a clock-driven rewrite of the identity row. */\nexport async function effectiveRecipe(\n manager: EntityManager,\n domainId: string,\n recipe: RecipeDefinition,\n at = new Date()\n) {\n const selected = await resolveRecipe(manager, domainId, recipe.id, at)\n return Object.assign(new RecipeDefinition(), recipe, {\n description: selected.revision.description,\n ...recipeContentValues(selected.revision),\n effectiveStart: selected.segment.validFrom,\n effectiveEnd: selected.segment.validTo ?? undefined\n })\n}\n\n/**\n * **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).\n * 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.\n * 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —\n * 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.\n */\nexport async function saveAndPublishRecipe(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n asked: { recipeId?: string; name?: string; baseRevisionId?: string; content: RecipeDraftContent; revisionId?: string; editGeneration?: number }\n) {\n // Reuse the owned draft and its concurrency guard; publishing failure rolls back the edit too.\n if (asked.revisionId && !Number.isInteger(asked.editGeneration)) refuse('DRAFT_CONFLICT')\n const draft = asked.revisionId\n ? await editRecipeDraft(manager, domainId, actorId, asked.revisionId, asked.editGeneration!, asked.content)\n : await createRecipeDraft(manager, domainId, actorId, asked)\n const plan = await publishUnregulatedRecipe(manager, domainId, actorId, draft.id, draft.editGeneration)\n return { revision: await revision(manager, domainId, draft.id, false), plan }\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type EntityManager, type EntityTarget, type SelectQueryBuilder } from 'typeorm';
|
|
2
|
+
/**
|
|
3
|
+
* **A write lock on the rows of one table only** - what every locking read of a revision service takes.
|
|
4
|
+
*
|
|
5
|
+
* Current reads are required after waiting for the subject lock, including MySQL REPEATABLE READ, so these reads lock.
|
|
6
|
+
* But a plain `FOR UPDATE` locks every row the query reads: a read filtered by its domain joins the domain row, and a
|
|
7
|
+
* read that loads a revision with its lines LEFT JOINs them - and postgres refuses `FOR UPDATE` on the nullable side of
|
|
8
|
+
* an outer join outright (`0A000`). Publishing a recipe failed that way on postgres (found 2026-10-23, the warehouse's
|
|
9
|
+
* kitting tests); test specifications and materials read their revisions the same way. Postgres names the table to lock
|
|
10
|
+
* (`FOR UPDATE OF`); the other drivers that lock are left as they were. The operato warehouse took the same turn for
|
|
11
|
+
* its stock rows (`writeLockOn`, `fb055e0d`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function writeLockOn(manager: EntityManager, entity: EntityTarget<any>): {
|
|
14
|
+
lock?: undefined;
|
|
15
|
+
} | {
|
|
16
|
+
lock: {
|
|
17
|
+
tables?: string[];
|
|
18
|
+
mode: "pessimistic_write";
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/** The same lock on a query builder's own alias - `setLock` takes the alias as written into the SQL. */
|
|
22
|
+
export declare function lockRowsOf<T extends object>(manager: EntityManager, query: SelectQueryBuilder<T>): SelectQueryBuilder<T>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeLockOn = writeLockOn;
|
|
4
|
+
exports.lockRowsOf = lockRowsOf;
|
|
5
|
+
const shell_1 = require("@things-factory/shell");
|
|
6
|
+
/**
|
|
7
|
+
* **A write lock on the rows of one table only** - what every locking read of a revision service takes.
|
|
8
|
+
*
|
|
9
|
+
* Current reads are required after waiting for the subject lock, including MySQL REPEATABLE READ, so these reads lock.
|
|
10
|
+
* But a plain `FOR UPDATE` locks every row the query reads: a read filtered by its domain joins the domain row, and a
|
|
11
|
+
* read that loads a revision with its lines LEFT JOINs them - and postgres refuses `FOR UPDATE` on the nullable side of
|
|
12
|
+
* an outer join outright (`0A000`). Publishing a recipe failed that way on postgres (found 2026-10-23, the warehouse's
|
|
13
|
+
* kitting tests); test specifications and materials read their revisions the same way. Postgres names the table to lock
|
|
14
|
+
* (`FOR UPDATE OF`); the other drivers that lock are left as they were. The operato warehouse took the same turn for
|
|
15
|
+
* its stock rows (`writeLockOn`, `fb055e0d`).
|
|
16
|
+
*/
|
|
17
|
+
function writeLockOn(manager, entity) {
|
|
18
|
+
if (!(0, shell_1.writeLockSupported)(manager))
|
|
19
|
+
return {};
|
|
20
|
+
return { lock: { mode: 'pessimistic_write', ...(isPostgres(manager) ? { tables: [manager.connection.getMetadata(entity).tableNameWithoutPrefix] } : {}) } };
|
|
21
|
+
}
|
|
22
|
+
/** The same lock on a query builder's own alias - `setLock` takes the alias as written into the SQL. */
|
|
23
|
+
function lockRowsOf(manager, query) {
|
|
24
|
+
if (!(0, shell_1.writeLockSupported)(manager))
|
|
25
|
+
return query;
|
|
26
|
+
return query.setLock('pessimistic_write', undefined, isPostgres(manager) ? [query.escape(query.alias)] : undefined);
|
|
27
|
+
}
|
|
28
|
+
function isPostgres(manager) {
|
|
29
|
+
return manager.connection?.options?.type === 'postgres';
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=row-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-lock.js","sourceRoot":"","sources":["../../server/service/row-lock.ts"],"names":[],"mappings":";;AAeA,kCAGC;AAGD,gCAGC;AAtBD,iDAA0D;AAE1D;;;;;;;;;;GAUG;AACH,SAAgB,WAAW,CAAC,OAAsB,EAAE,MAAyB;IAC3E,IAAI,CAAC,IAAA,0BAAkB,EAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAA;IAC3C,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,mBAA4B,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAA;AACtK,CAAC;AAED,wGAAwG;AACxG,SAAgB,UAAU,CAAmB,OAAsB,EAAE,KAA4B;IAC/F,IAAI,CAAC,IAAA,0BAAkB,EAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAA;IAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,mBAAmB,EAAE,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AACrH,CAAC;AAED,SAAS,UAAU,CAAC,OAAsB;IACxC,OAAO,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,KAAK,UAAU,CAAA;AACzD,CAAC","sourcesContent":["import { type EntityManager, type EntityTarget, type SelectQueryBuilder } from 'typeorm'\n\nimport { writeLockSupported } from '@things-factory/shell'\n\n/**\n * **A write lock on the rows of one table only** - what every locking read of a revision service takes.\n *\n * Current reads are required after waiting for the subject lock, including MySQL REPEATABLE READ, so these reads lock.\n * But a plain `FOR UPDATE` locks every row the query reads: a read filtered by its domain joins the domain row, and a\n * read that loads a revision with its lines LEFT JOINs them - and postgres refuses `FOR UPDATE` on the nullable side of\n * an outer join outright (`0A000`). Publishing a recipe failed that way on postgres (found 2026-10-23, the warehouse's\n * kitting tests); test specifications and materials read their revisions the same way. Postgres names the table to lock\n * (`FOR UPDATE OF`); the other drivers that lock are left as they were. The operato warehouse took the same turn for\n * its stock rows (`writeLockOn`, `fb055e0d`).\n */\nexport function writeLockOn(manager: EntityManager, entity: EntityTarget<any>) {\n if (!writeLockSupported(manager)) return {}\n return { lock: { mode: 'pessimistic_write' as const, ...(isPostgres(manager) ? { tables: [manager.connection.getMetadata(entity).tableNameWithoutPrefix] } : {}) } }\n}\n\n/** The same lock on a query builder's own alias - `setLock` takes the alias as written into the SQL. */\nexport function lockRowsOf<T extends object>(manager: EntityManager, query: SelectQueryBuilder<T>): SelectQueryBuilder<T> {\n if (!writeLockSupported(manager)) return query\n return query.setLock('pessimistic_write', undefined, isPostgres(manager) ? [query.escape(query.alias)] : undefined)\n}\n\nfunction isPostgres(manager: EntityManager): boolean {\n return manager.connection?.options?.type === 'postgres'\n}\n"]}
|
|
@@ -25,6 +25,7 @@ const criteria_check_1 = require("./criteria-check");
|
|
|
25
25
|
const test_specification_1 = require("./test-specification");
|
|
26
26
|
const test_spec_revision_1 = require("./test-spec-revision");
|
|
27
27
|
const approval_input_1 = require("../master-change-approval/approval-input");
|
|
28
|
+
const row_lock_1 = require("../row-lock");
|
|
28
29
|
class TestSpecificationRefusal extends shell_1.Refusal {
|
|
29
30
|
constructor(code, detail) {
|
|
30
31
|
super(code, {}, detail ?? TEST_SPECIFICATION_REFUSALS[code] ?? 'The test specification change could not be applied.');
|
|
@@ -61,10 +62,6 @@ function transaction(manager) {
|
|
|
61
62
|
if (!manager.queryRunner?.isTransactionActive)
|
|
62
63
|
refuse('TRANSACTION_REQUIRED');
|
|
63
64
|
}
|
|
64
|
-
/** Current reads are required after waiting for the subject lock, including MySQL REPEATABLE READ. */
|
|
65
|
-
function currentLock(manager) {
|
|
66
|
-
return (0, shell_1.writeLockSupported)(manager) ? { lock: { mode: 'pessimistic_write' } } : {};
|
|
67
|
-
}
|
|
68
65
|
function instant(value) {
|
|
69
66
|
if (!(value instanceof Date) && (typeof value !== 'string' || !/(Z|[+-]\d{2}:\d{2})$/.test(value)))
|
|
70
67
|
refuse('INVALID_INSTANT');
|
|
@@ -184,7 +181,7 @@ function content(input) {
|
|
|
184
181
|
async function subject(manager, domainId, specId) {
|
|
185
182
|
const spec = await manager.findOne(test_specification_1.TestSpecification, {
|
|
186
183
|
where: { id: specId, domain: { id: domainId } },
|
|
187
|
-
...
|
|
184
|
+
...(0, row_lock_1.writeLockOn)(manager, test_specification_1.TestSpecification)
|
|
188
185
|
});
|
|
189
186
|
if (!spec)
|
|
190
187
|
refuse('SPECIFICATION_NOT_FOUND');
|
|
@@ -205,7 +202,7 @@ async function subject(manager, domainId, specId) {
|
|
|
205
202
|
async function revision(manager, domainId, revisionId, locked = true) {
|
|
206
203
|
const found = await manager.findOne(test_spec_revision_1.TestSpecificationRevision, {
|
|
207
204
|
where: { id: revisionId, domain: { id: domainId } },
|
|
208
|
-
...(locked ?
|
|
205
|
+
...(locked ? (0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationRevision) : {})
|
|
209
206
|
});
|
|
210
207
|
if (!found)
|
|
211
208
|
refuse('REVISION_NOT_FOUND');
|
|
@@ -244,7 +241,7 @@ async function createTestSpecificationDraft(manager, domainId, creatorId, asked)
|
|
|
244
241
|
}
|
|
245
242
|
const previous = await manager.findOne(test_spec_revision_1.TestSpecificationRevision, {
|
|
246
243
|
where: { domain: { id: domainId }, spec: { id: spec.id } }, order: { revisionNumber: 'DESC' },
|
|
247
|
-
...
|
|
244
|
+
...(0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationRevision)
|
|
248
245
|
});
|
|
249
246
|
const revisionNumber = (previous?.revisionNumber ?? 0) + 1;
|
|
250
247
|
let baseRevisionId = null;
|
|
@@ -386,7 +383,7 @@ async function publishRevision(manager, domainId, revisionId, decision) {
|
|
|
386
383
|
text(decision.actorId, 'publisher');
|
|
387
384
|
const previousDecision = await manager.findOne(test_spec_revision_1.TestSpecificationPlan, {
|
|
388
385
|
where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },
|
|
389
|
-
...
|
|
386
|
+
...(0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationPlan)
|
|
390
387
|
});
|
|
391
388
|
if (previousDecision)
|
|
392
389
|
return previousDecision;
|
|
@@ -395,12 +392,12 @@ async function publishRevision(manager, domainId, revisionId, decision) {
|
|
|
395
392
|
// Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.
|
|
396
393
|
if (await manager.findOne(test_spec_revision_1.TestSpecificationBasis, {
|
|
397
394
|
where: { domain: { id: domainId }, spec: { id: spec.id }, businessTime: (0, typeorm_1.MoreThanOrEqual)(draft.effectiveFrom) },
|
|
398
|
-
...
|
|
395
|
+
...(0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationBasis)
|
|
399
396
|
}))
|
|
400
397
|
refuse('RETROACTIVE_IMPACT');
|
|
401
398
|
const oldPlan = await manager.findOne(test_spec_revision_1.TestSpecificationPlan, {
|
|
402
399
|
where: { domain: { id: domainId }, spec: { id: spec.id }, generation: spec.planGeneration },
|
|
403
|
-
...
|
|
400
|
+
...(0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationPlan)
|
|
404
401
|
});
|
|
405
402
|
if (spec.planGeneration > 0 && !oldPlan)
|
|
406
403
|
refuse('PLAN_CONFLICT');
|
|
@@ -408,7 +405,7 @@ async function publishRevision(manager, domainId, revisionId, decision) {
|
|
|
408
405
|
? await manager.find(test_spec_revision_1.TestSpecificationSegment, {
|
|
409
406
|
where: { domain: { id: domainId }, spec: { id: spec.id }, plan: { id: oldPlan.id } },
|
|
410
407
|
order: { validFrom: 'ASC' },
|
|
411
|
-
...
|
|
408
|
+
...(0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationSegment)
|
|
412
409
|
})
|
|
413
410
|
: [];
|
|
414
411
|
// Do not silently erase an already approved future appointment.
|
|
@@ -457,7 +454,7 @@ async function resolveTestSpecification(manager, domainId, specId, businessTime,
|
|
|
457
454
|
const plan = await manager.findOne(test_spec_revision_1.TestSpecificationPlan, {
|
|
458
455
|
where: { domain: { id: domainId }, spec: { id: specId }, recordedAt: (0, typeorm_1.LessThanOrEqual)(known) },
|
|
459
456
|
order: { generation: 'DESC' },
|
|
460
|
-
...
|
|
457
|
+
...(0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationPlan)
|
|
461
458
|
});
|
|
462
459
|
if (!plan)
|
|
463
460
|
refuse('NO_EFFECTIVE_REVISION');
|
|
@@ -468,8 +465,7 @@ async function resolveTestSpecification(manager, domainId, specId, businessTime,
|
|
|
468
465
|
.where({ domain: { id: domainId }, spec: { id: specId }, plan: { id: plan.id } })
|
|
469
466
|
.andWhere('segment.validFrom <= :at', { at })
|
|
470
467
|
.andWhere('(segment.validTo IS NULL OR segment.validTo > :at)', { at });
|
|
471
|
-
|
|
472
|
-
query.setLock('pessimistic_write');
|
|
468
|
+
(0, row_lock_1.lockRowsOf)(manager, query);
|
|
473
469
|
const segments = await query.getMany();
|
|
474
470
|
if (!segments.length)
|
|
475
471
|
await refuseBeforeBaseline(manager, domainId, specId, at);
|
|
@@ -603,7 +599,7 @@ async function captureTestSpecificationBasis(manager, domainId, specId, recordKe
|
|
|
603
599
|
await lockSubject(manager, domainId, specId);
|
|
604
600
|
const existing = await manager.findOne(test_spec_revision_1.TestSpecificationBasis, {
|
|
605
601
|
where: { domain: { id: domainId }, recordKey },
|
|
606
|
-
...
|
|
602
|
+
...(0, row_lock_1.writeLockOn)(manager, test_spec_revision_1.TestSpecificationBasis)
|
|
607
603
|
});
|
|
608
604
|
if (existing) {
|
|
609
605
|
if (existing.specId !== specId || existing.businessTime.getTime() !== at.getTime())
|