@xom11/whiteboard 0.28.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai.d.mts +236 -295
- package/dist/ai.d.ts +236 -295
- package/dist/ai.js +6019 -7612
- package/dist/ai.js.map +1 -1
- package/dist/ai.mjs +4804 -5457
- package/dist/ai.mjs.map +1 -1
- package/dist/catalog.json +2 -2
- package/dist/{chunk-AJAHD35N.mjs → chunk-E6EDOPGT.mjs} +3 -105
- package/dist/chunk-E6EDOPGT.mjs.map +1 -0
- package/dist/{chunk-QCZVFEN4.mjs → chunk-GEC2D2EQ.mjs} +3 -3
- package/dist/{chunk-QCZVFEN4.mjs.map → chunk-GEC2D2EQ.mjs.map} +1 -1
- package/dist/geometry-2d.d.mts +1 -2
- package/dist/geometry-2d.d.ts +1 -2
- package/dist/geometry-2d.js +888 -3623
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +1 -1
- package/dist/geometry-3d.d.mts +1 -2
- package/dist/geometry-3d.d.ts +1 -2
- package/dist/graph-2d.d.mts +1 -2
- package/dist/graph-2d.d.ts +1 -2
- package/dist/{host-4P766V4J.mjs → host-HKMZSCIT.mjs} +54 -313
- package/dist/host-HKMZSCIT.mjs.map +1 -0
- package/dist/index.d.mts +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +880 -3619
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -4
- package/dist/index.mjs.map +1 -1
- package/dist/latex.d.mts +1 -2
- package/dist/latex.d.ts +1 -2
- package/dist/{types-BHYC2Fiw.d.mts → types-C3FjpoUi.d.mts} +1 -232
- package/dist/{types-BHYC2Fiw.d.ts → types-C3FjpoUi.d.ts} +1 -232
- package/package.json +1 -9
- package/dist/chunk-AJAHD35N.mjs.map +0 -1
- package/dist/chunk-T3SOHYB2.mjs +0 -851
- package/dist/chunk-T3SOHYB2.mjs.map +0 -1
- package/dist/handleExtractProblem-C-U5KluK.d.mts +0 -158
- package/dist/handleExtractProblem-C-U5KluK.d.ts +0 -158
- package/dist/host-4P766V4J.mjs.map +0 -1
package/dist/ai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/stamps/geometry-2d/dsl/names.ts","../src/stamps/geometry-2d/dsl/kinds/_types.ts","../src/stamps/geometry-2d/dsl/kinds/_shared.ts","../src/stamps/geometry-2d/dsl/kinds/points/free.ts","../src/stamps/geometry-2d/dsl/kinds/points/midpoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/onSegment.ts","../src/stamps/geometry-2d/dsl/kinds/points/onLine.ts","../src/stamps/geometry-2d/dsl/kinds/points/onCircle.ts","../src/stamps/geometry-2d/dsl/kinds/points/perpFoot.ts","../src/stamps/geometry-2d/dsl/kinds/points/circumcenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/incenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/centroid.ts","../src/stamps/geometry-2d/dsl/kinds/points/orthocenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/intersection.ts","../src/stamps/geometry-2d/dsl/kinds/lines/segment.ts","../src/stamps/geometry-2d/dsl/kinds/lines/line.ts","../src/stamps/geometry-2d/dsl/kinds/lines/ray.ts","../src/stamps/geometry-2d/dsl/kinds/lines/perpendicular.ts","../src/stamps/geometry-2d/dsl/kinds/lines/parallel.ts","../src/stamps/geometry-2d/dsl/kinds/lines/perpBisector.ts","../src/stamps/geometry-2d/dsl/kinds/lines/angleBisector.ts","../src/stamps/geometry-2d/dsl/kinds/lines/lineThrough.ts","../src/stamps/geometry-2d/dsl/kinds/lines/radicalAxis.ts","../src/stamps/geometry-2d/dsl/kinds/lines/tangent.ts","../src/stamps/geometry-2d/dsl/kinds/polygons/polygon.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circleCP.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circle3.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circleDiameter.ts","../src/stamps/geometry-2d/dsl/kinds/points/secondIntersection.ts","../src/stamps/geometry-2d/dsl/kinds/points/circleIntersection.ts","../src/stamps/geometry-2d/dsl/kinds/points/circleSecondIntersection.ts","../src/stamps/geometry-2d/dsl/kinds/points/tangencyPoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/tangentPointExt.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circleCR.ts","../src/stamps/geometry-2d/dsl/kinds/circles/incircle.ts","../src/stamps/geometry-2d/dsl/kinds/circles/excircle.ts","../src/stamps/geometry-2d/dsl/kinds/points/arcMidpoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/excenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/reflectPoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/reflectLine.ts","../src/stamps/geometry-2d/dsl/kinds/points/pointAtDistance.ts","../src/stamps/geometry-2d/dsl/registry.ts","../src/stamps/geometry-2d/dsl/schema.ts","../src/core/scene/types.ts","../src/stamps/geometry-2d/dsl/transpile/errors.ts","../src/stamps/geometry-2d/dsl/transpile/symbols.ts","../src/stamps/geometry-2d/dsl/transpile/refs.ts","../src/stamps/geometry-2d/dsl/transpile/cycles.ts","../src/stamps/geometry-2d/dsl/transpile/topology.ts","../src/stamps/geometry-2d/dsl/transpile/ids.ts","../src/stamps/geometry-2d/dsl/transpile.ts","../src/stamps/geometry-2d/ai/repairCircleIntersections.ts","../src/stamps/geometry-2d/ai/layout/disjointOffset.ts","../src/stamps/geometry-2d/ai/intent-builders/_types.ts","../src/stamps/geometry-2d/ai/intent-builders/shared.ts","../src/stamps/geometry-2d/ai/intent-builders/draw-shape.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/midpoint.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/perpFoot.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/centers.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/intersections.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/tangency.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/onSegment-free.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/angleBisectorFoot.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/externalAngleBisectorFoot.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/rightAngleViewing.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/arcMidpoint.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/reflect.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/pointAtDistance.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/externalToCircle.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/onCircle.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/index.ts","../src/stamps/geometry-2d/ai/intent-builders/connect.ts","../src/stamps/geometry-2d/ai/intent-builders/draw-circle.ts","../src/stamps/geometry-2d/ai/intent-builders/draw-line.ts","../src/stamps/geometry-2d/ai/intent-builders/mark-shape.ts","../src/stamps/geometry-2d/ai/intent-builders/registry.ts","../src/stamps/geometry-2d/ai/intentToDsl.ts","../src/stamps/geometry-2d/ai/intentPrompt.ts","../src/stamps/geometry-2d/ai/intent.ts","../src/stamps/geometry-2d/ai/intentEnvelope.ts","../src/stamps/geometry-2d/ai/normalizeIntent.ts","../src/stamps/geometry-2d/ai/resolveCircleNames.ts","../src/stamps/geometry-2d/ai/completeRightAngle.ts","../src/stamps/geometry-2d/ai/verify.ts","../src/stamps/geometry-2d/ai/deterministic/vocabulary.ts","../src/stamps/geometry-2d/ai/deterministic/coverage.ts","../src/stamps/geometry-2d/ai/rules/_shared.ts","../src/stamps/geometry-2d/ai/rules/triangle.ts","../src/stamps/geometry-2d/ai/rules/quad.ts","../src/stamps/geometry-2d/ai/rules/connect.ts","../src/stamps/geometry-2d/ai/rules/midpoint.ts","../src/stamps/geometry-2d/ai/rules/perpBisector.ts","../src/stamps/geometry-2d/ai/rules/cevian.ts","../src/stamps/geometry-2d/ai/rules/angleBisectorAngle.ts","../src/stamps/geometry-2d/ai/rules/centers.ts","../src/stamps/geometry-2d/ai/rules/perpFoot.ts","../src/stamps/geometry-2d/ai/rules/circleRadius.ts","../src/stamps/geometry-2d/ai/rules/circleTriangle.ts","../src/stamps/geometry-2d/ai/rules/tangentFromExt.ts","../src/stamps/geometry-2d/ai/rules/externalPoint.ts","../src/stamps/geometry-2d/ai/rules/arcMidpoint.ts","../src/stamps/geometry-2d/ai/rules/excenter.ts","../src/stamps/geometry-2d/ai/rules/parallelPerp.ts","../src/stamps/geometry-2d/ai/rules/reflection.ts","../src/stamps/geometry-2d/ai/rules/pointAtDistance.ts","../src/stamps/geometry-2d/ai/rules/eulerLine.ts","../src/stamps/geometry-2d/ai/rules/radicalAxis.ts","../src/stamps/geometry-2d/ai/rules/simson.ts","../src/stamps/geometry-2d/ai/rules/ninePoint.ts","../src/stamps/geometry-2d/ai/rules/diameterCirclePairwise.ts","../src/stamps/geometry-2d/ai/rules/angleBisectorFoot.ts","../src/stamps/geometry-2d/ai/rules/intersection.ts","../src/stamps/geometry-2d/ai/rules/chord.ts","../src/stamps/geometry-2d/ai/rules/incircleTangency.ts","../src/stamps/geometry-2d/ai/rules/altitudeDiameterCircles.ts","../src/stamps/geometry-2d/ai/rules/diameterCircleCutsSides.ts","../src/stamps/geometry-2d/ai/rules/registry.ts","../src/stamps/geometry-2d/ai/deterministic/runDeterministicIntents.ts","../src/stamps/geometry-2d/ai/deterministic/guards.ts","../src/stamps/geometry-2d/ai/deterministic/tryDeterministicFigure.ts","../src/stamps/geometry-2d/ai/deterministic/describeMiss.ts","../src/stamps/geometry-2d/ai/providers/anthropic.ts","../src/stamps/geometry-2d/ai/providers/claude-agent-sdk.ts","../src/stamps/geometry-2d/ai/providers/claude-cli.ts","../src/stamps/geometry-2d/ai/providers/ollama.ts","../src/stamps/geometry-2d/ai/providers/index.ts","../src/stamps/geometry-2d/ai/buildFigureIntent.ts","../src/stamps/geometry-2d/ai/handleGenerateFigure.ts","../src/stamps/geometry-2d/ai/envelope.ts","../src/stamps/geometry-2d/ai/refineEnvelope.ts","../src/stamps/geometry-2d/ai/refineFixtures.ts","../src/stamps/geometry-2d/ai/refinePrompt.ts","../src/stamps/geometry-2d/ai/buildFigureDelta.ts","../src/stamps/geometry-2d/ai/handleGenerateFigureDelta.ts","../src/stamps/geometry-2d/ai/handleGenerateFigureIntent.ts","../src/stamps/geometry-2d/ai/mergeIntents.ts","../src/stamps/geometry-2d/ai/vision/envelope.ts","../src/stamps/geometry-2d/ai/vision/prompt.ts","../src/stamps/geometry-2d/ai/vision/tesseract.ts","../src/stamps/geometry-2d/ai/vision/extractProblem.ts","../src/stamps/geometry-2d/ai/handleExtractProblem.ts","../src/stamps/geometry-2d/ai/vision/preprocess.ts"],"names":["z","zodToJsonSchema","addPoint","others","PREFILTER","TRI","TRI_EN","TRI_G","TRI_EN_G","dm","CENTER","scanClause","from","circle","NAME_BEFORE","NAME_BEFORE_EN","opposite","PREFILTER_EN","parseNum","t","uniqueTriangle","CIRCLE_CENTER","LINE","CIRCLE_WORDS","CIRCLE_PAREN","resolveCircle","collect","Anthropic","DEFAULT_MODEL","toUsage","DEFAULT_MAX_TOKENS","tResult","DEFAULT_MAX_ATTEMPTS","clampAttempts","mapErrorToUi","readEnv"],"mappings":"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","file":"ai.js","sourcesContent":["// src/stamps/geometry-2d/dsl/names.ts\nimport { z } from 'zod';\n\n// Label-style name: chữ cái Latin đầu, cho phép unicode prime (') + subscript ₀-₉.\n// Max length 12 ký tự. Phân biệt hoa/thường.\nexport const NameZ = z\n .string()\n .regex(/^[A-Za-z][A-Za-z0-9_'₀-₉]{0,11}$/);\n","// src/stamps/geometry-2d/dsl/kinds/_types.ts\nimport type { z } from 'zod';\nimport type { SceneObject } from '../../../../core/scene/types';\n\nexport type KindRole =\n | 'point'\n | 'segment'\n | 'line'\n | 'ray'\n | 'lineConstruction'\n | 'circle'\n | 'polygon';\n\nexport type KindCategory = 'points' | 'lines' | 'polygons' | 'circles' | 'compound';\n\n/** Vai trò ref mà một field của kind yêu cầu — dùng cho validateRefs registry-driven. */\nexport type RefRole =\n | 'point'\n | 'line-like'\n | 'circle'\n | 'segment'\n | 'shape'\n | 'any-existing';\n\nexport interface RefSpec {\n /** Tên field trên entity chứa ref (vd 'from', 'circle', 'vertices'). */\n field: string;\n role: RefRole;\n /** field là mảng tên (vd vertices[]). */\n many?: boolean;\n}\n\nexport interface EmitContext {\n /** Look up the scene-object id assigned to a DSL symbol name. */\n resolveId(name: string): string;\n /** Hint lookup for intersection-style emit needing to know what a referenced symbol is. */\n hintOf(name: string): KindRole;\n /** Generate a unique auxiliary id for an internal entity (not addressable from DSL). */\n mintAuxId(parentName: string, suffix: string): string;\n}\n\nexport interface EmittedEntity {\n /** The first emitted entity per kind MUST have role 'primary'. */\n role: 'primary' | 'auxiliary';\n object: SceneObject;\n}\n\nexport interface DslKindModule<TKind extends string = string, TInput = unknown> {\n kind: TKind;\n role: KindRole;\n category: KindCategory;\n prefix: string;\n schema: z.ZodObject<any>;\n collectRefs: (entity: TInput) => string[];\n /**\n * Khai báo ref requirements để validateRefs kiểm tra unknown/mismatch mà không\n * cần switch theo kind. Dạng hàm cho kind có ref phụ thuộc discriminated union\n * (vd pointAtDistance.distance). Kind chưa khai → validateRefs dùng legacy switch.\n */\n refSpecs?: readonly RefSpec[] | ((entity: TInput) => readonly RefSpec[]);\n emit: (entity: TInput, ctx: EmitContext) => EmittedEntity[];\n}\n\n/**\n * Factory that widens a typed module into the registry's generic shape.\n * Each kind module exports its module via this factory so `ALL_MODULES`\n * in registry.ts can be typed as ReadonlyArray<DslKindModule> without a cast.\n */\nexport function defineModule<TKind extends string, TInput>(\n m: DslKindModule<TKind, TInput>,\n): DslKindModule {\n return m as DslKindModule;\n}\n","// src/stamps/geometry-2d/dsl/kinds/_shared.ts\nimport type { SceneObject } from '../../../../core/scene/types';\nimport type { EmitContext } from './_types';\n\nexport const POINT_BASE_FIELDS = {\n visible: true,\n locked: false,\n layer: 'default',\n schemaVersion: 1,\n} as const;\n\n/** Wrap a Constraint2D-style attrs into a primary 'point' SceneObject. */\nexport function emitPointObject(\n id: string,\n name: string,\n constraint: Record<string, unknown>,\n visible = true,\n): SceneObject {\n return {\n id,\n kind: 'point',\n label: name,\n ...POINT_BASE_FIELDS,\n visible,\n attrs: { constraint },\n };\n}\n\n/** Resolve a triangle's 3 vertex ids. */\nexport function resolveTriangleVertices(\n ctx: EmitContext,\n vertices: readonly [string, string, string],\n): [string, string, string] {\n return [ctx.resolveId(vertices[0]), ctx.resolveId(vertices[1]), ctx.resolveId(vertices[2])];\n}\n\nexport const SHAPE_BASE_FIELDS = {\n visible: true,\n locked: false,\n layer: 'default',\n schemaVersion: 1,\n} as const;\n","// src/stamps/geometry-2d/dsl/kinds/points/free.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'free' }>;\n\nexport const freeModule = defineModule<'free', Input>({\n kind: 'free',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('free'),\n x: z.number().finite(),\n y: z.number().finite(),\n }),\n collectRefs: () => [],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, { kind: 'free', x: e.x, y: e.y }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/midpoint.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'midpoint' }>;\n\nexport const midpointModule = defineModule<'midpoint', Input>({\n kind: 'midpoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('midpoint'),\n p1: NameZ,\n p2: NameZ,\n visible: z.boolean().optional(),\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'midpoint', p1: ctx.resolveId(e.p1), p2: ctx.resolveId(e.p2) },\n e.visible ?? true,\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/onSegment.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'onSegment' }>;\n\nexport const onSegmentModule = defineModule<'onSegment', Input>({\n kind: 'onSegment',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('onSegment'),\n segmentId: NameZ,\n t: z.number().min(0).max(1),\n }),\n collectRefs: (e) => [e.segmentId],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'onSegment', segmentId: ctx.resolveId(e.segmentId), t: e.t },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/onLine.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'onLine' }>;\n\nexport const onLineModule = defineModule<'onLine', Input>({\n kind: 'onLine',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('onLine'),\n lineId: NameZ,\n t: z.number().finite(),\n }),\n collectRefs: (e) => [e.lineId],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'onLine', lineId: ctx.resolveId(e.lineId), t: e.t },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/onCircle.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'onCircle' }>;\n\nexport const onCircleModule = defineModule<'onCircle', Input>({\n kind: 'onCircle',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('onCircle'),\n circleId: NameZ,\n theta: z.number().finite(),\n }),\n collectRefs: (e) => [e.circleId],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'onCircle', circleId: ctx.resolveId(e.circleId), theta: e.theta },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/perpFoot.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'perpFoot' }>;\n\nexport const perpFootModule = defineModule<'perpFoot', Input>({\n kind: 'perpFoot',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('perpFoot'),\n from: NameZ,\n onLine: NameZ,\n }),\n collectRefs: (e) => [e.from, e.onLine],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'perpFoot', from: ctx.resolveId(e.from), onLine: ctx.resolveId(e.onLine) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/circumcenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'circumcenter' }>;\n\nexport const circumcenterModule = defineModule<'circumcenter', Input>({\n kind: 'circumcenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circumcenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'circumcenter', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/incenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'incenter' }>;\n\nexport const incenterModule = defineModule<'incenter', Input>({\n kind: 'incenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('incenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'incenter', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/centroid.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'centroid' }>;\n\nexport const centroidModule = defineModule<'centroid', Input>({\n kind: 'centroid',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('centroid'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'centroid', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/orthocenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'orthocenter' }>;\n\nexport const orthocenterModule = defineModule<'orthocenter', Input>({\n kind: 'orthocenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('orthocenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'orthocenter', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/intersection.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { POINT_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'intersection' }>;\n\nexport const intersectionModule = defineModule<'intersection', Input>({\n kind: 'intersection',\n role: 'point',\n category: 'points',\n prefix: 'i',\n schema: z.object({\n name: NameZ,\n kind: z.literal('intersection'),\n ref1: NameZ,\n ref2: NameZ,\n branch: z.union([z.literal(0), z.literal(1)]).optional(),\n }),\n collectRefs: (e) => [e.ref1, e.ref2],\n emit: (e, ctx) => {\n const r1IsCircle = ctx.hintOf(e.ref1) === 'circle';\n const r2IsCircle = ctx.hintOf(e.ref2) === 'circle';\n let intersectKind: 'lineLine' | 'lineCircle' | 'circleCircle';\n if (r1IsCircle && r2IsCircle) intersectKind = 'circleCircle';\n else if (r1IsCircle || r2IsCircle) intersectKind = 'lineCircle';\n else intersectKind = 'lineLine';\n\n const attrs: Record<string, unknown> = {\n kind: intersectKind,\n ref1: ctx.resolveId(e.ref1),\n ref2: ctx.resolveId(e.ref2),\n };\n if (intersectKind !== 'lineLine') {\n attrs.branch = e.branch ?? 0;\n }\n return [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'intersection',\n label: e.name,\n ...POINT_BASE_FIELDS,\n attrs,\n },\n }];\n },\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/segment.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'segment' }>;\n\nexport const segmentModule = defineModule<'segment', Input>({\n kind: 'segment',\n role: 'segment',\n category: 'lines',\n prefix: 's',\n schema: z.object({\n name: NameZ,\n kind: z.literal('segment'),\n p1: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'segment',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { p1: ctx.resolveId(e.p1), p2: ctx.resolveId(e.p2) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/line.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'line' }>;\n\nexport const lineModule = defineModule<'line', Input>({\n kind: 'line',\n role: 'line',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('line'),\n p1: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { p1: ctx.resolveId(e.p1), p2: ctx.resolveId(e.p2) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/ray.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'ray' }>;\n\nexport const rayModule = defineModule<'ray', Input>({\n kind: 'ray',\n role: 'ray',\n category: 'lines',\n prefix: 'r',\n schema: z.object({\n name: NameZ,\n kind: z.literal('ray'),\n origin: NameZ,\n through: NameZ,\n }),\n collectRefs: (e) => [e.origin, e.through],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'ray',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { origin: ctx.resolveId(e.origin), through: ctx.resolveId(e.through) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/perpendicular.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'perpendicular' }>;\n\nexport const perpendicularModule = defineModule<'perpendicular', Input>({\n kind: 'perpendicular',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('perpendicular'),\n throughPoint: NameZ,\n toLine: NameZ,\n }),\n collectRefs: (e) => [e.throughPoint, e.toLine],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'perpendicular',\n throughPoint: ctx.resolveId(e.throughPoint),\n toLine: ctx.resolveId(e.toLine),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/parallel.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'parallel' }>;\n\nexport const parallelModule = defineModule<'parallel', Input>({\n kind: 'parallel',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('parallel'),\n throughPoint: NameZ,\n toLine: NameZ,\n }),\n collectRefs: (e) => [e.throughPoint, e.toLine],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'parallel',\n throughPoint: ctx.resolveId(e.throughPoint),\n toLine: ctx.resolveId(e.toLine),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/perpBisector.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'perpBisector' }>;\n\nexport const perpBisectorModule = defineModule<'perpBisector', Input>({\n kind: 'perpBisector',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('perpBisector'),\n p1: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'perpBisector',\n p1: ctx.resolveId(e.p1),\n p2: ctx.resolveId(e.p2),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/angleBisector.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'angleBisector' }>;\n\nexport const angleBisectorModule = defineModule<'angleBisector', Input>({\n kind: 'angleBisector',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('angleBisector'),\n p1: NameZ,\n vertex: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.vertex, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'angleBisector',\n p1: ctx.resolveId(e.p1),\n vertex: ctx.resolveId(e.vertex),\n p2: ctx.resolveId(e.p2),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/lineThrough.ts\n//\n// Đường thẳng qua ≥2 điểm đồng tuyến (vd 3 tâm Euler G/H/O). Render là đường\n// VÔ HẠN qua 2 điểm xa nhau nhất (ổn định số học). Kind tổng quát role\n// 'lineConstruction' — tái dùng cho Euler line (issue #47) và sau này Simson.\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport type { RefSpec } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'lineThrough' }>;\n\nexport const lineThroughModule = defineModule<'lineThrough', Input>({\n kind: 'lineThrough',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('lineThrough'),\n points: z.array(NameZ).min(2),\n }),\n collectRefs: (e) => [...e.points],\n refSpecs: [{ field: 'points', role: 'point', many: true }] as readonly RefSpec[],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'lineThrough',\n points: e.points.map((p) => ctx.resolveId(p)),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/radicalAxis.ts\n//\n// Trục đẳng phương 2 đường tròn (issue #47, construct 2): đường ⊥ đường nối tâm\n// O₁O₂, mọi điểm trên nó có lũy thừa (power) bằng nhau với 2 đường tròn. Kind\n// role 'lineConstruction' nhưng tham chiếu 2 CIRCLE (không phải điểm) — mirror\n// `lineThrough` về cấu trúc, khác ở refSpecs role 'circle'.\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport type { RefSpec } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'radicalAxis' }>;\n\nexport const radicalAxisModule = defineModule<'radicalAxis', Input>({\n kind: 'radicalAxis',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('radicalAxis'),\n circle1: NameZ,\n circle2: NameZ,\n }),\n collectRefs: (e) => [e.circle1, e.circle2],\n refSpecs: [\n { field: 'circle1', role: 'circle' },\n { field: 'circle2', role: 'circle' },\n ] as readonly RefSpec[],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'radicalAxis',\n circle1: ctx.resolveId(e.circle1),\n circle2: ctx.resolveId(e.circle2),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/tangent.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'tangent' }>;\n\nexport const tangentModule = defineModule<'tangent', Input>({\n kind: 'tangent',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('tangent'),\n throughPoint: NameZ,\n toCircle: NameZ,\n branch: z.union([z.literal(0), z.literal(1), z.literal('on')]).optional(),\n }),\n collectRefs: (e) => [e.throughPoint, e.toCircle],\n emit: (e, ctx) => {\n const construction: Record<string, unknown> = {\n kind: 'tangent',\n throughPoint: ctx.resolveId(e.throughPoint),\n toCircle: ctx.resolveId(e.toCircle),\n };\n if (e.branch !== undefined) construction.branch = e.branch;\n return [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { construction },\n },\n }];\n },\n});\n","// src/stamps/geometry-2d/dsl/kinds/polygons/polygon.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'polygon' }>;\n\nexport const polygonModule = defineModule<'polygon', Input>({\n kind: 'polygon',\n role: 'polygon',\n category: 'polygons',\n prefix: 'poly',\n schema: z.object({\n name: NameZ,\n kind: z.literal('polygon'),\n vertices: z.array(NameZ).min(3),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'polygon',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { vertices: e.vertices.map((v) => ctx.resolveId(v)) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/circles/circleCP.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circleCP' }>;\n\nexport const circleCPModule = defineModule<'circleCP', Input>({\n kind: 'circleCP',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleCP'),\n center: NameZ,\n surfacePoint: NameZ,\n visible: z.boolean().optional(),\n }),\n collectRefs: (e) => [e.center, e.surfacePoint],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n visible: e.visible ?? true,\n attrs: { center: ctx.resolveId(e.center), surfacePoint: ctx.resolveId(e.surfacePoint) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/circles/circle3.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circle3' }>;\n\nexport const circle3Module = defineModule<'circle3', Input>({\n kind: 'circle3',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circle3'),\n p1: NameZ,\n p2: NameZ,\n p3: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2, e.p3],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'circumscribed',\n p1: ctx.resolveId(e.p1),\n p2: ctx.resolveId(e.p2),\n p3: ctx.resolveId(e.p3),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/circles/circleDiameter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circleDiameter' }>;\n\n// Đường tròn đường kính p1p2 — tâm = trung điểm, bán kính = |p1p2|/2.\n// Emit circle với construction 'diameter'; renderer dựng midpoint ẩn + circle qua p2.\nexport const circleDiameterModule = defineModule<'circleDiameter', Input>({\n kind: 'circleDiameter',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleDiameter'),\n p1: NameZ,\n p2: NameZ,\n visible: z.boolean().optional(),\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n visible: e.visible ?? true,\n attrs: {\n construction: {\n kind: 'diameter',\n p1: ctx.resolveId(e.p1),\n p2: ctx.resolveId(e.p2),\n },\n },\n },\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'secondIntersection' }>;\n\nexport const secondIntersectionModule = defineModule<'secondIntersection', Input>({\n kind: 'secondIntersection',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('secondIntersection'),\n line: NameZ,\n circle: NameZ,\n other: NameZ,\n }),\n collectRefs: (e) => [e.line, e.circle, e.other],\n refSpecs: [\n { field: 'line', role: 'line-like' },\n { field: 'circle', role: 'circle' },\n { field: 'other', role: 'point' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'secondIntersection',\n line: ctx.resolveId(e.line),\n circle: ctx.resolveId(e.circle),\n other: ctx.resolveId(e.other),\n },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/circleIntersection.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'circleIntersection' }>;\n\nexport const circleIntersectionModule = defineModule<'circleIntersection', Input>({\n kind: 'circleIntersection',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleIntersection'),\n c1: NameZ,\n c2: NameZ,\n which: z.union([z.literal(0), z.literal(1)]),\n }),\n collectRefs: (e) => [e.c1, e.c2],\n refSpecs: [\n { field: 'c1', role: 'circle' },\n { field: 'c2', role: 'circle' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'circleIntersection',\n c1: ctx.resolveId(e.c1),\n c2: ctx.resolveId(e.c2),\n which: e.which,\n },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/circleSecondIntersection.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'circleSecondIntersection' }>;\n\n// Giao điểm THỨ HAI của 2 đường tròn (c1 ∩ c2), biết điểm chung `exclude`.\n// Renderer: JSXGraph 'otherintersection' → nghiệm KHÁC `exclude`.\nexport const circleSecondIntersectionModule = defineModule<'circleSecondIntersection', Input>({\n kind: 'circleSecondIntersection',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleSecondIntersection'),\n c1: NameZ,\n c2: NameZ,\n exclude: NameZ,\n }),\n collectRefs: (e) => [e.c1, e.c2, e.exclude],\n refSpecs: [\n { field: 'c1', role: 'circle' },\n { field: 'c2', role: 'circle' },\n { field: 'exclude', role: 'point' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'circleSecondIntersection',\n c1: ctx.resolveId(e.c1),\n c2: ctx.resolveId(e.c2),\n exclude: ctx.resolveId(e.exclude),\n },\n ),\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'tangencyPoint' }>;\n\nexport const tangencyPointModule = defineModule<'tangencyPoint', Input>({\n kind: 'tangencyPoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('tangencyPoint'),\n circle: NameZ,\n onLine: NameZ,\n }),\n collectRefs: (e) => [e.circle, e.onLine],\n refSpecs: [\n { field: 'circle', role: 'circle' },\n { field: 'onLine', role: 'line-like' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'tangencyPoint',\n circle: ctx.resolveId(e.circle),\n onLine: ctx.resolveId(e.onLine),\n },\n ),\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'tangentPointExt' }>;\n\nexport const tangentPointExtModule = defineModule<'tangentPointExt', Input>({\n kind: 'tangentPointExt',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('tangentPointExt'),\n from: NameZ,\n circle: NameZ,\n which: z.union([z.literal(0), z.literal(1)]),\n }),\n collectRefs: (e) => [e.from, e.circle],\n refSpecs: [\n { field: 'from', role: 'point' },\n { field: 'circle', role: 'circle' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'tangentPointExt',\n from: ctx.resolveId(e.from),\n circle: ctx.resolveId(e.circle),\n which: e.which,\n },\n ),\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circleCR' }>;\n\nexport const circleCRModule = defineModule<'circleCR', Input>({\n kind: 'circleCR',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleCR'),\n center: NameZ,\n radius: z.number().positive(),\n }),\n collectRefs: (e) => [e.center],\n refSpecs: [{ field: 'center', role: 'point' }],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { center: ctx.resolveId(e.center), radius: e.radius },\n },\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'incircle' }>;\n\nexport const incircleModule = defineModule<'incircle', Input>({\n kind: 'incircle',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('incircle'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n refSpecs: [{ field: 'vertices', role: 'point', many: true }],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n kind: 'incircle',\n vertices: [\n ctx.resolveId(e.vertices[0]),\n ctx.resolveId(e.vertices[1]),\n ctx.resolveId(e.vertices[2]),\n ],\n },\n },\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'excircle' }>;\n\nexport const excircleModule = defineModule<'excircle', Input>({\n kind: 'excircle',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('excircle'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n opposite: NameZ,\n }),\n collectRefs: (e) => [...e.vertices],\n refSpecs: [\n { field: 'vertices', role: 'point', many: true },\n { field: 'opposite', role: 'point' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'excircle',\n p1: ctx.resolveId(e.vertices[0]),\n p2: ctx.resolveId(e.vertices[1]),\n p3: ctx.resolveId(e.vertices[2]),\n opposite: ctx.resolveId(e.opposite),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/arcMidpoint.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'arcMidpoint' }>;\n\nexport const arcMidpointModule = defineModule<'arcMidpoint', Input>({\n kind: 'arcMidpoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('arcMidpoint'),\n circle: NameZ,\n a: NameZ,\n b: NameZ,\n notContaining: NameZ,\n }),\n collectRefs: (e) => [e.circle, e.a, e.b, e.notContaining],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'arcMidpoint',\n circle: ctx.resolveId(e.circle),\n a: ctx.resolveId(e.a),\n b: ctx.resolveId(e.b),\n notContaining: ctx.resolveId(e.notContaining),\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/excenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'excenter' }>;\n\nexport const excenterModule = defineModule<'excenter', Input>({\n kind: 'excenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('excenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n opposite: NameZ,\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'excenter',\n vertices: resolveTriangleVertices(ctx, e.vertices),\n opposite: ctx.resolveId(e.opposite),\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/reflectPoint.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'reflectPoint' }>;\n\nexport const reflectPointModule = defineModule<'reflectPoint', Input>({\n kind: 'reflectPoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({ name: NameZ, kind: z.literal('reflectPoint'), of: NameZ, through: NameZ }),\n collectRefs: (e) => [e.of, e.through],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'transformed',\n source: ctx.resolveId(e.of),\n transform: { kind: 'reflectPoint', center: ctx.resolveId(e.through) },\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/reflectLine.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'reflectLine' }>;\n\nexport const reflectLineModule = defineModule<'reflectLine', Input>({\n kind: 'reflectLine',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({ name: NameZ, kind: z.literal('reflectLine'), of: NameZ, through: NameZ }),\n collectRefs: (e) => [e.of, e.through],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'transformed',\n source: ctx.resolveId(e.of),\n transform: { kind: 'reflectLine', line: ctx.resolveId(e.through) },\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/pointAtDistance.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'pointAtDistance' }>;\n\n// scale/offset OPTIONAL (Issue #46 nhóm C): d = scale·base + offset. scale phải\n// > 0; offset bất kỳ (âm OK — guard d>0 ở render). Absent → giữ form cũ (additive).\nconst ScaleOffsetZ = {\n scale: z.number().positive().optional(),\n offset: z.number().optional(),\n};\nconst DistanceZ = z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('circleRadius'), circle: NameZ, ...ScaleOffsetZ }),\n z.object({ kind: z.literal('segmentLength'), p1: NameZ, p2: NameZ, ...ScaleOffsetZ }),\n z.object({ kind: z.literal('literal'), value: z.number().positive(), ...ScaleOffsetZ }),\n]);\n\n/** Chỉ chèn scale/offset khi có giá trị → object cũ KHÔNG mọc key (additive). */\nfunction withScaleOffset<T extends object>(base: T, d: { scale?: number; offset?: number }): T {\n const out = { ...base } as T & { scale?: number; offset?: number };\n if (d.scale !== undefined) out.scale = d.scale;\n if (d.offset !== undefined) out.offset = d.offset;\n return out;\n}\n\nexport const pointAtDistanceModule = defineModule<'pointAtDistance', Input>({\n kind: 'pointAtDistance',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('pointAtDistance'),\n from: NameZ,\n through: NameZ,\n distance: DistanceZ,\n }),\n collectRefs: (e) => {\n const d = e.distance;\n const extra = d.kind === 'circleRadius' ? [d.circle]\n : d.kind === 'segmentLength' ? [d.p1, d.p2] : [];\n return [e.from, e.through, ...extra];\n },\n // TODO(Mức 1 defer): distance.{circle,p1,p2} là nested trong `distance` — refSpec\n // phẳng đọc top-level không với tới, validate riêng nếu cần. Hiện validate from/through.\n refSpecs: [\n { field: 'from', role: 'point' },\n { field: 'through', role: 'point' },\n ],\n emit: (e, ctx) => {\n const d = e.distance;\n const distance = d.kind === 'circleRadius'\n ? withScaleOffset({ kind: 'circleRadius', circle: ctx.resolveId(d.circle) }, d)\n : d.kind === 'segmentLength'\n ? withScaleOffset({ kind: 'segmentLength', p1: ctx.resolveId(d.p1), p2: ctx.resolveId(d.p2) }, d)\n : withScaleOffset({ kind: 'literal', value: d.value }, d);\n return [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'pointAtDistance',\n from: ctx.resolveId(e.from),\n through: ctx.resolveId(e.through),\n distance,\n }),\n }];\n },\n});\n","// src/stamps/geometry-2d/dsl/registry.ts\nimport { z } from 'zod';\nimport type { DslKindModule } from './kinds/_types';\nimport { freeModule } from './kinds/points/free';\nimport { midpointModule } from './kinds/points/midpoint';\nimport { onSegmentModule } from './kinds/points/onSegment';\nimport { onLineModule } from './kinds/points/onLine';\nimport { onCircleModule } from './kinds/points/onCircle';\nimport { perpFootModule } from './kinds/points/perpFoot';\nimport { circumcenterModule } from './kinds/points/circumcenter';\nimport { incenterModule } from './kinds/points/incenter';\nimport { centroidModule } from './kinds/points/centroid';\nimport { orthocenterModule } from './kinds/points/orthocenter';\nimport { intersectionModule } from './kinds/points/intersection';\nimport { segmentModule } from './kinds/lines/segment';\nimport { lineModule } from './kinds/lines/line';\nimport { rayModule } from './kinds/lines/ray';\nimport { perpendicularModule } from './kinds/lines/perpendicular';\nimport { parallelModule } from './kinds/lines/parallel';\nimport { perpBisectorModule } from './kinds/lines/perpBisector';\nimport { angleBisectorModule } from './kinds/lines/angleBisector';\nimport { lineThroughModule } from './kinds/lines/lineThrough';\nimport { radicalAxisModule } from './kinds/lines/radicalAxis';\nimport { tangentModule } from './kinds/lines/tangent';\nimport { polygonModule } from './kinds/polygons/polygon';\nimport { circleCPModule } from './kinds/circles/circleCP';\nimport { circle3Module } from './kinds/circles/circle3';\nimport { circleDiameterModule } from './kinds/circles/circleDiameter';\nimport { secondIntersectionModule } from './kinds/points/secondIntersection';\nimport { circleIntersectionModule } from './kinds/points/circleIntersection';\nimport { circleSecondIntersectionModule } from './kinds/points/circleSecondIntersection';\nimport { tangencyPointModule } from './kinds/points/tangencyPoint';\nimport { tangentPointExtModule } from './kinds/points/tangentPointExt';\nimport { circleCRModule } from './kinds/circles/circleCR';\nimport { incircleModule } from './kinds/circles/incircle';\nimport { excircleModule } from './kinds/circles/excircle';\nimport { arcMidpointModule } from './kinds/points/arcMidpoint';\nimport { excenterModule } from './kinds/points/excenter';\nimport { reflectPointModule } from './kinds/points/reflectPoint';\nimport { reflectLineModule } from './kinds/points/reflectLine';\nimport { pointAtDistanceModule } from './kinds/points/pointAtDistance';\n\nconst ALL_MODULES: ReadonlyArray<DslKindModule> = [\n freeModule, midpointModule, onSegmentModule, onLineModule, onCircleModule,\n perpFootModule, circumcenterModule, incenterModule, centroidModule,\n orthocenterModule, intersectionModule,\n // NEW Tier 4+5 points\n secondIntersectionModule, circleIntersectionModule, circleSecondIntersectionModule,\n tangencyPointModule, tangentPointExtModule,\n segmentModule, lineModule, rayModule,\n perpendicularModule, parallelModule, perpBisectorModule,\n angleBisectorModule, lineThroughModule, radicalAxisModule, tangentModule,\n polygonModule,\n circleCPModule, circle3Module, circleDiameterModule,\n // NEW Tier 4+5 circles\n circleCRModule, incircleModule, excircleModule,\n // Cụm A points\n arcMidpointModule, excenterModule, reflectPointModule, reflectLineModule,\n // Cụm B points\n pointAtDistanceModule,\n];\n\nexport const KIND_REGISTRY: ReadonlyMap<string, DslKindModule> =\n new Map(ALL_MODULES.map((m) => [m.kind, m]));\n\nexport const POINT_KINDS: ReadonlySet<string> = new Set(\n ALL_MODULES.filter((m) => m.role === 'point').map((m) => m.kind),\n);\n\nexport const LINE_LIKE_SHAPE_KINDS: ReadonlySet<string> = new Set(\n ALL_MODULES.filter(\n (m) =>\n m.role === 'segment' ||\n m.role === 'line' ||\n m.role === 'ray' ||\n m.role === 'lineConstruction',\n ).map((m) => m.kind),\n);\n\nexport const CIRCLE_KINDS: ReadonlySet<string> = new Set(\n ALL_MODULES.filter((m) => m.role === 'circle').map((m) => m.kind),\n);\n\n// Top-level entity discriminated union — used internally by schema.ts for building DslPoint/DslShape.\nexport const DslEntitySchema = z.discriminatedUnion(\n 'kind',\n ALL_MODULES.map((m) => m.schema) as unknown as [z.ZodObject<any>, z.ZodObject<any>, ...z.ZodObject<any>[]],\n);\n","// src/stamps/geometry-2d/dsl/schema.ts\nimport { z } from 'zod';\nimport { NameZ } from './names';\nimport { KIND_REGISTRY, POINT_KINDS } from './registry';\n\n// Re-export NameZ for backward compat with consumers.\nexport { NameZ } from './names';\n\nfunction asTuple(arr: z.ZodObject<any>[]): [z.ZodObject<any>, z.ZodObject<any>, ...z.ZodObject<any>[]] {\n if (arr.length < 2) throw new Error('schema: need at least 2 variants for discriminatedUnion');\n return arr as never;\n}\n\nconst pointSchemas = Array.from(KIND_REGISTRY.values())\n .filter((m) => POINT_KINDS.has(m.kind))\n .map((m) => m.schema);\n\nconst shapeSchemas = Array.from(KIND_REGISTRY.values())\n .filter((m) => !POINT_KINDS.has(m.kind))\n .map((m) => m.schema);\n\n// Runtime schemas assembled from the registry (Phase 6).\nexport const DslPoint = z.discriminatedUnion('kind', asTuple(pointSchemas));\nexport const DslShape = z.discriminatedUnion('kind', asTuple(shapeSchemas));\n\nexport const DslInput = z.object({\n version: z.literal(1),\n points: z.array(DslPoint),\n shapes: z.array(DslShape).default([]),\n});\n\n// -----------------------------------------------------------------------------\n// Static types\n//\n// We cannot derive these via `z.infer<typeof DslPoint>` because the kind\n// modules use `Extract<DslPointT, { kind: '...' }>` to type their `emit` /\n// `collectRefs` callbacks. That creates a type-graph cycle\n// (schema.ts -> registry.ts -> kinds/* -> schema.ts) which TypeScript collapses\n// to `any` (and `Extract<any, ...>` to `never`) because the registry stores\n// schemas as the erased `z.ZodObject<any>`.\n//\n// Keeping the discriminated union types listed explicitly here breaks the cycle\n// while still letting `DslPoint`/`DslShape` (runtime) be registry-assembled.\n// Adding a new kind = 1 new module file + 1 entry in registry.ts + 1 variant\n// listed below (a single object literal — much smaller than duplicating the\n// full Zod schema).\n// -----------------------------------------------------------------------------\n\ntype Name = z.infer<typeof NameZ>;\n\n// scale/offset OPTIONAL (Issue #46 nhóm C): d = scale·base + offset. Absent →\n// d = base như cũ (additive, serialize/golden không đổi).\nexport type DslDistanceSpec =\n | { kind: 'circleRadius'; circle: Name; scale?: number; offset?: number }\n | { kind: 'segmentLength'; p1: Name; p2: Name; scale?: number; offset?: number }\n | { kind: 'literal'; value: number; scale?: number; offset?: number };\n\nexport type DslPointT =\n | { name: Name; kind: 'free'; x: number; y: number }\n | { name: Name; kind: 'midpoint'; p1: Name; p2: Name; visible?: boolean }\n | { name: Name; kind: 'onSegment'; segmentId: Name; t: number }\n | { name: Name; kind: 'onLine'; lineId: Name; t: number }\n | { name: Name; kind: 'onCircle'; circleId: Name; theta: number }\n | { name: Name; kind: 'perpFoot'; from: Name; onLine: Name }\n | { name: Name; kind: 'circumcenter'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'incenter'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'centroid'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'orthocenter'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'intersection'; ref1: Name; ref2: Name; branch?: 0 | 1 }\n // NEW Tier 4+5\n | { name: Name; kind: 'secondIntersection'; line: Name; circle: Name; other: Name }\n | { name: Name; kind: 'circleIntersection'; c1: Name; c2: Name; which: 0 | 1 }\n | { name: Name; kind: 'circleSecondIntersection'; c1: Name; c2: Name; exclude: Name }\n | { name: Name; kind: 'tangencyPoint'; circle: Name; onLine: Name }\n | { name: Name; kind: 'tangentPointExt'; from: Name; circle: Name; which: 0 | 1 }\n // Cụm A\n | { name: Name; kind: 'arcMidpoint'; circle: Name; a: Name; b: Name; notContaining: Name }\n | { name: Name; kind: 'excenter'; vertices: [Name, Name, Name]; opposite: Name }\n | { name: Name; kind: 'reflectPoint'; of: Name; through: Name }\n | { name: Name; kind: 'reflectLine'; of: Name; through: Name }\n // Cụm B points\n | { name: Name; kind: 'pointAtDistance'; from: Name; through: Name; distance: DslDistanceSpec };\n\nexport type DslShapeT =\n | { name: Name; kind: 'segment'; p1: Name; p2: Name }\n | { name: Name; kind: 'line'; p1: Name; p2: Name }\n | { name: Name; kind: 'ray'; origin: Name; through: Name }\n | { name: Name; kind: 'polygon'; vertices: Name[] }\n | { name: Name; kind: 'perpendicular'; throughPoint: Name; toLine: Name }\n | { name: Name; kind: 'parallel'; throughPoint: Name; toLine: Name }\n | { name: Name; kind: 'perpBisector'; p1: Name; p2: Name }\n | { name: Name; kind: 'angleBisector'; p1: Name; vertex: Name; p2: Name }\n | { name: Name; kind: 'lineThrough'; points: Name[] }\n | { name: Name; kind: 'radicalAxis'; circle1: Name; circle2: Name }\n | { name: Name; kind: 'tangent'; throughPoint: Name; toCircle: Name; branch?: 0 | 1 | 'on' }\n | { name: Name; kind: 'circleCP'; center: Name; surfacePoint: Name; visible?: boolean }\n | { name: Name; kind: 'circle3'; p1: Name; p2: Name; p3: Name }\n | { name: Name; kind: 'circleDiameter'; p1: Name; p2: Name; visible?: boolean }\n // NEW Tier 4+5\n | { name: Name; kind: 'circleCR'; center: Name; radius: number }\n | { name: Name; kind: 'incircle'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'excircle'; vertices: [Name, Name, Name]; opposite: Name };\n\nexport type DslInputT = {\n version: 1;\n points: DslPointT[];\n shapes: DslShapeT[];\n};\n","// src/core/scene/types.ts\n\nexport type SceneObject<A = Record<string, unknown>> = {\n id: string;\n kind: string;\n label: string;\n visible: boolean;\n locked: boolean;\n layer: string;\n schemaVersion: number;\n attrs: A;\n};\n\n// View per domain — narrow theo `state.meta.domain`.\nexport type View2D = {\n readonly bbox: readonly [number, number, number, number]; // [xmin, ymax, xmax, ymin]\n readonly showAxis: boolean;\n readonly showGrid: boolean;\n};\n\nexport type View3D = {\n readonly bbox3D: readonly [number, number, number, number, number, number]; // [xmin, xmax, ymin, ymax, zmin, zmax]\n readonly azimuth: number;\n readonly elevation: number;\n};\n\nexport type ViewGraph2D = {\n readonly xMin: number;\n readonly xMax: number;\n readonly yMin: number;\n readonly yMax: number;\n readonly showAxis: boolean;\n readonly showGrid: boolean;\n};\n\n// Union of all view shapes — narrow qua state.meta.domain.\nexport type SceneView = View2D | View3D | ViewGraph2D;\n\n// Discriminated union: domain narrow → view shape narrow.\nexport type StateMeta =\n | { readonly domain: '2d'; readonly version: number; readonly view: View2D }\n | { readonly domain: '3d'; readonly version: number; readonly view: View3D }\n | { readonly domain: 'graph2d'; readonly version: number; readonly view: ViewGraph2D };\n\nexport type Domain = StateMeta['domain'];\n\n// Backward-compat alias: UPDATE_VIEW patch dùng graph-2d shape (chỉ graph-2d\n// dispatch action này hiện tại).\nexport type ViewSettings = ViewGraph2D;\n\nexport type State = {\n readonly objects: Readonly<Record<string, SceneObject>>;\n readonly order: readonly string[];\n readonly counter: number;\n readonly meta: StateMeta;\n};\n\nexport type Action =\n | { type: 'ADD'; payload: { obj: SceneObject } }\n | { type: 'UPDATE'; payload: { id: string; patch: Partial<Omit<SceneObject, 'id' | 'kind' | 'attrs'>> } }\n | { type: 'UPDATE_ATTRS'; payload: { id: string; patch: Record<string, unknown> } }\n | { type: 'DELETE'; payload: { id: string } }\n | { type: 'RESET' }\n | { type: 'LOAD'; payload: { state: State } }\n | { type: 'TRANSACTION'; payload: { actions: Action[] } }\n | { type: 'UPDATE_VIEW'; payload: { patch: Partial<ViewSettings> } };\n\nexport type RenderCtx = {\n jxg: unknown;\n resolveRef: (id: string) => unknown;\n defaults: Readonly<Record<string, unknown>>;\n /** Map tham số (parameter.label → parameter.value). Chỉ graph2d dùng. */\n paramMap?: Readonly<Record<string, number>>;\n};\n\nexport type KindDef<A = Record<string, unknown>> = {\n type: string;\n schemaVersion: number;\n migrate: Record<number, (prev: any) => any>;\n validate?: (attrs: A) => void;\n dependsOn: (attrs: A) => string[];\n describe: (obj: SceneObject<A>, state?: State) => string;\n measure?: (obj: SceneObject<A>, state: State) =>\n | { label: string; value: number }[]\n | null;\n render: (obj: SceneObject<A>, ctx: RenderCtx) => unknown;\n update?: (\n obj: SceneObject<A>,\n prev: SceneObject<A>,\n ctx: RenderCtx,\n existing: unknown,\n ) => void;\n};\n\nexport const DEFAULT_VIEW_2D: View2D = {\n bbox: [-10, 10, 10, -10],\n showAxis: false,\n showGrid: false,\n};\n\nexport const DEFAULT_VIEW_3D: View3D = {\n bbox3D: [-5, 5, -5, 5, -5, 5],\n azimuth: 60,\n elevation: 30,\n};\n\nexport const DEFAULT_VIEW_GRAPH2D: ViewGraph2D = {\n xMin: -10, xMax: 10, yMin: -10, yMax: 10,\n showAxis: true, showGrid: true,\n};\n\n// EMPTY_STATE giữ shape '3d' (legacy default). Dùng `createEmptyState(domain)`\n// khi cần state cụ thể cho domain — đảm bảo meta.view khớp domain.\nexport const EMPTY_STATE: State = {\n objects: {},\n order: [],\n counter: 0,\n meta: { domain: '3d', version: 1, view: DEFAULT_VIEW_3D },\n};\n\nexport function createEmptyState(domain: Domain): State {\n const base = { objects: {}, order: [], counter: 0 } as const;\n switch (domain) {\n case '2d':\n return { ...base, meta: { domain: '2d', version: 1, view: DEFAULT_VIEW_2D } };\n case '3d':\n return { ...base, meta: { domain: '3d', version: 1, view: DEFAULT_VIEW_3D } };\n case 'graph2d':\n return { ...base, meta: { domain: 'graph2d', version: 1, view: DEFAULT_VIEW_GRAPH2D } };\n }\n}\n","// src/stamps/geometry-2d/dsl/transpile/errors.ts\nimport type { State } from '../../../../core/scene/types';\n\nexport type TranspileErrorCode =\n | 'SCHEMA'\n | 'DUPLICATE_NAME'\n | 'UNKNOWN_REF'\n | 'KIND_MISMATCH'\n | 'CYCLE';\n\nexport interface TranspileError {\n code: TranspileErrorCode;\n message: string;\n path?: string[];\n hint?: string;\n}\n\nexport type TranspileResult =\n | { ok: true; state: State }\n | { ok: false; errors: TranspileError[] };\n\nexport function mkError(\n code: TranspileErrorCode,\n message: string,\n opts?: { path?: string[]; hint?: string },\n): TranspileError {\n return { code, message, path: opts?.path, hint: opts?.hint };\n}\n","// src/stamps/geometry-2d/dsl/transpile/symbols.ts\nimport type { DslInputT, DslPointT, DslShapeT } from '../schema';\nimport { mkError, type TranspileError } from './errors';\n\nexport type Role = 'point' | 'shape';\n\nexport interface Symbol {\n name: string;\n role: Role;\n entity: DslPointT | DslShapeT;\n index: number; // vị trí trong list nguyên thuỷ (cho deterministic id assign sau)\n}\n\nexport interface SymbolResult {\n symbols: Map<string, Symbol>;\n errors: TranspileError[];\n}\n\nexport function buildSymbols(dsl: DslInputT): SymbolResult {\n const symbols = new Map<string, Symbol>();\n const errors: TranspileError[] = [];\n let counter = 0;\n\n for (const p of dsl.points) {\n if (symbols.has(p.name)) {\n errors.push(mkError('DUPLICATE_NAME', `Tên trùng: \"${p.name}\"`, { path: [p.name] }));\n continue;\n }\n symbols.set(p.name, { name: p.name, role: 'point', entity: p, index: counter++ });\n }\n\n for (const s of dsl.shapes) {\n if (symbols.has(s.name)) {\n errors.push(mkError('DUPLICATE_NAME', `Tên trùng: \"${s.name}\"`, { path: [s.name] }));\n continue;\n }\n symbols.set(s.name, { name: s.name, role: 'shape', entity: s, index: counter++ });\n }\n\n return { symbols, errors };\n}\n","// src/stamps/geometry-2d/dsl/transpile/refs.ts\nimport type { DslInputT, DslPointT, DslShapeT } from '../schema';\nimport { KIND_REGISTRY, LINE_LIKE_SHAPE_KINDS, CIRCLE_KINDS } from '../registry';\nimport type { RefRole, RefSpec } from '../kinds/_types';\nimport type { Symbol } from './symbols';\nimport { mkError, type TranspileError } from './errors';\n\nfunction isPointLike(sym: Symbol | undefined): boolean {\n return !!sym && sym.role === 'point';\n}\n\nfunction isLineLike(sym: Symbol | undefined): boolean {\n if (!sym || sym.role !== 'shape') return false;\n return LINE_LIKE_SHAPE_KINDS.has((sym.entity as DslShapeT).kind);\n}\n\nfunction isCircleLike(sym: Symbol | undefined): boolean {\n if (!sym || sym.role !== 'shape') return false;\n return CIRCLE_KINDS.has((sym.entity as DslShapeT).kind);\n}\n\nfunction isSegmentExact(sym: Symbol | undefined): boolean {\n return !!sym && sym.role === 'shape' && (sym.entity as DslShapeT).kind === 'segment';\n}\n\nconst ROLE_PREDICATE: Record<RefRole, (s: Symbol | undefined) => boolean> = {\n point: isPointLike,\n 'line-like': isLineLike,\n circle: isCircleLike,\n segment: isSegmentExact,\n shape: (s) => !!s && s.role === 'shape',\n 'any-existing': (s) => !!s,\n};\nconst ROLE_EXPECTED: Record<RefRole, string> = {\n point: 'point',\n 'line-like': 'line-like',\n circle: 'circle',\n segment: 'segment',\n shape: 'shape',\n 'any-existing': 'tồn tại',\n};\n\nexport interface RefsResult {\n errors: TranspileError[];\n}\n\nexport function validateRefs(dsl: DslInputT, symbols: Map<string, Symbol>): RefsResult {\n const errors: TranspileError[] = [];\n\n const check = (\n owner: string,\n field: string,\n refName: string,\n predicate: (s: Symbol | undefined) => boolean,\n expected: string,\n ) => {\n const sym = symbols.get(refName);\n if (!sym) {\n errors.push(mkError('UNKNOWN_REF',\n `${owner}.${field} tham chiếu \"${refName}\" không tồn tại`,\n { path: [owner, field] }));\n return;\n }\n if (!predicate(sym)) {\n errors.push(mkError('KIND_MISMATCH',\n `${owner}.${field}=\"${refName}\" sai kiểu (cần ${expected}, gặp ${sym.role === 'point' ? 'point' : (sym.entity as DslShapeT).kind})`,\n { path: [owner, field] }));\n }\n };\n\n // Registry-driven pass: kind nào khai refSpecs thì validate ở đây, switch bỏ qua.\n const handledByRegistry = new Set<string>();\n const runSpecs = (owner: string, entity: DslPointT | DslShapeT): boolean => {\n const mod = KIND_REGISTRY.get(entity.kind);\n const raw = mod?.refSpecs;\n if (!raw) return false;\n const specs: readonly RefSpec[] =\n typeof raw === 'function' ? raw(entity as never) : raw;\n for (const spec of specs) {\n const val = (entity as Record<string, unknown>)[spec.field];\n const names: string[] = spec.many\n ? ((val as string[]) ?? [])\n : val == null\n ? []\n : [val as string];\n names.forEach((refName, i) => {\n const field = spec.many ? `${spec.field}[${i}]` : spec.field;\n check(owner, field, refName, ROLE_PREDICATE[spec.role], ROLE_EXPECTED[spec.role]);\n });\n }\n handledByRegistry.add(owner);\n return true;\n };\n for (const p of dsl.points) runSpecs(p.name, p);\n for (const s of dsl.shapes) runSpecs(s.name, s);\n\n for (const p of dsl.points) {\n if (handledByRegistry.has(p.name)) continue;\n switch (p.kind) {\n case 'free': break;\n case 'midpoint':\n check(p.name, 'p1', p.p1, isPointLike, 'point');\n check(p.name, 'p2', p.p2, isPointLike, 'point');\n break;\n case 'onSegment':\n check(p.name, 'segmentId', p.segmentId, isSegmentExact, 'segment');\n break;\n case 'onLine':\n check(p.name, 'lineId', p.lineId, isLineLike, 'line-like');\n break;\n case 'onCircle':\n check(p.name, 'circleId', p.circleId, isCircleLike, 'circle');\n break;\n case 'perpFoot':\n check(p.name, 'from', p.from, isPointLike, 'point');\n check(p.name, 'onLine', p.onLine, isLineLike, 'line-like');\n break;\n case 'circumcenter':\n case 'incenter':\n case 'centroid':\n case 'orthocenter':\n for (let i = 0; i < 3; i++) {\n check(p.name, `vertices[${i}]`, p.vertices[i], isPointLike, 'point');\n }\n break;\n case 'intersection': {\n const refPredicate = (s: Symbol | undefined) => isLineLike(s) || isCircleLike(s);\n check(p.name, 'ref1', p.ref1, refPredicate, 'line-like hoặc circle');\n check(p.name, 'ref2', p.ref2, refPredicate, 'line-like hoặc circle');\n break;\n }\n case 'arcMidpoint':\n check(p.name, 'circle', p.circle, isCircleLike, 'circle');\n check(p.name, 'a', p.a, isPointLike, 'point');\n check(p.name, 'b', p.b, isPointLike, 'point');\n check(p.name, 'notContaining', p.notContaining, isPointLike, 'point');\n break;\n case 'excenter':\n for (let i = 0; i < 3; i++) {\n check(p.name, `vertices[${i}]`, p.vertices[i], isPointLike, 'point');\n }\n check(p.name, 'opposite', p.opposite, isPointLike, 'point');\n break;\n case 'reflectPoint':\n check(p.name, 'of', p.of, isPointLike, 'point');\n check(p.name, 'through', p.through, isPointLike, 'point');\n break;\n case 'reflectLine':\n check(p.name, 'of', p.of, isPointLike, 'point');\n check(p.name, 'through', p.through, isLineLike, 'line-like');\n break;\n }\n }\n\n for (const s of dsl.shapes) {\n if (handledByRegistry.has(s.name)) continue;\n switch (s.kind) {\n case 'segment':\n case 'line':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n break;\n case 'ray':\n check(s.name, 'origin', s.origin, isPointLike, 'point');\n check(s.name, 'through', s.through, isPointLike, 'point');\n break;\n case 'polygon':\n s.vertices.forEach((v, i) =>\n check(s.name, `vertices[${i}]`, v, isPointLike, 'point'));\n break;\n case 'perpendicular':\n case 'parallel':\n check(s.name, 'throughPoint', s.throughPoint, isPointLike, 'point');\n check(s.name, 'toLine', s.toLine, isLineLike, 'line-like');\n break;\n case 'perpBisector':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n break;\n case 'angleBisector':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'vertex', s.vertex, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n break;\n case 'tangent':\n check(s.name, 'throughPoint', s.throughPoint, isPointLike, 'point');\n check(s.name, 'toCircle', s.toCircle, isCircleLike, 'circle');\n break;\n case 'circleCP':\n check(s.name, 'center', s.center, isPointLike, 'point');\n check(s.name, 'surfacePoint', s.surfacePoint, isPointLike, 'point');\n break;\n case 'circle3':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n check(s.name, 'p3', s.p3, isPointLike, 'point');\n break;\n }\n }\n\n return { errors };\n}\n\n// Helper export cho cycles.ts: collect refs cho mỗi entity (name) trả về list ref names.\nexport function collectRefs(entity: DslPointT | DslShapeT): string[] {\n const mod = KIND_REGISTRY.get(entity.kind);\n if (!mod) throw new Error(`collectRefs: no registry entry for kind \"${entity.kind}\"`);\n return mod.collectRefs(entity as never);\n}\n","// src/stamps/geometry-2d/dsl/transpile/cycles.ts\nimport type { Symbol } from './symbols';\nimport { collectRefs } from './refs';\nimport { mkError, type TranspileError } from './errors';\n\ntype Color = 'white' | 'gray' | 'black';\n\nexport interface CyclesResult {\n errors: TranspileError[];\n}\n\nexport function detectCycles(symbols: Map<string, Symbol>): CyclesResult {\n const color = new Map<string, Color>();\n const parent = new Map<string, string | null>();\n const errors: TranspileError[] = [];\n const reportedCycles = new Set<string>();\n\n for (const name of symbols.keys()) color.set(name, 'white');\n\n function reportCycle(start: string, hit: string) {\n // reconstruct chain hit ← ... ← start\n const chain: string[] = [start];\n let cur: string | null | undefined = parent.get(start);\n while (cur && cur !== hit && chain.length < symbols.size + 2) {\n chain.push(cur);\n cur = parent.get(cur);\n }\n chain.push(hit);\n // normalize cho dedupe (rotate min-first)\n const minIdx = chain.indexOf(chain.reduce((a, b) => (a < b ? a : b)));\n const rotated = [...chain.slice(minIdx), ...chain.slice(0, minIdx)];\n const key = rotated.join('→');\n if (reportedCycles.has(key)) return;\n reportedCycles.add(key);\n errors.push(mkError('CYCLE',\n `Phụ thuộc vòng: ${chain.reverse().join(' → ')}`,\n { path: [...chain], hint: 'Kiểm tra lại quan hệ midpoint/perpFoot/intersection.' }));\n }\n\n function dfs(name: string) {\n color.set(name, 'gray');\n const sym = symbols.get(name);\n if (sym) {\n for (const ref of collectRefs(sym.entity)) {\n if (!symbols.has(ref)) continue; // unknown — refs.ts handle\n const c = color.get(ref);\n if (c === 'gray') {\n reportCycle(name, ref);\n continue;\n }\n if (c === 'white') {\n parent.set(ref, name);\n dfs(ref);\n }\n }\n }\n color.set(name, 'black');\n }\n\n for (const name of symbols.keys()) {\n if (color.get(name) === 'white') {\n parent.set(name, null);\n dfs(name);\n }\n }\n\n return { errors };\n}\n","// src/stamps/geometry-2d/dsl/transpile/topology.ts\n//\n// Stable topological sort: preserve DSL insertion order khi không có constraint,\n// chỉ trì hoãn entity tới khi mọi reference đã emit. Fix bug render perpFoot\n// đứng trước segment dùng làm onLine.\n//\n// Khác DFS post-order (kéo deps lên trước): Kahn-style iterative đảm bảo\n// roundtrip stability — entity không có constraint phụ thuộc lẫn nhau giữ\n// đúng thứ tự DSL gốc.\n\nimport type { Symbol } from './symbols';\nimport { collectRefs } from './refs';\n\n/**\n * Trả về danh sách tên entity theo thứ tự topological STABLE:\n * - Mọi name X xuất hiện SAU mọi name X tham chiếu.\n * - Khi 2 entity không phụ thuộc lẫn nhau, giữ relative order từ symbols\n * (= DSL insertion order: points trước shapes, mỗi nhóm theo DSL order).\n *\n * Giả định cycles đã được loại bởi detectCycles trước đó. Nếu vẫn có cycle,\n * entity unresolved sẽ append cuối để output đủ count.\n */\nexport function topoSort(symbols: Map<string, Symbol>): string[] {\n const all = [...symbols.keys()];\n const emitted = new Set<string>();\n const order: string[] = [];\n\n // Pre-compute deps filtered xuống chỉ tên có trong symbols.\n const depsOf = new Map<string, string[]>();\n for (const name of all) {\n const sym = symbols.get(name);\n if (!sym) {\n depsOf.set(name, []);\n continue;\n }\n const refs = collectRefs(sym.entity).filter((r) => symbols.has(r));\n depsOf.set(name, refs);\n }\n\n // Lặp: mỗi vòng emit tất cả entity có deps đã emit, theo DSL order.\n // Worst case O(n^2) but n nhỏ (~20 entity/figure).\n let progressed = true;\n while (progressed) {\n progressed = false;\n for (const name of all) {\n if (emitted.has(name)) continue;\n const deps = depsOf.get(name)!;\n if (deps.every((d) => emitted.has(d))) {\n emitted.add(name);\n order.push(name);\n progressed = true;\n }\n }\n }\n\n // Cycle leftovers (defensive — detectCycles đáng lẽ catch): append đúng count.\n for (const name of all) {\n if (!emitted.has(name)) order.push(name);\n }\n\n return order;\n}\n","// src/stamps/geometry-2d/dsl/transpile/ids.ts\nimport type { Symbol } from './symbols';\nimport { KIND_REGISTRY } from '../registry';\n\nexport function assignIds(symbols: Map<string, Symbol>): Map<string, string> {\n const counters = new Map<string, number>();\n const ids = new Map<string, string>();\n for (const [name, sym] of symbols.entries()) {\n const mod = KIND_REGISTRY.get(sym.entity.kind);\n if (!mod) throw new Error(`assignIds: no registry entry for kind \"${sym.entity.kind}\"`);\n const prefix = mod.prefix;\n counters.set(prefix, (counters.get(prefix) ?? 0) + 1);\n ids.set(name, `${prefix}${counters.get(prefix)}`);\n }\n return ids;\n}\n","// src/stamps/geometry-2d/dsl/transpile.ts\nimport type { SceneObject, State } from '../../../core/scene/types';\nimport { createEmptyState } from '../../../core/scene/types';\nimport { DslInput, type DslInputT, type DslPointT, type DslShapeT } from './schema';\nimport { buildSymbols } from './transpile/symbols';\nimport { validateRefs } from './transpile/refs';\nimport { detectCycles } from './transpile/cycles';\nimport { topoSort } from './transpile/topology';\nimport { assignIds } from './transpile/ids';\nimport { mkError, type TranspileError, type TranspileResult } from './transpile/errors';\nimport { KIND_REGISTRY } from './registry';\nimport type { EmitContext, EmittedEntity, KindRole } from './kinds/_types';\n\ntype EntityKindHint = 'point' | 'line' | 'segment' | 'ray' | 'lineConstruction' | 'circle';\n\nfunction hintOf(entity: DslPointT | DslShapeT): EntityKindHint {\n const mod = KIND_REGISTRY.get(entity.kind);\n if (!mod) throw new Error(`hintOf: no registry entry for kind \"${entity.kind}\"`);\n // 'polygon' role maps to 'point' for legacy MVP behavior (polygon never used as ref target).\n return mod.role === 'polygon' ? 'point' : (mod.role as EntityKindHint);\n}\n\nfunction buildEmitContext(\n ids: Map<string, string>,\n kindHints: Map<string, EntityKindHint>,\n): EmitContext {\n const auxCounters = new Map<string, number>();\n return {\n resolveId(name) {\n const id = ids.get(name);\n if (!id) throw new Error(`emit: id not assigned for \"${name}\"`);\n return id;\n },\n hintOf(name) {\n const hint = kindHints.get(name);\n if (!hint) throw new Error(`emit: hint not assigned for \"${name}\"`);\n // EntityKindHint and KindRole share these literals; safe to widen.\n return hint as KindRole;\n },\n mintAuxId(parentName, suffix) {\n const key = `${parentName}.${suffix}`;\n auxCounters.set(key, (auxCounters.get(key) ?? 0) + 1);\n const seq = auxCounters.get(key)!;\n return `aux_${parentName}_${suffix}${seq}`;\n },\n };\n}\n\nexport function transpile(dslRaw: unknown): TranspileResult {\n // Stage 1: schema parse\n const parsed = DslInput.safeParse(dslRaw);\n if (!parsed.success) {\n const errors: TranspileError[] = parsed.error.issues.map((iss) =>\n mkError('SCHEMA', iss.message, { path: iss.path.map(String) }),\n );\n return { ok: false, errors };\n }\n // Cast: parsed.data is statically `{[x: string]: any}[]` because the registry\n // stores schemas as the erased `z.ZodObject<any>`. Runtime parse already\n // validated the variant shape, so widening to DslInputT is safe.\n const dsl = parsed.data as DslInputT;\n\n // Stage 2-4: collect errors\n const { symbols, errors: dupErrors } = buildSymbols(dsl);\n const { errors: refErrors } = validateRefs(dsl, symbols);\n const { errors: cycleErrors } = detectCycles(symbols);\n\n const allErrors = [...dupErrors, ...refErrors, ...cycleErrors];\n if (allErrors.length > 0) return { ok: false, errors: allErrors };\n\n // Stage 5: id assignment\n const ids = assignIds(symbols);\n\n // Build kindHints (DSL name → EntityKindHint) cho intersection inference.\n const kindHints = new Map<string, EntityKindHint>();\n for (const [name, sym] of symbols.entries()) {\n kindHints.set(name, hintOf(sym.entity));\n }\n\n // Stage 6: emit via registry\n const objects: Record<string, SceneObject> = {};\n const order: string[] = [];\n const ctx = buildEmitContext(ids, kindHints);\n\n const emitEntity = (entity: DslPointT | DslShapeT) => {\n const mod = KIND_REGISTRY.get(entity.kind);\n if (!mod) throw new Error(`emit: no registry entry for kind \"${entity.kind}\"`);\n const emitted: EmittedEntity[] = mod.emit(entity as never, ctx);\n for (const ent of emitted) {\n objects[ent.object.id] = ent.object;\n order.push(ent.object.id);\n }\n };\n\n // Emit theo thứ tự topological — đảm bảo entity dependent emit SAU mọi\n // reference của nó (vd perpFoot point sau segment dùng làm onLine).\n const sortedNames = topoSort(symbols);\n for (const name of sortedNames) {\n const sym = symbols.get(name);\n if (sym) emitEntity(sym.entity);\n }\n\n const empty = createEmptyState('2d');\n const state: State = {\n objects,\n order,\n counter: order.length,\n meta: empty.meta,\n };\n return { ok: true, state };\n}\n","import type { DslPointT, DslShapeT } from '../dsl/schema';\n\n// Reposition auto-injected circle centers so two circles referenced by a\n// `circleIntersection` point actually cross at TWO points.\n//\n// Bối cảnh: builder inject free coord cho circle center theo bảng spread cách\n// nhau ~6 unit. Hai circle centerRadius cùng r=3 → distance = 6 = r1+r2 →\n// tiếp xúc ngoài (1 điểm) → JSXGraph intersection branch 0/1 trùng nhau hoặc\n// NaN → cascade hỏng (bug eval cau-08). Disjoint (d > r1+r2) còn tệ hơn.\n//\n// Điều kiện 2 giao điểm: |r1-r2| < d < r1+r2.\n// Khi d nằm ngoài \"vùng an toàn\" (sát biên tiếp xúc / disjoint), dời 1 center\n// FREE dọc theo hướng hiện tại về khoảng cách mục tiêu = trung điểm của khoảng\n// hợp lệ = (|r1-r2| + r1+r2)/2 = max(r1, r2). Giữ nguyên hướng để bố cục tương\n// đối không đảo lộn.\n\ntype FreePoint = Extract<DslPointT, { kind: 'free' }>;\n\n/** Resolve toạ độ tĩnh cho center (free hoặc midpoint của free/midpoint). */\nfunction resolveCoord(points: DslPointT[], name: string): [number, number] | null {\n const p = points.find((x) => x.name === name);\n if (!p) return null;\n if (p.kind === 'free') return [p.x, p.y];\n if (p.kind === 'midpoint') {\n const a = resolveCoord(points, p.p1);\n const b = resolveCoord(points, p.p2);\n if (!a || !b) return null;\n return [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n }\n return null;\n}\n\nexport function repairCircleIntersections(points: DslPointT[], shapes: DslShapeT[]): void {\n const shapeByName = new Map(shapes.map((s) => [s.name, s]));\n\n for (const pt of points) {\n if (pt.kind !== 'circleIntersection') continue;\n const c1 = shapeByName.get(pt.c1);\n const c2 = shapeByName.get(pt.c2);\n if (!c1 || !c2 || c1.kind !== 'circleCR' || c2.kind !== 'circleCR') continue;\n\n const r1 = c1.radius;\n const r2 = c2.radius;\n const lower = Math.abs(r1 - r2);\n const upper = r1 + r2;\n\n const coord1 = resolveCoord(points, c1.center);\n const coord2 = resolveCoord(points, c2.center);\n if (!coord1 || !coord2) continue;\n\n const d = Math.hypot(coord1[0] - coord2[0], coord1[1] - coord2[1]);\n const safeLow = lower * 1.05 + 1e-6;\n const safeHigh = upper * 0.95;\n if (d > safeLow && d < safeHigh) continue; // đã cắt 2 điểm gọn gàng\n\n // Cần 1 center FREE để dời. Ưu tiên center của c2 (thường inject sau), fallback c1.\n const p1 = points.find((p) => p.name === c1.center);\n const p2 = points.find((p) => p.name === c2.center);\n let mover: FreePoint | undefined;\n let anchor: [number, number] | undefined;\n if (p2?.kind === 'free') { mover = p2; anchor = coord1; }\n else if (p1?.kind === 'free') { mover = p1; anchor = coord2; }\n if (!mover || !anchor) continue; // không có center free để dời an toàn\n\n const targetD = (lower + upper) / 2; // = max(r1, r2)\n let dx = mover.x - anchor[0];\n let dy = mover.y - anchor[1];\n const len = Math.hypot(dx, dy);\n if (len < 1e-9) { dx = 1; dy = 0; }\n const norm = Math.hypot(dx, dy) || 1;\n mover.x = anchor[0] + (targetD * dx) / norm;\n mover.y = anchor[1] + (targetD * dy) / norm;\n }\n}\n","// src/stamps/geometry-2d/ai/layout/disjointOffset.ts\n//\n// Layout pass (issue #46 nhóm D, D1, Mức 1): tách các component RỜI NHAU (không\n// chia điểm/ref) theo trục ngang để không render chồng tại canonical origin.\n//\n// Pure, mutate in place (giống repairCircleIntersections). Chỉ dịch free point\n// (kind:'free' — điểm DUY NHẤT có x/y); điểm phái sinh KHÔNG có coord → transpile\n// tính lại từ ref đã dịch → tự đúng. Bất biến: ≤1 component → no-op (đề 1-figure\n// byte-identical).\n\nimport type { DslPointT, DslShapeT } from '../../dsl/schema';\nimport { collectRefs } from '../../dsl/transpile/refs';\n\nconst GAP = 2; // board-unit giữa 2 component liền kề\n\ntype FreePoint = Extract<DslPointT, { kind: 'free' }>;\ninterface Bbox { minX: number; maxX: number; minY: number; maxY: number; }\n\nexport function layoutDisjointComponents(points: DslPointT[], shapes: DslShapeT[]): void {\n // --- union-find trên mọi entity name (point + shape) ---\n const parent = new Map<string, string>();\n const find = (x: string): string => {\n const r = parent.get(x);\n if (r === undefined) { parent.set(x, x); return x; }\n if (r === x) return x;\n const root = find(r);\n parent.set(x, root);\n return root;\n };\n const union = (a: string, b: string) => {\n const ra = find(a), rb = find(b);\n if (ra !== rb) parent.set(ra, rb);\n };\n\n const entities: (DslPointT | DslShapeT)[] = [...points, ...shapes];\n for (const e of entities) {\n find(e.name); // đảm bảo node tồn tại\n for (const ref of collectRefs(e)) union(e.name, ref);\n }\n\n // --- free point + thứ tự xuất hiện trong mảng points ---\n const freeByName = new Map<string, { p: FreePoint; index: number }>();\n points.forEach((p, i) => {\n if (p.kind === 'free') freeByName.set(p.name, { p, index: i });\n });\n if (freeByName.size === 0) return;\n\n // --- gom free point theo component root + min free-index ---\n const compFree = new Map<string, { p: FreePoint; index: number }[]>();\n const compMinIndex = new Map<string, number>();\n for (const [name, rec] of freeByName) {\n const root = find(name);\n if (!compFree.has(root)) { compFree.set(root, []); compMinIndex.set(root, rec.index); }\n compFree.get(root)!.push(rec);\n compMinIndex.set(root, Math.min(compMinIndex.get(root)!, rec.index));\n }\n\n // --- bất biến: ≤1 component có free point → no-op ---\n if (compFree.size <= 1) return;\n\n // --- thứ tự component theo min free-index (= thứ tự đọc đề) ---\n const roots = [...compFree.keys()].sort(\n (a, b) => compMinIndex.get(a)! - compMinIndex.get(b)!,\n );\n\n // --- bbox per-component: free-point coords + mở rộng bán kính khi tâm là free ---\n const bboxOf = (root: string): Bbox => {\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n const ext = (x: number, y: number) => {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n };\n for (const { p } of compFree.get(root)!) ext(p.x, p.y);\n for (const s of shapes) {\n if (find(s.name) !== root) continue;\n if (s.kind === 'circleCR') {\n const c = freeByName.get(s.center);\n if (c) { ext(c.p.x - s.radius, c.p.y - s.radius); ext(c.p.x + s.radius, c.p.y + s.radius); }\n } else if (s.kind === 'circleCP') {\n const c = freeByName.get(s.center);\n const sp = freeByName.get(s.surfacePoint);\n if (c && sp) {\n const r = Math.hypot(c.p.x - sp.p.x, c.p.y - sp.p.y);\n ext(c.p.x - r, c.p.y - r); ext(c.p.x + r, c.p.y + r);\n }\n }\n }\n return { minX, maxX, minY, maxY };\n };\n\n // --- pack ngang trái→phải (anchor giữ gốc, dx=0) ---\n let cursorX = bboxOf(roots[0]).maxX + GAP;\n for (let i = 1; i < roots.length; i++) {\n const root = roots[i];\n const bb = bboxOf(root);\n const dx = cursorX - bb.minX;\n for (const { p } of compFree.get(root)!) p.x += dx;\n cursorX = bb.maxX + dx + GAP;\n }\n}\n","// src/stamps/geometry-2d/ai/intent-builders/_types.ts\n//\n// Shared types cho intent-builders: BuildState (mutable build context),\n// newState() factory, IntentBuilderError, và IntentBuilder signature.\n// Tách ra từ intentToDsl.ts (Phase 2a, #45) — không đổi logic.\n\nimport type { DslPointT, DslShapeT } from '../../dsl/schema';\nimport type { IntentT } from '../intent';\n\nexport interface BuildState {\n points: DslPointT[];\n shapes: DslShapeT[];\n /** Map label → ensures uniqueness. */\n pointNames: Set<string>;\n shapeNames: Set<string>;\n /** Map \"AB\"/\"BA\" → segment shape name, dùng cho lookup of='BC'. */\n segmentByEnds: Map<string, string>;\n}\n\nexport function newState(): BuildState {\n return {\n points: [],\n shapes: [],\n pointNames: new Set(),\n shapeNames: new Set(),\n segmentByEnds: new Map(),\n };\n}\n\nexport class IntentBuilderError extends Error {\n constructor(\n message: string,\n public readonly intent: IntentT,\n public readonly cause?: string,\n ) {\n super(message);\n this.name = 'IntentBuilderError';\n }\n}\n\n/** Builder mutate BuildState theo 1 intent op (idempotent, giữ thứ tự gọi). */\nexport type IntentBuilder<T extends IntentT = IntentT> = (s: BuildState, intent: T) => void;\n","// src/stamps/geometry-2d/ai/intent-builders/shared.ts\n//\n// Shared helpers + canonical coord tables + SHAPE_VARIANTS cho intent-builders.\n// Move verbatim từ intentToDsl.ts (Phase 2a, #45) — không đổi logic.\n\nimport type { DslPointT, DslShapeT } from '../../dsl/schema';\nimport type { BuildState } from './_types';\n\n// ---------------------------------------------------------------------------\n// Canonical coord tables\n// ---------------------------------------------------------------------------\n\nexport type Pt = readonly [number, number];\n\nexport const SQRT3 = 1.7320508075688772;\n\nexport function triangleCanonical(variant: string): readonly [Pt, Pt, Pt] {\n switch (variant) {\n case 'equilateral':\n return [[0, 0], [4, 0], [2, 2 * SQRT3]];\n case 'isoceles-AB':\n // AB là đáy, C đỉnh cân\n return [[0, 0], [4, 0], [2, 3]];\n case 'isoceles-BC':\n // BC là đáy, A đỉnh cân\n return [[0, 3], [-2, 0], [2, 0]];\n case 'isoceles-CA':\n // CA là đáy, B đỉnh cân\n return [[0, 0], [2, 3], [4, 0]];\n case 'right-at-A':\n return [[0, 0], [4, 0], [0, 3]];\n case 'right-at-B':\n return [[0, 0], [4, 0], [4, 3]];\n case 'right-at-C':\n // C ở (4,3); AC ⊥ BC\n // chọn A=(0,0), C=(4,3), B=(7.36,1.92) sao cho CA·CB=0\n // Đơn giản hơn: A=(0,0), B=(7,0), C=(0,4) → vuông tại A. Wait — đó là right-at-A.\n // Cần vuông tại C: chọn 3 đỉnh sao cho (CA)·(CB)=0.\n // A=(0,0), B=(7,0), C=(3,4). Check: CA=(−3,−4), CB=(4,−4), dot=−12+16=4 ≠0. Sửa.\n // A=(0,0), C=(3,3), B=(6,0): CA=(−3,−3), CB=(3,−3), dot=−9+9=0 ✓\n return [[0, 0], [6, 0], [3, 3]];\n case 'any':\n default:\n // Tam giác scalene cố định, tránh vuông tại gốc\n return [[0, 0], [5, 0], [2, 3]];\n }\n}\n\nexport function squareCanonical(): readonly [Pt, Pt, Pt, Pt] {\n // Cạnh 4, gốc tại đỉnh đầu (counter-clockwise)\n return [[0, 0], [4, 0], [4, 4], [0, 4]];\n}\n\nexport function rectangleCanonical(variant: string): readonly [Pt, Pt, Pt, Pt] {\n if (variant === 'tall') return [[0, 0], [2.5, 0], [2.5, 4], [0, 4]];\n // wide / standard (default)\n return [[0, 0], [4, 0], [4, 2.5], [0, 2.5]];\n}\n\nexport function rhombusCanonical(): readonly [Pt, Pt, Pt, Pt] {\n // Đường chéo nằm trên trục, 4 đỉnh trên trục: (±2, 0) và (0, ±1.5)\n return [[-2, 0], [0, -1.5], [2, 0], [0, 1.5]];\n}\n\nexport function trapezoidCanonical(variant: string): readonly [Pt, Pt, Pt, Pt] {\n switch (variant) {\n case 'right':\n // Vuông tại A và D\n return [[0, 0], [5, 0], [3, 3], [0, 3]];\n case 'isoceles':\n // Cân — AB đáy lớn, CD đáy nhỏ\n return [[0, 0], [5, 0], [4, 3], [1, 3]];\n case 'general':\n default:\n return [[0, 0], [5, 0], [3.5, 3], [1, 3]];\n }\n}\n\nexport function parallelogramCanonical(): readonly [Pt, Pt, Pt, Pt] {\n return [[0, 0], [4, 0], [5, 3], [1, 3]];\n}\n\nexport function quadrilateralCanonical(): readonly [Pt, Pt, Pt, Pt] {\n return [[0, 0], [5, 0], [4.5, 3.5], [0.5, 3]];\n}\n\n// ---------------------------------------------------------------------------\n// Build helpers\n// ---------------------------------------------------------------------------\n\nexport function addPoint(s: BuildState, p: DslPointT) {\n if (s.pointNames.has(p.name)) return; // idempotent\n s.points.push(p);\n s.pointNames.add(p.name);\n}\n\n// Default coord cho free point khi LLM không truyền `at`. Spread theo thứ tự\n// thêm để tránh nhiều free point collide tại (3, 3) → segment degenerate,\n// circle radius=0, intersection NaN cascade (bug eval cau-14: A=B=D=(3,3)).\n// Pattern: 8 vị trí phân bố xung quanh gốc, vòng lại khi >8.\nexport const FREE_DEFAULT_SPREAD: readonly [number, number][] = [\n [3, 3],\n [-3, 3],\n [3, -3],\n [-3, -3],\n [4, 0],\n [-4, 0],\n [0, 4],\n [0, -4],\n];\n\nexport function defaultFreeCoord(s: BuildState): [number, number] {\n // Đếm số free point đã add (cả từ polygon vertices + add-point free).\n // Position trong array trùng index modulo SPREAD.\n let count = 0;\n for (const p of s.points) if (p.kind === 'free') count++;\n return [...FREE_DEFAULT_SPREAD[count % FREE_DEFAULT_SPREAD.length]];\n}\n\nexport function addShape(s: BuildState, sh: DslShapeT) {\n if (s.shapeNames.has(sh.name)) return;\n s.shapes.push(sh);\n s.shapeNames.add(sh.name);\n}\n\nexport function uniqueShapeName(s: BuildState, base: string): string {\n if (!s.shapeNames.has(base)) return base;\n let i = 2;\n while (s.shapeNames.has(`${base}${i}`)) i++;\n return `${base}${i}`;\n}\n\nexport function uniquePointName(s: BuildState, base: string): string {\n if (!s.pointNames.has(base)) return base;\n let i = 2;\n while (s.pointNames.has(`${base}${i}`)) i++;\n return `${base}${i}`;\n}\n\nexport function ensureSegment(s: BuildState, a: string, b: string): string {\n const k1 = `${a}-${b}`;\n const k2 = `${b}-${a}`;\n const existing = s.segmentByEnds.get(k1) ?? s.segmentByEnds.get(k2);\n if (existing) return existing;\n const name = uniqueShapeName(s, `${a}${b}`);\n addShape(s, { name, kind: 'segment', p1: a, p2: b });\n s.segmentByEnds.set(k1, name);\n return name;\n}\n\n// Resolve line ref cho draw-line (perpThrough/parallelThrough) với fallback:\n// LLM nhiều khi nhầm \"Đường vuông góc với AB tại B\" → to:\"A\" (1 chữ — POINT)\n// thay vì to:\"AB\" (2 chữ — LINE). Khi `ref` là 1 chữ POINT và `anchor` cũng\n// 1 chữ POINT khác, auto build segment qua 2 điểm (alphabetize canonical).\nexport function resolveLineRefWithFallback(s: BuildState, ref: string, anchor: string): string {\n // Single-letter point swap fallback — chỉ áp dụng khi cả 2 đều là POINT\n // đã định nghĩa và khác nhau.\n if (\n /^[A-Za-z]$/.test(ref) && /^[A-Za-z]$/.test(anchor) && ref !== anchor &&\n s.pointNames.has(ref) && s.pointNames.has(anchor)\n ) {\n const [a, b] = ref < anchor ? [ref, anchor] : [anchor, ref];\n return ensureSegment(s, a, b);\n }\n // Path bình thường: 2-char shorthand hoặc tên shape đã có.\n return resolveSegmentRef(s, ref);\n}\n\nexport function resolveSegmentRef(s: BuildState, ref: string): string {\n // ref có thể là tên segment ('AB') hoặc shape name đã có.\n // Nếu là 2 ký tự label đều đã tồn tại → ensure segment 2 đỉnh đó.\n if (s.shapeNames.has(ref)) return ref;\n // Tách \"AB\" → A,B\n if (ref.length === 2 && s.pointNames.has(ref[0]) && s.pointNames.has(ref[1])) {\n return ensureSegment(s, ref[0], ref[1]);\n }\n // Pattern \"A-B\" / \"AB\"\n const dashMatch = ref.match(/^([A-Za-z][A-Za-z0-9'_]*)[-_]?([A-Za-z][A-Za-z0-9'_]*)$/);\n if (dashMatch && s.pointNames.has(dashMatch[1]) && s.pointNames.has(dashMatch[2])) {\n return ensureSegment(s, dashMatch[1], dashMatch[2]);\n }\n // Trả về ref gốc (transpile sẽ báo lỗi nếu invalid)\n return ref;\n}\n\nexport function parseEnds(ref: string): [string, string] | null {\n if (ref.length === 2) return [ref[0], ref[1]];\n const m = ref.match(/^([A-Za-z][A-Za-z0-9'_]*)[-_]?([A-Za-z][A-Za-z0-9'_]*)$/);\n if (m) return [m[1], m[2]];\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// draw-shape variants\n// ---------------------------------------------------------------------------\n\n// Map shape → allowed variants (runtime check, schema cho phép enum chung)\nexport const SHAPE_VARIANTS: Record<string, readonly string[]> = {\n triangle: ['any', 'equilateral', 'isoceles-AB', 'isoceles-BC', 'isoceles-CA', 'right-at-A', 'right-at-B', 'right-at-C'],\n square: ['standard'],\n rectangle: ['standard', 'wide', 'tall'],\n rhombus: ['standard'],\n trapezoid: ['right', 'isoceles', 'general'],\n parallelogram: ['standard'],\n quadrilateral: ['any'],\n};\n","// src/stamps/geometry-2d/ai/intent-builders/draw-shape.ts\n//\n// op: draw-shape — move verbatim từ intentToDsl.ts handleDrawShape (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport {\n addPoint, addShape, uniqueShapeName,\n SHAPE_VARIANTS, triangleCanonical, squareCanonical, rectangleCanonical,\n rhombusCanonical, trapezoidCanonical, parallelogramCanonical, quadrilateralCanonical,\n type Pt,\n} from './shared';\nimport type { DrawShapeIntentT } from '../intent';\n\nexport const buildDrawShape: IntentBuilder<DrawShapeIntentT> = (s, intent) => {\n const labels = intent.labels;\n const explicit = intent.explicitCoords ?? {};\n\n // Validate variant ∈ allowed\n const allowed = SHAPE_VARIANTS[intent.shape];\n if (!allowed || !allowed.includes(intent.variant)) {\n // Fallback to default variant cho shape thay vì throw\n intent = { ...intent, variant: (allowed?.[0] ?? 'any') as typeof intent.variant };\n }\n\n let coords: readonly Pt[];\n switch (intent.shape) {\n case 'triangle': coords = triangleCanonical(intent.variant); break;\n case 'square': coords = squareCanonical(); break;\n case 'rectangle': coords = rectangleCanonical(intent.variant); break;\n case 'rhombus': coords = rhombusCanonical(); break;\n case 'trapezoid': coords = trapezoidCanonical(intent.variant); break;\n case 'parallelogram': coords = parallelogramCanonical(); break;\n case 'quadrilateral': coords = quadrilateralCanonical(); break;\n default:\n throw new IntentBuilderError(`Shape không hỗ trợ: ${intent.shape}`, intent);\n }\n\n if (coords.length !== labels.length) {\n throw new IntentBuilderError(\n `Shape ${intent.shape} cần ${coords.length} labels, nhận ${labels.length}`,\n intent,\n );\n }\n\n labels.forEach((label, i) => {\n const ec = explicit[label];\n const [x, y] = ec ?? coords[i];\n addPoint(s, { name: label, kind: 'free', x, y });\n });\n\n const polyName = uniqueShapeName(s, labels.join(''));\n addShape(s, { name: polyName, kind: 'polygon', vertices: [...labels] });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/midpoint.ts\n//\n// add-point constraint.kind=midpoint — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { IntentBuilderError } from '../_types';\nimport { addPoint, ensureSegment, parseEnds } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildMidpoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'midpoint') return;\n const name = intent.name;\n const ends = parseEnds(c.of);\n if (!ends) throw new IntentBuilderError(`midpoint.of không parse được: ${c.of}`, intent);\n // Ensure segment for the midpoint reference (optional but nice for rendering)\n ensureSegment(s, ends[0], ends[1]);\n addPoint(s, { name, kind: 'midpoint', p1: ends[0], p2: ends[1] });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/perpFoot.ts\n//\n// add-point constraint.kind=perpFoot — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildPerpFoot = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'perpFoot') return;\n const name = intent.name;\n const lineName = resolveSegmentRef(s, c.onLine);\n addPoint(s, { name, kind: 'perpFoot', from: c.from, onLine: lineName });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/centers.ts\n//\n// add-point centers: centroid/circumcenter/incenter/orthocenter/excenter\n// — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildCentroid = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'centroid') return;\n addPoint(s, { name: intent.name, kind: 'centroid', vertices: c.of });\n};\n\nexport const buildCircumcenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'circumcenter') return;\n addPoint(s, { name: intent.name, kind: 'circumcenter', vertices: c.of });\n};\n\nexport const buildIncenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'incenter') return;\n addPoint(s, { name: intent.name, kind: 'incenter', vertices: c.of });\n};\n\nexport const buildOrthocenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'orthocenter') return;\n addPoint(s, { name: intent.name, kind: 'orthocenter', vertices: c.of });\n};\n\nexport const buildExcenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'excenter') return;\n addPoint(s, { name: intent.name, kind: 'excenter', vertices: c.of, opposite: c.opposite });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/intersections.ts\n//\n// add-point intersections: intersection/secondIntersection/circleIntersection\n// — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'intersection') return;\n const r1 = resolveSegmentRef(s, c.of[0]);\n const r2 = resolveSegmentRef(s, c.of[1]);\n addPoint(s, {\n name: intent.name,\n kind: 'intersection',\n ref1: r1,\n ref2: r2,\n ...(c.branch !== undefined ? { branch: c.branch } : {}),\n });\n};\n\nexport const buildSecondIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'secondIntersection') return;\n const lineRef = resolveSegmentRef(s, c.line);\n addPoint(s, {\n name: intent.name, kind: 'secondIntersection',\n line: lineRef, circle: c.circle, other: c.other,\n });\n};\n\nexport const buildCircleIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'circleIntersection') return;\n addPoint(s, {\n name: intent.name, kind: 'circleIntersection',\n c1: c.c1, c2: c.c2, which: c.which,\n });\n};\n\nexport const buildCircleSecondIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'circleSecondIntersection') return;\n addPoint(s, {\n name: intent.name, kind: 'circleSecondIntersection',\n c1: c.c1, c2: c.c2, exclude: c.exclude,\n });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/tangency.ts\n//\n// add-point tangency: tangencyPoint/tangentPoint — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildTangencyPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'tangencyPoint') return;\n const lineRef = resolveSegmentRef(s, c.onLine);\n addPoint(s, {\n name: intent.name, kind: 'tangencyPoint',\n circle: c.circle, onLine: lineRef,\n });\n};\n\nexport const buildTangentPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'tangentPoint') return;\n addPoint(s, {\n name: intent.name, kind: 'tangentPointExt',\n from: c.from, circle: c.circle, which: c.which,\n });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/onSegment-free.ts\n//\n// add-point onSegment/free — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, defaultFreeCoord, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildOnSegment = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'onSegment') return;\n const ref = resolveSegmentRef(s, c.of);\n addPoint(s, { name: intent.name, kind: 'onSegment', segmentId: ref, t: c.t ?? 0.5 });\n};\n\nexport const buildFree = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'free') return;\n const [x, y] = c.at ?? defaultFreeCoord(s);\n addPoint(s, { name: intent.name, kind: 'free', x, y });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/angleBisectorFoot.ts\n//\n// add-point constraint.kind=angleBisectorFoot — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n// Multi-emit: angleBisector shape + ensureSegment + intersection point.\n\nimport type { BuildState } from '../_types';\nimport { IntentBuilderError } from '../_types';\nimport { addPoint, addShape, ensureSegment, parseEnds, resolveSegmentRef, uniqueShapeName } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildAngleBisectorFoot = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'angleBisectorFoot') return;\n const name = intent.name;\n const ends = parseEnds(c.onLine);\n if (!ends) throw new IntentBuilderError(`angleBisectorFoot.onLine không parse: ${c.onLine}`, intent);\n const bisName = uniqueShapeName(s, `ab_${c.from}${c.onLine}`);\n addShape(s, { name: bisName, kind: 'angleBisector', p1: ends[0], vertex: c.from, p2: ends[1] });\n ensureSegment(s, ends[0], ends[1]);\n addPoint(s, { name, kind: 'intersection', ref1: bisName, ref2: resolveSegmentRef(s, c.onLine) });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/externalAngleBisectorFoot.ts\n//\n// add-point constraint.kind=externalAngleBisectorFoot — phân giác NGOÀI (Issue #46 nhóm A).\n// Mirror buildAngleBisectorFoot, nhưng phân giác ngoài = đường VUÔNG GÓC với phân\n// giác trong tại đỉnh `from`. Multi-emit:\n// 1. angleBisector shape (phân giác TRONG — helper, làm cơ sở dựng);\n// 2. perpendicular shape qua `from`, ⊥ phân giác trong = phân giác NGOÀI;\n// 3. ensureSegment(onLine) — cạnh đối (kéo dài) để giao;\n// 4. intersection point = phân giác ngoài ∩ đường thẳng cạnh đối.\n\nimport type { BuildState } from '../_types';\nimport { IntentBuilderError } from '../_types';\nimport { addPoint, addShape, ensureSegment, parseEnds, resolveSegmentRef, uniqueShapeName } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildExternalAngleBisectorFoot = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'externalAngleBisectorFoot') return;\n const name = intent.name;\n const ends = parseEnds(c.onLine);\n if (!ends) throw new IntentBuilderError(`externalAngleBisectorFoot.onLine không parse: ${c.onLine}`, intent);\n // Phân giác trong (helper, cơ sở dựng phân giác ngoài).\n const bisName = uniqueShapeName(s, `ab_${c.from}${c.onLine}`);\n addShape(s, { name: bisName, kind: 'angleBisector', p1: ends[0], vertex: c.from, p2: ends[1] });\n // Phân giác ngoài = đường vuông góc với phân giác trong tại đỉnh `from`.\n const extName = uniqueShapeName(s, `abx_${c.from}${c.onLine}`);\n addShape(s, { name: extName, kind: 'perpendicular', throughPoint: c.from, toLine: bisName });\n ensureSegment(s, ends[0], ends[1]);\n addPoint(s, { name, kind: 'intersection', ref1: extName, ref2: resolveSegmentRef(s, c.onLine) });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/rightAngleViewing.ts\n//\n// add-point constraint.kind=rightAngleViewing — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n// Multi-emit: hidden midpoint + hidden circleCP (Thales diameter) + intersection line∩circle.\n\nimport type { BuildState } from '../_types';\nimport { addPoint, addShape, resolveSegmentRef, uniquePointName, uniqueShapeName } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildRightAngleViewing = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'rightAngleViewing') return;\n const name = intent.name;\n // ∠ a-name-b = 90° ⇔ name trên đường tròn đường kính ab (Thales).\n // Dựng: midpoint(ab) ẩn → circleCP đường kính ab ẩn → giao line∩circle.\n const midName = uniquePointName(s, `mid_${c.a}${c.b}`);\n addPoint(s, { name: midName, kind: 'midpoint', p1: c.a, p2: c.b, visible: false });\n const circName = uniqueShapeName(s, `dia_${c.a}${c.b}`);\n addShape(s, { name: circName, kind: 'circleCP', center: midName, surfacePoint: c.a, visible: false });\n const lineRef = resolveSegmentRef(s, c.onLine);\n addPoint(s, { name, kind: 'intersection', ref1: lineRef, ref2: circName, branch: c.which ?? 0 });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/arcMidpoint.ts\n//\n// add-point constraint.kind=arcMidpoint (Cụm A) — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildArcMidpoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'arcMidpoint') return;\n addPoint(s, { name: intent.name, kind: 'arcMidpoint', circle: c.circle, a: c.a, b: c.b, notContaining: c.notContaining });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/reflect.ts\n//\n// add-point reflectPoint/reflectLine (Cụm A) — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildReflectPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'reflectPoint') return;\n addPoint(s, { name: intent.name, kind: 'reflectPoint', of: c.of, through: c.through });\n};\n\nexport const buildReflectLine = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'reflectLine') return;\n const lineRef = resolveSegmentRef(s, c.through);\n addPoint(s, { name: intent.name, kind: 'reflectLine', of: c.of, through: lineRef });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/pointAtDistance.ts\n//\n// add-point constraint.kind=pointAtDistance (Cụm B) — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n// Multi-emit: ensureSegment + pointAtDistance point.\n\nimport type { BuildState } from '../_types';\nimport { addPoint, ensureSegment } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildPointAtDistance = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'pointAtDistance') return;\n ensureSegment(s, c.from, c.through);\n addPoint(s, { name: intent.name, kind: 'pointAtDistance', from: c.from, through: c.through, distance: c.distance });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/externalToCircle.ts\n//\n// add-point externalToCircle — điểm A nằm NGOÀI đường tròn `circle` (free\n// external point). Builder đọc circle shape từ build state, tính tâm+bán kính,\n// rồi đặt A = free tại [cx + d, cy] với d = max(r*2, r+2) (đảm bảo distance > r\n// → A NGOÀI). Unblock tangentFromExt render END-TO-END (đề \"Lấy A ngoài (O), kẻ\n// 2 tiếp tuyến\").\n//\n// Fail-safe (skip → A KHÔNG add → tangent UNKNOWN_REF / named-missing →\n// escalate, KHÔNG render sai):\n// - circle shape không tồn tại trong build state.\n// - tâm/bán kính không xác định được (tâm không phải free, surfacePoint thiếu).\n//\n// Field name theo dsl/schema.ts: circleCR = { center, radius }; circleCP =\n// { center, surfacePoint } (KHÔNG phải `through`).\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildExternalToCircle = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'externalToCircle') return;\n const circle = s.shapes.find((sh) => sh.name === c.circle);\n if (!circle) return; // fail-safe: A không add → escalate\n\n let cx: number | undefined;\n let cy: number | undefined;\n let r: number | undefined;\n\n if (circle.kind === 'circleCR') {\n const center = s.points.find((p) => p.name === circle.center);\n if (center && center.kind === 'free') {\n cx = center.x;\n cy = center.y;\n r = circle.radius;\n }\n } else if (circle.kind === 'circleCP') {\n const center = s.points.find((p) => p.name === circle.center);\n const surf = s.points.find((p) => p.name === circle.surfacePoint);\n if (center && center.kind === 'free' && surf && surf.kind === 'free') {\n cx = center.x;\n cy = center.y;\n r = Math.hypot(surf.x - cx, surf.y - cy);\n }\n }\n\n if (cx === undefined || cy === undefined || r === undefined || !(r > 0)) return; // fail-safe\n const d = Math.max(r * 2, r + 2);\n addPoint(s, { name: intent.name, kind: 'free', x: cx + d, y: cy });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/onCircle.ts\n//\n// add-point constraint.kind=onCircle — điểm trên đường tròn `circle` tại góc\n// `theta` (glider). Map intent.circle → DSL circleId, theta default 0. Dùng cho\n// đường thẳng Simson (issue #47): P trên đường tròn ngoại tiếp tam giác.\n\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildOnCircle = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'onCircle') return;\n addPoint(s, { name: intent.name, kind: 'onCircle', circleId: c.circle, theta: c.theta ?? 0 });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/index.ts\n//\n// Dispatcher cho op add-point: map constraint.kind → builder (Phase 2b, #45).\n// ADD_POINT_BUILDERS được export cho Phase 6 matrix script.\n\nimport type { BuildState } from '../_types';\nimport type { AddPointIntentT } from '../../intent';\nimport { buildMidpoint } from './midpoint';\nimport { buildPerpFoot } from './perpFoot';\nimport { buildCentroid, buildCircumcenter, buildIncenter, buildOrthocenter, buildExcenter } from './centers';\nimport { buildIntersection, buildSecondIntersection, buildCircleIntersection, buildCircleSecondIntersection } from './intersections';\nimport { buildTangencyPoint, buildTangentPoint } from './tangency';\nimport { buildOnSegment, buildFree } from './onSegment-free';\nimport { buildAngleBisectorFoot } from './angleBisectorFoot';\nimport { buildExternalAngleBisectorFoot } from './externalAngleBisectorFoot';\nimport { buildRightAngleViewing } from './rightAngleViewing';\nimport { buildArcMidpoint } from './arcMidpoint';\nimport { buildReflectPoint, buildReflectLine } from './reflect';\nimport { buildPointAtDistance } from './pointAtDistance';\nimport { buildExternalToCircle } from './externalToCircle';\nimport { buildOnCircle } from './onCircle';\n\nexport const ADD_POINT_BUILDERS: Record<string, (s: BuildState, intent: AddPointIntentT) => void> = {\n midpoint: buildMidpoint, perpFoot: buildPerpFoot,\n centroid: buildCentroid, circumcenter: buildCircumcenter, incenter: buildIncenter,\n orthocenter: buildOrthocenter, excenter: buildExcenter,\n intersection: buildIntersection, secondIntersection: buildSecondIntersection, circleIntersection: buildCircleIntersection,\n circleSecondIntersection: buildCircleSecondIntersection,\n tangencyPoint: buildTangencyPoint, tangentPoint: buildTangentPoint,\n onSegment: buildOnSegment, free: buildFree,\n angleBisectorFoot: buildAngleBisectorFoot, externalAngleBisectorFoot: buildExternalAngleBisectorFoot,\n rightAngleViewing: buildRightAngleViewing,\n arcMidpoint: buildArcMidpoint, reflectPoint: buildReflectPoint, reflectLine: buildReflectLine,\n pointAtDistance: buildPointAtDistance,\n externalToCircle: buildExternalToCircle,\n onCircle: buildOnCircle,\n};\n\nexport const buildAddPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const fn = ADD_POINT_BUILDERS[intent.constraint.kind];\n if (fn) fn(s, intent);\n};\n","// src/stamps/geometry-2d/ai/intent-builders/connect.ts\n//\n// op: connect — move verbatim từ intentToDsl.ts handleConnect (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { ensureSegment, addShape, uniqueShapeName } from './shared';\nimport type { ConnectIntentT } from '../intent';\n\nexport const buildConnect: IntentBuilder<ConnectIntentT> = (s, intent) => {\n const { from, to, style } = intent;\n switch (style) {\n case 'segment':\n ensureSegment(s, from, to);\n break;\n case 'line':\n addShape(s, { name: uniqueShapeName(s, `l_${from}${to}`), kind: 'line', p1: from, p2: to });\n break;\n case 'ray':\n addShape(s, { name: uniqueShapeName(s, `r_${from}${to}`), kind: 'ray', origin: from, through: to });\n break;\n case 'perpBisector':\n addShape(s, { name: uniqueShapeName(s, `pb_${from}${to}`), kind: 'perpBisector', p1: from, p2: to });\n break;\n case 'angleBisector':\n // angleBisector cần 3 điểm (p1, vertex, p2). connect chỉ có 2 điểm → bỏ qua,\n // caller nên dùng intent.add-point với incenter/internalBisector.\n throw new IntentBuilderError(\n 'connect.style=angleBisector cần 3 điểm; dùng add-point/incenter thay',\n intent,\n );\n }\n};\n","// src/stamps/geometry-2d/ai/intent-builders/draw-circle.ts\n//\n// op: draw-circle — move verbatim từ intentToDsl.ts handleDrawCircle (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { addPoint, addShape, defaultFreeCoord } from './shared';\nimport type { DrawCircleIntentT } from '../intent';\n\nexport const buildDrawCircle: IntentBuilder<DrawCircleIntentT> = (s, intent) => {\n if (intent.spec === 'centerThrough') {\n if (!intent.center || !intent.through) {\n throw new IntentBuilderError('centerThrough cần center + through', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'circleCP',\n center: intent.center,\n surfacePoint: intent.through,\n });\n } else if (intent.spec === 'through3') {\n if (!intent.points) {\n throw new IntentBuilderError('through3 cần points', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'circle3',\n p1: intent.points[0],\n p2: intent.points[1],\n p3: intent.points[2],\n });\n } else if (intent.spec === 'centerRadius') {\n if (!intent.center || intent.radius === undefined) {\n throw new IntentBuilderError('centerRadius cần center + radius', intent);\n }\n if (!s.points.find((p) => p.name === intent.center)) {\n const [x, y] = defaultFreeCoord(s);\n addPoint(s, { name: intent.center!, kind: 'free', x, y });\n }\n addShape(s, { name: intent.name, kind: 'circleCR', center: intent.center, radius: intent.radius });\n } else if (intent.spec === 'diameter') {\n if (!intent.endpoints) {\n throw new IntentBuilderError('diameter cần endpoints', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'circleDiameter',\n p1: intent.endpoints[0],\n p2: intent.endpoints[1],\n });\n } else if (intent.spec === 'inscribedIn') {\n if (!intent.triangle) throw new IntentBuilderError('inscribedIn cần triangle', intent);\n for (const v of intent.triangle) {\n if (!s.points.find((p) => p.name === v)) {\n throw new IntentBuilderError(`inscribedIn: vertex ${v} chưa định nghĩa`, intent);\n }\n }\n addShape(s, { name: intent.name, kind: 'incircle', vertices: intent.triangle });\n }\n};\n","// src/stamps/geometry-2d/ai/intent-builders/draw-line.ts\n//\n// op: draw-line — move verbatim từ intentToDsl.ts handleDrawLine (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { addShape, resolveLineRefWithFallback } from './shared';\nimport type { DrawLineIntentT } from '../intent';\n\nexport const buildDrawLine: IntentBuilder<DrawLineIntentT> = (s, intent) => {\n switch (intent.kind) {\n case 'perpThrough': {\n if (!intent.through || !intent.to) throw new IntentBuilderError('perpThrough cần through + to', intent);\n const toLine = resolveLineRefWithFallback(s, intent.to, intent.through);\n addShape(s, { name: intent.name, kind: 'perpendicular', throughPoint: intent.through, toLine });\n break;\n }\n case 'parallelThrough': {\n if (!intent.through || !intent.to) throw new IntentBuilderError('parallelThrough cần through + to', intent);\n const toLine = resolveLineRefWithFallback(s, intent.to, intent.through);\n addShape(s, { name: intent.name, kind: 'parallel', throughPoint: intent.through, toLine });\n break;\n }\n case 'tangentAt': {\n if (!intent.through || !intent.circle) throw new IntentBuilderError('tangentAt cần through + circle', intent);\n addShape(s, { name: intent.name, kind: 'tangent', throughPoint: intent.through, toCircle: intent.circle, branch: 'on' });\n break;\n }\n case 'tangentFromExt': {\n if (!intent.from || !intent.circle) throw new IntentBuilderError('tangentFromExt cần from + circle', intent);\n if (intent.which === 'both') {\n addShape(s, { name: `${intent.name}_0`, kind: 'tangent', throughPoint: intent.from, toCircle: intent.circle, branch: 0 });\n addShape(s, { name: `${intent.name}_1`, kind: 'tangent', throughPoint: intent.from, toCircle: intent.circle, branch: 1 });\n } else {\n const branch = intent.which === 'second' ? 1 : 0;\n addShape(s, { name: intent.name, kind: 'tangent', throughPoint: intent.from, toCircle: intent.circle, branch });\n }\n break;\n }\n case 'angleBisector': {\n // Phân giác TRONG của góc ∠(p1·vertex·p2), VISIBLE, KHÔNG sinh chân\n // (khác cevian \"phân giác AD\" → foot). vertex = đỉnh góc. Issue #46 nhóm A.\n if (!intent.p1 || !intent.vertex || !intent.p2) {\n throw new IntentBuilderError('angleBisector cần p1 + vertex + p2', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'angleBisector',\n p1: intent.p1,\n vertex: intent.vertex,\n p2: intent.p2,\n });\n break;\n }\n case 'lineThrough': {\n // Đường qua ≥2 điểm đồng tuyến (vd Euler line qua G/H/O — issue #47).\n if (!intent.points || intent.points.length < 2) {\n throw new IntentBuilderError('lineThrough cần ≥2 điểm', intent);\n }\n addShape(s, { name: intent.name, kind: 'lineThrough', points: intent.points });\n break;\n }\n case 'radicalAxis': {\n // Trục đẳng phương 2 đường tròn (issue #47, construct 2).\n if (!intent.circle1 || !intent.circle2) {\n throw new IntentBuilderError('radicalAxis cần circle1 + circle2', intent);\n }\n addShape(s, { name: intent.name, kind: 'radicalAxis', circle1: intent.circle1, circle2: intent.circle2 });\n break;\n }\n }\n};\n","// src/stamps/geometry-2d/ai/intent-builders/mark-shape.ts\n//\n// op: mark-shape — move verbatim từ intentToDsl.ts handleMarkShape (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { addShape, uniqueShapeName } from './shared';\nimport type { MarkShapeIntentT } from '../intent';\n\nexport const buildMarkShape: IntentBuilder<MarkShapeIntentT> = (s, intent) => {\n for (const label of intent.labels) {\n if (!s.points.find((p) => p.name === label)) {\n throw new IntentBuilderError(`mark-shape: label ${label} chưa định nghĩa`, intent);\n }\n }\n const polyName = uniqueShapeName(s, intent.labels.join(''));\n addShape(s, { name: polyName, kind: 'polygon', vertices: [...intent.labels] });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/registry.ts\n//\n// OP_BUILDERS: map intent.op → builder (Phase 2b, #45).\n// Thêm 1 op = 1 builder module + 1 dòng ở đây, không sửa switch trung tâm.\n\nimport type { BuildState } from './_types';\nimport type { IntentT } from '../intent';\nimport { buildDrawShape } from './draw-shape';\nimport { buildAddPoint } from './add-point';\nimport { buildConnect } from './connect';\nimport { buildDrawCircle } from './draw-circle';\nimport { buildDrawLine } from './draw-line';\nimport { buildMarkShape } from './mark-shape';\n\nexport const OP_BUILDERS: Record<IntentT['op'], (s: BuildState, intent: any) => void> = {\n 'draw-shape': buildDrawShape,\n 'add-point': buildAddPoint,\n 'connect': buildConnect,\n 'draw-circle': buildDrawCircle,\n 'draw-line': buildDrawLine,\n 'mark-shape': buildMarkShape,\n};\n","// src/stamps/geometry-2d/ai/intentToDsl.ts\n//\n// Stage 2: deterministic Intent[] → DslInputT builder.\n//\n// Pure function. Không gọi AI. Mỗi Intent op map sang 1 hoặc nhiều DSL entries\n// với canonical coords cố định per variant. Builder rejects intent không hợp lệ\n// (vd connect to point chưa tồn tại) thay vì silent skip.\n//\n// Phase 2b (#45): orchestrator mỏng — dispatch qua OP_BUILDERS registry.\n// Thứ tự loop intents giữ nguyên (ordering dependency: draw-shape trước add-point\n// tham chiếu điểm của nó). repairCircleIntersections chạy post-dispatch.\n\nimport type { DslInputT } from '../dsl/schema';\nimport type { IntentT } from './intent';\nimport { repairCircleIntersections } from './repairCircleIntersections';\nimport { layoutDisjointComponents } from './layout/disjointOffset';\nimport { newState } from './intent-builders/_types';\nimport { OP_BUILDERS } from './intent-builders/registry';\n\nexport { IntentBuilderError } from './intent-builders/_types';\n\nexport function intentsToDsl(intents: readonly IntentT[]): DslInputT {\n const s = newState();\n for (const intent of intents) {\n const build = OP_BUILDERS[intent.op];\n if (build) build(s, intent);\n }\n // Geometric repair: đảm bảo circle dùng cho circleIntersection thực sự cắt\n // nhau 2 điểm (dời center auto-inject nếu tiếp xúc/rời nhau).\n repairCircleIntersections(s.points, s.shapes);\n // Layout: tách các component RỜI NHAU theo trục ngang (không chồng origin).\n layoutDisjointComponents(s.points, s.shapes);\n return { version: 1, points: s.points, shapes: s.shapes };\n}\n","// src/stamps/geometry-2d/ai/intentPrompt.ts\n//\n// System prompt cho Intent extraction (Stage 1). AI chỉ làm NLU — đọc đề\n// (VN hoặc EN), tách thành Intent[]. KHÔNG sinh DSL, KHÔNG đặt tọa độ.\n//\n// Khác prompt cũ (prompt.ts):\n// - Output là `intents: Intent[]` thay vì `figure: DSL`\n// - Bilingual: ví dụ cả VN + EN\n// - Anti-pattern explicit: AI không tự thêm intent ngoài đề\n//\n// IntentEnvelopeZ.refine() guards build/refuse semantics.\n\nimport type { IntentT, IntentEnvelopeT } from './intent';\n\ninterface IntentFixture {\n problem: string;\n intents: IntentT[];\n}\n\n// Tier 0+1 sample fixtures (in-prompt examples).\n// Note: chỉ shape examples — augmentation examples thêm khi mở Tier 1.\nconst FIXTURES: IntentFixture[] = [\n {\n problem: 'Tam giác ABC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n ],\n },\n {\n problem: 'Tam giác đều ABC cạnh 4.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'equilateral' },\n ],\n },\n {\n problem: 'Tam giác ABC vuông tại A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'right-at-A' },\n ],\n },\n {\n problem: 'Hình vuông MNPQ.',\n intents: [\n { op: 'draw-shape', shape: 'square', labels: ['M', 'N', 'P', 'Q'], variant: 'standard' },\n ],\n },\n {\n problem: 'Hình chữ nhật ABCD.',\n intents: [\n { op: 'draw-shape', shape: 'rectangle', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n ],\n },\n // \"cân tại X\" → X là đỉnh cân, cạnh đối diện là đáy\n {\n problem: 'Tam giác ABC cân tại A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'isoceles-BC' },\n ],\n },\n {\n problem: 'Tam giác MNP cân tại N.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['M', 'N', 'P'], variant: 'isoceles-CA' },\n ],\n },\n {\n problem: 'Hình thoi ABCD.',\n intents: [\n { op: 'draw-shape', shape: 'rhombus', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n ],\n },\n {\n problem: 'Hình bình hành ABCD.',\n intents: [\n { op: 'draw-shape', shape: 'parallelogram', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n ],\n },\n {\n problem: 'Hình thang ABCD cân, AB là đáy lớn.',\n intents: [\n { op: 'draw-shape', shape: 'trapezoid', labels: ['A', 'B', 'C', 'D'], variant: 'isoceles' },\n ],\n },\n // Tier 1 examples\n {\n problem: 'Tam giác ABC, M là trung điểm BC, vẽ đoạn AM.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'M', constraint: { kind: 'midpoint', of: 'BC' } },\n { op: 'connect', from: 'A', to: 'M', style: 'segment' },\n ],\n },\n {\n problem: 'Tam giác ABC, H là chân đường cao từ A xuống BC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'H', constraint: { kind: 'perpFoot', from: 'A', onLine: 'BC' } },\n { op: 'connect', from: 'A', to: 'H', style: 'segment' },\n ],\n },\n {\n problem: 'Triangle ABC with M the midpoint of BC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'M', constraint: { kind: 'midpoint', of: 'BC' } },\n ],\n },\n {\n problem: 'Triangle ABC, G is the centroid.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'G', constraint: { kind: 'centroid', of: ['A', 'B', 'C'] } },\n ],\n },\n // Compound: triangle + circumcircle (cần CẢ HAI intent)\n {\n problem: 'Đường tròn đi qua 3 điểm A, B, C.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n ],\n },\n {\n problem: 'Tam giác ABC nội tiếp đường tròn O.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n ],\n },\n // Compound: parallelogram with diagonals + intersection\n {\n problem: 'Hình bình hành ABCD, hai đường chéo AC và BD cắt nhau tại O.',\n intents: [\n { op: 'draw-shape', shape: 'parallelogram', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n { op: 'connect', from: 'A', to: 'C', style: 'segment' },\n { op: 'connect', from: 'B', to: 'D', style: 'segment' },\n { op: 'add-point', name: 'O', constraint: { kind: 'intersection', of: ['AC', 'BD'] } },\n ],\n },\n // Build examples — đề có MỆNH LỆNH proof/tính NHƯNG mô tả hình → vẫn build\n {\n problem: 'Cho tam giác ABC vuông tại A. Chứng minh rằng AB² + AC² = BC².',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'right-at-A' },\n ],\n },\n {\n problem: 'Cho tứ giác ABCD nội tiếp (O). Chứng minh rằng AC.BD = AB.CD + AD.BC.',\n intents: [\n { op: 'draw-shape', shape: 'quadrilateral', labels: ['A', 'B', 'C', 'D'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n { op: 'connect', from: 'A', to: 'C', style: 'segment' },\n { op: 'connect', from: 'B', to: 'D', style: 'segment' },\n ],\n },\n // draw-line: perpThrough — đường vuông góc với LINE, đi qua POINT\n {\n problem: 'Tam giác ABC. Vẽ đường thẳng d vuông góc với AB tại B.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-line', name: 'd', kind: 'perpThrough', through: 'B', to: 'AB' },\n ],\n },\n // draw-line: tangentAt — tiếp tuyến TẠI POINT trên CIRCLE\n {\n problem: 'Tam giác ABC nội tiếp đường tròn (O). Vẽ tiếp tuyến tại A của (O).',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n { op: 'draw-line', name: 'tA', kind: 'tangentAt', through: 'A', circle: 'O' },\n ],\n },\n // draw-line: tangentFromExt — tiếp tuyến TỪ POINT ngoài CIRCLE (chọn nhánh)\n {\n problem: 'Cho đường tròn (O) và điểm P ngoài đường tròn. Vẽ hai tiếp tuyến PT₁ và PT₂ từ P tới (O).',\n intents: [\n { op: 'draw-circle', name: 'O', spec: 'centerRadius', center: 'O', radius: 3 },\n { op: 'add-point', name: 'P', constraint: { kind: 'free' } },\n { op: 'draw-line', name: 'PT1', kind: 'tangentFromExt', from: 'P', circle: 'O', which: 'first' },\n { op: 'draw-line', name: 'PT2', kind: 'tangentFromExt', from: 'P', circle: 'O', which: 'second' },\n ],\n },\n // Refuse examples — đề THUẦN tính / KHÔNG mô tả hình hình học\n {\n problem: 'Tính sin(30°) + cos(60°).',\n intents: [],\n },\n {\n problem: 'Vẽ con mèo.',\n intents: [],\n },\n {\n problem: 'Giải phương trình x² - 5x + 6 = 0.',\n intents: [],\n },\n {\n problem: 'Tam giác ABC nội tiếp (O). M là trung điểm cung BC không chứa A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n { op: 'add-point', name: 'M', constraint: { kind: 'arcMidpoint', circle: 'O', a: 'B', b: 'C', notContaining: 'A' } },\n ],\n },\n {\n problem: 'Tam giác ABC trực tâm H. D là điểm đối xứng của H qua BC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'H', constraint: { kind: 'orthocenter', of: ['A', 'B', 'C'] } },\n { op: 'add-point', name: 'D', constraint: { kind: 'reflectLine', of: 'H', through: 'BC' } },\n ],\n },\n {\n problem: 'Tam giác ABC, J là tâm bàng tiếp góc A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'J', constraint: { kind: 'excenter', of: ['A', 'B', 'C'], opposite: 'A' } },\n ],\n },\n {\n problem: 'Cho tam giác nhọn ABC, đường cao CK, H là trực tâm. Gọi M là một điểm trên CK sao cho góc AMB = 90°.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'K', constraint: { kind: 'perpFoot', from: 'C', onLine: 'AB' } },\n { op: 'add-point', name: 'H', constraint: { kind: 'orthocenter', of: ['A', 'B', 'C'] } },\n { op: 'connect', from: 'C', to: 'K', style: 'segment' },\n { op: 'add-point', name: 'M', constraint: { kind: 'rightAngleViewing', a: 'A', b: 'B', onLine: 'CK' } },\n ],\n },\n {\n problem: 'Cho đoạn AB và đường thẳng d. Điểm M trên d sao cho góc AMB = 90°.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'D'], variant: 'any' },\n { op: 'add-point', name: 'M', constraint: { kind: 'rightAngleViewing', a: 'A', b: 'B', onLine: 'd' } },\n ],\n },\n];\n\nexport function buildIntentSystemPrompt(): string {\n const examples = FIXTURES.map((f, i) => {\n const envelope: IntentEnvelopeT =\n f.intents.length > 0\n ? { decision: 'build', intents: f.intents }\n : { decision: 'refuse', reason: 'Đề không phải hình học — không vẽ được hình.' };\n return `### Ví dụ ${i + 1}\n**Đề:** ${f.problem}\n**Output:**\n${JSON.stringify(envelope, null, 2)}`;\n }).join('\\n\\n');\n\n return `Bạn là trợ lý tách lệnh vẽ hình học 2D cho học sinh THCS / lớp 10.\nChấp nhận đề bài tiếng Việt HOẶC tiếng Anh.\n\n## Nhiệm vụ\nĐọc đề → tách thành danh sách \"intents\" (lệnh vẽ cấp cao). KHÔNG sinh tọa độ,\nKHÔNG sinh DSL chi tiết — chỉ tách lệnh.\n\n## Output format (CHỈ JSON, KHÔNG markdown, KHÔNG text khác)\n{ \"decision\": \"build\", \"intents\": [ ... ] }\nhoặc\n{ \"decision\": \"refuse\", \"reason\": \"lý do tiếng Việt\" }\n\n## Quy tắc tuyệt đối\n\n1. **MỘT intent = MỘT đối tượng nêu trong đề.** Đề nói gì, emit intent đó.\n KHÔNG tự thêm trung tuyến/đường cao/tâm nếu đề không nói.\n\n2. **Shape variant phải khớp đề:**\n - \"đều\" → variant: \"equilateral\"\n - \"vuông tại X\" → variant: \"right-at-X\" (X là label đầu tiên trong labels[] khớp đề)\n - \"cân tại X\" — X là ĐỈNH CÂN, base là cạnh đối diện:\n * \"tam giác ABC cân tại A\" → variant: \"isoceles-BC\" (BC là đáy, A là apex)\n * \"tam giác MNP cân tại N\" → variant: \"isoceles-CA\" (CA là đáy theo canonical position)\n * Rule: variant đặt tên theo position trong labels[], KHÔNG phải tên literal.\n apex ở position 0 → \"isoceles-BC\"; position 1 → \"isoceles-CA\"; position 2 → \"isoceles-AB\".\n - không có từ khoá đặc biệt → variant: \"any\"\n\n3. **Labels phải đúng đề:** \"tam giác MNP\" → labels: [\"M\",\"N\",\"P\"], không tự đổi sang ABC.\n\n4. **Augmentations (Tier 1) dùng add-point + connect:**\n - \"M trung điểm BC\" → add-point name=M, constraint=midpoint of=BC\n - \"H chân đường cao từ A xuống BC\" → add-point name=H, constraint=perpFoot from=A onLine=BC\n - \"vẽ đoạn AM\" → connect from=A to=M\n - Trọng tâm/tâm ngoại/nội/trực tâm → add-point constraint=centroid/circumcenter/incenter/orthocenter\n\n5. **KHÔNG bịa.** Nếu đề mơ hồ hoặc không thuộc hình học 2D phổ thông → decision=refuse.\n\n6. **Đặt tên draw-circle**: nếu đề có ký hiệu rõ ràng \"(X)\" (vd \"(O)\", \"(I)\", \"(I1)\") → dùng đúng ký hiệu đó làm name. KHÔNG thêm hậu tố như \"Ic\", \"In\", \"Oc\". Nếu đề không có ký hiệu thì name tự do (preprocessor xử lý mọi collision).\n\n7. **Mệnh lệnh \"Chứng minh\" / \"Tính\" / \"Tìm\" / \"Hỏi\" KHÔNG ảnh hưởng quyết định build/refuse.** Quyết định CHỈ dựa vào việc đề có MÔ TẢ hình vẽ được hay không. Nếu đề bắt đầu / kết thúc bằng \"Chứng minh rằng …\" hoặc \"Tính …\" nhưng phần MÔ TẢ (giả thiết) có hình (tam giác, tứ giác, đường tròn, giao điểm …) → vẫn decision=build, vẽ phần giả thiết. KẾT QUẢ proof / phép tính KHÔNG cần biểu diễn. Chỉ refuse khi đề THUẦN tính / đại số không kèm mô tả hình (vd \"Tính sin(30°)+cos(60°)\", \"Giải x²-5x+6=0\").\n\n## Variant enum (chỉ dùng giá trị này)\n- triangle: any | equilateral | isoceles-AB | isoceles-BC | isoceles-CA | right-at-A | right-at-B | right-at-C\n- square: standard\n- rectangle: standard (default) | wide | tall\n- rhombus: standard\n- trapezoid: right | isoceles | general\n- parallelogram: standard\n- quadrilateral: any\n\n## Constraint kinds (cho add-point)\nmidpoint, perpFoot, centroid, circumcenter, incenter, orthocenter, intersection, onSegment, free, secondIntersection, circleIntersection, tangencyPoint, tangentPoint, angleBisectorFoot, externalAngleBisectorFoot, arcMidpoint, reflectPoint, reflectLine, excenter, rightAngleViewing, pointAtDistance\n\n## Style enum (cho connect)\nsegment, line, ray, perpBisector\n\n## draw-line — phân biệt field theo kind (RẤT QUAN TRỌNG, dễ sai)\n\ndraw-line dùng cho 4 loại đường thẳng đặc biệt. Mỗi kind có schema field khác\nnhau — đặt đúng field, KHÔNG bỏ field bắt buộc, KHÔNG nhầm POINT với LINE:\n\n- **perpThrough** — đường vuông góc với một đường thẳng, đi qua một điểm.\n Fields: \\`through\\` (POINT), \\`to\\` (LINE — ≥2 chữ, vd \"AB\", \"BC\").\n - Ví dụ: \"Đường vuông góc với AB tại B\" → \\`{kind:\"perpThrough\", through:\"B\", to:\"AB\"}\\`.\n - **SAI**: \\`{through:\"B\", to:\"A\"}\\` (A là 1 chữ → POINT, không phải LINE).\n - Nếu đề chỉ nói \"vuông góc với AB\" thì \\`to:\"AB\"\\` (2 chữ); KHÔNG đặt \\`to:\"A\"\\` hay \\`to:\"B\"\\`.\n\n- **parallelThrough** — đường song song với LINE, đi qua POINT. Field giống\n perpThrough: \\`through\\` (POINT), \\`to\\` (LINE 2+ chữ).\n - Ví dụ: \"qua M kẻ đường song song với BC\" → \\`{kind:\"parallelThrough\", through:\"M\", to:\"BC\"}\\`.\n\n- **tangentAt** — tiếp tuyến TẠI điểm trên đường tròn.\n Fields: \\`through\\` (POINT, phải nằm TRÊN circle), \\`circle\\` (CIRCLE name).\n - Ví dụ: \"Tiếp tuyến tại A của (O)\" → \\`{kind:\"tangentAt\", through:\"A\", circle:\"O\"}\\`.\n - KHÔNG dùng \\`from\\` ở đây — chỉ tangentFromExt mới dùng \\`from\\`.\n\n- **tangentFromExt** — tiếp tuyến TỪ điểm NGOÀI đường tròn (có 2 nhánh).\n Fields: \\`from\\` (POINT, ngoài circle), \\`circle\\` (CIRCLE), \\`which\\` ('first'|'second'|'both').\n - Ví dụ: \"Vẽ tiếp tuyến PA và PB từ P\" → 2 intent với \\`which:\"first\"\\` và \\`which:\"second\"\\`.\n\n## Cụm A — constraint hình học nâng cao (đặt ĐÚNG field)\n\n- **arcMidpoint** — trung điểm CUNG. Fields: \\`circle\\` (tên đường tròn), \\`a\\`, \\`b\\` (2 đầu cung), \\`notContaining\\` (đỉnh KHÔNG nằm trên cung đó).\n - Ví dụ: \"M là trung điểm cung BC không chứa A của (O)\" → \\`{kind:\"arcMidpoint\", circle:\"O\", a:\"B\", b:\"C\", notContaining:\"A\"}\\`.\n - LƯU Ý: phải có draw-circle tạo \\`circle\\` trước (vd đường tròn ngoại tiếp → spec:\"through3\", points:[A,B,C]).\n\n- **reflectPoint** — đối xứng qua một ĐIỂM. Fields: \\`of\\` (điểm gốc), \\`through\\` (tâm đối xứng, 1 chữ = POINT).\n - Ví dụ: \"Q đối xứng P qua trung điểm M\" → \\`{kind:\"reflectPoint\", of:\"P\", through:\"M\"}\\`.\n\n- **reflectLine** — đối xứng qua một ĐƯỜNG. Fields: \\`of\\` (điểm gốc), \\`through\\` (đường, 2 chữ = LINE vd \"BC\").\n - Ví dụ: \"D đối xứng H qua BC\" → \\`{kind:\"reflectLine\", of:\"H\", through:\"BC\"}\\`.\n\n- **excenter** — tâm BÀNG tiếp tam giác. Fields: \\`of\\` ([A,B,C]), \\`opposite\\` (đỉnh đối diện).\n - Ví dụ: \"J là tâm bàng tiếp góc A của tam giác ABC\" → \\`{kind:\"excenter\", of:[\"A\",\"B\",\"C\"], opposite:\"A\"}\\`.\n - KHÁC incenter (tâm NỘI tiếp): bàng tiếp nằm NGOÀI tam giác.\n\n- **rightAngleViewing** — điểm GÓC VUÔNG nhìn đoạn. Fields: \\`a\\`, \\`b\\` (2 mút đoạn), \\`onLine\\` (đường điểm nằm trên), \\`which\\` (0|1, optional — chọn giao điểm).\n - Dùng khi: \"M trên <đường> sao cho góc AMB = 90°\" / \"∠AMB = 90°\" / \"góc AMB vuông\" / \"MA ⊥ MB\" / \"M nhìn AB dưới góc vuông\".\n - Chữ GIỮA của góc = tên điểm (name); 2 chữ ngoài = \\`a\\`, \\`b\\`.\n - Ví dụ: \"M trên CK sao cho góc AMB = 90°\" → \\`{op:\"add-point\", name:\"M\", constraint:{kind:\"rightAngleViewing\", a:\"A\", b:\"B\", onLine:\"CK\"}}\\`.\n - KHÔNG tự tạo đường tròn phụ — chỉ phát ra constraint này, hệ thống tự dựng đường tròn đường kính AB (Thales).\n- **pointAtDistance** — điểm trên TIA kéo dài, cách mốc một khoảng cho trước. Fields: \\`from\\` (điểm gốc của tia), \\`through\\` (điểm mốc — điểm mới nằm BÊN NGOÀI \\`through\\` trên tia from→through), \\`distance\\` — một trong:\n - \\`{kind:\"circleRadius\", circle:\"O\"}\\` = bán kính R của đường tròn (O)\n - \\`{kind:\"segmentLength\", p1:\"O\", p2:\"A\"}\\` = độ dài đoạn OA\n - \\`{kind:\"literal\", value:2}\\` = số đo cho sẵn\n - Ví dụ: \"Kéo dài AB về phía B, lấy C sao cho BC = R của (O)\" → \\`{op:\"add-point\", name:\"C\", constraint:{kind:\"pointAtDistance\", from:\"A\", through:\"B\", distance:{kind:\"circleRadius\", circle:\"O\"}}}\\`.\n - Ví dụ: \"Trên tia đối của tia BA lấy D sao cho BD = AB\" (hướng từ B ra xa A) → \\`{op:\"add-point\", name:\"D\", constraint:{kind:\"pointAtDistance\", from:\"A\", through:\"B\", distance:{kind:\"segmentLength\", p1:\"A\", p2:\"B\"}}}\\`.\n - KHÁC reflectPoint (cho 2·through−from, không cần distance) và onSegment (nằm GIỮA hai điểm, t∈[0,1]).\n\n## Quy ước LINE name\n- 2 ký tự viết liền = SEGMENT/LINE qua 2 điểm: \"AB\", \"BC\", \"MN\" → \\`to: \"AB\"\\`.\n- 1 ký tự = POINT, KHÔNG dùng cho field \\`to\\` của perpThrough/parallelThrough.\n- Nếu đề chỉ nêu 2 điểm và bạn cần đường thẳng qua chúng, gọi nó là \"AB\"\n (alphabet order canonical), KHÔNG cần emit connect intent riêng — builder\n tự suy ra đoạn.\n\n---\n\n# ${FIXTURES.length} ví dụ\n\n${examples}\n`;\n}\n","// src/stamps/geometry-2d/ai/intent.ts\n//\n// Intent schema — replacement for free-form DSL output.\n//\n// AI emit Intent[] thay vì DSL trực tiếp. Mỗi Intent là 1 \"lệnh vẽ\" cấp\n// semantic (\"vẽ tam giác đều ABC\", \"thêm trung điểm M của BC\"). Builder\n// (intentToDsl.ts) deterministic dịch Intent → DSL với canonical coords.\n//\n// Lợi ích:\n// - AI chỉ làm NLU (đọc-tách-lệnh), không tự đặt coord → 0% hallucinate coord\n// - Variant enum loại bỏ \"tam giác vuông tại A nhưng coord vuông tại B\"\n// - Schema explicit slot cho augmentations → guard \"không thừa\"\n\nimport { z } from 'zod';\n\n// Tên label/point — alphanumeric, 1-8 chars, không trùng kind enum.\nexport const LabelZ = z.string().min(1).max(8).regex(/^[A-Za-z][A-Za-z0-9'_]*$/);\n\n// ---------------------------------------------------------------------------\n// Shape variants per shape type\n// ---------------------------------------------------------------------------\n\n// triangle variants\nexport const TriangleVariantZ = z.enum([\n 'any', // tam giác bất kỳ (scalene cố định)\n 'equilateral', // tam giác đều\n 'isoceles-AB', // cân tại C (AB đáy)\n 'isoceles-BC', // cân tại A (BC đáy)\n 'isoceles-CA', // cân tại B (CA đáy)\n 'right-at-A', // vuông tại A\n 'right-at-B', // vuông tại B\n 'right-at-C', // vuông tại C\n]);\n\nexport const QuadVariantZ = z.enum([\n 'any', // tứ giác bất kỳ\n]);\n\nexport const SquareVariantZ = z.enum([\n 'standard', // canonical\n]);\n\nexport const RectangleVariantZ = z.enum([\n 'wide', // mặc định 4×2.5\n 'tall', // 2.5×4\n]);\n\nexport const RhombusVariantZ = z.enum([\n 'standard', // canonical (diagonals 4,2)\n]);\n\nexport const TrapezoidVariantZ = z.enum([\n 'right', // vuông\n 'isoceles', // cân\n 'general', // thường\n]);\n\nexport const ParallelogramVariantZ = z.enum([\n 'standard', // mặc định\n]);\n\n// ---------------------------------------------------------------------------\n// Intent ops\n// ---------------------------------------------------------------------------\n//\n// Note: zod's discriminatedUnion không cho phép duplicate discriminator value\n// (vd nhiều 'draw-shape' schemas khác nhau). Solution: flatten — mỗi op là 1\n// schema duy nhất với `shape` là enum, runtime check variant ∈ allowed-for-shape\n// trong builder. Đánh đổi: kém type-safety hơn variant-per-shape DSU, nhưng\n// schema flatter → JSON Schema rõ ràng hơn cho LLM, Ollama format không phải\n// nested anyOf.\n\nconst ShapeNameZ = z.enum([\n 'triangle',\n 'square',\n 'rectangle',\n 'rhombus',\n 'trapezoid',\n 'parallelogram',\n 'quadrilateral',\n]);\n\n// Tất cả variant gộp 1 enum — runtime check ở builder.\nconst ShapeVariantZ = z.enum([\n // triangle\n 'any', 'equilateral',\n 'isoceles-AB', 'isoceles-BC', 'isoceles-CA',\n 'right-at-A', 'right-at-B', 'right-at-C',\n // square / rhombus / parallelogram\n 'standard',\n // rectangle\n 'wide', 'tall',\n // trapezoid\n 'right', 'isoceles', 'general',\n]);\n\n// op: draw-shape\nexport const DrawShapeIntentZ = z.object({\n op: z.literal('draw-shape'),\n shape: ShapeNameZ,\n labels: z.array(LabelZ).min(3).max(8),\n variant: ShapeVariantZ.default('any'),\n explicitCoords: z.record(LabelZ, z.tuple([z.number(), z.number()])).optional(),\n});\n\n// op: add-point\nexport const AddPointIntentZ = z.object({\n op: z.literal('add-point'),\n name: LabelZ,\n constraint: z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('midpoint'), of: z.string() }),\n z.object({ kind: z.literal('perpFoot'), from: LabelZ, onLine: z.string() }),\n z.object({ kind: z.literal('centroid'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({ kind: z.literal('circumcenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({ kind: z.literal('incenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({ kind: z.literal('orthocenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({\n kind: z.literal('intersection'),\n of: z.tuple([z.string(), z.string()]),\n branch: z.union([z.literal(0), z.literal(1)]).optional(),\n }),\n z.object({ kind: z.literal('onSegment'), of: z.string(), t: z.number().min(0).max(1).optional() }),\n z.object({ kind: z.literal('free'), at: z.tuple([z.number(), z.number()]).optional() }),\n // Điểm A nằm NGOÀI đường tròn `circle` (free external point) — builder đọc\n // tâm+bán kính của circle từ build state rồi đặt A free tại coord ngoài\n // circle. Unblock tangentFromExt render (đề \"Lấy A ngoài (O), kẻ 2 tiếp tuyến\").\n z.object({ kind: z.literal('externalToCircle'), circle: LabelZ }),\n // Điểm trên đường tròn `circle` tại góc `theta` (mặc định 0) — glider.\n // Dùng cho đường thẳng Simson (issue #47): P trên đường tròn ngoại tiếp.\n z.object({ kind: z.literal('onCircle'), circle: LabelZ, theta: z.number().optional() }),\n // NEW Tier 4+5\n z.object({ kind: z.literal('secondIntersection'), line: z.string(), circle: LabelZ, other: LabelZ }),\n z.object({ kind: z.literal('circleIntersection'), c1: LabelZ, c2: LabelZ, which: z.union([z.literal(0), z.literal(1)]) }),\n // Giao điểm THỨ HAI của 2 đường tròn, loại điểm chung `exclude` (đề \"đường\n // tròn đường kính AB, AC đôi một cắt nhau lần thứ hai\" — điểm chung A).\n z.object({ kind: z.literal('circleSecondIntersection'), c1: LabelZ, c2: LabelZ, exclude: LabelZ }),\n z.object({ kind: z.literal('tangencyPoint'), circle: LabelZ, onLine: z.string() }),\n z.object({ kind: z.literal('tangentPoint'), from: LabelZ, circle: LabelZ, which: z.union([z.literal(0), z.literal(1)]) }),\n z.object({ kind: z.literal('angleBisectorFoot'), from: LabelZ, onLine: z.string() }),\n // Phân giác NGOÀI: chân phân giác ngoài đỉnh `from` trên đường thẳng `onLine`\n // (phân giác ngoài ⊥ phân giác trong tại `from`). Issue #46 nhóm A.\n z.object({ kind: z.literal('externalAngleBisectorFoot'), from: LabelZ, onLine: z.string() }),\n // Cụm A\n z.object({ kind: z.literal('arcMidpoint'), circle: LabelZ, a: LabelZ, b: LabelZ, notContaining: LabelZ }),\n z.object({ kind: z.literal('reflectPoint'), of: LabelZ, through: LabelZ }),\n z.object({ kind: z.literal('reflectLine'), of: LabelZ, through: z.string() }),\n z.object({ kind: z.literal('excenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]), opposite: LabelZ }),\n // Góc vuông nhìn đoạn: M trên onLine sao cho ∠ a-name-b = 90°\n z.object({ kind: z.literal('rightAngleViewing'), a: LabelZ, b: LabelZ, onLine: z.string(), which: z.union([z.literal(0), z.literal(1)]).optional() }),\n z.object({\n kind: z.literal('pointAtDistance'),\n from: LabelZ,\n through: LabelZ,\n // scale/offset OPTIONAL (Issue #46 nhóm C): d = scale·base + offset.\n // scale > 0; absent → giữ d = base như cũ (additive).\n distance: z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('circleRadius'), circle: LabelZ, scale: z.number().positive().optional(), offset: z.number().optional() }),\n z.object({ kind: z.literal('segmentLength'), p1: LabelZ, p2: LabelZ, scale: z.number().positive().optional(), offset: z.number().optional() }),\n z.object({ kind: z.literal('literal'), value: z.number().positive(), scale: z.number().positive().optional(), offset: z.number().optional() }),\n ]),\n }),\n ]),\n});\n\n// op: connect\nexport const ConnectIntentZ = z.object({\n op: z.literal('connect'),\n from: LabelZ,\n to: LabelZ,\n style: z.enum([\n 'segment',\n 'line',\n 'ray',\n 'perpBisector',\n 'angleBisector',\n ]).default('segment'),\n});\n\n// op: draw-circle — single schema, spec là enum, points conditional\nexport const DrawCircleIntentZ = z.object({\n op: z.literal('draw-circle'),\n name: LabelZ,\n spec: z.enum(['centerThrough', 'through3', 'centerRadius', 'inscribedIn', 'diameter']),\n center: LabelZ.optional(),\n through: LabelZ.optional(),\n points: z.tuple([LabelZ, LabelZ, LabelZ]).optional(),\n // NEW Tier 4+5\n radius: z.number().positive().optional(),\n triangle: z.tuple([LabelZ, LabelZ, LabelZ]).optional(),\n // spec 'diameter' — đường tròn đường kính nối 2 đầu mút.\n endpoints: z.tuple([LabelZ, LabelZ]).optional(),\n});\n\n// op: draw-line\nexport const DrawLineIntentZ = z.object({\n op: z.literal('draw-line'),\n name: LabelZ,\n kind: z.enum(['perpThrough', 'parallelThrough', 'tangentAt', 'tangentFromExt', 'angleBisector', 'lineThrough', 'radicalAxis']),\n through: LabelZ.optional(),\n to: LabelZ.optional(),\n from: LabelZ.optional(),\n circle: LabelZ.optional(),\n which: z.enum(['first', 'second', 'both']).optional(),\n // lineThrough (đường qua ≥2 điểm đồng tuyến — vd Euler line G/H/O, issue #47).\n points: z.array(LabelZ).optional(),\n // radicalAxis (trục đẳng phương 2 đường tròn — issue #47, construct 2).\n circle1: LabelZ.optional(),\n circle2: LabelZ.optional(),\n // angleBisector (phân giác TRONG của góc ∠p1·vertex·p2, VISIBLE, không foot —\n // Issue #46 nhóm A). vertex = đỉnh góc.\n p1: LabelZ.optional(),\n vertex: LabelZ.optional(),\n p2: LabelZ.optional(),\n});\n\n// op: mark-shape (sub-shape từ điểm đã có, không tạo coord mới)\nexport const MarkShapeIntentZ = z.object({\n op: z.literal('mark-shape'),\n shape: z.enum(['triangle', 'quadrilateral']),\n labels: z.array(LabelZ).min(3).max(4),\n});\n\n// Master discriminated union — 6 variants theo op\nexport const IntentZ = z.discriminatedUnion('op', [\n DrawShapeIntentZ,\n AddPointIntentZ,\n ConnectIntentZ,\n DrawCircleIntentZ,\n DrawLineIntentZ, // NEW\n MarkShapeIntentZ, // NEW\n]);\n\n// Re-export variant enums cho consumer (vd UI dropdown)\nexport {\n TriangleVariantZ as TriangleVariants,\n SquareVariantZ as SquareVariants,\n RectangleVariantZ as RectangleVariants,\n RhombusVariantZ as RhombusVariants,\n TrapezoidVariantZ as TrapezoidVariants,\n ParallelogramVariantZ as ParallelogramVariants,\n QuadVariantZ as QuadVariants,\n};\n\nexport type IntentT = z.infer<typeof IntentZ>;\nexport type DrawShapeIntentT = z.infer<typeof DrawShapeIntentZ>;\nexport type AddPointIntentT = z.infer<typeof AddPointIntentZ>;\nexport type ConnectIntentT = z.infer<typeof ConnectIntentZ>;\nexport type DrawCircleIntentT = z.infer<typeof DrawCircleIntentZ>;\nexport type DrawLineIntentT = z.infer<typeof DrawLineIntentZ>;\nexport type MarkShapeIntentT = z.infer<typeof MarkShapeIntentZ>;\n\n// ---------------------------------------------------------------------------\n// Envelope — wraps intents[] + decision\n// ---------------------------------------------------------------------------\n\nexport const IntentEnvelopeZ = z\n .object({\n decision: z.enum(['build', 'refuse']),\n intents: z.array(IntentZ).optional(),\n reason: z.string().optional(),\n })\n .refine(\n (e) =>\n e.decision === 'build'\n ? Array.isArray(e.intents) && e.intents.length > 0\n : e.reason != null && e.reason.length > 0,\n {\n message:\n 'decision=build cần intents non-empty; decision=refuse cần reason',\n },\n );\n\nexport type IntentEnvelopeT = z.infer<typeof IntentEnvelopeZ>;\n","// src/stamps/geometry-2d/ai/intentEnvelope.ts\n//\n// JSON Schema helper cho Intent envelope. Provider truyền schema này cho LLM:\n// - Anthropic: tool_use input_schema\n// - Ollama: chat `format` field\n//\n// Refine() check ở Zod runtime; JSON Schema không representable.\n\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { IntentEnvelopeZ, type IntentEnvelopeT } from './intent';\nimport type { IntentT } from './intent';\n\nexport function intentEnvelopeJsonSchema(): Record<string, unknown> {\n return zodToJsonSchema(IntentEnvelopeZ, {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n }) as Record<string, unknown>;\n}\n\nexport function envelopeIntentList(env: IntentEnvelopeT): readonly IntentT[] {\n if (env.decision !== 'build' || env.intents == null) {\n throw new Error(\n 'envelopeIntentList: envelope không phải decision=build hoặc thiếu intents',\n );\n }\n return env.intents;\n}\n","// src/stamps/geometry-2d/ai/normalizeIntent.ts\n//\n// Post-LLM variant normalizer cho Intent pipeline.\n//\n// Mục đích: fix 2 nhóm bias quan sát được trong eval gemma3:12b:\n// 1. LLM emit isoceles variant SAI position (vd \"cân tại A\" → 'isoceles-AB'\n// thay vì 'isoceles-BC') vì naming rule canonical không trực giác.\n// 2. LLM follow prompt \"rectangle: wide | tall\" → emit 'wide' trong khi\n// eval + đa số sản phẩm muốn 'standard' (rendering identical với 'wide').\n//\n// Pure function, không mutate input.\n\nimport type { IntentT, DrawShapeIntentT, DrawLineIntentT } from './intent';\n\nconst CAN_TAI_RE = /c[aâ]n\\s+t[aạ]i\\s+([A-Z])/i;\nconst ISOCELES_AT_RE = /isoceles\\s+(?:at|with\\s+apex)\\s+([A-Z])/i;\nconst TALL_RECT_RE = /(cao|hẹp|thin|tall|portrait)/i;\n\n/**\n * Apply variant normalization. Returns new array; input unmodified.\n *\n * Rules áp dụng (chỉ override khi MATCH chắc; otherwise pass-through):\n * - triangle + \"cân tại X\" → variant theo position của X trong labels\n * - rectangle: default 'standard' (giữ 'tall' khi đề có \"cao\"/\"hẹp\")\n * - square|rhombus|parallelogram: ép 'standard' (chỉ 1 variant hợp lệ)\n */\nexport function normalizeIntents(\n intents: readonly IntentT[],\n problem: string,\n): IntentT[] {\n // Đếm tam giác: chỉ normalize \"cân tại X\" khi đề có ĐÚNG 1 tam giác — đa tam\n // giác thì không thể bind \"cân tại X\" toàn-problem cho đúng tam giác, mà rule\n // deterministic (window) / LLM đã set variant per-intent → tin theo đó.\n const triangleCount = intents.filter(\n (i) => i.op === 'draw-shape' && i.shape === 'triangle',\n ).length;\n return intents.map((intent) => {\n if (intent.op === 'draw-shape') return normalizeShape(intent, problem, triangleCount);\n if (intent.op === 'draw-line') return normalizeLine(intent);\n return intent;\n });\n}\n\n// Builder enforce strict field per kind. LLM nhầm field giữa các kind cùng\n// schema (through/from/to/circle/which đều optional). Fix: swap field khi\n// pattern rõ ràng (no ambiguity).\n//\n// Rules:\n// - tangentAt cần `through` (điểm trên đường tròn). Nếu LLM dùng `from` → swap.\n// - tangentFromExt cần `from` (điểm ngoài). Nếu LLM dùng `through` → swap.\n// - perpThrough / parallelThrough cần `through` (điểm) + `to` (line).\n// Nếu LLM dùng `from` thay `through` → swap.\nfunction normalizeLine(intent: DrawLineIntentT): DrawLineIntentT {\n if (intent.kind === 'tangentAt' && intent.from && !intent.through) {\n const { from, ...rest } = intent;\n return { ...rest, through: from };\n }\n if (intent.kind === 'tangentFromExt' && intent.through && !intent.from) {\n const { through, ...rest } = intent;\n return { ...rest, from: through };\n }\n if (\n (intent.kind === 'perpThrough' || intent.kind === 'parallelThrough') &&\n intent.from &&\n !intent.through\n ) {\n const { from, ...rest } = intent;\n return { ...rest, through: from };\n }\n return intent;\n}\n\nfunction normalizeShape(\n intent: DrawShapeIntentT,\n problem: string,\n triangleCount: number,\n): IntentT {\n switch (intent.shape) {\n case 'triangle':\n return normalizeTriangle(intent, problem, triangleCount);\n case 'rectangle':\n return normalizeRectangle(intent, problem);\n case 'square':\n case 'rhombus':\n case 'parallelogram':\n return forceStandard(intent);\n default:\n return intent;\n }\n}\n\nfunction normalizeRectangle(\n intent: DrawShapeIntentT,\n problem: string,\n): DrawShapeIntentT {\n if (intent.variant === 'tall' && TALL_RECT_RE.test(problem)) return intent;\n if (intent.variant === 'standard') return intent;\n return { ...intent, variant: 'standard' };\n}\n\nfunction forceStandard(intent: DrawShapeIntentT): DrawShapeIntentT {\n if (intent.variant === 'standard') return intent;\n return { ...intent, variant: 'standard' };\n}\n\nfunction normalizeTriangle(\n intent: DrawShapeIntentT,\n problem: string,\n triangleCount: number,\n): DrawShapeIntentT {\n // Đa tam giác: không clobber — variant đã được set đúng per-intent ở nguồn.\n if (triangleCount !== 1) return intent;\n const m = problem.match(CAN_TAI_RE) ?? problem.match(ISOCELES_AT_RE);\n if (!m) return intent;\n const apex = m[1].toUpperCase();\n const i = intent.labels.indexOf(apex);\n if (i < 0) return intent;\n // Variant POSITIONAL theo INDEX apex (builder: isoceles-BC ⇒ apex=vertex[0]).\n // KHÔNG dùng chữ-cái-nhãn để đúng cho nhãn ≠ ABC.\n const variantByPos: Record<number, DrawShapeIntentT['variant']> = {\n 0: 'isoceles-BC',\n 1: 'isoceles-CA',\n 2: 'isoceles-AB',\n };\n const target = variantByPos[i];\n if (!target || intent.variant === target) return intent;\n return { ...intent, variant: target };\n}\n","// src/stamps/geometry-2d/ai/resolveCircleNames.ts\n//\n// Preprocessor giải quyết naming collision giữa circle name và point ref.\n// DSL schema enforce global-unique name (point + shape share namespace), nên\n// circle X + point X không cùng tồn tại được. Notation Việt \"(O)\" thường ám\n// chỉ TÂM (point) của đường tròn, nhưng Claude/LLM hay đặt circle name là \"O\"\n// → connect M→O segment fail KIND_MISMATCH.\n//\n// Pure function — không gọi AI, idempotent:\n// 1. Detect circle names được reference như point trong intent khác\n// 2. Inject add-point center (circumcenter/incenter dựa trên spec) BEFORE circle\n// 3. Rename circle \"X\" → \"X_c\"\n// 4. Rewrite các CIRCLE-context ref tới circle name → \"X_c\"\n\nimport type { IntentT } from './intent';\n\nexport function resolveCircleNameCollisions(intents: readonly IntentT[]): IntentT[] {\n const circleNames = new Set<string>();\n for (const i of intents) {\n if (i.op === 'draw-circle') circleNames.add(i.name);\n }\n if (circleNames.size === 0) return [...intents];\n\n const pointRefs = collectPointRefs(intents);\n\n const existingPoints = new Set<string>();\n for (const i of intents) {\n if (i.op === 'draw-shape') {\n for (const l of i.labels) existingPoints.add(l);\n } else if (i.op === 'add-point') {\n existingPoints.add(i.name);\n }\n }\n\n const collisions = new Set<string>();\n for (const name of circleNames) {\n if (pointRefs.has(name)) collisions.add(name);\n }\n if (collisions.size === 0) return [...intents];\n\n const rename = new Map<string, string>();\n for (const name of collisions) {\n rename.set(name, `${name}_c`);\n }\n\n const result: IntentT[] = [];\n for (const i of intents) {\n if (i.op === 'draw-circle' && collisions.has(i.name)) {\n if (!existingPoints.has(i.name)) {\n const centerIntent = makeCenterIntent(i);\n if (centerIntent) {\n result.push(centerIntent);\n existingPoints.add(i.name);\n }\n }\n result.push({ ...i, name: rename.get(i.name)! });\n } else {\n result.push(rewriteCircleRefs(i, rename));\n }\n }\n\n return result;\n}\n\nfunction makeCenterIntent(circle: Extract<IntentT, { op: 'draw-circle' }>): IntentT | null {\n if (circle.spec === 'through3' && circle.points) {\n return {\n op: 'add-point',\n name: circle.name,\n constraint: { kind: 'circumcenter', of: circle.points },\n };\n }\n if (circle.spec === 'inscribedIn' && circle.triangle) {\n return {\n op: 'add-point',\n name: circle.name,\n constraint: { kind: 'incenter', of: circle.triangle },\n };\n }\n // centerThrough/centerRadius: AI nhiều khi đặt `center === name` (vd `(O)` =\n // circle \"O\" có center \"O\") — cần inject `add-point name=center kind=free`\n // để point tồn tại sau khi circle được rename. Trường hợp center khác name\n // thì caller phải đảm bảo point center đã tồn tại (preprocessor không derive).\n if (\n (circle.spec === 'centerThrough' || circle.spec === 'centerRadius') &&\n circle.center === circle.name\n ) {\n return {\n op: 'add-point',\n name: circle.name,\n constraint: { kind: 'free' },\n };\n }\n return null;\n}\n\nfunction collectPointRefs(intents: readonly IntentT[]): Set<string> {\n const refs = new Set<string>();\n // 2-letter line/edge ref (vd \"BC\", \"AO\") → tách thành single-letter chars.\n // Cần thiết để detect collision khi line ref CHỨA tên circle (vd `line:\"AO\"`\n // + circle name \"O\" → O dùng như point ở \"AO\", phải inject center O).\n const addEdgeRef = (ref: string) => {\n if (/^[A-Za-z]{2}$/.test(ref)) {\n refs.add(ref[0]);\n refs.add(ref[1]);\n }\n };\n for (const i of intents) {\n if (i.op === 'connect') {\n refs.add(i.from);\n refs.add(i.to);\n } else if (i.op === 'add-point') {\n const c = i.constraint;\n if (c.kind === 'centroid' || c.kind === 'circumcenter' || c.kind === 'incenter' || c.kind === 'orthocenter') {\n for (const v of c.of) refs.add(v);\n } else if (c.kind === 'perpFoot' || c.kind === 'angleBisectorFoot') {\n refs.add(c.from);\n addEdgeRef(c.onLine);\n } else if (c.kind === 'tangentPoint') {\n refs.add(c.from);\n } else if (c.kind === 'secondIntersection') {\n refs.add(c.other);\n addEdgeRef(c.line);\n } else if (c.kind === 'tangencyPoint') {\n addEdgeRef(c.onLine);\n } else if (c.kind === 'midpoint' || c.kind === 'onSegment') {\n addEdgeRef(c.of);\n } else if (c.kind === 'intersection') {\n for (const r of c.of) addEdgeRef(r);\n }\n } else if (i.op === 'draw-circle') {\n if (i.center) refs.add(i.center);\n if (i.through) refs.add(i.through);\n if (i.points) for (const p of i.points) refs.add(p);\n if (i.triangle) for (const p of i.triangle) refs.add(p);\n } else if (i.op === 'draw-line') {\n if (i.through) refs.add(i.through);\n if (i.from) refs.add(i.from);\n if (i.to) addEdgeRef(i.to);\n // i.circle là circle ref — skip.\n } else if (i.op === 'mark-shape') {\n for (const l of i.labels) refs.add(l);\n }\n }\n return refs;\n}\n\nfunction rewriteCircleRefs(intent: IntentT, rename: Map<string, string>): IntentT {\n if (intent.op === 'add-point') {\n const c = intent.constraint;\n if (\n c.kind === 'tangencyPoint' ||\n c.kind === 'tangentPoint' ||\n c.kind === 'secondIntersection' ||\n c.kind === 'externalToCircle' ||\n c.kind === 'onCircle'\n ) {\n const newCircle = rename.get(c.circle);\n if (newCircle) {\n return { ...intent, constraint: { ...c, circle: newCircle } };\n }\n } else if (c.kind === 'circleIntersection') {\n const newC1 = rename.get(c.c1) ?? c.c1;\n const newC2 = rename.get(c.c2) ?? c.c2;\n if (newC1 !== c.c1 || newC2 !== c.c2) {\n return { ...intent, constraint: { ...c, c1: newC1, c2: newC2 } };\n }\n }\n } else if (intent.op === 'draw-line') {\n if (intent.circle && rename.has(intent.circle)) {\n return { ...intent, circle: rename.get(intent.circle)! };\n }\n if (intent.kind === 'radicalAxis') {\n const n1 = intent.circle1 ? rename.get(intent.circle1) : undefined;\n const n2 = intent.circle2 ? rename.get(intent.circle2) : undefined;\n if (n1 || n2) {\n return { ...intent, circle1: n1 ?? intent.circle1, circle2: n2 ?? intent.circle2 };\n }\n }\n }\n return intent;\n}\n","// src/stamps/geometry-2d/ai/completeRightAngle.ts\n//\n// Stage 1.5c (deterministic): bắt cấu hình \"góc vuông nhìn đoạn\" trong đề\n// tiếng Việt → đảm bảo có add-point intent với constraint rightAngleViewing.\n// LLM thường không nhận ra cần dựng đường tròn đường kính (Thales) để đặt M,\n// nên ta inject deterministic. Pure function, idempotent.\n//\n// ∠ a-M-b = 90° (hoặc Ma ⊥ Mb) + \"M trên <LINE>\"\n// → add-point M { kind: 'rightAngleViewing', a, b, onLine: LINE }\n\nimport type { IntentT } from './intent';\n\ninterface RightAngleSpec {\n vertex: string;\n a: string;\n b: string;\n onLine: string;\n}\n\n// ∠AMB = 90° / góc AMB = 90 độ / góc AMB vuông\nconst ANGLE_EQ_RE = /(?:góc|∠)\\s*([A-Z])\\s*([A-Z])\\s*([A-Z])\\s*(?:=|bằng|là)?\\s*90\\s*(?:°|độ|o\\b)/i;\nconst ANGLE_VUONG_RE = /(?:góc|∠)\\s*([A-Z])\\s*([A-Z])\\s*([A-Z])\\s*vuông/i;\n// MA ⊥ MB / MA vuông góc (với) MB\nconst PERP_RE = /([A-Z])([A-Z])\\s*(?:⊥|vuông\\s*góc(?:\\s*với)?)\\s*([A-Z])([A-Z])/i;\n\n/** Tìm đường mà điểm `vertex` nằm trên: \"M (là (một) điểm) trên|thuộc|nằm trên (đường…)? <LINE>\". */\nfunction findOnLine(problem: string, vertex: string): string | null {\n const re = new RegExp(\n `${vertex}\\\\s*(?:là\\\\s+(?:một\\\\s+)?điểm\\\\s+)?(?:trên|thuộc|nằm\\\\s+trên)\\\\s*` +\n `(?:đường\\\\s*thẳng|đường\\\\s*cao|đường|cạnh|tia)?\\\\s*([A-Za-z]{1,2})`,\n 'i',\n );\n const m = problem.match(re);\n if (!m) return null;\n return m[1];\n}\n\nfunction detectSpec(problem: string): RightAngleSpec | null {\n // 1. Angle = 90 / vuông: vertex là chữ GIỮA.\n for (const re of [ANGLE_EQ_RE, ANGLE_VUONG_RE]) {\n const m = problem.match(re);\n if (m) {\n const [, a, vertex, b] = m;\n const onLine = findOnLine(problem, vertex);\n if (onLine) return { vertex, a, b, onLine };\n }\n }\n // 2. Perp: chữ chung của 2 cặp là vertex.\n const p = problem.match(PERP_RE);\n if (p) {\n const [, x1, x2, y1, y2] = p;\n let vertex: string | null = null;\n let a: string | null = null;\n let b: string | null = null;\n if (x1 === y1) { vertex = x1; a = x2; b = y2; }\n else if (x1 === y2) { vertex = x1; a = x2; b = y1; }\n else if (x2 === y1) { vertex = x2; a = x1; b = y2; }\n else if (x2 === y2) { vertex = x2; a = x1; b = y1; }\n if (vertex && a && b) {\n const onLine = findOnLine(problem, vertex);\n if (onLine) return { vertex, a, b, onLine };\n }\n }\n return null;\n}\n\nexport function completeRightAngle(\n intents: readonly IntentT[],\n problem: string,\n): IntentT[] {\n const spec = detectSpec(problem);\n if (!spec) return [...intents];\n\n const injected: IntentT = {\n op: 'add-point',\n name: spec.vertex,\n constraint: { kind: 'rightAngleViewing', a: spec.a, b: spec.b, onLine: spec.onLine },\n };\n\n const idx = intents.findIndex((i) => i.op === 'add-point' && i.name === spec.vertex);\n if (idx === -1) {\n // inject ở cuối (sau khi các điểm phụ thuộc onLine đã được định nghĩa)\n return [...intents, injected];\n }\n\n const existing = intents[idx];\n if (existing.op === 'add-point' && existing.constraint.kind === 'rightAngleViewing') {\n return [...intents]; // keep\n }\n // replace in place\n const out = [...intents];\n out[idx] = injected;\n return out;\n}\n","// src/stamps/geometry-2d/ai/verify.ts\n//\n// Stage 4 verifier. Sau khi Intent[] → DSL → render, kiểm tra 3 trục:\n// - đủ (missing): intent expected nhưng DSL không có\n// - đúng (wrong): variant/labels mismatch\n// - không thừa (extra): DSL có entity không tương ứng intent nào\n//\n// Hai chế độ dùng:\n// 1. eval mode: so sánh actualIntents vs expectedIntents (golden)\n// 2. runtime mode: tự verify pipeline (intent→DSL, không có golden)\n\nimport type { DslInputT } from '../dsl/schema';\nimport type { IntentT, DrawShapeIntentT, AddPointIntentT } from './intent';\n\nexport interface VerifyIssue {\n readonly axis: 'missing' | 'wrong' | 'extra';\n readonly detail: string;\n}\n\nexport interface VerifyReport {\n readonly ok: boolean;\n readonly missing: readonly VerifyIssue[];\n readonly wrong: readonly VerifyIssue[];\n readonly extra: readonly VerifyIssue[];\n readonly geometric?: readonly VerifyIssue[];\n}\n\n// ---------------------------------------------------------------------------\n// Eval-mode: compare actual intents vs golden expected\n// ---------------------------------------------------------------------------\n\nexport function compareIntents(\n expected: readonly IntentT[],\n actual: readonly IntentT[],\n): VerifyReport {\n const expectedKey = expected.map(intentKey);\n const actualKey = actual.map(intentKey);\n\n const missing: VerifyIssue[] = [];\n const extra: VerifyIssue[] = [];\n const wrong: VerifyIssue[] = [];\n\n // Track which expected/actual entries matched.\n const matchedActual = new Set<number>();\n for (let i = 0; i < expectedKey.length; i++) {\n const ek = expectedKey[i];\n // Exact match first\n const exactIdx = actualKey.findIndex((ak, idx) => !matchedActual.has(idx) && ak === ek);\n if (exactIdx >= 0) {\n matchedActual.add(exactIdx);\n continue;\n }\n // Partial match: same op + same shape/name → \"wrong\"\n const partialIdx = actualKey.findIndex((ak, idx) =>\n !matchedActual.has(idx) && samePrefix(ak, ek, 2),\n );\n if (partialIdx >= 0) {\n matchedActual.add(partialIdx);\n wrong.push({\n axis: 'wrong',\n detail: `expected ${ek}, got ${actualKey[partialIdx]}`,\n });\n continue;\n }\n // No match → missing\n missing.push({ axis: 'missing', detail: ek });\n }\n // Unmatched actual entries → extra\n for (let i = 0; i < actualKey.length; i++) {\n if (!matchedActual.has(i)) {\n extra.push({ axis: 'extra', detail: actualKey[i] });\n }\n }\n\n return {\n ok: missing.length === 0 && wrong.length === 0 && extra.length === 0,\n missing,\n wrong,\n extra,\n };\n}\n\n// \"draw-shape/triangle/equilateral/A,B,C\" — canonical short string for compare.\nfunction intentKey(intent: IntentT): string {\n switch (intent.op) {\n case 'draw-shape':\n return [\n 'draw-shape',\n intent.shape,\n (intent as DrawShapeIntentT).variant,\n intent.labels.join(','),\n ].join('/');\n case 'add-point':\n return ['add-point', intent.name, intent.constraint.kind, constraintKey(intent.constraint)].join('/');\n case 'connect':\n return ['connect', intent.style, intent.from, intent.to].join('/');\n case 'draw-circle': {\n if (intent.spec === 'centerThrough') return `draw-circle/${intent.name}/centerThrough/${intent.center}/${intent.through}`;\n if (intent.spec === 'through3') return `draw-circle/${intent.name}/through3/${intent.points?.join(',') ?? ''}`;\n if (intent.spec === 'centerRadius') return `draw-circle/${intent.name}/centerRadius/${intent.center}/${intent.radius}`;\n if (intent.spec === 'inscribedIn') return `draw-circle/${intent.name}/inscribedIn/${intent.triangle?.join(',') ?? ''}`;\n return `draw-circle/${intent.name}/${(intent as any).spec}`;\n }\n case 'draw-line': {\n const base = [\n 'draw-line', intent.name, intent.kind,\n intent.through ?? '', intent.to ?? '', intent.from ?? '', intent.circle ?? '', intent.which ?? '',\n ].join('/');\n if (intent.kind === 'lineThrough') return `${base}/${(intent.points ?? []).join('+')}`;\n if (intent.kind === 'radicalAxis') return `${base}/${intent.circle1 ?? ''}+${intent.circle2 ?? ''}`;\n return base;\n }\n case 'mark-shape':\n return ['mark-shape', intent.shape, intent.labels.join(',')].join('/');\n }\n}\n\nfunction constraintKey(c: AddPointIntentT['constraint']): string {\n switch (c.kind) {\n case 'midpoint': return c.of;\n case 'perpFoot': return `${c.from}->${c.onLine}`;\n case 'centroid':\n case 'circumcenter':\n case 'incenter':\n case 'orthocenter':\n return c.of.join(',');\n case 'intersection': return c.of.join('×');\n case 'onSegment': return `${c.of}@${c.t ?? 'mid'}`;\n case 'free': return c.at ? c.at.join(',') : '*';\n case 'secondIntersection': return `secondIntersection:${c.line}:${c.circle}:${c.other}`;\n case 'circleIntersection': return `circleIntersection:${c.c1}:${c.c2}:${c.which}`;\n case 'circleSecondIntersection': return `circleSecondIntersection:${c.c1}:${c.c2}:${c.exclude}`;\n case 'tangencyPoint': return `tangencyPoint:${c.circle}:${c.onLine}`;\n case 'tangentPoint': return `tangentPoint:${c.from}:${c.circle}:${c.which}`;\n case 'angleBisectorFoot': return `angleBisectorFoot:${c.from}:${c.onLine}`;\n case 'externalAngleBisectorFoot': return `externalAngleBisectorFoot:${c.from}:${c.onLine}`;\n case 'arcMidpoint': return `arcMidpoint:${c.circle}:${c.a}:${c.b}:${c.notContaining}`;\n case 'reflectPoint': return `reflectPoint:${c.of}:${c.through}`;\n case 'reflectLine': return `reflectLine:${c.of}:${c.through}`;\n case 'excenter': return `excenter:${c.of.join(',')}:${c.opposite}`;\n case 'rightAngleViewing': return `rightAngleViewing:${c.a}:${c.b}:${c.onLine}:${c.which ?? 0}`;\n case 'pointAtDistance': {\n const d = c.distance;\n const dKey = d.kind === 'circleRadius' ? `r:${d.circle}`\n : d.kind === 'segmentLength' ? `seg:${d.p1}:${d.p2}`\n : `lit:${d.value}`;\n return `pointAtDistance:${c.from}:${c.through}:${dKey}`;\n }\n case 'externalToCircle': return `externalToCircle:${c.circle}`;\n case 'onCircle': return `onCircle:${c.circle}:${c.theta ?? ''}`;\n }\n}\n\nfunction samePrefix(a: string, b: string, depth: number): boolean {\n const aP = a.split('/').slice(0, depth).join('/');\n const bP = b.split('/').slice(0, depth).join('/');\n return aP === bP;\n}\n\n// ---------------------------------------------------------------------------\n// Intent metric: recall / precision / F1 (for eval)\n// ---------------------------------------------------------------------------\n\nexport interface IntentMetrics {\n recall: number;\n precision: number;\n f1: number;\n matched: number;\n expected: number;\n actual: number;\n}\n\nexport function computeIntentMetrics(\n expected: readonly IntentT[],\n actual: readonly IntentT[],\n): IntentMetrics {\n const expectedKeys = expected.map(intentKey);\n const actualKeys = actual.map(intentKey);\n const matched = new Set<number>();\n let hit = 0;\n for (const ek of expectedKeys) {\n const idx = actualKeys.findIndex((ak, i) => !matched.has(i) && ak === ek);\n if (idx >= 0) { matched.add(idx); hit++; }\n }\n const recall = expectedKeys.length === 0 ? 1 : hit / expectedKeys.length;\n const precision = actualKeys.length === 0 ? 1 : hit / actualKeys.length;\n const f1 = (recall + precision) === 0 ? 0 : (2 * recall * precision) / (recall + precision);\n return {\n recall, precision, f1,\n matched: hit,\n expected: expectedKeys.length,\n actual: actualKeys.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Geometric verification on DSL with resolved coords (scope: on-circle only;\n// tangent-touch / concyclic / collinear deferred until JSXGraph runtime hook).\n// ---------------------------------------------------------------------------\n\nconst GEOM_TOL = 1e-3;\n\nfunction resolveCoord(dsl: DslInputT, name: string): [number, number] | null {\n const p = dsl.points.find((x) => x.name === name);\n if (!p) return null;\n if (p.kind === 'free') return [p.x, p.y];\n if (p.kind === 'midpoint') {\n const a = resolveCoord(dsl, p.p1);\n const b = resolveCoord(dsl, p.p2);\n if (!a || !b) return null;\n return [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n }\n // Other kinds: computed by JSXGraph at runtime — skip static check.\n return null;\n}\n\nexport function verifyGeometric(dsl: DslInputT): VerifyReport {\n const geometric: VerifyIssue[] = [];\n\n for (const shape of dsl.shapes) {\n if (shape.kind !== 'circleCR') continue;\n // on-circle check: any point with onCircle constraint referencing this circle\n for (const p of dsl.points) {\n if (p.kind !== 'onCircle') continue;\n if (p.circleId !== shape.name) continue;\n const c = resolveCoord(dsl, shape.center);\n const pp = resolveCoord(dsl, p.name);\n if (!c || !pp) continue;\n const d = Math.hypot(pp[0] - c[0], pp[1] - c[1]);\n if (Math.abs(d - shape.radius) > GEOM_TOL) {\n geometric.push({\n axis: 'wrong',\n detail: `on-circle: |${p.name}-${shape.name}|=${d.toFixed(3)} ≠ R=${shape.radius}`,\n });\n }\n }\n }\n\n return {\n ok: geometric.length === 0,\n missing: [],\n wrong: [],\n extra: [],\n geometric,\n } as VerifyReport;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime-mode: verify DSL geometry constraints\n// ---------------------------------------------------------------------------\n\nexport function verifyGeometry(intents: readonly IntentT[], dsl: DslInputT): VerifyReport {\n const issues: VerifyIssue[] = [];\n\n // Check right-triangle variant has actual right angle at named vertex.\n for (const intent of intents) {\n if (intent.op !== 'draw-shape' || intent.shape !== 'triangle') continue;\n const variant = intent.variant;\n if (!variant.startsWith('right-at-')) continue;\n const apex = variant.slice('right-at-'.length); // 'A' | 'B' | 'C'\n const [A, B, C] = intent.labels;\n const ptByName = new Map(\n dsl.points.filter((p) => p.kind === 'free').map((p) => [p.name, [p.x, p.y] as [number, number]]),\n );\n const pA = ptByName.get(A);\n const pB = ptByName.get(B);\n const pC = ptByName.get(C);\n if (!pA || !pB || !pC) continue;\n const apexP = apex === 'A' ? pA : apex === 'B' ? pB : pC;\n const other1 = apex === 'A' ? pB : apex === 'B' ? pA : pA;\n const other2 = apex === 'A' ? pC : apex === 'B' ? pC : pB;\n const v1 = [other1[0] - apexP[0], other1[1] - apexP[1]];\n const v2 = [other2[0] - apexP[0], other2[1] - apexP[1]];\n const dot = v1[0] * v2[0] + v1[1] * v2[1];\n if (Math.abs(dot) > 1e-6) {\n issues.push({\n axis: 'wrong',\n detail: `triangle ${A}${B}${C} variant=right-at-${apex} không vuông (dot=${dot.toFixed(3)})`,\n });\n }\n }\n\n return {\n ok: issues.length === 0,\n missing: [],\n wrong: issues,\n extra: [],\n };\n}\n","// src/stamps/geometry-2d/ai/deterministic/vocabulary.ts\n//\n// Tập từ khóa \"geometry-relevant\" để confidence.ts đo coverage.\n// Format: lowercase, có dấu. countGeometryKeywords lowercase input rồi match.\n\nexport const GEOMETRY_KEYWORDS: readonly string[] = [\n // Base shapes\n 'tam giác', 'đường tròn', 'đương tròn', 'hình chữ nhật', 'hình vuông',\n 'hình bình hành', 'hình thoi', 'hình thang', 'tứ giác',\n // Triangle variants\n 'vuông tại', 'cân tại', 'đều',\n // Circle parts\n 'bán kính', 'tâm', 'đường kính', 'đương kính',\n // Segments / on-segment\n 'đoạn',\n // Derived points\n 'trung điểm', 'chân đường cao', 'chân đương cao', 'hình chiếu',\n 'trọng tâm', 'trực tâm', 'tâm nội tiếp', 'tâm ngoại tiếp',\n // Cevian names\n 'đường cao', 'đương cao', 'trung tuyến', 'phân giác', 'trung trực',\n // Special lines/circles\n 'tiếp tuyến', 'tiếp điểm', 'tiếp xúc',\n 'nội tiếp', 'ngoại tiếp',\n // Euler line (issue #47). Đánh dấu mọi clause \"Euler\" là geo-clause để\n // mention Euler chưa được claim (suy biến tam giác đều, hoặc đường tròn Euler\n // 9 điểm defer) → escalate fail-safe thay vì silent render-nothing.\n 'euler',\n // Trục đẳng phương (issue #47, construct 2). \"đẳng phương\" (≥10 ký tự, phân\n // biệt) đánh dấu clause là geo-clause: nếu radicalAxis rule miss (đồng tâm /\n // ≠2 đường tròn) → clause không phủ → escalate fail-safe (KHÔNG silent\n // render-nothing). Lowercase vì countGeometryKeywords lowercase input.\n 'đẳng phương',\n // Đường thẳng Simson (issue #47, construct 3). \"simson\" (danh từ riêng phân\n // biệt) đánh dấu clause là geo-clause: nếu simson rule miss (thiếu đường tròn\n // ngoại tiếp / >1 tam giác / P trùng đỉnh) → clause không phủ → escalate\n // fail-safe (KHÔNG silent render-nothing). Lowercase vì countGeometryKeywords\n // lowercase input.\n 'simson',\n // Đường tròn chín điểm / đường tròn Euler (issue #47, construct 4). \"chín điểm\"\n // đánh dấu clause là geo-clause: \"đường tròn Euler\" đã geo qua \"đường tròn\"/\n // \"euler\" sẵn, nhưng \"chín điểm\" (≥8 ký tự, phân biệt) phủ thêm cách diễn đạt\n // trần \"đường tròn chín điểm\" + làm fail-safe tường minh (nếu ninePoint rule\n // miss vì >1 tam giác → clause không phủ → escalate, KHÔNG silent render-nothing).\n // Lowercase vì countGeometryKeywords lowercase input.\n 'chín điểm',\n // Relations\n 'song song', 'vuông góc', 'giao điểm', 'cắt', 'đường thẳng', 'đương thẳng',\n // Ký hiệu (symbol-only phrasing tương đương từ chữ): \"⊥\" ≡ \"vuông góc\".\n // perpFoot rule đã nhận \"⊥\" ở tầng construct (PERP_DRAW), nhưng gate\n // hasGeometry trước đây CHỈ nhận chữ \"vuông góc\" → clause mà \"⊥\" là tín hiệu\n // hình học DUY NHẤT bị coi là văn xuôi (hasGeometry=false). Thêm \"⊥\" để 2\n // phrasing hành xử như nhau ở gate coverage (issue #46 nhóm A).\n '⊥',\n\n // === EN keywords (issue #46 group B) =======================================\n // Bộ từ khoá tiếng Anh để 1 clause TOÀN tiếng Anh được tính là geo-clause\n // (countGeometryKeywords > 0) → coverage gate không escalate sai dù rule EN đã\n // match. countGeometryKeywords lowercase input nên lưu lowercase ở đây.\n //\n // CHỈ thêm danh từ construct ĐA-KÝ-TỰ phân biệt, KHÔNG va chạm có hại như\n // substring của text tiếng Việt hay của nhau. KHÔNG thêm từ ngắn mơ hồ (\"on\",\n // \"at\", \"line\", \"point\", \"right\") vì dễ false-positive (\"point\" ⊂ \"appoint\",\n // \"at\" ⊂ \"tại\"…). Một danh từ construct / clause là đủ để đánh dấu geo.\n //\n // GOTCHA substring: \"centre\" ⊃ \"center\" KHÔNG xảy ra (khác chính tả); \"circle\"\n // KHÔNG ⊂ từ VN. \"radius\"/\"diameter\"/\"center\" là danh từ riêng cho circle.\n 'triangle',\n 'circle',\n 'square',\n 'rectangle',\n 'parallelogram',\n 'rhombus',\n 'trapezoid',\n 'trapezium',\n 'quadrilateral',\n 'midpoint',\n 'radius',\n 'diameter',\n 'center',\n 'centre',\n 'equilateral',\n 'isosceles',\n // Triangle centers (issue #46 group B). \"orthocenter\"/\"circumcenter\"/\n // \"incenter\" already contain \"center\" (already a keyword) — but list all four\n // explicitly for clarity + robustness. British -centre spellings included.\n 'centroid',\n 'orthocenter',\n 'orthocentre',\n 'circumcenter',\n 'circumcentre',\n 'incenter',\n 'incentre',\n // perpBisector + reflection EN (issue #46 group B). Hai danh từ này biến clause\n // \"perpendicular bisector …\" / \"reflection …\" tiếng Anh thành geo-clause để\n // coverage gate hoạt động: nếu rule EN match đủ thì clause được phủ; nếu clause\n // malformed (thiếu cặp đỉnh / thiếu trục) thì geo-clause không được phủ →\n // escalate (fail-safe), KHÔNG silent-incomplete. Đều ≥8 ký tự, phân biệt, không\n // substring của từ VN/EN nào hiện có (không va chạm).\n 'bisector',\n 'reflection',\n // tangentFromExt EN (issue #46 group B). Clause \"Draw the tangents from A to\n // (O)\" dùng ký hiệu \"(O)\" — KHÔNG có text keyword nào khác → coverage gate = 0\n // → escalate dù rule match. \"tangent\" (≥7 ký tự, phân biệt, KHÔNG substring của\n // từ VN/EN nào hiện có) đánh dấu clause là geo-clause. indexOf nên \"tangent\" tự\n // khớp trong \"tangents\"/\"tangent lines\" — KHÔNG cần thêm \"tangents\" riêng.\n 'tangent',\n // perpFoot EN (issue #46 group B). Clause \"Let H be the projection of A onto\n // BC\" / \"foot of the perpendicular from A to BC\" / \"Draw AH perpendicular to\n // BC\" → đánh dấu geo-clause để coverage gate fail-safe: nếu rule EN miss thì\n // geo-clause không phủ → escalate, KHÔNG silent-incomplete (triangle-only bỏ\n // điểm H). Cả hai ≥10 ký tự, phân biệt, không substring của từ VN/EN nào hiện\n // có. \"perpendicular bisector of BC\" đã có 'bisector' → 'perpendicular' chỉ\n // tăng count, không đổi hành vi.\n 'perpendicular',\n 'projection',\n // pointAtDistance EN (issue #46 group B). Clause \"On ray BA extended beyond A,\n // take D such that AD = AB\" / \"Extend AB beyond B to D ...\" / \"On the opposite\n // ray of ray BA, take D ...\" → mark geo-clause. \"extend\" (indexOf also matches\n // \"extended\"/\"extending\") + the phrase \"opposite ray\" (geometry-specific). If\n // the rule misses a malformed clause → geo-clause unclaimed → escalate\n // (fail-safe), NOT silent-drop of point D. No harmful substring collision with\n // any existing VN/EN keyword.\n 'extend',\n 'opposite ray',\n // cevian EN (issue #46 group B). Clause \"Draw the median AM\" / \"Draw the\n // altitude AH\" → mark geo-clause. Nếu rule không parse được clause median/\n // altitude bị lỗi → geo-clause không phủ → escalate (fail-safe), KHÔNG\n // silent-incomplete (triangle-only bỏ điểm chân). ('bisector' đã có ở trên.)\n // Cả hai đều là danh từ hình học riêng, không substring va chạm có hại.\n 'median',\n 'altitude',\n // connect EN (issue #46 nhóm B). VN \"đoạn\" LÀ keyword → \"segment\" parity để\n // \"Draw segment XY\" standalone là geo-clause: rule connect EN claim → render;\n // clause malformed (\"segment\" không cặp HOA) → geo unclaimed → escalate\n // (fail-safe). ≥7 ký tự, phân biệt, không substring va chạm. \"line\"/\"ray\"/\"draw\"/\n // \"join\"/\"connect\" CỐ Ý KHÔNG thêm (đối VN \"đường thẳng\"/\"tia\"/… cũng không phải\n // keyword → parity: render in-context, escalate standalone).\n 'segment',\n];\n\nexport function countGeometryKeywords(text: string): number {\n const lower = text.toLowerCase();\n let count = 0;\n for (const kw of GEOMETRY_KEYWORDS) {\n let from = 0;\n while (true) {\n const i = lower.indexOf(kw, from);\n if (i < 0) break;\n count++;\n from = i + kw.length;\n }\n }\n return count;\n}\n","// src/stamps/geometry-2d/ai/deterministic/coverage.ts\n//\n// Clause segmentation + coverage cho deterministic-first gate.\n// Track A chỉ \"tự tin\" dùng kết quả khi MỌI clause mang nội dung hình học\n// đều được ít nhất 1 rule match claim. Còn sót → escalate AI.\nimport { countGeometryKeywords } from './vocabulary';\n\nexport interface Clause {\n id: number;\n text: string;\n /** clause chứa ≥1 từ khoá hình học → tính vào mẫu số coverage. */\n hasGeometry: boolean;\n}\n\nexport interface CoverageReport {\n complete: boolean;\n coveredClauseIds: number[];\n uncovered: Clause[];\n ratio: number;\n}\n\ninterface MatchLike {\n clauseIds: number[];\n}\n\n/**\n * Tách đề thành clause theo dấu câu (. ; xuống dòng) và dấu phẩy đứng trước\n * từ dẫn (\"Gọi\", \"Vẽ\", \"Kẻ\"…). Clause thuần văn xuôi (không từ khoá hình học)\n * vẫn được giữ nhưng `hasGeometry=false` để không ép escalate.\n */\nexport function segmentClauses(problem: string): Clause[] {\n // Comma-split lookahead: tách clause ở dấu phẩy đứng TRƯỚC từ dẫn. VN dùng\n // (Gọi|Vẽ|Kẻ|Cho|Lấy|Dựng|trên|với). EN ADDITIVE (issue #46 group B): các từ\n // dẫn sub-clause viết HOA đầu câu (Let|Draw|Mark|Take|Construct|Join) — \"Triangle\n // ABC, let M be the midpoint of BC\" tách thành 2 clause. Thuần additive: không\n // đổi segmentation VN (alternation rời nhau, không trùng từ).\n return problem\n .split(\n /[.;\\n]+|,\\s*(?=(?:Gọi|Vẽ|Kẻ|Cho|Lấy|Dựng|trên|với|Let|Draw|Mark|Take|Construct|Join)\\b)/u,\n )\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .map((text, id) => ({ id, text, hasGeometry: countGeometryKeywords(text) > 0 }));\n}\n\nexport function computeCoverage(\n clauses: readonly Clause[],\n matches: readonly MatchLike[],\n): CoverageReport {\n const claimed = new Set<number>();\n for (const m of matches) for (const id of m.clauseIds) claimed.add(id);\n\n const geoClauses = clauses.filter((c) => c.hasGeometry);\n const uncovered = geoClauses.filter((c) => !claimed.has(c.id));\n const coveredClauseIds = geoClauses\n .filter((c) => claimed.has(c.id))\n .map((c) => c.id);\n\n return {\n complete: uncovered.length === 0 && geoClauses.length > 0,\n coveredClauseIds,\n uncovered,\n ratio: geoClauses.length === 0 ? 0 : coveredClauseIds.length / geoClauses.length,\n };\n}\n","// src/stamps/geometry-2d/ai/rules/_shared.ts\n//\n// Helper dùng chung cho rule module: intent factory (cast IntentT tập trung 1 chỗ)\n// + trích tên điểm từ lời dẫn tiếng Việt. Rule module KHÔNG tự cast `as any`.\nimport type { IntentT } from '../intent';\n\n// --- Intent factories (cast tập trung) ---------------------------------------\n// variant/shape/kind là string runtime; zod validate lại ở builder/transpile,\n// nên cast qua unknown an toàn trong phạm vi NLU.\n\nexport function drawShape(\n shape: string,\n labels: string[],\n variant = 'any',\n explicitCoords?: Record<string, readonly [number, number]>,\n): IntentT {\n return {\n op: 'draw-shape',\n shape,\n labels,\n variant,\n ...(explicitCoords ? { explicitCoords } : {}),\n } as unknown as IntentT;\n}\n\nexport function addPoint(name: string, constraint: Record<string, unknown>): IntentT {\n return { op: 'add-point', name, constraint } as unknown as IntentT;\n}\n\nexport function connect(from: string, to: string, style = 'segment'): IntentT {\n return { op: 'connect', from, to, style } as unknown as IntentT;\n}\n\nexport function drawCircle(\n name: string,\n spec: string,\n extra: Record<string, unknown> = {},\n): IntentT {\n return { op: 'draw-circle', name, spec, ...extra } as unknown as IntentT;\n}\n\nexport function drawLine(\n name: string,\n kind: string,\n extra: Record<string, unknown> = {},\n): IntentT {\n return { op: 'draw-line', name, kind, ...extra } as unknown as IntentT;\n}\n\n/** Đa giác con (triangle|quadrilateral) nối các ĐIỂM ĐÃ CÓ — không tạo coord mới. */\nexport function markShape(shape: string, labels: string[]): IntentT {\n return { op: 'mark-shape', shape, labels } as unknown as IntentT;\n}\n\n// --- Point-name extraction ----------------------------------------------------\n\nconst INTRO_NAME =\n /(?:Gọi|Lấy|Dựng|Vẽ|Kẻ|Đặt|Xác định)\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)\\b/u;\nconst NAME_LA = /\\b([A-Z])(?:['′]?)\\s+là\\b/u;\n\n/**\n * Trích tên điểm được giới thiệu trong clause:\n * \"Gọi M là trung điểm BC\" → \"M\"\n * \"Lấy điểm D trên cạnh AB\" → \"D\"\n * \"H là trực tâm\" → \"H\"\n * Trả undefined nếu không tìm thấy (caller tự quyết fallback / bỏ qua).\n */\nexport function extractPointName(clauseText: string): string | undefined {\n const intro = INTRO_NAME.exec(clauseText);\n if (intro) return intro[1];\n const la = NAME_LA.exec(clauseText);\n if (la) return la[1];\n return undefined;\n}\n\n/** Tách \"BC\" → [\"B\",\"C\"]; \"AB\" → [\"A\",\"B\"]. Trả [] nếu không phải cặp đỉnh. */\nexport function pairFromToken(token: string): string[] {\n const m = /^([A-Z])([A-Z])$/u.exec(token.trim());\n return m ? [m[1], m[2]] : [];\n}\n\n// --- Side / segment prefix ----------------------------------------------------\n// Tiền tố \"cạnh\"/\"đoạn\" tuỳ chọn TRƯỚC cặp đỉnh, cho phép bổ ngữ \"huyền\"/\"thẳng\"\n// chen giữa: \"cạnh BC\", \"cạnh huyền BC\", \"đoạn AC\", \"đoạn thẳng AC\". Fail-safe:\n// \"cạnh thẳng\"/\"đoạn huyền\" (sai cặp) KHÔNG khớp vì bổ ngữ bị buộc đúng loại.\n// Là FRAGMENT regex (string, không cờ) để nhúng vào pattern lớn hơn — bổ ngữ là\n// optional nên prefix vẫn khớp dạng trần \"cạnh BC\".\nexport const SIDE_PREFIX = '(?:cạnh(?:\\\\s+huyền)?\\\\s+|đoạn(?:\\\\s+thẳng)?\\\\s+)?';\n\n/** \"đường\" và typo \"đương\" (thiếu dấu huyền). */\nexport const DUONG_KW = '[Đđ]ư[ờơ]ng';\n\n/** \"đường tròn\" và typo \"đương tròn\". */\nexport const CIRCLE_KW = DUONG_KW + '\\\\s*tròn';\n\n/**\n * Kiểm tra tên có phải là nhãn điểm (tâm) hay không.\n * Thỏa mãn: 1 chữ HOA + tuỳ chọn dấu phẩy/số (vd: O, O', O1).\n */\nexport function isCenterName(name: string): boolean {\n return /^[A-Z]['′]?\\d*$/u.test(name);\n}\n","// src/stamps/geometry-2d/ai/rules/triangle.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { drawShape, addPoint, drawCircle, markShape } from './_shared';\n\n// MULTI-MATCH: 1 clause có thể chứa NHIỀU tam giác (\"tam giác ABC và tam giác\n// ABD vuông tại A\", \"tam giác đều DEF nội tiếp tam giác ABC\"). Bắt MỌI tam giác\n// (cờ 'g'), variant bind từ TEXT WINDOW giữa tam giác này và tam giác KẾ — KHÔNG\n// vơ chữ \"đều\"/\"vuông tại X\" của tam giác khác.\n//\n// leadMod = từ bổ nghĩa ĐỨNG TRƯỚC bộ 3 đỉnh (\"tam giác đều DEF\", \"tam giác\n// vuông ABC\", \"tam giác cân ABC\"). leadMod \"đều\" → equilateral ngay; \"vuông\"/\n// \"cân\" leadMod (không có \"tại X\") không đủ thông tin chọn đỉnh → để window xử lý.\nconst TRI_G = /tam giác\\s+(?:(đều|vuông|cân)\\s+)?([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\nconst RIGHT_AT = /vuông\\s+tại\\s+([A-Z])(?![A-Za-z])/u;\nconst ISO_AT = /cân\\s+tại\\s+([A-Z])(?![A-Za-z])/u;\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Dùng lookaround \\p{L} để chặn match giữa từ dài hơn.\nconst EQUILATERAL = /(?<!\\p{L})đều(?!\\p{L})/u;\n\n// === EN patterns (issue #46 group B) ========================================\n// MULTI-MATCH như VN: cờ 'g'. leadMod ĐỨNG TRƯỚC \"triangle\" (mirror \"tam giác đều\n// DEF\"): \"equilateral triangle ABC\", \"right triangle ABC\", \"isosceles triangle\n// ABC\". First-letter case flexibility ([Tt], [Ee]…) — KHÔNG cờ 'i' (sẽ phá [A-Z]\n// nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]).\nconst TRI_EN_G =\n /(?:([Ee]quilateral|[Rr]ight-angled|[Rr]ight|[Ii]sosceles)\\s+)?[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n// Window modifiers (đứng SAU nhãn): \"right angle at A\" / \"right-angled at A\".\nconst RIGHT_AT_EN = /[Rr]ight(?:\\s+angle|-angled)\\s+at\\s+([A-Z])(?![A-Za-z])/u;\n// \"with apex A\" / \"apex at A\" / \"apex A\". CHỈ nhận khi ngữ cảnh cân (isosceles).\nconst APEX_AT_EN = /apex\\s+(?:at\\s+)?([A-Z])(?![A-Za-z])/u;\n// \"... is equilateral\" / \"equilateral triangle …\" trong window riêng tam giác này.\nconst EQUILATERAL_EN = /(?<![A-Za-z])[Ee]quilateral(?![A-Za-z])/u;\nconst ISOSCELES_EN = /(?<![A-Za-z])[Ii]sosceles(?![A-Za-z])/u;\n\n/** Chuẩn hoá leadMod EN về token canonical: 'equilateral'|'right'|'isosceles'. */\nfunction normLeadEn(lead: string | undefined): string | undefined {\n if (!lead) return undefined;\n const l = lead.toLowerCase();\n if (l === 'equilateral') return 'equilateral';\n if (l === 'right' || l === 'right-angled') return 'right';\n if (l === 'isosceles') return 'isosceles';\n return undefined;\n}\n\ninterface TriHit {\n labels: string[];\n /** leadMod đứng ngay trước bộ 3 đỉnh, hoặc undefined. */\n lead?: string;\n /** ngôn ngữ của hit — quyết định dùng window VN hay EN khi suy variant. */\n lang: 'vi' | 'en';\n /** offset bắt đầu match (để sắp xếp + tính window theo thứ tự text). */\n start: number;\n /** vị trí ngay sau match (đầu window). */\n end: number;\n}\n\n/**\n * Suy variant cho 1 tam giác từ: leadMod (\"tam giác đều DEF\") + WINDOW text\n * (đoạn từ ngay sau bộ 3 đỉnh tới đầu tam giác kế / hết clause). \"vuông tại X\" /\n * \"cân tại X\" CHỈ áp nếu X ∈ labels của tam giác NÀY (tránh bind nhầm sang tam\n * giác khác cùng clause). Quy ước enum (xem TriangleVariantZ): cân tại A ⇒\n * isoceles-BC (đáy CYCLIC: apex A→BC, B→CA, C→AB); vuông tại A ⇒ right-at-A.\n */\n// Variant enum là POSITIONAL theo INDEX đỉnh đặc biệt trong labels (builder\n// triangleCanonical: isoceles-BC ⇒ apex = vertex[0], right-at-A ⇒ vertex[0]\n// vuông). KHÔNG dùng chữ-cái-nhãn: tam giác [A,C,D] \"cân tại A\" (apex idx 0) →\n// isoceles-BC (positional), KHÔNG phải \"isoceles-CD\". Với nhãn ABC chuẩn,\n// positional trùng label nên tương thích ngược.\nconst RIGHT_BY_IDX = ['right-at-A', 'right-at-B', 'right-at-C'];\nconst ISO_BY_IDX = ['isoceles-BC', 'isoceles-CA', 'isoceles-AB'];\n\n// === Thales: tam giác VUÔNG nội tiếp đường tròn → đường kính + glider ===========\n// Vuông tại A nội tiếp (O) ⟺ BC là ĐƯỜNG KÍNH (góc nội tiếp chắn nửa đường tròn).\n// Dựng RÀNG BUỘC (kéo vẫn vuông): 2 đầu mút đường kính free + tâm O = trung điểm +\n// đường tròn centerThrough (bán kính theo đầu mút) + apex là glider onCircle.\n// → góc vuông tại apex luôn đúng; AB<AC chọn bằng vị trí đầu mút cạnh ngắn (bên trái).\n//\n// CHỈ kích hoạt khi tam giác VUÔNG + có ngữ cảnh \"nội tiếp đường tròn/(O)\" SAU nhãn\n// (window). \"đường tròn nội tiếp tam giác\" (incircle) đứng TRƯỚC nhãn → KHÔNG ở\n// trong window → không kích hoạt (đúng: incircle không liên quan góc vuông).\nconst THALES_R = 4;\nconst THALES_THETA = 2.3; // ~131° (góc phần tư II) → apex gần đầu mút TRÁI = cạnh ngắn\n\n// \"nội tiếp (trong)? (đường tròn (O)/tâm O)? | (O)\" — circumcircle tam giác inscribed.\nconst TRI_INSCRIBED =\n /nội\\s*tiếp\\s+(?:trong\\s+)?(?:đường\\s*tròn\\s*(?:\\(\\s*([A-Z])\\s*\\)|tâm\\s+([A-Z]))?|\\(\\s*([A-Z])\\s*\\))/u;\n// Bất đẳng thức cạnh \"AB < AC\" / \"AC > AB\" (2 cạnh chia sẻ đỉnh vuông).\nconst INEQ = /([A-Z])([A-Z])\\s*([<>])\\s*([A-Z])([A-Z])/u;\n\n/** Tên đường tròn ngoại tiếp từ window; undefined nếu không có \"nội tiếp …\". */\nfunction inscribedCircleName(window: string): string | undefined {\n const m = TRI_INSCRIBED.exec(window);\n if (!m) return undefined;\n return m[1] ?? m[2] ?? m[3] ?? ''; // '' → caller default 'O'\n}\n\n/** Đầu mút (≠ apex) của cạnh NGẮN hơn theo \"AB < AC\"; default others[0]. */\nfunction shorterLegEnd(window: string, apex: string, others: string[]): string {\n const m = INEQ.exec(window);\n if (m) {\n const op = m[3];\n const o1 = m[1] === apex ? m[2] : m[2] === apex ? m[1] : undefined; // cạnh 1 (≠apex)\n const o2 = m[4] === apex ? m[5] : m[5] === apex ? m[4] : undefined; // cạnh 2 (≠apex)\n if (o1 && o2 && others.includes(o1) && others.includes(o2)) {\n return op === '<' ? o1 : o2; // '<' → cạnh 1 ngắn; '>' → cạnh 2 ngắn\n }\n }\n return others[0];\n}\n\n/**\n * Dựng Thales cho tam giác vuông (apex tại index `apexIdx`) nội tiếp đường tròn\n * `circleNameRaw`. Trả null nếu tên tâm đụng nhãn đỉnh (fail-safe → drawShape).\n */\nfunction thalesIntents(\n labels: string[],\n apexIdx: number,\n circleNameRaw: string,\n window: string,\n): IntentT[] | null {\n const apex = labels[apexIdx];\n const others = labels.filter((_, i) => i !== apexIdx); // 2 đầu mút đường kính\n const cn = circleNameRaw || 'O';\n if (labels.includes(cn)) return null; // tên tâm trùng đỉnh → bỏ Thales (an toàn)\n const shortEnd = shorterLegEnd(window, apex, others);\n const longEnd = others[0] === shortEnd ? others[1] : others[0];\n return [\n addPoint(shortEnd, { kind: 'free', at: [-THALES_R, 0] }), // cạnh ngắn: đầu mút TRÁI\n addPoint(longEnd, { kind: 'free', at: [THALES_R, 0] }),\n addPoint(cn, { kind: 'midpoint', of: shortEnd + longEnd }), // tâm O = trung điểm đường kính\n drawCircle(cn, 'centerThrough', { center: cn, through: shortEnd }),\n addPoint(apex, { kind: 'onCircle', circle: cn, theta: THALES_THETA }), // apex glider (gần TRÁI)\n markShape('triangle', labels),\n ];\n}\n\nfunction variantFor(hit: TriHit, window: string): string {\n return hit.lang === 'en' ? variantForEn(hit, window) : variantForVi(hit, window);\n}\n\nfunction variantForVi(hit: TriHit, window: string): string {\n const { labels, lead } = hit;\n // \"tam giác đều DEF\" hoặc chữ \"đều\" trong window riêng của tam giác này.\n if (lead === 'đều' || EQUILATERAL.test(window)) return 'equilateral';\n\n const ra = RIGHT_AT.exec(window);\n if (ra) {\n const i = labels.indexOf(ra[1]);\n if (i >= 0) return RIGHT_BY_IDX[i];\n }\n\n const iso = ISO_AT.exec(window);\n if (iso) {\n const i = labels.indexOf(iso[1]);\n if (i >= 0) return ISO_BY_IDX[i];\n }\n\n return 'any';\n}\n\n/**\n * EN variant — mirror VN POSITIONAL semantics. leadMod canonical ('equilateral'/\n * 'right'/'isosceles') + WINDOW riêng tam giác này. \"right triangle ABC\" KHÔNG có\n * \"right angle at X\" → 'any' (đủ thông tin loại nhưng không biết đỉnh, fail-safe\n * như VN \"tam giác vuông ABC\"). \"isosceles\" không \"apex X\" → 'any'. apex/right-at\n * CHỈ áp nếu đỉnh ∈ labels (tránh bind nhầm / đỉnh ngoài tam giác).\n */\nfunction variantForEn(hit: TriHit, window: string): string {\n const { labels, lead } = hit;\n if (lead === 'equilateral' || EQUILATERAL_EN.test(window)) return 'equilateral';\n\n // \"right angle at A\" / \"right-angled at A\" → positional. CHỈ trong window\n // (không vơ modifier của tam giác kế).\n const ra = RIGHT_AT_EN.exec(window);\n if (ra) {\n const i = labels.indexOf(ra[1]);\n if (i >= 0) return RIGHT_BY_IDX[i];\n }\n\n // Apex CHỈ có nghĩa trong ngữ cảnh cân: leadMod 'isosceles' HOẶC từ \"isosceles\"\n // trong window. \"with apex A\" → isoceles theo INDEX của A trong labels.\n const isoCtx = lead === 'isosceles' || ISOSCELES_EN.test(window);\n if (isoCtx) {\n const ap = APEX_AT_EN.exec(window);\n if (ap) {\n const i = labels.indexOf(ap[1]);\n if (i >= 0) return ISO_BY_IDX[i];\n }\n }\n\n return 'any';\n}\n\n/**\n * \"tam giác ABC\" / \"triangle ABC\" → draw-shape triangle. NHIỀU tam giác / clause\n * → emit-all (mỗi tam giác 1 intent), variant bind theo cú pháp gần (leadMod +\n * window) để KHÔNG mis-render (vd không gán \"đều\"/\"equilateral\" của DEF cho ABC).\n *\n * EN ADDITIVE (issue #46 group B): quét THÊM TRI_EN_G. Hit VN+EN gom chung, sắp\n * theo vị trí TEXT; window mỗi hit = từ sau nhãn tới START của hit KẾ (modifier\n * tiền-vị của tam giác kế KHÔNG lọt vào window hit hiện tại). VN behavior giữ\n * nguyên: với chỉ-VN, start hit kế = vị trí \"tam giác\" kế ≡ logic indexOf cũ.\n */\nexport const triangleRule: LanguageRule = {\n id: 'triangle',\n priority: 100,\n languages: ['vi', 'en'],\n patterns: [TRI_G, TRI_EN_G],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const hits: TriHit[] = [];\n\n TRI_G.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(c.text)) !== null) {\n hits.push({\n lead: m[1],\n lang: 'vi',\n labels: [m[2], m[3], m[4]],\n start: m.index,\n end: m.index + m[0].length,\n });\n }\n\n TRI_EN_G.lastIndex = 0;\n while ((m = TRI_EN_G.exec(c.text)) !== null) {\n hits.push({\n lead: normLeadEn(m[1]),\n lang: 'en',\n labels: [m[2], m[3], m[4]],\n start: m.index,\n end: m.index + m[0].length,\n });\n }\n\n if (hits.length === 0) continue;\n\n // Sắp theo vị trí TEXT để window mỗi hit kết thúc ở START hit kế (gồm cả\n // modifier tiền-vị của hit kế) → không leak modifier giữa các tam giác.\n hits.sort((a, b) => a.start - b.start);\n\n const intents = hits.flatMap((hit, idx) => {\n const next = hits[idx + 1];\n const windowEnd = next ? next.start : c.text.length;\n const window = c.text.slice(hit.end, windowEnd);\n const variant = variantFor(hit, window);\n // Thales: tam giác VUÔNG + nội tiếp đường tròn (window) → dựng ràng buộc\n // (đường kính + apex glider) thay draw-shape free (free chỉ \"may mắn\" vuông,\n // kéo là vỡ + không thoả AB<AC). circle3 của circleTriangle bị idempotent\n // loại (cùng tên → centerThrough của triangle prio 100 thắng).\n const rightIdx = RIGHT_BY_IDX.indexOf(variant);\n if (rightIdx >= 0) {\n const circleName = inscribedCircleName(window);\n if (circleName !== undefined) {\n const thales = thalesIntents(hit.labels, rightIdx, circleName, window);\n if (thales) return thales;\n }\n }\n return [drawShape('triangle', hit.labels, variant)];\n });\n\n out.push({ ruleId: 'triangle', clauseIds: [c.id], intents });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/quad.ts\n//\n// Tứ giác / đa giác 4 đỉnh: hình vuông, chữ nhật, bình hành, thoi, thang\n// (cân/vuông/thường), tứ giác chung. Mỗi loại trích 4 ký tự HOA liền sau tên\n// hình → draw-shape với shape + variant tương ứng.\nimport type { LanguageRule, RuleContext, RuleMatch } from './_types';\nimport { drawShape, drawCircle, addPoint, markShape } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Dùng lookaround \\p{L} (cờ 'u') ở prefilter để chặn biên từ.\n// 4 đỉnh = ĐÚNG 4 ký tự HOA liền nhau (vd \"ABCD\") neo ngay sau tên hình; neo\n// biên cuối (?![A-Z]) để 5+ đỉnh (\"ABCDE\") KHÔNG match → escalate qua guard.\nconst QUAD = '([A-Z])([A-Z])([A-Z])([A-Z])(?![A-Z])';\n\n// Mỗi entry: regex tên hình (đã neo trước 4 đỉnh) → shape + variant.\n// CỜ 'g' để matchAll quét MỌI khai báo hình trong cùng một clause (vd \"hình\n// bình hành ABCD và hình chữ nhật EFGH\" → 2 shape, theo thứ tự TEXT).\n// Thứ tự QUAN TRỌNG: loại cụ thể (hình thang cân/vuông) phải đứng TRƯỚC loại\n// chung (hình thang), và mọi \"hình ...\" phải đứng trước \"tứ giác\" chung — vì\n// engine consume vùng text đã match nên loại cụ thể giành quyền trước.\ninterface QuadKind {\n name: RegExp;\n shape: string;\n variant: string;\n}\n\nconst KINDS: QuadKind[] = [\n // hình thang cân / vuông (modifier TRƯỚC đỉnh) — phải match trước thang chung\n {\n name: new RegExp('hình\\\\s+thang\\\\s+cân\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'isoceles',\n },\n {\n name: new RegExp('hình\\\\s+thang\\\\s+vuông\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'right',\n },\n // hình thang chung — sau đó dò modifier 'vuông'/'cân' đứng SAU đỉnh\n // (\"hình thang ABCD vuông tại A\" → right; \"...cân\" → isoceles).\n {\n name: new RegExp('hình\\\\s+thang\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'general',\n },\n {\n name: new RegExp('hình\\\\s+vuông\\\\s+' + QUAD, 'gu'),\n shape: 'square',\n variant: 'standard',\n },\n {\n name: new RegExp('hình\\\\s+chữ\\\\s+nhật\\\\s+' + QUAD, 'gu'),\n shape: 'rectangle',\n variant: 'wide',\n },\n {\n name: new RegExp('hình\\\\s+bình\\\\s+hành\\\\s+' + QUAD, 'gu'),\n shape: 'parallelogram',\n variant: 'standard',\n },\n {\n name: new RegExp('hình\\\\s+thoi\\\\s+' + QUAD, 'gu'),\n shape: 'rhombus',\n variant: 'standard',\n },\n {\n name: new RegExp('tứ\\\\s+giác(?:\\\\s+lồi)?\\\\s+' + QUAD, 'gu'),\n shape: 'quadrilateral',\n variant: 'any',\n },\n\n // === EN names (issue #46 group B) — same shape/variant mapping as VN ========\n // First-letter case flex ([Ss]quare…) — KHÔNG cờ 'i' (sẽ phá [A-Z] nhãn QUAD).\n // Modifier EN đứng TRƯỚC tên (\"isosceles trapezoid ABCD\") → entry riêng cho\n // isosceles/right trapezoid, đặt TRƯỚC trapezoid chung để giành quyền (overlaps).\n // KHÔNG có post-positional modifier EN trong slice này (chỉ pre-positional).\n {\n name: new RegExp('[Ii]sosceles\\\\s+(?:[Tt]rapezoid|[Tt]rapezium)\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'isoceles',\n },\n {\n name: new RegExp('[Rr]ight\\\\s+(?:[Tt]rapezoid|[Tt]rapezium)\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'right',\n },\n {\n name: new RegExp('(?:[Tt]rapezoid|[Tt]rapezium)\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'general',\n },\n {\n name: new RegExp('[Ss]quare\\\\s+' + QUAD, 'gu'),\n shape: 'square',\n variant: 'standard',\n },\n {\n name: new RegExp('[Rr]ectangle\\\\s+' + QUAD, 'gu'),\n shape: 'rectangle',\n variant: 'wide',\n },\n {\n name: new RegExp('[Pp]arallelogram\\\\s+' + QUAD, 'gu'),\n shape: 'parallelogram',\n variant: 'standard',\n },\n {\n name: new RegExp('[Rr]hombus\\\\s+' + QUAD, 'gu'),\n shape: 'rhombus',\n variant: 'standard',\n },\n {\n name: new RegExp('[Qq]uadrilateral\\\\s+' + QUAD, 'gu'),\n shape: 'quadrilateral',\n variant: 'any',\n },\n];\n\n// Prefilter toàn đề: bất kỳ tên hình 4 đỉnh nào (VN + EN).\nconst PREFILTER =\n /hình\\s+(?:vuông|chữ\\s+nhật|bình\\s+hành|thoi|thang)|tứ\\s+giác|[Ss]quare|[Rr]ectangle|[Pp]arallelogram|[Rr]hombus|[Tt]rapezoid|[Tt]rapezium|[Qq]uadrilateral/u;\n\n// \"hình thang ABCD vuông tại A\" / \"...cân ...\" — modifier đứng SAU đỉnh, ngay\n// sau cụm 4 đỉnh (cho phép xen khoảng trắng). Cờ 'u' bắt buộc cho ký tự Việt.\nconst RIGHT_AFTER = /vuông(?!\\p{L})/u;\nconst ISO_AFTER = /(?<!\\p{L})cân(?!\\p{L})/u;\n// Biên cắt tail: KHÔNG cho modifier \"vuông\"/\"cân\" của hình SAU (\"…và hình vuông\n// EFGH\") bị gán nhầm cho hình thang đứng trước → dừng tail ở khai báo hình kế.\nconst NEXT_SHAPE = /hình\\s|tứ\\s+giác/u;\n\ninterface Hit {\n index: number;\n shape: string;\n variant: string;\n labels: string[];\n /** offset ngay sau cụm 4 đỉnh, để dò modifier hậu vị cho hình thang chung. */\n afterEnd: number;\n}\n\n/**\n * Quét MỌI khai báo hình trong một clause. Mỗi vị trí ký tự chỉ thuộc một kind\n * (kind cụ thể giành trước nhờ thứ tự KINDS). Trả về danh sách hit đã sắp theo\n * vị trí TEXT để emit đúng thứ tự xuất hiện trong đề.\n */\nfunction scanClause(text: string): Hit[] {\n const claimed: Hit[] = [];\n const taken: Array<[number, number]> = []; // vùng [start,end) đã thuộc kind trước\n\n const overlaps = (start: number, end: number) =>\n taken.some(([s, e]) => start < e && end > s);\n\n for (const k of KINDS) {\n k.name.lastIndex = 0;\n for (const m of text.matchAll(k.name)) {\n const start = m.index ?? 0;\n const end = start + m[0].length;\n if (overlaps(start, end)) continue; // đã bị kind cụ thể hơn chiếm\n taken.push([start, end]);\n\n let variant = k.variant;\n // Hình thang chung: dò modifier hậu vị ngay sau 4 đỉnh (\"ABCD vuông tại A\").\n // Cắt tail tại khai báo hình kế tiếp để không nuốt modifier của hình sau.\n if (k.shape === 'trapezoid' && k.variant === 'general') {\n let tail = text.slice(end, end + 24);\n const next = NEXT_SHAPE.exec(tail);\n if (next) tail = tail.slice(0, next.index);\n if (RIGHT_AFTER.test(tail)) variant = 'right';\n else if (ISO_AFTER.test(tail)) variant = 'isoceles';\n }\n claimed.push({\n index: start,\n shape: k.shape,\n variant,\n labels: [m[1], m[2], m[3], m[4]],\n afterEnd: end,\n });\n }\n }\n\n claimed.sort((a, b) => a.index - b.index);\n return claimed;\n}\n\n// --- Tứ giác nội tiếp đường tròn (cyclic quadrilateral) — issue #46 nhóm C/B --\n//\n// \"Cho tứ giác ABCD nội tiếp đường tròn (O)\" hiện chỉ vẽ tứ giác, BỎ đường tròn\n// (render coverage-complete nhưng thiếu hình). Bổ sung đường tròn ngoại tiếp đi\n// qua đúng 4 đỉnh — đặt 4 đỉnh ĐỒNG VIÊN để circle3 thực sự đi qua cả 4.\n//\n// EN (nhóm B Tier 2, fix silent-incomplete): detectCyclic nay nhận thêm các dạng\n// tiếng Anh — Pattern A \"(is/are) inscribed in (a/the) circle (O)\", Pattern B\n// \"circle (O) circumscribes/(is) circumscribed (about/around) ...\". Trước đây đề\n// EN render quad-ONLY (rớt circle âm thầm); nay parity VN (quad concyclic +\n// through3). TRIANGLE_DECL cũng nhận \"Triangle ABC\" để fail-safe ownedByOthers\n// chặn silent-wrong khi tứ giác EN chia đỉnh với tam giác EN.\n//\n// KIẾN TRÚC single-emitter: quadRule LÀ emitter DUY NHẤT của hình tứ giác. Khi\n// phát hiện ngữ cảnh nội tiếp, CHÍNH rule này emit (circle + 4 glider + polygon)\n// — KHÔNG dùng draw-shape (vốn tạo đỉnh FREE) cho nhánh nội tiếp.\n//\n// FIX 2026-06-09 (bug \"đỉnh D không trên đường tròn, kéo đường tròn D không theo\"):\n// trước đây nhánh nội tiếp emit draw-shape (4 đỉnh FREE ở toạ độ đồng viên TĨNH) +\n// circle3 qua 3 đỉnh → đỉnh thứ 4 chỉ TÌNH CỜ nằm trên circle, KHÔNG ràng buộc →\n// kéo 1 trong 3 đỉnh kia (định nghĩa lại circle3) thì đỉnh 4 ở lại, rời đường tròn.\n// NAY: đường tròn centerRadius (tâm O hiện) + 4 đỉnh là glider `onCircle` (theta cố\n// định) → TẤT CẢ ràng buộc trên đường tròn; kéo tâm O cả 4 di chuyển theo, luôn\n// đồng viên. polygon nối 4 đỉnh qua mark-shape (không tạo coord mới).\n//\n// 4 đỉnh trên đường tròn bán kính 5 (đồng viên), góc theta cố định cho layout lồi\n// A→B→C→D (chiều kim đồng hồ), bảo toàn bố cục cũ.\nconst CYCLIC_QUAD_COORDS: readonly [number, number][] = [\n [-3, 4],\n [4, 3],\n [3, -4],\n [-4, -3],\n];\n// Bán kính + góc theta dẫn xuất TỪ toạ độ trên (đồng bộ layout): glider đặt tại\n// (cos θ, sin θ)·r quanh tâm → giữ đúng vị trí lồi như bản free cũ.\nconst CYCLIC_RADIUS = Math.hypot(CYCLIC_QUAD_COORDS[0][0], CYCLIC_QUAD_COORDS[0][1]);\nconst CYCLIC_QUAD_THETAS: readonly number[] = CYCLIC_QUAD_COORDS.map(([x, y]) =>\n Math.atan2(y, x),\n);\n\n// Tên tâm tuỳ chọn: \"(O)\" hoặc \"tâm O\" (mượn idiom của circleTriangle).\nconst CENTER = '(?:\\\\(\\\\s*([A-Z])\\\\s*\\\\)|tâm\\\\s+([A-Z]))?';\n\n// Pattern A — tứ giác nội tiếp đường tròn: \"ABCD nội tiếp (trong) đường tròn\n// (O)/tâm O\". Neo ^ vào phần text NGAY SAU 4 đỉnh (hit.afterEnd). Center group 1|2.\nconst QUAD_INSCRIBED_IN_CIRCLE = new RegExp(\n '^[\\\\s,]*(?:nội\\\\s*tiếp\\\\s+(?:trong\\\\s+)?(?:một\\\\s+)?đường\\\\s*tròn|(?:is\\\\s+|are\\\\s+)?inscribed\\\\s+in\\\\s+(?:a\\\\s+|the\\\\s+)?circle)\\\\s*' +\n CENTER,\n 'iu',\n);\n\n// Pattern B — đường tròn ngoại tiếp tứ giác: \"đường tròn (O)/tâm O ngoại tiếp\"\n// đứng NGAY TRƯỚC \"tứ giác ABCD\". Neo $ vào phần text TRƯỚC hit.index. Center 1|2.\nconst CIRCLE_CIRCUMSCRIBES_QUAD = new RegExp(\n '(?:đường\\\\s*tròn|circle)\\\\s*' +\n CENTER +\n '\\\\s*(?:ngoại\\\\s*tiếp|(?:is\\\\s+|are\\\\s+)?circumscrib(?:es|ed)(?:\\\\s+(?:about|around))?)\\\\s+$',\n 'iu',\n);\n\n// Khai báo tam giác bất kỳ trong đề — 3 đỉnh HOA của nó \"thuộc\" tam giác (không\n// được dời sang toạ độ đồng viên của tứ giác). Cờ 'g' để quét mọi khai báo.\nconst TRIANGLE_DECL = /(?:tam\\s*giác|[Tt]riangle)\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n\n/**\n * Tập ký tự đỉnh \"thuộc về hình khác\" trong TOÀN đề: mọi đỉnh tam giác + đỉnh\n * của mọi tứ giác hit KHÁC (chuỗi nhãn khác hit hiện tại). Nếu 4 đỉnh của tứ\n * giác này giao tập đó → KHÔNG áp dụng đồng viên (đặt chúng theo CYCLIC_QUAD\n * sẽ phá toạ độ đã có của hình kia → silent-wrong).\n */\nfunction ownedByOthers(ctx: RuleContext, selfLabels: string[]): Set<string> {\n const owned = new Set<string>();\n TRIANGLE_DECL.lastIndex = 0;\n for (const m of ctx.problem.matchAll(TRIANGLE_DECL)) {\n owned.add(m[1]);\n owned.add(m[2]);\n owned.add(m[3]);\n }\n const selfKey = selfLabels.join('');\n for (const c of ctx.clauses) {\n for (const h of scanClause(c.text)) {\n if (h.labels.join('') === selfKey) continue; // chính tứ giác này\n for (const lbl of h.labels) owned.add(lbl);\n }\n }\n return owned;\n}\n\n/**\n * Phát hiện ngữ cảnh nội tiếp cho 1 hit tứ giác chung trong clause `text`.\n * Trả tên tâm (hoặc '') nếu khớp Pattern A/B; undefined nếu không nội tiếp.\n */\nfunction detectCyclic(text: string, hit: Hit): string | undefined {\n // Pattern A: phần text NGAY SAU 4 đỉnh.\n const a = QUAD_INSCRIBED_IN_CIRCLE.exec(text.slice(hit.afterEnd));\n if (a) return a[1] ?? a[2] ?? '';\n // Pattern B: phần text TRƯỚC \"tứ giác\" (hit.index = đầu \"tứ giác\").\n const b = CIRCLE_CIRCUMSCRIBES_QUAD.exec(text.slice(0, hit.index));\n if (b) return b[1] ?? b[2] ?? '';\n return undefined;\n}\n\n/**\n * Tứ giác / đa giác 4 đỉnh → draw-shape. Duyệt từng clause, quét EMIT-ALL mọi\n * khai báo hình (theo thứ tự text). KHÔNG trích được ĐÚNG 4 đỉnh HOA liền (vd\n * \"ABCDE\" 5 đỉnh) → bỏ qua khai báo đó (escalate AI qua guard).\n *\n * Tứ giác CHUNG (shape 'quadrilateral') có ngữ cảnh nội tiếp đường tròn → emit\n * THÊM draw-circle (through3) + đặt 4 đỉnh đồng viên qua explicitCoords. Hình\n * có tên (vuông/chữ nhật/...) NGOÀI phạm vi increment này (giữ hành vi cũ).\n *\n * GIỚI HẠN ĐÃ BIẾT (defer, không sửa): nếu CÙNG nhãn tứ giác được khai báo ở\n * HAI clause (vd \"Cho tứ giác ABCD. Đường tròn ngoại tiếp tứ giác ABCD\") — một\n * plain + một cyclic — cả hai draw-shape sống sót qua JSON dedup (explicitCoords\n * khác nhau) → polygon trùng \"ABCD2\" chồng lên nhau. Hiếm gặp + lành tính\n * (polygon trùng khít, không sai hình học). Test/probe để 1-clause để né.\n */\nexport const quadRule: LanguageRule = {\n id: 'quad',\n priority: 100,\n languages: ['vi', 'en'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n for (const hit of scanClause(c.text)) {\n let intents = [drawShape(hit.shape, hit.labels, hit.variant)];\n // Chỉ tứ giác CHUNG: thử phát hiện đường tròn ngoại tiếp.\n if (hit.shape === 'quadrilateral') {\n const center = detectCyclic(c.text, hit);\n if (center !== undefined) {\n // Fail-safe: đỉnh dùng chung với hình khác → giữ quad-only.\n const owned = ownedByOthers(ctx, hit.labels);\n const shared = hit.labels.some((lbl) => owned.has(lbl));\n if (!shared) {\n const centerName = center || 'O';\n // Đường tròn centerRadius (tâm `centerName`) — resolveCircleNames sẽ\n // inject point tâm + rename circle khi name trùng center (\"(O)\"=tâm O).\n // 4 đỉnh = glider onCircle (theta cố định, layout lồi) → CONSTRAINED.\n // polygon nối 4 đỉnh qua mark-shape (đỉnh đã có, không tạo coord mới).\n // Thứ tự: circle TRƯỚC (glider ref nó), rồi 4 glider, rồi polygon.\n intents = [\n drawCircle(centerName, 'centerRadius', {\n center: centerName,\n radius: CYCLIC_RADIUS,\n }),\n ...hit.labels.map((lbl, i) =>\n addPoint(lbl, { kind: 'onCircle', circle: centerName, theta: CYCLIC_QUAD_THETAS[i] }),\n ),\n markShape(hit.shape, hit.labels),\n ];\n }\n }\n }\n out.push({\n ruleId: 'quad',\n clauseIds: [c.id],\n intents,\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/connect.ts\n//\n// Construct 'connect': vẽ đoạn / đường thẳng / tia giữa 2 đỉnh có tên.\n// BẢO THỦ (priority thấp 40): chỉ claim clause khi có TỪ KHOÁ vẽ rõ ràng\n// (đoạn | cạnh | nối | kẻ | đường thẳng | tia) đi kèm cặp 2 ký tự HOA.\n// KHÔNG khớp \"tam giác ABC\" (3 ký tự liền) hay tên đường 1 ký tự (\"đường d\").\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { connect } from './_shared';\nimport type { IntentT } from '../intent';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Dùng lookaround \\p{L}; cờ 'u' bắt buộc cho mọi regex Việt.\n// Cặp đỉnh = 2 ký tự HOA liền; (?![A-Z]) chặn \"ABC\" (tam giác) khỏi bị bắt.\n\n// LƯU Ý case: KHÔNG dùng cờ 'i' (nó khiến [A-Z] khớp chữ thường → \"đoạn THẳng\"\n// bắt \"th\" làm cặp T,H rác, vỡ pipeline). Nhưng vẫn cần khớp keyword HOA đầu câu\n// (\"Kẻ\", \"Nối\", \"Đoạn\") → case-insensitive CHỈ ở ký tự đầu keyword bằng [Xx].\n// Vertices LUÔN strict [A-Z].\n// \"đường thẳng AB\" → line. \"đường thẳng\" phải đứng trước cặp.\nconst LINE_KW = /[Đđ]ường\\s*thẳng\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"tia AB\" → ray. Không bắt \"tia phân giác\", \"tia đối\" (theo sau là chữ thường).\nconst RAY_KW = /(?<!\\p{L})[Tt]ia\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"tia đối của tia XY\": cụm tia ĐỐI — match \"tia XY\" bên trong KHÔNG được emit ray\n// naive X→Y vì điểm mới nằm trên tia NGƯỢC hướng (gốc X, đi xa Y). Vẽ ray X→Y\n// sẽ minh hoạ SAI hướng (tia gốc thay vì tia đối). pointAtDistance đã dựng điểm\n// mới đúng trên tia đối; connect suppress để tránh ray double/sai hướng.\n// Kiểm tra text NGAY TRƯỚC vị trí match \"tia\": kết thúc bằng \"đối của \" (≥0 space).\nconst TIA_DOI_BEFORE = /tia\\s*đối\\s+của\\s+$/u;\n// \"nối A với/và B\" → segment. Tên 1 ký tự, không phải cặp.\nconst NOI_KW = /(?<!\\p{L})[Nn]ối\\s+([A-Z])\\s+(?:với|và)\\s+([A-Z])(?![A-Za-z])/gu;\n// \"đoạn (thẳng) AB\" | \"cạnh AB\" | \"kẻ AB\" → segment.\nconst SEG_KW =\n /(?<!\\p{L})(?:[Đđ]oạn(?:\\s*thẳng)?|[Cc]ạnh|[Kk]ẻ)\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n\n// ============ EN connect forms (issue #46 nhóm B) ============================\n// connect.ts vốn VN-only. Mirror các form VN sang EN, GIỮ NGUYÊN parity ở gate\n// vocab: VN \"đoạn\" LÀ keyword → EN \"segment\" cũng vào vocab (standalone render).\n// VN \"đường thẳng\"/\"tia\"/\"nối\"/\"kẻ\" KHÔNG phải keyword → EN \"line\"/\"ray\"/\"connect\"/\n// \"join\"/\"draw\" cũng KHÔNG vào vocab → chỉ render IN-CONTEXT (vd có tam giác), đề\n// standalone → escalate (geoClauses=0). Đối xứng VN/EN tuyệt đối + tôn trọng\n// do-not-add list (\"line\" đã bị cấm trong vocabulary.ts).\n//\n// runDeterministicIntents dedup intent theo JSON.stringify CROSS-RULE → \"Draw AH\n// perpendicular to BC\" khớp CẢ perpFoot (emit connect(A,H,'segment')) lẫn DRAW_PAIR_EN\n// (cũng connect(A,H,'segment')) → IDENTICAL → deduped, vô hại.\n\n// \"segment XY\" → segment (đối VN \"đoạn\"). Group 1,2 = cặp HOA.\nconst SEG_NOUN_EN = /(?<![A-Za-z])[Ss]egment\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"line XY\" → line (đối VN \"đường thẳng\").\nconst LINE_NOUN_EN = /(?<![A-Za-z])[Ll]ine\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// Guard cho segment/line noun: BỎ match nếu cặp thuộc clause của rule prio cao\n// hơn đã SỞ HỮU cặp: perpBisector (\"(perpendicular) bisector (segment|line) PAIR\")\n// / perpFoot (\"perpendicular to (line|segment) PAIR\") / pointAtDistance (\"Extend(ed)\n// segment|line XY beyond …\"). 3 rule đó emit cặp đúng style HOẶC dựng điểm phái sinh;\n// connect KHÔNG được double-emit segment/line trần — đặc biệt với pointAtDistance:\n// clause malformed (thiếu distance / sai hướng) → pointAtDistance KHÔNG emit → clause\n// cần ESCALATE; connect claim sẽ MASK escalate đó (silent-incomplete, bỏ điểm mới).\n// Case flex [Bb]/[Pp]/[Ee] (BẮT BUỘC: HOA đầu clause không được slip — bài học batch16).\nconst NOUN_OWNED_BEFORE_EN = /(?:[Bb]isector|[Pp]erpendicular\\s+to|[Ee]xtend(?:ed)?)\\s+$/u;\n// \"ray XY\" → ray (đối VN \"tia\"). 2 guard:\n// (a) preceding \"opposite ray of ray XY\" (OPPOSITE_RAY_BEFORE_EN): điểm mới nằm trên\n// tia ĐỐI → vẽ ray X→Y SAI hướng (EN mirror VN TIA_DOI_BEFORE, batch9 8ee33af).\n// (b) trailing \"(?!\\s*,?\\s*extended)\": \"ray XY extended beyond Z\" là construct CỦA\n// pointAtDistance (RAY_EXTENDED_EN). connect KHÔNG claim — nếu malformed (thiếu\n// distance / Z≠Y sai hướng) pointAtDistance escalate fail-safe; connect claim sẽ\n// MASK (silent-incomplete bỏ điểm D). Well-formed thì pointAtDistance đã lo điểm\n// D — connect đứng ngoài để giữ EN-cũ (batch15) byte-identical.\n// \"Draw ray AB\" trần (không \"extended\"/không \"opposite ray of\") → vẫn vẽ ray A→B.\nconst RAY_NOUN_EN = /(?<![A-Za-z])[Rr]ay\\s+([A-Z])([A-Z])(?![A-Za-z])(?!\\s*,?\\s*extended)/gu;\nconst OPPOSITE_RAY_BEFORE_EN = /opposite\\s+ray\\s+of\\s+$/u;\n// \"Connect/Join XY\" → segment (đối VN \"nối\", form cặp HOA).\nconst JOIN_PAIR_EN = /(?<![A-Za-z])(?:[Cc]onnect|[Jj]oin)\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"Connect/Join X and/to/with Y\" → segment (tên 1 ký tự, mirror VN NOI_KW).\nconst JOIN_AND_EN =\n /(?<![A-Za-z])(?:[Cc]onnect|[Jj]oin)\\s+([A-Z])\\s+(?:and|to|with)\\s+([A-Z])(?![A-Za-z])/gu;\n// \"Draw XY\" trần → segment (đối VN \"kẻ\"). perpFoot draw-form \"Draw AH perpendicular\n// to BC\" cũng khớp nhưng emit connect(A,H,'segment') IDENTICAL → deduped.\n// perpBisector/cevian/tangent draw-form có \"the\"/\"two\"/chữ thường sau \"Draw\" →\n// KHÔNG cặp HOA → KHÔNG match ở đây.\nconst DRAW_PAIR_EN = /(?<![A-Za-z])[Dd]raw\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n\nfunction collect(\n re: RegExp,\n text: string,\n style: string,\n used: Set<string>,\n out: IntentT[],\n // Guard tuỳ chọn: bỏ qua match nếu text NGAY TRƯỚC vị trí match khớp regex này\n // (vd \"tia đối của \" trước \"tia XY\" → không emit ray naive sai hướng).\n skipIfPrecededBy?: RegExp,\n): void {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n if (skipIfPrecededBy && skipIfPrecededBy.test(text.slice(0, m.index))) {\n continue;\n }\n const a = m[1].toUpperCase();\n const b = m[2].toUpperCase();\n // Dedup theo cặp đỉnh trong cùng clause: vẽ trùng AB nhiều lần vô nghĩa,\n // và tránh 2 từ khoá khác nhau cùng claim 1 cặp (vd \"đoạn AB\" + \"kẻ AB\").\n const key = `${a}${b}`;\n if (used.has(key)) continue;\n used.add(key);\n out.push(connect(a, b, style));\n }\n}\n\n/**\n * Mỗi clause khớp ≥1 từ khoá vẽ → push 1 RuleMatch (gom mọi cặp tìm được).\n * Nhiều cặp trong cùng clause ⇒ nhiều intent, cùng clauseId.\n * Priority 40: thấp để rule chuyên biệt (trung trực, phân giác…) claim trước.\n */\nexport const connectRule: LanguageRule = {\n id: 'connect',\n priority: 40,\n languages: ['vi', 'en'],\n patterns: [\n LINE_KW, RAY_KW, NOI_KW, SEG_KW,\n SEG_NOUN_EN, LINE_NOUN_EN, RAY_NOUN_EN, JOIN_PAIR_EN, JOIN_AND_EN, DRAW_PAIR_EN,\n ],\n match(ctx) {\n const result: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const intents: IntentT[] = [];\n // Dùng span-key để 1 vị trí không bị 2 từ khoá double-count, nhưng cho\n // phép nhiều cặp khác vị trí trong cùng clause.\n const used = new Set<string>();\n // Thứ tự quan trọng: \"đường thẳng AB\" phải claim trước SEG (chứa \"thẳng\"\n // KHÔNG match SEG vì SEG yêu cầu \"đoạn thẳng\"/\"cạnh\"/\"kẻ\", không \"đường\").\n collect(LINE_KW, c.text, 'line', used, intents);\n // RAY: suppress ray naive khi nằm trong cụm \"tia đối của tia XY\" (hướng tia\n // gốc X→Y sai so với điểm mới trên tia đối). pointAtDistance lo điểm mới.\n collect(RAY_KW, c.text, 'ray', used, intents, TIA_DOI_BEFORE);\n collect(NOI_KW, c.text, 'segment', used, intents);\n collect(SEG_KW, c.text, 'segment', used, intents);\n // EN forms (issue #46 nhóm B). `used` dedup cặp đã claim bởi form VN trong\n // cùng clause (clause trộn ngôn ngữ hiếm, nhưng an toàn). Thứ tự: noun trước,\n // verb sau; DRAW cuối (trần nhất).\n collect(SEG_NOUN_EN, c.text, 'segment', used, intents, NOUN_OWNED_BEFORE_EN);\n collect(LINE_NOUN_EN, c.text, 'line', used, intents, NOUN_OWNED_BEFORE_EN);\n collect(RAY_NOUN_EN, c.text, 'ray', used, intents, OPPOSITE_RAY_BEFORE_EN);\n collect(JOIN_PAIR_EN, c.text, 'segment', used, intents);\n collect(JOIN_AND_EN, c.text, 'segment', used, intents);\n collect(DRAW_PAIR_EN, c.text, 'segment', used, intents);\n if (intents.length > 0) {\n result.push({ ruleId: 'connect', clauseIds: [c.id], intents });\n }\n }\n return result;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/midpoint.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, pairFromToken, SIDE_PREFIX } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\n\n// Prefilter toàn đề. \"trung điểm\" KHÔNG khớp \"trung trực\" (an toàn, rule khác lo).\nconst MIDPOINT = /trung\\s*điểm/u;\n\n// Dạng A (GLOBAL): tên điểm ĐỨNG TRƯỚC \"(là) trung điểm (của (cạnh|đoạn)) <PAIR>\".\n// \"Gọi M là trung điểm BC\" | \"M là trung điểm của BC\" | \"M trung điểm cạnh BC\"\n// | \"M là trung điểm cạnh huyền BC\" | \"trung điểm đoạn thẳng AC\"\n// Tên = ký tự HOA NGAY TRƯỚC cụm trung điểm (cục bộ quanh match, KHÔNG quét intro).\nconst NAME_BEFORE_G = new RegExp(\n `([A-Z])(?:['′]?)\\\\s+(?:là\\\\s+|=\\\\s+)?trung\\\\s*điểm\\\\s+(?:của\\\\s+)?${SIDE_PREFIX}([A-Z])([A-Z])(?!\\\\p{L})`,\n 'gu',\n);\n\n// Dạng B (GLOBAL): tên điểm ĐỨNG SAU \"trung điểm <NAME> của (cạnh|đoạn) <PAIR>\".\n// \"trung điểm I của (cạnh huyền) AB\" | \"trung điểm I của đoạn thẳng BC\"\nconst NAME_AFTER_G = new RegExp(\n `trung\\\\s*điểm\\\\s+([A-Z])(?:['′]?)\\\\s+của\\\\s+${SIDE_PREFIX}([A-Z])([A-Z])(?!\\\\p{L})`,\n 'gu',\n);\n\n// Distributive \"lần lượt\": \"M, N (, P) lần lượt là trung điểm AB, AC (, BC)\" →\n// zip 1-1: M=mid(AB), N=mid(AC), P=mid(BC). group1 = blob tên (≥2, phẩy),\n// group2 = blob cặp đỉnh (≥2, phẩy). Số tên PHẢI bằng số cặp (else bỏ qua,\n// escalate — không đoán lệch). SIDE_PREFIX cho \"(các) cạnh/đoạn\" trước blob cặp.\nconst DISTRIB = new RegExp(\n `((?:[A-Z](?:['′]?)\\\\s*,\\\\s*)+[A-Z](?:['′]?))\\\\s+lần\\\\s*lượt\\\\s+(?:là\\\\s+)?(?:điểm\\\\s+)?trung\\\\s*điểm\\\\s+(?:của\\\\s+)?(?:các\\\\s+)?${SIDE_PREFIX}((?:[A-Z][A-Z]\\\\s*,\\\\s*)*(?:[A-Z][A-Z]\\\\s*,\\\\s*)?[A-Z][A-Z](?:\\\\s*và\\\\s*[A-Z][A-Z])?)`,\n 'u',\n);\n\n// Tách 1 token tên trong blob distributive → \"M\" / \"M'\" (prime normalize ′→').\nfunction nameToken(raw: string): string | undefined {\n const m = /^([A-Z])(['′]?)/u.exec(raw.trim());\n if (!m) return undefined;\n return m[2] ? `${m[1]}'` : m[1];\n}\n\n// === EN patterns (issue #46 group B) ========================================\n// Prefilter EN: \"midpoint\" (first-letter case flex [Mm], KHÔNG cờ 'i' — phá [A-Z]).\nconst MIDPOINT_EN = /[Mm]idpoint/u;\n// EN side/segment prefix tuỳ chọn TRƯỚC cặp đỉnh: \"segment BC\", \"side BC\".\nconst SIDE_PREFIX_EN = '(?:segment\\\\s+|side\\\\s+)?';\n\n// EN dạng A (GLOBAL): tên ĐỨNG TRƯỚC. \"M is the midpoint of BC\" | \"let M be the\n// midpoint of segment BC\". Tên = HOA NGAY TRƯỚC \"is/be the midpoint\" (cục bộ).\n// (?![A-Za-z]) neo cuối cặp đỉnh (chặn \"BCD\" 3 chữ → escalate-safe).\nconst NAME_BEFORE_EN_G = new RegExp(\n `([A-Z])(?:['′]?)\\\\s+(?:is|be)\\\\s+the\\\\s+midpoint\\\\s+of\\\\s+${SIDE_PREFIX_EN}([A-Z])([A-Z])(?![A-Za-z])`,\n 'gu',\n);\n\n// EN dạng B (GLOBAL): tên ĐỨNG SAU. \"midpoint M of BC\" | \"midpoint I of segment AB\".\nconst NAME_AFTER_EN_G = new RegExp(\n `[Mm]idpoint\\\\s+([A-Z])(?:['′]?)\\\\s+of\\\\s+${SIDE_PREFIX_EN}([A-Z])([A-Z])(?![A-Za-z])`,\n 'gu',\n);\n\n/**\n * \"Gọi M là trung điểm BC\" → add-point M {kind:'midpoint', of:'BC'}.\n *\n * GLOBAL: emit MỌI cụm \"trung điểm <PAIR>\" trong clause (vd \"M là trung điểm BC\n * và N là trung điểm AC\" → 2 add-point). Tên điểm bind THEO TỪNG MATCH cục bộ:\n * - dạng A: ký tự HOA NGAY TRƯỚC \"(là) trung điểm\" — KHÔNG quét lời dẫn\n * toàn clause (tránh \"Lấy điểm D, gọi M là trung điểm BC\" gán nhầm 'D').\n * - dạng B: ký tự HOA NGAY SAU \"trung điểm\" (\"trung điểm I của AB\").\n * Match nào không có tên cục bộ HOẶC cặp đỉnh không hợp lệ → BỎ QUA match đó\n * (escalate AI), không bịa tên.\n */\nexport const midpointRule: LanguageRule = {\n id: 'midpoint',\n priority: 50,\n languages: ['vi', 'en'],\n patterns: [MIDPOINT, MIDPOINT_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const hasVi = MIDPOINT.test(c.text);\n const hasEn = MIDPOINT_EN.test(c.text);\n if (!hasVi && !hasEn) continue;\n\n const emit = (name: string, pairToken: string, clauseId: number) => {\n const pair = pairFromToken(pairToken);\n if (!name || pair.length !== 2) return;\n out.push({\n ruleId: 'midpoint',\n clauseIds: [clauseId],\n intents: [addPoint(name, { kind: 'midpoint', of: pair.join('') })],\n });\n };\n\n if (hasVi) {\n // Distributive \"lần lượt\" ưu tiên: \"M, N lần lượt là trung điểm AB, AC\"\n // → M=mid(AB), N=mid(AC). Số tên = số cặp mới emit (else bỏ qua → escalate).\n const dm = DISTRIB.exec(c.text);\n if (dm) {\n const names = dm[1]\n .split(',')\n .map((s) => nameToken(s))\n .filter((x): x is string => !!x);\n const pairs = dm[2]\n .split(/\\s*,\\s*|\\s+và\\s+/u)\n .map((s) => s.trim())\n .filter(Boolean);\n if (names.length >= 2 && names.length === pairs.length) {\n for (let i = 0; i < names.length; i++) emit(names[i], pairs[i], c.id);\n continue; // clause đã xử lý bằng distributive — skip dạng A/B + EN\n }\n }\n\n // Theo dõi vị trí cụm \"trung điểm\" đã được dạng A claim, để dạng B không\n // nhân đôi cùng một occurrence.\n const consumed = new Set<number>();\n\n // Dạng A — tên đứng trước. Vị trí cụm \"trung điểm\" = chỉ số bắt đầu match\n // (gần đúng: match bắt đầu ở ký tự tên, \"trung điểm\" theo ngay sau).\n NAME_BEFORE_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_BEFORE_G)) {\n const tdIdx = c.text.indexOf('trung', m.index ?? 0);\n if (tdIdx >= 0) consumed.add(tdIdx);\n emit(m[1], m[2] + m[3], c.id);\n }\n\n // Dạng B — tên đứng sau \"trung điểm\". Bỏ qua occurrence đã được dạng A claim.\n NAME_AFTER_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_AFTER_G)) {\n const tdIdx = m.index ?? 0;\n if (consumed.has(tdIdx)) continue;\n emit(m[1], m[2] + m[3], c.id);\n }\n }\n\n // --- EN (issue #46 group B) — dạng A (name before) + B (name after) -----\n // EN dạng A khớp \"X is/be the midpoint of …\"; dạng B khớp \"midpoint X of …\".\n // 2 dạng không chồng (A cần \"is/be the\", B cần HOA ngay sau \"midpoint\") nên\n // KHÔNG cần consumed-set như VN.\n if (hasEn) {\n NAME_BEFORE_EN_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_BEFORE_EN_G)) {\n emit(m[1], m[2] + m[3], c.id);\n }\n NAME_AFTER_EN_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_AFTER_EN_G)) {\n emit(m[1], m[2] + m[3], c.id);\n }\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/perpBisector.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, pairFromToken } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Dùng lookaround \\p{L} (cờ 'u') thay cho \\b.\n//\n// \"(đường) trung trực (của) (đoạn|đoạn thẳng|cạnh) <PAIR>\"\n// \"đường trung trực của BC\" → connect('B','C','perpBisector')\n// \"trung trực AB\" → connect('A','B','perpBisector')\n// \"d là đường trung trực BC\" → connect('B','C','perpBisector') (tên 'd' bỏ qua;\n// connect không nhận name)\n//\n// Cụm nối giữa \"trung trực\" và cặp đỉnh: optional \"của\", \"đoạn\", \"đoạn thẳng\",\n// \"cạnh\" (lặp tự do). Cặp đỉnh = 2 ký tự HOA liền.\n// Cờ 'g' để bắt MỌI cụm \"trung trực <PAIR>\" trong 1 clause (vd \"trung trực BC\n// và trung trực CA\" → emit cả 2). Reset lastIndex trước mỗi clause.\nconst PERP_BISECTOR =\n /(?<!\\p{L})trung\\s*trực\\s+(?:(?:của|đoạn|đoạn\\s+thẳng|cạnh)\\s+)*([A-Z][A-Z])(?!\\p{L})/gu;\n\n// \"(đường) trung trực (của) PAIR1 cắt [đường thẳng|đoạn|cạnh|tia]? PAIR2 tại D\":\n// đường trung trực CỦA PAIR1 (line dựng) ∩ đường PAIR2 = điểm D.\n// \"Đường trung trực của BC cắt AB tại D\" → perpBisector(B,C) + D=giao(pb_BC, AB)\n// group1 = PAIR1 (đoạn lấy trung trực); group2 = PAIR2 (đường bị cắt); group3 = D.\n//\n// perpBisector là LINE dựng (không phải đoạn) nên KHÔNG dùng intersection rule\n// generic (vốn chỉ nhận cặp đỉnh): rule này tự đặt perpBisector + intersection ref\n// TÊN shape mà connect builder sinh ('pb_<PAIR1>', deterministic + dedup JSON nên\n// duy nhất). PAIR1/PAIR2 chia sẻ đỉnh là BÌNH THƯỜNG (pb là đường khác đoạn PAIR2).\nconst PERP_BIS_CUT =\n /(?<!\\p{L})[Tt]rung\\s*trực\\s+(?:(?:của|đoạn|đoạn\\s+thẳng|cạnh)\\s+)*([A-Z][A-Z])(?!\\p{L})\\s+cắt\\s+(?:đường\\s*thẳng\\s+|đoạn(?:\\s+thẳng)?\\s+|cạnh\\s+|tia\\s+)?([A-Z][A-Z])(?!\\p{L})\\s+tại\\s+([A-Z])(?!\\p{L})/gu;\n\n/** prefilter nhanh trên toàn đề. */\nconst PREFILTER = /trung\\s*trực/u;\n\n// === EN (issue #46 group B) ===\n// \"(the)? perpendicular bisector (of|the|segment|line|side)* PAIR\" → connect(P1,P2,'perpBisector').\n// First-letter flex [Pp] (KHÔNG cờ 'i'). Global để bắt nhiều cụm/clause như VN.\nconst PERP_BISECTOR_EN =\n /[Pp]erpendicular\\s+bisector\\s+(?:(?:of|the|segment|line|side)\\s+)*([A-Z][A-Z])(?!\\p{L})/gu;\nconst PERP_BISECTOR_EN_PRE = /[Pp]erpendicular\\s+bisector/u;\n\n/**\n * \"(đường) trung trực của <PAIR>\" → connect(P1, P2, 'perpBisector').\n *\n * GLOBAL: 1 clause có thể chứa nhiều cụm trung trực (\"trung trực BC và trung\n * trực CA\") → emit connect cho MỖI cặp. Lấy cặp đỉnh ngay sau mỗi \"trung trực\"\n * (bỏ qua \"của/đoạn/cạnh\" xen giữa). Cụm không trích được cặp đỉnh hợp lệ →\n * bỏ qua cụm đó (escalate AI, an toàn hơn đoán sai). Tên đường (vd \"d là …\")\n * không cần — connect không nhận name.\n */\nexport const perpBisectorRule: LanguageRule = {\n id: 'perpBisector',\n priority: 70,\n languages: ['vi', 'en'],\n patterns: [PREFILTER, PERP_BISECTOR_EN_PRE],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n PERP_BISECTOR.lastIndex = 0; // regex 'g' có state — reset mỗi clause\n for (const m of c.text.matchAll(PERP_BISECTOR)) {\n const pair = pairFromToken(m[1]);\n if (pair.length !== 2) continue; // không trích được cặp đỉnh → bỏ cụm\n out.push({\n ruleId: 'perpBisector',\n clauseIds: [c.id],\n intents: [connect(pair[0], pair[1], 'perpBisector')],\n });\n }\n\n // \"trung trực PAIR1 cắt PAIR2 tại D\" → perpBisector(PAIR1) + giao điểm D.\n // Emit connect(perpBisector) NGAY TRƯỚC intersection (cùng match) để shape\n // 'pb_<PAIR1>' tồn tại khi transpile resolve ref của intersection (connect\n // trùng với loop plain ở trên sẽ bị dedup JSON → an toàn).\n PERP_BIS_CUT.lastIndex = 0;\n for (const m of c.text.matchAll(PERP_BIS_CUT)) {\n const pb = pairFromToken(m[1]);\n const line = pairFromToken(m[2]);\n const d = m[3];\n if (pb.length !== 2 || line.length !== 2) continue;\n // Giao điểm phải là điểm MỚI: D không trùng đỉnh nào của 2 cặp.\n if (new Set([pb[0], pb[1], line[0], line[1]]).has(d)) continue;\n const pbName = `pb_${pb[0]}${pb[1]}`; // khớp connect builder uniqueShapeName('pb_BC')\n out.push({\n ruleId: 'perpBisector',\n clauseIds: [c.id],\n intents: [\n connect(pb[0], pb[1], 'perpBisector'),\n addPoint(d, { kind: 'intersection', of: [pbName, m[2]] }),\n ],\n });\n }\n\n // --- EN (issue #46 group B) — mirror VN: global, emit-all, escalate-safe ---\n PERP_BISECTOR_EN.lastIndex = 0;\n for (const m of c.text.matchAll(PERP_BISECTOR_EN)) {\n const pair = pairFromToken(m[1]);\n if (pair.length !== 2) continue;\n out.push({\n ruleId: 'perpBisector',\n clauseIds: [c.id],\n intents: [connect(pair[0], pair[1], 'perpBisector')],\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/cevian.ts\n//\n// Cevian (đường đồng quy từ đỉnh): đường cao / trung tuyến / phân giác.\n// Phrasing thực tế: tên cevian dạng VF = đỉnh + chân (vd \"đường cao AH\",\n// \"AM là trung tuyến\", \"vẽ phân giác AD\"). Cần triangle context (ctx.problem)\n// để suy ra cạnh đối diện đỉnh = 2 đỉnh còn lại.\n//\n// Mỗi cevian khớp → RuleMatch với 2 intent cùng clauseId:\n// - add-point (chân: perpFoot / midpoint / angleBisectorFoot)\n// - connect (đoạn cevian visible VF, style segment)\n//\n// Nguyên tắc fail-safe:\n// - 1 clause có thể chứa NHIỀU cevian (cùng/khác loại): dùng matchAll (cờ /g)\n// để emit ĐỦ, không chỉ match đầu tiên.\n// - foot trùng đỉnh tam giác (\"đường cao AB\" → foot=B) → SKIP (đừng tạo\n// add-point sẽ bị builder hạ về 'free' → fidelity guard escalate).\n// - 2 cevian KHÁC nhau cùng đặt 1 tên chân (vd \"đường cao AH\" + \"trung tuyến\n// BH\" — cùng tên H nhưng ràng buộc mâu thuẫn) → SKIP tất cả cevian mang tên\n// chân đó (không claim → coverage escalate). Thà escalate còn hơn dựng SAI.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect } from './_shared';\n\n// Tam giác từ toàn đề (cần để suy cạnh đối diện). LƯU Ý: \\b không khớp quanh\n// ký tự Việt → dùng class trực tiếp, có cờ 'u'.\nconst TRI = /tam\\s*giác(?:\\s+(?:vuông|cân|đều|nhọn|tù))?\\s+([A-Z])([A-Z])([A-Z])/u;\n\n// === EN (issue #46 group B) =================================================\n// Tam giác tiếng Anh: \"triangle ABC\" (first-letter case flex [Tt], KHÔNG cờ 'i'\n// — sẽ phá [A-Z] nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]). Adjective\n// \"right/isosceles/…\" chỉ đứng TRƯỚC \"triangle\" nên vẫn khớp (vd \"right triangle\n// ABC\"). Đề VN không chứa \"triangle\" và đề EN không chứa \"tam giác\" → VN\n// byte-identical.\nconst TRI_EN = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\n\n// Cevian type → patterns. Mỗi pattern capture đỉnh (g1) + chân (g2): 2 ký tự\n// HOA liền (vd \"AH\"). (?![A-Z]) chặn match nhầm vào cụm 3 ký tự (vd \"ABC\").\n// TẤT CẢ pattern dùng cờ /g để matchAll bắt MỌI cevian trong 1 clause.\ntype CevianType = 'altitude' | 'median' | 'bisector' | 'externalBisector';\n\n// LƯU Ý case: KHÔNG dùng cờ 'i' (làm [A-Z] khớp chữ thường → bắt rác). Nhưng\n// keyword có thể HOA ở đầu câu (\"Đường cao AH\", \"Trung tuyến AM\", \"Phân giác AD\")\n// → ký tự đầu keyword + verb dùng [Xx]; vertices LUÔN strict [A-Z].\nconst CEVIAN_PATTERNS: ReadonlyArray<{ type: CevianType; patterns: readonly RegExp[] }> = [\n {\n type: 'altitude',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Hh]ạ|[Dd]ựng)\\s+[Đđ]ường\\s*cao\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /[Đđ]ường\\s*cao\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?đường\\s*cao/gu,\n // EN (issue #46 group B). g1=apex g2=foot, nhãn strict [A-Z], NO cờ 'i'.\n // First-letter flex [Aa] (HOA đầu câu \"Altitude AH\"); KHÔNG cờ 'i' (phá nhãn).\n // forward \"altitude AH\" (lời dẫn \"Draw the \" phía trước bỏ qua). \"foot of\n // the altitude from A to BC\" KHÔNG khớp: sau \"altitude\" là \"from\" (chữ\n // thường), không cặp HOA → perpFoot.ts sở hữu.\n /[Aa]ltitude\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n // reverse \"AH is/be the altitude\". (?![A-Za-z]) chặn \"altitudes\"/nối chữ.\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:is|be)\\s+(?:the\\s+)?altitude(?![A-Za-z])/gu,\n ],\n },\n {\n type: 'median',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\s+[Tt]rung\\s*tuyến\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /[Tt]rung\\s*tuyến\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?trung\\s*tuyến/gu,\n // EN (issue #46 group B). g1=apex g2=foot. First-letter flex [Mm].\n /[Mm]edian\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:is|be)\\s+(?:the\\s+)?median(?![A-Za-z])/gu,\n ],\n },\n {\n // \"phân giác (trong) AD\": từ \"trong\" (phân giác TRONG = internal bisector,\n // loại thường) tuỳ chọn chen giữa \"phân giác\" và cặp đỉnh. \"phân giác NGOÀI\"\n // (external bisector) CHƯA hỗ trợ: forward tự reject (sau \"phân giác\" là chữ\n // thường \"ngoài\", không HOA pair); suffix cần (?!\\s+ngoài) để KHÔNG nhận nhầm\n // \"AD là phân giác ngoài\" thành internal → escalate (fail-safe).\n type: 'bisector',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\s+(?:[Đđ]ường\\s*|[Tt]ia\\s+)?phân\\s*giác(?:\\s+trong)?\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?:[Đđ]ường\\s*phân\\s*giác|[Tt]ia\\s+phân\\s*giác|[Pp]hân\\s*giác)(?:\\s+trong)?\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?(?:đường\\s*|tia\\s+)?phân\\s*giác(?:\\s+trong)?(?!\\s+ngoài)/gu,\n // EN (issue #46 group B) — internal bisector ONLY. g1=apex g2=foot.\n // forward \"(angle)? bisector AD\". 3 negative lookbehind:\n // (?<![Pp]erpendicular\\s) — \"perpendicular bisector AD\" thuộc perpBisector.ts\n // (EN regex của nó CŨNG khớp cặp HOA) → tránh double-emit.\n // (?<![Ee]xternal\\s)/(?<![Ee]xterior\\s) — external bisector EN DEFER → KHÔNG\n // nhận nhầm thành internal (silent-wrong).\n // Dạng \"of angle\"/\"angle bisector of\" (angleBisectorAngle.ts) tự loại: cần\n // cặp HOA NGAY sau \"bisector\", \"of\" chen vào sẽ phá khớp. First-letter flex\n // [Bb] (HOA đầu câu) — lookbehind PHẢI first-letter flex [Pp]/[Ee] để chặn cả\n // \"Perpendicular\"/\"External\" HOA đầu clause (else double-emit silent-wrong).\n /(?<![Pp]erpendicular\\s)(?<![Ee]xternal\\s)(?<![Ee]xterior\\s)(?:[Aa]ngle\\s+)?[Bb]isector\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n // reverse \"AD is/be the (angle)? bisector\". (?!\\s+of) chặn \"is the bisector\n // of …\" (thuộc angleBisectorAngle). \"the perpendicular/external bisector\"\n // tự loại: từ chen giữa \"the\" và \"bisector\" phá (?:angle\\s+)?bisector.\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:is|be)\\s+(?:the\\s+)?(?:angle\\s+)?bisector(?!\\s+of)(?![A-Za-z])/gu,\n ],\n },\n {\n // \"phân giác NGOÀI AD\" (external bisector, Issue #46 nhóm A). Nhánh RIÊNG,\n // BẮT BUỘC có từ \"ngoài\" sau \"phân giác\" (forward) hoặc trước/sau cặp đỉnh\n // (suffix). Phân giác ngoài ⊥ phân giác trong tại đỉnh → builder dựng qua\n // angleBisector(trong) + perpendicular. KHÔNG đụng pattern 'bisector' nội bộ\n // (vốn đã reject \"ngoài\" qua chữ thường forward + (?!\\s+ngoài) suffix).\n type: 'externalBisector',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\s+(?:[Đđ]ường\\s*|[Tt]ia\\s+)?phân\\s*giác\\s+ngoài\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?:[Đđ]ường\\s*phân\\s*giác|[Tt]ia\\s+phân\\s*giác|[Pp]hân\\s*giác)\\s+ngoài\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?(?:đường\\s*|tia\\s+)?phân\\s*giác\\s+ngoài/gu,\n ],\n },\n];\n\n// Prefilter: bất kỳ từ khoá cevian nào trên toàn đề (hoa đầu câu → [Đđ]/[Tt]/[Pp]).\n// EN (issue #46 group B): runRules prefilter theo `patterns` (BỎ QUA field\n// `languages`) → đề EN thuần cần EN prefilter thì match() mới chạy. Đây là cờ\n// boolean .test() thuần (KHÔNG capture nhãn) nên cờ 'i' AN TOÀN.\nconst PREFILTER = [\n /[Đđ]ường\\s*cao/u,\n /[Tt]rung\\s*tuyến/u,\n /[Pp]hân\\s*giác/u,\n /median/i,\n /altitude/i,\n /bisector/i,\n];\n\n/** Cạnh đối diện đỉnh V trong tam giác = 2 đỉnh còn lại, join token (vd \"BC\"). */\nfunction opposite(tri: readonly string[], vertex: string): string | undefined {\n const rest = tri.filter((v) => v !== vertex);\n return rest.length === 2 ? rest[0] + rest[1] : undefined;\n}\n\ninterface Cevian {\n clauseId: number;\n type: CevianType;\n apex: string;\n foot: string;\n opp: string;\n}\n\n/**\n * \"đường cao AH\" / \"trung tuyến AM\" / \"phân giác AD\" → add-point(chân) +\n * connect(VF). apex PHẢI là đỉnh tam giác (else bỏ qua: tránh match nhầm\n * cặp như \"BD cắt\"). Không có tam giác hoặc apex ngoài tam giác → escalate.\n */\nexport const cevianRule: LanguageRule = {\n id: 'cevian',\n priority: 60,\n languages: ['vi', 'en'],\n patterns: PREFILTER,\n match(ctx) {\n // Tam giác gate: VN trước, EN fallback (mirror angleBisectorAngle). Đề VN\n // không chứa \"triangle\", đề EN không chứa \"tam giác\" → VN byte-identical.\n const triMatch = TRI.exec(ctx.problem);\n const triMatchEN = TRI_EN.exec(ctx.problem);\n const tri = triMatch\n ? [triMatch[1], triMatch[2], triMatch[3]]\n : triMatchEN\n ? [triMatchEN[1], triMatchEN[2], triMatchEN[3]]\n : null;\n if (!tri) return []; // không có tam giác → escalate\n\n // ── Pass 1: gom MỌI cevian hợp lệ (apex là đỉnh, foot không trùng đỉnh) ──\n // Dedup theo (apex,foot,type) — KHÔNG dedup chỉ theo tên chân: 2 cevian\n // khác nhau cùng tên chân là XUNG ĐỘT (xử ở pass 2), không phải trùng lặp.\n const candidates: Cevian[] = [];\n const seen = new Set<string>(); // \"apex|foot|type\"\n\n for (const c of ctx.clauses) {\n for (const cp of CEVIAN_PATTERNS) {\n for (const re of cp.patterns) {\n re.lastIndex = 0;\n for (const m of c.text.matchAll(re)) {\n const apex = m[1];\n const foot = m[2];\n // apex phải là đỉnh tam giác; else có thể là cặp cạnh ngẫu nhiên.\n if (!tri.includes(apex)) continue;\n // foot trùng đỉnh tam giác (\"đường cao AB\" → foot=B) → SKIP sớm:\n // builder sẽ hạ điểm về 'free' → fidelity guard escalate; bỏ ở đây\n // cho sạch (không claim → coverage escalate trực tiếp).\n if (tri.includes(foot)) continue;\n const opp = opposite(tri, apex);\n if (!opp) continue; // apex không suy ra được cạnh đối diện → bỏ qua\n\n const key = `${apex}|${foot}|${cp.type}`;\n if (seen.has(key)) continue;\n seen.add(key);\n candidates.push({ clauseId: c.id, type: cp.type, apex, foot, opp });\n }\n }\n }\n }\n\n // ── Pass 2: phát hiện XUNG ĐỘT tên chân ──\n // Nếu 1 tên chân được ≥2 cevian khác nhau đặt (vd \"đường cao AH\" +\n // \"trung tuyến BH\" cùng tên H, ràng buộc mâu thuẫn) → bỏ TẤT cevian mang\n // tên đó. Không claim → escalate (thà escalate còn hơn dựng SAI ngữ nghĩa).\n const footCount = new Map<string, number>();\n for (const cv of candidates) footCount.set(cv.foot, (footCount.get(cv.foot) ?? 0) + 1);\n\n const out: RuleMatch[] = [];\n for (const cv of candidates) {\n if ((footCount.get(cv.foot) ?? 0) > 1) continue; // tên chân xung đột → skip\n\n let pointIntent;\n if (cv.type === 'altitude') {\n pointIntent = addPoint(cv.foot, { kind: 'perpFoot', from: cv.apex, onLine: cv.opp });\n } else if (cv.type === 'median') {\n pointIntent = addPoint(cv.foot, { kind: 'midpoint', of: cv.opp });\n } else if (cv.type === 'externalBisector') {\n pointIntent = addPoint(cv.foot, {\n kind: 'externalAngleBisectorFoot',\n from: cv.apex,\n onLine: cv.opp,\n });\n } else {\n pointIntent = addPoint(cv.foot, {\n kind: 'angleBisectorFoot',\n from: cv.apex,\n onLine: cv.opp,\n });\n }\n\n out.push({\n ruleId: 'cevian',\n clauseIds: [cv.clauseId],\n intents: [pointIntent, connect(cv.apex, cv.foot, 'segment')],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/angleBisectorAngle.ts\n//\n// Phân giác theo GÓC (3-point angle, KHÔNG đặt tên chân) — Issue #46 nhóm A.\n//\n// Phrasing đề thi RẤT phổ biến: \"Vẽ tia phân giác của góc BAC\", \"phân giác góc\n// BAC\", \"đường phân giác của góc A\"… → vẽ phân giác TRONG của góc, VISIBLE,\n// KHÔNG có tên chân (khác hẳn cevian \"phân giác AD\" foot-named).\n//\n// Emit 1 intent draw-line/angleBisector (VISIBLE), KHÔNG add-point foot, KHÔNG\n// connect. vertex = đỉnh góc:\n// - \"góc XYZ\" (3 ký tự HOA): vertex = chữ GIỮA (Y), p1=X, p2=Z.\n// - \"góc A\" (1 ký tự, trong tam giác): vertex=A, p1/p2 = 2 đỉnh còn lại\n// (suy như cevian opposite). Không có tam giác để suy 2 tia → escalate.\n//\n// Discriminator: PHẢI có \"góc\" + (cụm 3 HOA HOẶC 1 HOA là đỉnh tam giác). KHÔNG\n// đụng cevian \"phân giác AD\"/\"phân giác ngoài AD\" (2 ký tự foot-named): cevian\n// pattern yêu cầu cặp HOA NGAY sau \"phân giác\", nhưng ở đây sau \"phân giác\" là\n// \"góc\" (chữ thường) → cevian không khớp → KHÔNG double-emit.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { drawLine } from './_shared';\n\n// Tam giác từ toàn đề (cần để suy 2 cạnh cho \"góc A\"). \\b không khớp quanh ký\n// tự Việt → dùng class trực tiếp, cờ 'u'.\nconst TRI = /tam\\s*giác(?:\\s+(?:vuông|cân|đều|nhọn|tù))?\\s+([A-Z])([A-Z])([A-Z])/u;\n\n// === EN (issue #46 group B) =================================================\n// Tam giác tiếng Anh: \"triangle ABC\" (first-letter case flex [Tt], KHÔNG cờ 'i'\n// — sẽ phá [A-Z] nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]). Không cần\n// 'g' (chỉ cần tam giác đầu tiên để fallback suy 2 cạnh, như TRI VN).\nconst TRI_EN = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\n\n// Prefilter: VN cần \"phân giác\" + \"góc\"; EN cần \"angle bisector\" (Form B) hoặc\n// \"bisector of (the)? angle/∠\" (Form A). `.some` → ANY khớp là trigger match().\n// \"languages\" là metadata thuần (runRules prefilter theo `patterns`, BỎ QUA nó).\nconst PREFILTER = [\n /[Pp]hân\\s*giác/u,\n /góc/u,\n /[Aa]ngle\\s+bisector/u, // Form B EN\n /[Bb]isector\\s+of\\s+(?:the\\s+)?(?:[Aa]ngle|∠)/u, // Form A EN\n];\n\n// \"phân giác … góc XYZ\" (3 ký tự HOA liền). (?![A-Z]) chặn cụm 4+ ký tự.\n// Cho phép cụm dẫn \"(đường|tia) phân giác (của)? góc\" — bổ ngữ optional.\nconst ANGLE3 =\n /phân\\s*giác\\s+(?:(?:của|cho)\\s+)?góc\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/giu;\n// \"phân giác … góc A\" (1 ký tự HOA, không theo sau bởi HOA khác → không phải 3-point).\nconst ANGLE1 =\n /phân\\s*giác\\s+(?:(?:của|cho)\\s+)?góc\\s+([A-Z])(?![A-Z])/giu;\n\n// \"chân (của)? (đường|tia)? \" NGAY TRƯỚC \"phân giác\" → cụm \"CHÂN phân giác\" là\n// FOOT (điểm), thuộc angleBisectorFoot.ts. angleBisectorAngle né để KHÔNG vẽ tia\n// phân giác trùng (foot builder đã tự dựng tia bên trong) → tránh double-emit.\nconst CHAN_BEFORE = /chân\\s+(?:của\\s+)?(?:đường\\s*|tia\\s+)?$/u;\n\n// === EN regex (issue #46 group B) ===========================================\n// First-letter flex [Bb]/[Aa] (KHÔNG cờ 'i' — sẽ phá [A-Z] nhãn). Nhãn HOA\n// strict, neo (?![A-Z]). Cờ 'g' để emit-all + matchAll. Yêu cầu chữ\n// \"angle\"/∠ → KHÔNG khớp \"perpendicular bisector of BC\" (không có \"angle\").\n//\n// Form A: \"(the)? bisector of (the)? (angle|∠) XYZ\" — bổ ngữ \"the\" optional.\n// \"Draw the bisector of angle BAC.\" → {p1:B, vertex:A, p2:C}\n// Form B: \"(the)? angle bisector of XYZ\" — \"of\" sau \"bisector\", KHÔNG \"angle/∠\".\n// \"The angle bisector of MNP.\" → {M,N,P}\nconst ANGLE3_EN_A =\n /[Bb]isector\\s+of\\s+(?:the\\s+)?(?:[Aa]ngle|∠)\\s*([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\nconst ANGLE3_EN_B =\n /[Aa]ngle\\s+bisector\\s+of\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n// 1-letter \"angle A\" (Form A only — Form B \"angle bisector of A\" hiếm/mơ hồ,\n// defer). Cần tam giác EN để suy 2 cạnh.\nconst ANGLE1_EN_A =\n /[Bb]isector\\s+of\\s+(?:the\\s+)?(?:[Aa]ngle|∠)\\s*([A-Z])(?![A-Z])/gu;\n\n/** 2 đỉnh còn lại của tam giác (≠ vertex), giữ thứ tự xuất hiện trong tri. */\nfunction others(tri: readonly string[], vertex: string): string[] {\n return tri.filter((v) => v !== vertex);\n}\n\ninterface Hit {\n clauseId: number;\n p1: string;\n vertex: string;\n p2: string;\n}\n\n/**\n * \"phân giác (của) góc XYZ/A\" → draw-line/angleBisector VISIBLE (1 intent,\n * không foot, không connect). vertex = chữ giữa (3-point) hoặc đỉnh tam giác\n * (1-letter, suy 2 cạnh từ tam giác). Mơ hồ / không suy được 2 tia → escalate.\n */\nexport const angleBisectorAngleRule: LanguageRule = {\n id: 'angleBisectorAngle',\n // Cao hơn cevian (60) — chạy trước; tuy nhiên 2 rule không tranh chấp vì\n // discriminator \"góc\" loại cevian khỏi cụm này.\n priority: 62,\n languages: ['vi', 'en'],\n patterns: PREFILTER,\n match(ctx) {\n // Tam giác fallback (suy 2 cạnh cho \"góc A\"/\"angle A\"): VN trước, EN sau.\n // Đề VN không chứa \"triangle\" và đề EN không chứa \"tam giác\" → KHÔNG đụng\n // nhau (VN byte-identical).\n const triMatch = TRI.exec(ctx.problem);\n const triMatchEN = TRI_EN.exec(ctx.problem);\n const tri = triMatch\n ? [triMatch[1], triMatch[2], triMatch[3]]\n : triMatchEN\n ? [triMatchEN[1], triMatchEN[2], triMatchEN[3]]\n : null;\n\n const hits: Hit[] = [];\n const seen = new Set<string>(); // \"p1|vertex|p2\" dedup\n\n for (const c of ctx.clauses) {\n // ── 3-point \"góc XYZ\": vertex = chữ giữa, không cần tam giác ──\n ANGLE3.lastIndex = 0;\n for (const m of c.text.matchAll(ANGLE3)) {\n if (CHAN_BEFORE.test(c.text.slice(0, m.index))) continue; // \"chân … phân giác\" = foot\n const [p1, vertex, p2] = [m[1], m[2], m[3]];\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n\n // ── 1-letter \"góc A\": cần tam giác để suy 2 cạnh ──\n // Dùng pattern ANGLE1 nhưng BỎ QUA những match đã bị ANGLE3 nuốt (cùng vị\n // trí bắt đầu): so vị trí của vertex 1-letter với các 3-point đã thấy.\n ANGLE1.lastIndex = 0;\n for (const m of c.text.matchAll(ANGLE1)) {\n if (CHAN_BEFORE.test(c.text.slice(0, m.index))) continue; // \"chân … phân giác\" = foot\n const vertex = m[1];\n if (!tri) continue; // không tam giác → escalate\n if (!tri.includes(vertex)) continue; // đỉnh ngoài tam giác → bỏ qua\n const rest = others(tri, vertex);\n if (rest.length !== 2) continue; // không suy được 2 tia → bỏ qua\n const [p1, p2] = rest;\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n\n // ── EN 3-point: Form A \"(bisector of) angle XYZ\" + Form B \"angle bisector\n // of XYZ\". vertex = chữ giữa, không cần tam giác. seen dedup chung VN.\n for (const re of [ANGLE3_EN_A, ANGLE3_EN_B]) {\n re.lastIndex = 0;\n for (const m of c.text.matchAll(re)) {\n const [p1, vertex, p2] = [m[1], m[2], m[3]];\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n }\n\n // ── EN 1-letter \"angle A\" (Form A): cần tam giác EN/VN để suy 2 cạnh.\n ANGLE1_EN_A.lastIndex = 0;\n for (const m of c.text.matchAll(ANGLE1_EN_A)) {\n const vertex = m[1];\n if (!tri) continue; // không tam giác → escalate\n if (!tri.includes(vertex)) continue; // đỉnh ngoài tam giác → bỏ qua\n const rest = others(tri, vertex);\n if (rest.length !== 2) continue; // không suy được 2 tia → bỏ qua\n const [p1, p2] = rest;\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n }\n\n return hits.map<RuleMatch>((h) => ({\n ruleId: 'angleBisectorAngle',\n clauseIds: [h.clauseId],\n intents: [\n drawLine(`bis${h.p1}${h.vertex}${h.p2}`, 'angleBisector', {\n p1: h.p1,\n vertex: h.vertex,\n p2: h.p2,\n }) as IntentT,\n ],\n }));\n },\n};\n","// src/stamps/geometry-2d/ai/rules/centers.ts\n//\n// Tâm tam giác: trọng tâm (centroid), trực tâm (orthocenter), tâm đường tròn\n// ngoại tiếp (circumcenter), tâm đường tròn nội tiếp (incenter).\n//\n// Mọi kind này cần bộ 3 đỉnh of=[A,B,C]. Bind theo tam giác NÊU TRONG CÙNG\n// CLAUSE với cụm từ khoá (vd \"trọng tâm tam giác DEF\" → of=[D,E,F]) — KHÔNG lấy\n// tam giác đầu đề. Chỉ fallback tam giác toàn đề khi clause không nêu tam giác\n// nào VÀ đề có ĐÚNG 1 tam giác. Nhập nhằng (clause không nêu, đề >1 tam giác)\n// → bỏ qua (escalate). Không có tam giác nào → bỏ qua (escalate).\n// Tên điểm phải trích được (HOA ngay sau cụm từ khoá, hoặc \"X là <từ khoá>\");\n// nếu không → bỏ qua, KHÔNG bịa tên.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// Tam giác (global): quét mọi tam giác nêu trong một đoạn text.\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// === EN (issue #46 group B) =================================================\n// Tam giác tiếng Anh: \"triangle ABC\" (first-letter case flex [Tt], KHÔNG cờ 'i'\n// — sẽ phá [A-Z] nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]). ADDITIVE:\n// quét THÊM cùng TRI_G; merge theo vị trí TEXT để VN behavior giữ nguyên.\nconst TRI_EN_G = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n\n// Từ khoá tâm. \\b không khớp quanh ký tự Việt nên dùng lookaround \\p{L}.\n// \"trọng tâm\" — chặn nhầm với \"trung tâm\" bằng cách yêu cầu đúng \"trọng\".\nconst CENTROID_KW = /(?<!\\p{L})trọng\\s*tâm(?!\\p{L})/u;\n// \"trực tâm\" — chặn nhầm với \"trung trực\" (kết thúc bằng \"trực\", không phải \"trực tâm\").\nconst ORTHO_KW = /(?<!\\p{L})trực\\s*tâm(?!\\p{L})/u;\n// \"ngoại tiếp\" → circumcenter.\nconst CIRCUM_KW = /(?<!\\p{L})ngoại\\s*tiếp(?!\\p{L})/u;\n// \"nội tiếp\" → incenter (chỉ khi nói về TÂM, không phải \"tam giác nội tiếp đường tròn\").\nconst INSCRIBE_KW = /(?<!\\p{L})nội\\s*tiếp(?!\\p{L})/u;\n// Tên tâm đứng trước \"tâm\" qua \"là\": \"O là tâm\", \"Gọi O là tâm (đường tròn)…\".\nconst NAME_BEFORE_TAM = /(?<!\\p{L})([A-Z])\\s+là\\s+tâm(?!\\p{L})/u;\n\n// === EN keyword (issue #46 group B) =========================================\n// Từ khoá tâm tiếng Anh. First-letter case flex ([Cc], [Oo]…) — KHÔNG cờ 'i'\n// (sẽ phá [A-Z] nhãn). British spelling -centre cũng nhận. Neo (?![A-Za-z]) để\n// không khớp giữa từ dài hơn. centroid → centroid; orthocenter/-centre →\n// orthocenter; circumcenter/-centre → circumcenter; incenter/-centre → incenter.\nconst CENTROID_KW_EN = /(?<![A-Za-z])[Cc]entroid(?![A-Za-z])/u;\nconst ORTHO_KW_EN = /(?<![A-Za-z])[Oo]rthocent(?:er|re)(?![A-Za-z])/u;\nconst CIRCUM_KW_EN = /(?<![A-Za-z])[Cc]ircumcent(?:er|re)(?![A-Za-z])/u;\nconst INCENTER_KW_EN = /(?<![A-Za-z])[Ii]ncent(?:er|re)(?![A-Za-z])/u;\n\n// Tên điểm đứng NGAY SAU cụm từ khoá: \"trọng tâm G\", \"tâm (đường tròn) ngoại tiếp O\".\nfunction nameAfter(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const rest = text.slice(m.index + m[0].length);\n // bỏ qua các từ chêm phổ biến (\"của\", \"là\", \"tam giác\", \"đường tròn\", dấu câu)\n const after = /^[\\s,:của là]*?(?:tam\\s*giác\\s+)?([A-Z])(?!\\p{L})/u.exec(rest);\n return after ? after[1] : undefined;\n}\n\n// Tên điểm đứng TRƯỚC cụm từ khoá: \"G là trọng tâm\", \"H là trực tâm\".\nfunction nameBefore(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const before = text.slice(0, m.index);\n // \"...<HOA> (là)? \" ngay trước từ khoá\n const mm = /(?<!\\p{L})([A-Z])\\s+(?:là\\s+)?$/u.exec(before);\n return mm ? mm[1] : undefined;\n}\n\nfunction resolveName(text: string, kw: RegExp): string | undefined {\n return nameBefore(text, kw) ?? nameAfter(text, kw);\n}\n\n// Tâm đường tròn ngoại/nội tiếp: tên đứng trước \"tâm\" (qua \"là\") — vd \"Gọi O là\n// tâm đường tròn ngoại tiếp\" — hoặc sau cụm từ khoá — vd \"ngoại tiếp O\".\nfunction resolveCenterName(text: string, kw: RegExp): string | undefined {\n const before = NAME_BEFORE_TAM.exec(text);\n if (before) return before[1];\n return nameAfter(text, kw);\n}\n\n// --- EN name resolution (issue #46 group B) ---------------------------------\n// Tên điểm đứng TRƯỚC cụm từ khoá EN qua \"is/be the\": \"G is the centroid\",\n// \"Let H be the orthocenter\". Tên = ký tự HOA NGAY TRƯỚC \"is/be the <kw>\"\n// (cục bộ, KHÔNG quét lời dẫn toàn clause). KHÔNG cờ 'i' (giữ [A-Z]).\nfunction nameBeforeEn(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const before = text.slice(0, m.index);\n // \"...<HOA> (is|be) the \" ngay trước từ khoá.\n const mm = /(?<![A-Za-z])([A-Z])\\s+(?:is|be)\\s+the\\s+$/u.exec(before);\n return mm ? mm[1] : undefined;\n}\n\n// Tên điểm đứng NGAY SAU cụm từ khoá EN: \"centroid G\", \"orthocenter H\".\n// Bỏ qua từ chêm \"of\"/\"the\" KHÔNG được phép ở đây — nếu sau từ khoá là \"of …\"\n// (vd \"centroid of triangle ABC\") thì KHÔNG có tên điểm → undefined (fail-safe,\n// KHÔNG bịa tên).\nfunction nameAfterEn(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const rest = text.slice(m.index + m[0].length);\n const after = /^\\s+([A-Z])(?![A-Za-z])/u.exec(rest);\n return after ? after[1] : undefined;\n}\n\nfunction resolveNameEn(text: string, kw: RegExp): string | undefined {\n return nameBeforeEn(text, kw) ?? nameAfterEn(text, kw);\n}\n\n/** Một tam giác phát hiện trong text: bộ 3 đỉnh + offset bắt đầu match. */\ninterface TriHit {\n tri: string[];\n index: number;\n}\n\n/**\n * Tập tam giác (bộ 3 đỉnh + vị trí) nêu trong một đoạn text, gồm CẢ VN\n * (\"tam giác ABC\") VÀ EN (\"triangle ABC\"), sắp theo vị trí TEXT. ADDITIVE:\n * với đề thuần VN, chỉ TRI_G khớp ⇒ kết quả identical với hành vi cũ.\n */\nfunction triangleHits(text: string): TriHit[] {\n const hits: TriHit[] = [];\n TRI_G.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(text)) !== null) {\n hits.push({ tri: [m[1], m[2], m[3]], index: m.index });\n }\n TRI_EN_G.lastIndex = 0;\n while ((m = TRI_EN_G.exec(text)) !== null) {\n hits.push({ tri: [m[1], m[2], m[3]], index: m.index });\n }\n hits.sort((a, b) => a.index - b.index);\n return hits;\n}\n\n/**\n * Tập tam giác (mỗi tam giác = bộ 3 đỉnh) nêu trong một đoạn text. Trùng (cùng\n * 3 chữ liền) được giữ theo lượt xuất hiện; caller dedup nếu cần.\n */\nfunction trianglesIn(text: string): string[][] {\n return triangleHits(text).map((h) => h.tri);\n}\n\n/**\n * Tam giác để bind 'of' cho 1 clause:\n * 1. Ưu tiên tam giác nêu NGAY TRONG clause (gần cụm từ khoá nhất theo index).\n * 2. Nếu clause không nêu tam giác nào → fallback tam giác toàn đề CHỈ KHI đề\n * có duy nhất 1 tam giác (theo bộ đỉnh, dedup). Nhiều tam giác → undefined\n * (nhập nhằng, escalate). Không có tam giác → undefined.\n */\nfunction resolveTriangle(\n clauseText: string,\n kwIndex: number,\n uniqueProblemTri: string[] | undefined,\n): string[] | undefined {\n const inClause = triangleHits(clauseText);\n if (inClause.length > 0) {\n // chọn tam giác gần cụm từ khoá nhất (ưu tiên đứng SAU; nếu không có thì lấy\n // tam giác gần nhất bất kể phía). Gồm cả tam giác VN lẫn EN trong clause.\n let best: { tri: string[]; dist: number } | undefined;\n for (const h of inClause) {\n const idx = h.index;\n // khoảng cách: ưu tiên tam giác đứng sau từ khoá (idx >= kwIndex).\n const after = idx >= kwIndex;\n const dist = Math.abs(idx - kwIndex) + (after ? 0 : 1_000);\n if (!best || dist < best.dist) best = { tri: h.tri, dist };\n }\n return best?.tri;\n }\n return uniqueProblemTri;\n}\n\n/**\n * Tâm tam giác → add-point với of=[A,B,C]. Một clause có thể nêu nhiều tâm\n * (vd \"trọng tâm G và trực tâm H\"); emit từng intent, cùng claim clause.\n */\nexport const centersRule: LanguageRule = {\n id: 'centers',\n priority: 70,\n languages: ['vi', 'en'],\n patterns: [\n CENTROID_KW,\n ORTHO_KW,\n CIRCUM_KW,\n INSCRIBE_KW,\n CENTROID_KW_EN,\n ORTHO_KW_EN,\n CIRCUM_KW_EN,\n INCENTER_KW_EN,\n ],\n match(ctx) {\n // Tam giác duy nhất toàn đề (dedup theo bộ đỉnh) — dùng làm fallback khi\n // clause KHÔNG tự nêu tam giác. Nhiều tam giác khác nhau → undefined (nhập\n // nhằng → escalate). Không có → undefined (không dựng được → escalate).\n const allTri = trianglesIn(ctx.problem);\n const distinct = new Set(allTri.map((t) => t.join('')));\n const uniqueProblemTri = distinct.size === 1 ? allTri[0] : undefined;\n\n // helper: bind 'of' cho 1 cụm từ khoá tại vị trí kwIndex trong clause.\n const ofFor = (text: string, kw: RegExp): string[] | undefined => {\n const m = kw.exec(text);\n const kwIndex = m ? m.index : 0;\n return resolveTriangle(text, kwIndex, uniqueProblemTri);\n };\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const intents = [];\n\n if (CENTROID_KW.test(c.text)) {\n const name = resolveName(c.text, CENTROID_KW);\n const of = ofFor(c.text, CENTROID_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'centroid', of }));\n }\n if (ORTHO_KW.test(c.text)) {\n const name = resolveName(c.text, ORTHO_KW);\n const of = ofFor(c.text, ORTHO_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'orthocenter', of }));\n }\n // circumcenter: \"ngoại tiếp\". incenter: \"nội tiếp\" nhưng KHÔNG khi clause\n // cũng có \"ngoại tiếp\" (cùng cụm gây nhập nhằng) — ưu tiên ngoại tiếp.\n if (CIRCUM_KW.test(c.text)) {\n const name = resolveCenterName(c.text, CIRCUM_KW);\n const of = ofFor(c.text, CIRCUM_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'circumcenter', of }));\n } else if (INSCRIBE_KW.test(c.text)) {\n const name = resolveCenterName(c.text, INSCRIBE_KW);\n const of = ofFor(c.text, INSCRIBE_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'incenter', of }));\n }\n\n // --- EN (issue #46 group B) — mirror VN semantics, mỗi từ khoá độc lập --\n // Các danh từ tâm EN là chính tả riêng biệt (centroid/orthocenter/\n // circumcenter/incenter) nên KHÔNG nhập nhằng lẫn nhau như \"ngoại/nội\n // tiếp\" VN — xử lý từng cái độc lập. Tên + of giải qua helper EN; thiếu\n // tên HOẶC of không bind được → bỏ qua (escalate, KHÔNG bịa).\n if (CENTROID_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, CENTROID_KW_EN);\n const of = ofFor(c.text, CENTROID_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'centroid', of }));\n }\n if (ORTHO_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, ORTHO_KW_EN);\n const of = ofFor(c.text, ORTHO_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'orthocenter', of }));\n }\n if (CIRCUM_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, CIRCUM_KW_EN);\n const of = ofFor(c.text, CIRCUM_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'circumcenter', of }));\n }\n if (INCENTER_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, INCENTER_KW_EN);\n const of = ofFor(c.text, INCENTER_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'incenter', of }));\n }\n\n if (intents.length > 0) {\n out.push({ ruleId: 'centers', clauseIds: [c.id], intents });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/perpFoot.ts\n//\n// Hình chiếu vuông góc / chân đường vuông góc (đường cao):\n// \"Gọi H là hình chiếu (vuông góc) của A trên/lên/xuống (đường thẳng|cạnh)? BC\"\n// \"Gọi H là chân đường vuông góc (hạ|kẻ) từ A (đến|xuống) BC\"\n// \"H, K lần lượt là hình chiếu của B trên AC và của C trên AB\" → 2 foot\n// → addPoint('H', { kind:'perpFoot', from:'A', onLine:'BC' })\n//\n// onLine giữ nguyên token sau giới từ (pair 'BC' hoặc tên đường 1 ký tự 'd').\n//\n// Tên foot bind CỤC BỘ (ký tự HOA + \"là\" NGAY TRƯỚC cụm \"hình chiếu\"/\"chân đường\"),\n// KHÔNG lấy lời dẫn đầu clause — tránh gán nhầm cho \"Gọi N là điểm bất kỳ, H là …\".\n// Match GLOBAL để dựng đủ nhiều foot trong cùng clause.\n//\n// SKIP (để pipeline escalate AI thay vì đoán sai):\n// - không trích được tên foot cục bộ;\n// - modifier \"trung điểm (của)? hình chiếu …\" — đổi nghĩa, foot không còn là điểm cần dựng.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, DUONG_KW } from './_shared';\n\n// LƯU Ý: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt. Mọi\n// regex chứa ký tự Việt dùng cờ 'u' + tránh \\b.\n\n// Prefilter toàn đề: \"hình chiếu\" / \"chân đường (cao|vuông góc)\" / ký hiệu ⊥ /\n// \"vuông góc\" (cho dạng \"Kẻ AH ⊥ BC tại H\"). \"vuông góc\" rộng nhưng match() chỉ\n// emit khi pattern khớp thật → an toàn.\nconst PREFILTER = new RegExp(\n 'hình\\\\s*chiếu|chân\\\\s+(?:của\\\\s+)?' +\n DUONG_KW +\n '\\\\s+(?:cao|vuông\\\\s*góc)|⊥|vuông\\\\s*góc',\n 'u',\n);\n// EN prefilter (issue #46 group B). runRules prefilter theo `patterns` (BỎ QUA\n// field `languages`) → BẮT BUỘC có 1 EN regex thì match() mới chạy cho đề EN\n// thuần. Rộng nhưng match() chỉ emit khi core khớp thật → an toàn.\nconst PREFILTER_EN = /projection|perpendicular|foot\\s+of/i;\n\n// onLine token: tên đường 1 ký tự HOA HOẶC cặp đỉnh 2 ký tự HOA (vd 'BC'). Chấp\n// nhận tiền tố \"đường thẳng\" / \"cạnh\" / \"đoạn\" trước token.\nconst LINE = '(?:' + DUONG_KW + '\\\\s*thẳng\\\\s+|cạnh\\\\s+|đoạn\\\\s+)?([A-Z]{1,2})(?![A-Z])';\nconst PREP = '(?:trên|lên|xuống|đến|tới)';\n\n// \"hình chiếu (vuông góc)? (của)? X PREP [cạnh|đường thẳng] LINE\"\nconst PROJ_CORE = `hình\\\\s*chiếu\\\\s+(?:vuông\\\\s*góc\\\\s+)?(?:của\\\\s+)?([A-Z])\\\\s+${PREP}\\\\s+${LINE}`;\n// \"chân đường (vuông góc|cao) (hạ|kẻ|vẽ|dựng)? (từ)? X PREP LINE\"\nconst FOOT_CORE = `chân\\\\s+(?:của\\\\s+)?${DUONG_KW}\\\\s+(?:vuông\\\\s*góc|cao)\\\\s*(?:hạ\\\\s+|kẻ\\\\s+|vẽ\\\\s+|dựng\\\\s+)?(?:từ\\\\s+)?([A-Z])\\\\s+${PREP}\\\\s+${LINE}`;\n\n// Phân phối \"X, Y lần lượt là <core của FROM1 ... LINE1> và (của|từ)? FROM2 PREP LINE2\".\n// groups: 1=name1 2=name2 | PROJ: 3=from1 4=line1 | FOOT: 5=from1 6=line1 | tail: 7=from2 8=line2\nconst LANLUOT = new RegExp(\n `([A-Z])(?:[′'])?\\\\s*,\\\\s*([A-Z])(?:[′'])?\\\\s+lần\\\\s+lượt\\\\s+là\\\\s+(?:${PROJ_CORE}|${FOOT_CORE})\\\\s+và\\\\s+(?:của\\\\s+|từ\\\\s+)?([A-Z])\\\\s+${PREP}\\\\s+${LINE}`,\n 'gu',\n);\n\n// Một foot đơn (projection hoặc chân đường).\n// groups: PROJ 1=from 2=line | FOOT 3=from 4=line\nconst SINGLE = new RegExp(`(?:${PROJ_CORE})|(?:${FOOT_CORE})`, 'gu');\n\n// Distributive SHARED-FROM: \"X, Y, Z lần lượt là hình chiếu (vuông góc)? của D\n// trên BC, CA, AB\" → zip tên↔cạnh, MỘT `from` (D) chung. KHÁC LANLUOT (2 chân,\n// mỗi chân from riêng, nối \"và\"): ở đây 1 from + DANH SÁCH cạnh ngăn phẩy (≥2).\n// Số tên PHẢI bằng số cạnh (else bỏ → escalate, không đoán lệch).\n// groups: 1=names blob (≥2, phẩy) | 2=from | 3=lines blob (≥2, phẩy)\nconst NAMES_BLOB = \"((?:[A-Z](?:['′]?)\\\\s*,\\\\s*)+[A-Z](?:['′]?))\";\nconst LINES_BLOB = '((?:[A-Z]{1,2}\\\\s*,\\\\s*)+[A-Z]{1,2})(?!\\\\p{L})';\nconst DISTRIB_PROJ = new RegExp(\n NAMES_BLOB +\n '\\\\s+lần\\\\s*lượt\\\\s+(?:là\\\\s+)?hình\\\\s*chiếu\\\\s+(?:vuông\\\\s*góc\\\\s+)?(?:của\\\\s+)?([A-Z])(?!\\\\p{L})' +\n '\\\\s+(?:trên|lên|xuống|đến)\\\\s+(?:các\\\\s+)?' +\n LINES_BLOB,\n 'gu',\n);\nconst DISTRIB_FOOT = new RegExp(\n NAMES_BLOB +\n '\\\\s+lần\\\\s*lượt\\\\s+(?:là\\\\s+)?chân\\\\s+(?:của\\\\s+)?đường\\\\s+(?:vuông\\\\s*góc|cao)\\\\s*(?:hạ\\\\s+|kẻ\\\\s+|vẽ\\\\s+|dựng\\\\s+)?(?:từ\\\\s+)?([A-Z])(?!\\\\p{L})' +\n '\\\\s+(?:đến|xuống|trên|tới)\\\\s+(?:các\\\\s+)?' +\n LINES_BLOB,\n 'gu',\n);\n\n/** Tách blob tên distributive \"X, Y, Z\" → ['X','Y','Z'] (chuẩn hoá prime ′→'). */\nfunction splitNames(blob: string): string[] {\n return blob\n .split(',')\n .map((s) => {\n const mm = /^([A-Z])(['′]?)/u.exec(s.trim());\n return mm ? (mm[2] ? `${mm[1]}'` : mm[1]) : '';\n })\n .filter(Boolean);\n}\n\n// \"Kẻ/Vẽ/Dựng XY (⊥|vuông góc với?) [cạnh|đường thẳng]? LINE (tại Z)?\"\n// \"Kẻ AH ⊥ BC tại H\" | \"Vẽ AH vuông góc với BC\" | \"Dựng AH vuông góc cạnh BC\"\n// Tên foot = chữ thứ 2 của cặp XY (g2); from = g1; onLine = g3. \"tại Z\" (g4) nếu\n// có PHẢI trùng foot (else xung đột → skip). connect.ts (SEG_KW \"Kẻ AH\") đã lo\n// đoạn AH → rule này CHỈ emit add-point, KHÔNG connect (tránh double).\n// groups: 1=from 2=foot 3=onLine 4=tại-point(optional)\nconst PERP_DRAW = new RegExp(\n `(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\\\s+([A-Z])([A-Z])(?![A-Z])\\\\s+(?:⊥|vuông\\\\s*góc(?:\\\\s+với)?)\\\\s+(?:với\\\\s+)?(?:đường\\\\s*thẳng\\\\s+|cạnh\\\\s+|đoạn\\\\s+)?([A-Z]{1,2})(?![A-Z])(?:\\\\s+tại\\\\s+([A-Z]))?`,\n 'gu',\n);\n\n// modifier \"trung điểm (của)?\" NGAY TRƯỚC cụm → đổi nghĩa, không dựng foot.\nconst MID_BEFORE = /trung\\s+điểm(?:\\s+của)?\\s*$/u;\n// Tên foot cục bộ: ký tự HOA + \"là\" NGAY TRƯỚC cụm (vd \"Gọi H là \", \"… , H là \").\nconst NAME_BEFORE = /([A-Z])(?:[′'])?\\s+là\\s+$/u;\n\n// === EN (issue #46 group B) ==================================================\n// Additive — KHÔNG đụng building block VN ở trên. Nhãn STRICT [A-Z] (KHÔNG cờ\n// 'i' — sẽ nuốt chữ thường); first-letter flex của verb bằng [Dd]/[Cc].\n//\n// onLine token EN: tiền tố \"line \"/\"side \"/\"segment \" optional + 1-2 ký tự HOA,\n// neo (?![A-Z]) để chặn cụm 3+ ký tự.\nconst LINE_EN = '(?:line\\\\s+|side\\\\s+|segment\\\\s+)?([A-Z]{1,2})(?![A-Z])';\n\n// Form A — \"(orthogonal)? projection of X (onto|on|to) LINE\"\n// groups: 1=from 2=line\nconst PROJ_CORE_EN = `(?:orthogonal\\\\s+)?projection\\\\s+of\\\\s+([A-Z])\\\\s+(?:onto|on|to)\\\\s+${LINE_EN}`;\n// Form B — \"foot of (the)? (perpendicular|altitude) from X (to|onto|on) LINE\"\n// groups: 1=from 2=line\nconst FOOT_CORE_EN = `foot\\\\s+of\\\\s+(?:the\\\\s+)?(?:perpendicular|altitude)\\\\s+from\\\\s+([A-Z])\\\\s+(?:to|onto|on)\\\\s+${LINE_EN}`;\n\n// Single EN core (projection HOẶC foot-of). Ghép 2 group block → group dịch:\n// PROJ: 1=from 2=line | FOOT: 3=from 4=line → đọc bằng m[1]??m[3], m[2]??m[4].\nconst SINGLE_EN = new RegExp(`(?:${PROJ_CORE_EN})|(?:${FOOT_CORE_EN})`, 'gu');\n\n// Form C draw — \"Draw|Construct|Drop XY perpendicular to (line|side|segment)? LINE (at Z)?\"\n// \"Draw AH perpendicular to BC at H\" | \"Construct AH perpendicular to BC\"\n// foot = chữ thứ 2 cặp XY (g2); from = g1; onLine = g3; at = g4 (optional).\n// \"Draw the perpendicular bisector …\" KHÔNG khớp: sau \"Draw\" là \"the\" (chữ\n// thường) chứ không phải cặp HOA → perpBisector territory, không double-emit.\n// groups: 1=from 2=foot 3=onLine 4=at(optional)\nconst PERP_DRAW_EN = new RegExp(\n `(?:[Dd]raw|[Cc]onstruct|[Dd]rop)\\\\s+([A-Z])([A-Z])(?![A-Z])\\\\s+perpendicular\\\\s+to\\\\s+(?:line\\\\s+|side\\\\s+|segment\\\\s+)?([A-Z]{1,2})(?![A-Z])(?:\\\\s+at\\\\s+([A-Z]))?`,\n 'gu',\n);\n\n// Tên foot ĐỨNG TRƯỚC core qua \"Let X be the …\" / \"X is the …\".\n// \"Let H be the projection …\" | \"K is the orthogonal projection …\"\nconst NAME_BEFORE_EN = /([A-Z])(?:[′'])?\\s+(?:be|is)\\s+(?:the\\s+)?$/u;\n\ninterface Foot {\n name: string;\n from: string;\n onLine: string;\n /** Emit thêm connect(from, foot) — đoạn vuông góc từ điểm tới chân. Dùng cho:\n * Form C (EN draw \"Draw AH ⊥ BC\") + distributive VN \"X,Y,Z hình chiếu của D…\"\n * (thể hiện hình chiếu DX/DY/DZ). Foot đơn VN KHÔNG set → byte-identical. */\n withSegment?: boolean;\n}\n\n/** Parse mọi foot trong 1 clause. Trả [] nếu không bind được tên / bị skip. */\nfunction parseFeet(text: string): Foot[] {\n const out: Foot[] = [];\n const consumed: Array<[number, number]> = [];\n\n // 0) Distributive SHARED-FROM: \"X, Y, Z lần lượt là hình chiếu/chân vuông góc\n // của D trên BC, CA, AB\" → zip tên↔cạnh (from D chung). Span đã khớp →\n // consumed để SINGLE không xử lại. Zip lệch (số tên ≠ số cạnh) → bỏ.\n for (const re of [DISTRIB_PROJ, DISTRIB_FOOT]) {\n re.lastIndex = 0;\n for (const dm of text.matchAll(re)) {\n const names = splitNames(dm[1]);\n const from = dm[2];\n const lines = dm[3].split(',').map((s) => s.trim()).filter(Boolean);\n if (names.length < 2 || names.length !== lines.length) continue; // zip lệch → escalate\n // withSegment: vẽ kèm đoạn vuông góc from→foot (DX/DY/DZ) để THỂ HIỆN hình\n // chiếu (render perpFoot chỉ tạo điểm chân, không tự vẽ đường rớt vuông góc).\n names.forEach((name, i) => out.push({ name, from, onLine: lines[i], withSegment: true }));\n consumed.push([dm.index ?? 0, (dm.index ?? 0) + dm[0].length]);\n }\n }\n\n // 1) \"X, Y lần lượt là … và …\" → 2 foot (name bind sẵn trong cú pháp).\n LANLUOT.lastIndex = 0;\n let lm: RegExpExecArray | null;\n while ((lm = LANLUOT.exec(text)) !== null) {\n if (MID_BEFORE.test(text.slice(0, lm.index))) continue; // \"trung điểm của …\" → skip\n const from1 = lm[3] ?? lm[5];\n const line1 = lm[4] ?? lm[6];\n out.push({ name: lm[1], from: from1, onLine: line1 });\n out.push({ name: lm[2], from: lm[7], onLine: lm[8] });\n consumed.push([lm.index, lm.index + lm[0].length]);\n }\n\n // 2) foot đơn — bind tên CỤC BỘ. Bỏ qua nếu nằm trong span \"lần lượt\" đã xử lý.\n SINGLE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = SINGLE.exec(text)) !== null) {\n const start = m.index;\n if (consumed.some(([a, b]) => start >= a && start < b)) continue;\n const before = text.slice(0, start);\n if (MID_BEFORE.test(before)) continue; // \"trung điểm của hình chiếu …\" → đổi nghĩa\n const nm = NAME_BEFORE.exec(before);\n if (!nm) continue; // không có tên cục bộ → escalate AI\n out.push({ name: nm[1], from: m[1] ?? m[3], onLine: m[2] ?? m[4] });\n }\n\n // 3) \"Kẻ XY ⊥ LINE (tại Z)\" — tên foot lấy từ cặp XY (không cần \"X là\").\n PERP_DRAW.lastIndex = 0;\n let pm: RegExpExecArray | null;\n while ((pm = PERP_DRAW.exec(text)) !== null) {\n const from = pm[1];\n const foot = pm[2];\n const onLine = pm[3];\n const at = pm[4]; // \"tại Z\" (optional)\n if (at && at !== foot) continue; // \"tại K\" ≠ chân H → xung đột → escalate\n if (onLine.includes(foot)) continue; // chân trùng đỉnh của đường → degenerate\n out.push({ name: foot, from, onLine });\n }\n\n // 4) EN projection / foot-of — tên bind ĐỨNG TRƯỚC qua \"Let X be the …\"/\"X is\n // the …\". Không có tên-trước → escalate (fail-safe). \"trung điểm\" KHÔNG\n // áp dụng EN; MID_BEFORE giữ nguyên VN, ở đây không cần.\n SINGLE_EN.lastIndex = 0;\n let em: RegExpExecArray | null;\n while ((em = SINGLE_EN.exec(text)) !== null) {\n const before = text.slice(0, em.index);\n const nm = NAME_BEFORE_EN.exec(before);\n if (!nm) continue; // không có \"X be/is the\" → escalate AI\n const from = em[1] ?? em[3];\n const onLine = em[2] ?? em[4];\n out.push({ name: nm[1], from, onLine });\n }\n\n // 5) EN draw form \"Draw XY perpendicular to LINE (at Z)\" — foot = chữ 2 cặp XY.\n // connect.ts VN-only → tự emit connect(from, foot) để vẽ đoạn (parity VN).\n PERP_DRAW_EN.lastIndex = 0;\n let dm: RegExpExecArray | null;\n while ((dm = PERP_DRAW_EN.exec(text)) !== null) {\n const from = dm[1];\n const foot = dm[2];\n const onLine = dm[3];\n const at = dm[4]; // \"at Z\" (optional)\n if (at && at !== foot) continue; // \"at K\" ≠ chân H → xung đột → escalate\n if (onLine.includes(foot)) continue; // chân trùng đỉnh đường → degenerate\n out.push({ name: foot, from, onLine, withSegment: true });\n }\n return out;\n}\n\n/**\n * Mỗi clause → 0..n add-point perpFoot. Tên foot bind cục bộ theo cú pháp gần,\n * match global để dựng đủ (vd \"H, K lần lượt …\" = 2 foot).\n */\nexport const perpFootRule: LanguageRule = {\n id: 'perpFoot',\n priority: 65,\n languages: ['vi', 'en'],\n patterns: [PREFILTER, PREFILTER_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const feet = parseFeet(c.text);\n if (feet.length === 0) continue;\n // Foot add-point TRƯỚC; với EN draw form (withSegment) push THÊM connect\n // NGAY SAU add-point của foot đó (H phải tồn tại trước khi connect tham\n // chiếu). VN feet không set withSegment → byte-identical.\n const intents = feet.flatMap((f) => {\n const add = addPoint(f.name, { kind: 'perpFoot', from: f.from, onLine: f.onLine });\n return f.withSegment ? [add, connect(f.from, f.name, 'segment')] : [add];\n });\n out.push({ ruleId: 'perpFoot', clauseIds: [c.id], intents });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/circleRadius.ts\n//\n// Đường tròn theo TÂM: bán kính số / bán kính ký hiệu CHỮ / \"đi qua <điểm>\".\n// - \"đường tròn (tâm) O bán kính 3\" → centerRadius {center:'O', radius:3}\n// - \"(O; 3)\" / \"(O, 3)\" → centerRadius {center:'O', radius:3}\n// - \"(O; R)\" / \"(I; r)\" / \"bán kính R\" → centerRadius bán kính CANONICAL\n// (issue #46 nhóm A — xem dưới)\n// - \"đường tròn tâm O đi qua A\" → centerThrough {center:'O', through:'A'}\n//\n// CHỈ emit khi có bán kính SỐ, bán kính ký hiệu CHỮ (R/r), hoặc \"đi qua <điểm>\".\n// \"(O)\" trơ (không số/chữ/\"đi qua\") → bỏ qua (chỉ tham chiếu; rule khác/AI xử lý).\n//\n// BÁN KÍNH KÝ HIỆU CHỮ (issue #46): \"Cho đường tròn (O; R)\" cực phổ biến ở đề thi.\n// R là KÝ HIỆU (giá trị thực không cho) → vẽ với bán kính CANONICAL dương để minh\n// hoạ (fail-safe: không sai ngữ nghĩa — đường tròn tâm O bán kính tuỳ ý). CHỈ nhận\n// đúng [Rr] đứng riêng: hệ số \"2R\" (defer Cụm C) và chữ khác \"(A; B)\" → bỏ qua.\n//\n// GOTCHA segmentation: segmentClauses() tách trên '.' ';' ',' nên ký hiệu gọn\n// \"(O; 3)\" / \"(O, 2.5)\" BỊ cắt ngang clause (\"(O\" và \"3)\" thành 2 clause). Vì\n// vậy nhánh PAREN quét trên TOÀN đề (ctx.problem) rồi gán match cho clause chứa\n// fragment \"(<tâm>\". Nhánh WORDS / THROUGH segment nguyên vẹn → quét per-clause.\n//\n// GOTCHA \\b: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { Clause } from '../deterministic/coverage';\nimport { drawCircle, CIRCLE_KW } from './_shared';\n\n// \"đường tròn tâm O bán kính 3\" / \"(O) bán kính 3\" / \"O bán kính 3\".\n// Tâm 1 ký tự HOA; \"tâm\" optional; có thể bọc trong ngoặc \"(O)\".\n// Hỗ trợ PAREN tên chữ (alpha, omega...).\n//\n// GLOBAL (/gu) vì 1 clause có thể nêu NHIỀU đường tròn (\"tâm I bán kính 2 và\n// tâm O bán kính 5\" không có dấu câu tách → cùng clause). matchAll quét hết.\n//\n// Gap tâm→\"bán kính\" dùng tempered quantifier `(?:(?!đường|và\\s)[^A-Z])*?` để\n// KHÔNG nhảy qua một \"đường tròn\" khác hay liên từ \"và \" (ranh giới giữa 2 hình).\n// Nếu nhảy qua được, \"tâm O và … tâm I bán kính 5\" sẽ bind nhầm 5 vào O. Chặn ở\n// đây ⇒ match bắt đầu từ O thất bại, regex tự dời tới \"tâm I bán kính 5\" (đúng),\n// còn \"tâm O\" trơ (không số) không bị nuốt → không claim → escalate phần đó.\nconst CENTER_RADIUS_WORDS_G = new RegExp(\n CIRCLE_KW +\n '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?:\\\\s*\\\\))?(?:(?!đường|và\\\\s)[^A-Z])*?bán\\\\s*kính\\\\s+(\\\\d+(?:[.,]\\\\d+)?)',\n 'gu',\n);\n\n// \"đường tròn tâm O đi qua A\" / \"(O) đi qua A\" / \"O đi qua A\".\n// GLOBAL: nhiều \"đường tròn … đi qua …\" trong 1 clause.\nconst CENTER_THROUGH_G = new RegExp(\n CIRCLE_KW + '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?:\\\\s*\\\\))?\\\\s+đi\\\\s+qua\\\\s+([A-Z])',\n 'gu',\n);\n\n// Phần \"đi qua B và C\" (≥2 điểm surface): chưa hỗ trợ (DSL centerThrough 1 điểm).\n// Phát hiện để SKIP match đó → điểm thứ 2 (C) thiếu trong DSL → named-entity\n// guard escalate AI (an toàn) thay vì render thiếu C.\nconst THROUGH_MULTI = /đi\\s+qua\\s+[A-Z]\\s*(?:và|,)\\s*[A-Z]/u;\n\n// Ký hiệu gọn \"(O; 3)\" / \"(O, 3)\" — quét toàn đề (global) vì có thể nhiều.\nconst CENTER_RADIUS_PAREN_G = /\\(\\s*([A-Z])\\s*[;,]\\s*(\\d+(?:[.,]\\d+)?)\\s*\\)/gu;\n\n/**\n * Bán kính CANONICAL (board units) khi đề cho bán kính KÝ HIỆU CHỮ (\"(O; R)\",\n * \"bán kính R\"). Giá trị thực là ký hiệu → vẽ minh hoạ; khớp scale với bán kính\n * số mặc định nhỏ (vd \"(O; 3)\"). circleCR yêu cầu radius > 0.\n */\nexport const SYMBOLIC_RADIUS = 3;\n\n// Ký hiệu gọn bán kính CHỮ \"(O; R)\" / \"(I; r)\" — quét toàn đề. Bán kính CHỈ [Rr]\n// đứng RIÊNG (theo sau là ')'): \"2R\" (hệ số, defer) và chữ khác \"(A; B)\" KHÔNG\n// khớp → escalate (fail-safe). Center 1 ký tự HOA như nhánh số.\nconst CENTER_RADIUS_LETTER_PAREN_G = /\\(\\s*([A-Z])\\s*[;,]\\s*[Rr]\\s*\\)/gu;\n\n// \"đường tròn tâm O bán kính R\" — words, bán kính CHỮ. Mirror tempered của\n// CENTER_RADIUS_WORDS_G; (?![A-Za-z]) chặn \"Ra\"/\"Rồi\"… và phần số (\"2R\") để\n// nhánh số lo. GLOBAL: nhiều đường tròn / clause.\n// \"đường tròn tâm O bán kính R\" — words, bán kính CHỮ. Mirror tempered của\n// CENTER_RADIUS_WORDS_G; (?![A-Za-z]) chặn \"Ra\"/hệ số \"2R\" (nhánh số lo phần \"2\", nhưng \"radius 2R\"\n// hiếm; vẫn fail-safe vì \\d không có sau \"radius\" khi viết \"radius R\").\nconst CENTER_RADIUS_LETTER_WORDS_G = new RegExp(\n CIRCLE_KW +\n '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?:\\\\s*\\\\))?(?:(?!đường|và\\\\s)[^A-Z])*?bán\\\\s*kính\\\\s+[Rr](?![A-Za-z])',\n 'gu',\n);\n\n// === EN words patterns (issue #46 group B) ==================================\n// Tiền tố tâm EN dùng chung cho cả 3 dạng (radius số / radius CHỮ / passing\n// through). Chấp nhận: \"circle with center O\", \"circle centered at O\", \"circle\n// of center O\" + chính tả Anh-Anh \"centre\". cent(?:er|re) + (?:ed)? + (?:at|of)?\n// First-letter case flex [Cc] — KHÔNG cờ 'i' (sẽ phá [A-Z] tâm/điểm).\n//\n// Gap tâm→keyword: tempered `(?:(?![Cc]ircle)[^A-Z])*?` — KHÔNG nhảy qua \"circle\"\n// khác (ranh giới giữa 2 đường tròn) và KHÔNG nuốt chữ HOA (tâm/điểm kế). Lazy →\n// dừng ở \"radius\"/\"passing\" gần nhất. GLOBAL: nhiều đường tròn / clause.\nconst CIRCLE_CENTER_EN =\n '[Cc]ircle\\\\s+(?:with\\\\s+|of\\\\s+)?cent(?:er|re)(?:ed)?\\\\s+(?:at\\\\s+|of\\\\s+)?([A-Z])(?![A-Za-z])';\nconst EN_GAP = '(?:(?![Cc]ircle)[^A-Z])*?';\n\n// \"circle with center O and radius 3\" / \"circle centered at O with radius 3\" /\n// \"circle of center O radius 3\" → centerRadius số.\nconst CIRCLE_CR_EN_G = new RegExp(\n CIRCLE_CENTER_EN + EN_GAP + 'radius\\\\s+(\\\\d+(?:[.,]\\\\d+)?)',\n 'gu',\n);\n\n// \"circle with center O and radius R\" (bán kính CHỮ ký hiệu) → canonical.\n// (?![A-Za-z]) chặn \"Ra\"/hệ số \"2R\" (nhánh số lo phần \"2\", nhưng \"radius 2R\"\n// hiếm; vẫn fail-safe vì \\d không có sau \"radius\" khi viết \"radius R\").\nconst CIRCLE_CR_LETTER_EN_G = new RegExp(\n CIRCLE_CENTER_EN + EN_GAP + 'radius\\\\s+[Rr](?![A-Za-z])',\n 'gu',\n);\n\n// \"circle with center O passing through A\" / \"circle centered at O passing\n// through A\" → centerThrough. Điểm = 1 ký tự HOA neo (?![A-Za-z]).\nconst CIRCLE_THROUGH_EN_G = new RegExp(\n CIRCLE_CENTER_EN + EN_GAP + 'passing\\\\s+through\\\\s+([A-Z])(?![A-Za-z])',\n 'gu',\n);\n\n// Prefilter EN (NON-global để không vướng lastIndex ở .some(test)).\nconst EN_PREFILTER = new RegExp(CIRCLE_CENTER_EN, 'u');\n\n/** \"3\" / \"3.5\" / \"3,5\" → number. NaN nếu không parse được. */\nfunction parseNum(raw: string): number {\n return Number(raw.replace(',', '.'));\n}\n\n/**\n * Circle này là đường tròn NGOẠI/NỘI TIẾP tam giác? (\"tam giác ABC nội tiếp\n * đường tròn (O; 3)\") → circleTriangle sở hữu (through3/inscribedIn theo 3 đỉnh);\n * circleRadius KHÔNG emit thêm 1 đường tròn rời (sẽ chồng + không nhất quán).\n * Bán kính chỉ là chú thích — circumcircle xác định bởi 3 đỉnh, bỏ radius là OK.\n */\nfunction isInscribedCircumscribed(problem: string, center: string): boolean {\n // Quan hệ \"nội/ngoại tiếp\" (VN) + \"inscribed/circumscribes/circumscribed\" (EN,\n // issue #46 group B). EN mirror chống silent-WRONG: \"Triangle ABC inscribed in\n // circle (O; 3)\" — circleTriangle EN sở hữu through3 (qua 3 đỉnh) → circleRadius\n // KHÔNG emit centerRadius rời quanh O.\n const REL = '(?:(?:nội|ngoại)\\\\s*tiếp|[Ii]nscribed|[Cc]ircumscrib(?:es|ed))';\n // Chiều 1 — quan hệ ĐỨNG TRƯỚC circle: \"(tam giác) nội/ngoại tiếp … (O\".\n // Gap [^.]{0,30}? đủ nuốt \"in circle \" trước \"(O\" (EN).\n const after = new RegExp(\n `${REL}[^.]{0,30}?(?:đường\\\\s*tròn\\\\s*|[Cc]ircle\\\\s*)?\\\\(?\\\\s*${center}(?![A-Z])`,\n 'u',\n );\n // Chiều 2 — circle ĐỨNG TRƯỚC quan hệ: ký hiệu \"(O; R) … ngoại/nội tiếp\".\n // circleTriangle sở hữu circumcircle/incircle (qua 3 đỉnh) → circleRadius bỏ\n // để tránh DOUBLE-circle quanh O. [^()]* không vượt ngoặc khác; [^.]{0,30}?\n // không nhảy câu (giữ proximity, tránh false-positive với circle rời khác).\n const before = new RegExp(\n `\\\\(\\\\s*${center}\\\\s*[;,][^()]*\\\\)[^.]{0,30}?${REL}`,\n 'u',\n );\n return after.test(problem) || before.test(problem);\n}\n\n/** Clause chứa fragment \"(<center>\" (ký hiệu gọn bị segmentation cắt vào đây). */\nfunction findParenClauseId(\n clauses: readonly Clause[],\n center: string,\n): number | undefined {\n const frag = new RegExp(`\\\\(\\\\s*${center}(?![A-Z])`, 'u');\n for (const c of clauses) if (frag.test(c.text)) return c.id;\n return undefined;\n}\n\nexport const circleRadiusRule: LanguageRule = {\n id: 'circleRadius',\n priority: 75,\n languages: ['vi', 'en'],\n patterns: [\n CENTER_RADIUS_WORDS_G,\n CENTER_THROUGH_G,\n /\\(\\s*[A-Z]\\s*[;,]\\s*\\d/u,\n /\\(\\s*[A-Z]\\s*[;,]\\s*[Rr]\\s*\\)/u, // ký hiệu bán kính CHỮ \"(O; R)\"\n /bán\\s*kính\\s+[Rr](?![A-Za-z])/u, // words bán kính CHỮ \"bán kính R\"\n EN_PREFILTER, // EN \"circle with center O …\" (issue #46 group B)\n ],\n match(ctx) {\n const out: RuleMatch[] = [];\n\n // --- Per-clause: dạng \"bán kính <số>\" + \"đi qua <điểm>\" (segment nguyên) ---\n for (const c of ctx.clauses) {\n // 1) \"đi qua <điểm>\" (centerThrough). GLOBAL: nhiều đường tròn / clause.\n // \"đi qua B và C\" (≥2 điểm) → SKIP toàn bộ centerThrough clause này:\n // chưa hỗ trợ multi-surface-point, để guard escalate (không render thiếu).\n const throughMulti = THROUGH_MULTI.test(c.text);\n if (!throughMulti) {\n CENTER_THROUGH_G.lastIndex = 0;\n let ct: RegExpExecArray | null;\n while ((ct = CENTER_THROUGH_G.exec(c.text)) !== null) {\n const center = ct[1];\n const through = ct[2];\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerThrough', { center, through })],\n });\n }\n }\n\n // 2) \"bán kính <số>\". GLOBAL: \"tâm I bán kính 2 và tâm O bán kính 5\" emit\n // 2 intent. Gap tempered (xem CENTER_RADIUS_WORDS_G) ⇒ không bind nhầm.\n // radius CHỮ (\"R\") → \\d không match → bỏ qua → escalate.\n CENTER_RADIUS_WORDS_G.lastIndex = 0;\n let crw: RegExpExecArray | null;\n while ((crw = CENTER_RADIUS_WORDS_G.exec(c.text)) !== null) {\n const center = crw[1];\n const radius = parseNum(crw[2]);\n if (!Number.isFinite(radius) || radius <= 0) continue;\n if (isInscribedCircumscribed(ctx.problem, center)) continue; // circleTriangle sở hữu\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius })],\n });\n }\n\n // 3) \"bán kính R/r\" (bán kính CHỮ ký hiệu) → centerRadius bán kính canonical.\n // Clause có \"nội/ngoại tiếp\" → mơ hồ (circleTriangle/escalate sở hữu) → bỏ\n // (clause-local, không ảnh hưởng nhánh số ở clause khác).\n if (!/(?:nội|ngoại)\\s*tiếp/u.test(c.text)) {\n CENTER_RADIUS_LETTER_WORDS_G.lastIndex = 0;\n let clw: RegExpExecArray | null;\n while ((clw = CENTER_RADIUS_LETTER_WORDS_G.exec(c.text)) !== null) {\n const center = clw[1];\n if (isInscribedCircumscribed(ctx.problem, center)) continue;\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius: SYMBOLIC_RADIUS })],\n });\n }\n }\n\n // --- EN words (issue #46 group B) ---------------------------------------\n // Fail-safe: clause có \"inscribed\"/\"circumscribed\" → circle phụ thuộc\n // tam giác/hình (circleTriangle EN OUT OF SCOPE) → KHÔNG emit lone circle.\n if (!/[Ii]nscribed|[Cc]ircumscribed/u.test(c.text)) {\n // 1) passing through → centerThrough.\n CIRCLE_THROUGH_EN_G.lastIndex = 0;\n let ent: RegExpExecArray | null;\n while ((ent = CIRCLE_THROUGH_EN_G.exec(c.text)) !== null) {\n const center = ent[1];\n const through = ent[2];\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerThrough', { center, through })],\n });\n }\n\n // 2) radius <số> → centerRadius.\n CIRCLE_CR_EN_G.lastIndex = 0;\n let ecr: RegExpExecArray | null;\n while ((ecr = CIRCLE_CR_EN_G.exec(c.text)) !== null) {\n const center = ecr[1];\n const radius = parseNum(ecr[2]);\n if (!Number.isFinite(radius) || radius <= 0) continue;\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius })],\n });\n }\n\n // 3) radius R/r (ký hiệu CHỮ) → centerRadius canonical.\n CIRCLE_CR_LETTER_EN_G.lastIndex = 0;\n let ecl: RegExpExecArray | null;\n while ((ecl = CIRCLE_CR_LETTER_EN_G.exec(c.text)) !== null) {\n const center = ecl[1];\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius: SYMBOLIC_RADIUS })],\n });\n }\n }\n }\n\n // --- Toàn đề: ký hiệu gọn \"(O; 3)\" / \"(O, 3)\" (bị segmentation cắt) -------\n CENTER_RADIUS_PAREN_G.lastIndex = 0;\n let pm: RegExpExecArray | null;\n while ((pm = CENTER_RADIUS_PAREN_G.exec(ctx.problem)) !== null) {\n const center = pm[1];\n const radius = parseNum(pm[2]);\n if (!Number.isFinite(radius) || radius <= 0) continue;\n if (isInscribedCircumscribed(ctx.problem, center)) continue; // circleTriangle sở hữu\n const clauseId = findParenClauseId(ctx.clauses, center);\n out.push({\n ruleId: 'circleRadius',\n clauseIds: clauseId === undefined ? [] : [clauseId],\n intents: [drawCircle(center, 'centerRadius', { center, radius })],\n });\n }\n\n // --- Toàn đề: ký hiệu bán kính CHỮ \"(O; R)\" / \"(I; r)\" (segmenter cắt ';') ---\n // Bán kính ký hiệu → bán kính canonical. Guard 2 chiều bỏ qua khi đường tròn\n // nội/ngoại tiếp tam giác (circleTriangle sở hữu).\n CENTER_RADIUS_LETTER_PAREN_G.lastIndex = 0;\n let lpm: RegExpExecArray | null;\n while ((lpm = CENTER_RADIUS_LETTER_PAREN_G.exec(ctx.problem)) !== null) {\n const center = lpm[1];\n if (isInscribedCircumscribed(ctx.problem, center)) continue; // circleTriangle sở hữu\n const clauseId = findParenClauseId(ctx.clauses, center);\n out.push({\n ruleId: 'circleRadius',\n clauseIds: clauseId === undefined ? [] : [clauseId],\n intents: [drawCircle(center, 'centerRadius', { center, radius: SYMBOLIC_RADIUS })],\n });\n }\n\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/circleTriangle.ts\n//\n// Đường tròn nội/ngoại tiếp tam giác:\n// \"đường tròn ngoại tiếp tam giác ABC\" → circumcircle → drawCircle through3\n// \"đường tròn nội tiếp tam giác ABC\" → incircle → drawCircle inscribedIn\n//\n// LƯU Ý disambiguate \"nội tiếp\" có 2 nghĩa ngược nhau tuỳ ngữ cảnh:\n// - \"ĐƯỜNG TRÒN nội tiếp tam giác\" → incircle (inscribedIn)\n// - \"TAM GIÁC nội tiếp đường tròn\" → circumcircle (through3) — tam giác nội\n// tiếp tức đường tròn NGOẠI tiếp tam giác.\n// \"ngoại tiếp\" (đường tròn ngoại tiếp tam giác) luôn là circumcircle.\n//\n// QUAN TRỌNG (chống mis-render):\n// - \"đường tròn ngoại/nội tiếp\" PHẢI theo sau bởi \"tam giác <XYZ>\" (token \"tam\n// giác\" bắt buộc). Nếu theo sau là \"tứ giác\"/\"hình ...\" (vd \"đường tròn\n// ngoại tiếp tứ giác BCEF\") → CHƯA hỗ trợ → KHÔNG claim để escalate AI, KHÔNG\n// được vơ tam giác đầu đề (mis-render circle qua 3 đỉnh khác).\n// - Bind tam giác từ cụm ngay SAU từ khoá trong clause (không phải tam giác\n// đầu tiên trong đề). Nhiều cấu trúc / clause → emit-all (matchAll cờ 'g').\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawCircle, CIRCLE_KW } from './_shared';\n\n// \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Dùng lookaround \\p{L} + cờ 'u'.\nconst HAS_INSCRIBE = /(?<!\\p{L})(?:nội|ngoại)\\s*tiếp(?!\\p{L})/iu;\n\n// Tên tâm tuỳ chọn xen giữa \"đường tròn\" và \"ngoại/nội tiếp\": \"(O)\" hoặc \"tâm O\".\n// (?:...)? để có thể vắng. Cờ 'i' an toàn ở cụm từ khoá; ([A-Z]) vẫn HOA-only.\n// PAREN hỗ trợ cả tên chữ (alpha, omega, (O)...).\nconst CENTER = '(?:\\\\(\\\\s*([^\\\\s;,).:]+)\\\\s*\\\\)|tâm\\\\s+([A-Z]))?';\n\n// \"đường tròn [ (O)/tâm O ] ngoại tiếp tam giác XYZ\" → circumcircle (through3).\n// Token \"tam giác\" + 3 đỉnh HOA BẮT BUỘC ngay sau \"ngoại tiếp\". Cờ 'g' để bắt\n// MỌI cấu trúc trong clause; 'i' để hoa đầu câu (\"Đường\"/\"Ngoại\"/\"Tam\") cũng\n// khớp — nhưng group đỉnh ([A-Z]) KHÔNG dùng 'i' (regex 'i' không tác động lên\n// lớp ký tự đã chỉ định HOA → vẫn chỉ khớp HOA, tránh nuốt chữ thường).\nconst CIRCUM_TRI = new RegExp(\n CIRCLE_KW + '\\\\s*' +\n CENTER +\n '\\\\s*ngoại\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\n\n// \"đường tròn [ (I)/tâm I ] nội tiếp tam giác XYZ\" → incircle (inscribedIn).\nconst INCIRCLE_TRI = new RegExp(\n CIRCLE_KW + '\\\\s*' +\n CENTER +\n '\\\\s*nội\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\n\n// \"tam giác XYZ nội tiếp (trong) đường tròn [ (O)/tâm O ]\" → circumcircle.\n// Tam giác đứng TRƯỚC, đường tròn đứng SAU. Center (nếu có) đứng sau \"đường tròn\".\nconst TRI_INSCRIBED_IN_CIRCLE = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?nội\\\\s*tiếp\\\\s+(?:trong\\\\s+)?' +\n CIRCLE_KW +\n '\\\\s*' +\n CENTER,\n 'giu',\n);\n\n// \"tam giác XYZ ngoại tiếp đường tròn [ (I)/tâm I ]\" → incircle (inscribedIn).\n// Tam giác NGOẠI tiếp (circumscribes) đường tròn = đường tròn NỘI tiếp tam giác.\n// \"đường tròn\" BẮT BUỘC NGAY sau \"ngoại tiếp\" (KHÔNG optional) để phân biệt với\n// \"đường tròn ngoại tiếp tam giác\" (circumcircle — đường tròn đứng TRƯỚC, \"ngoại\n// tiếp\" theo sau bởi \"tam giác\"). [^.]{0,40}? không vượt dấu '.' (không nhảy câu).\nconst TRI_CIRCUMSCRIBES_CIRCLE = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?ngoại\\\\s*tiếp\\\\s+' +\n CIRCLE_KW +\n '\\\\s*' +\n CENTER,\n 'giu',\n);\n\n// Dạng TẮT: \"(O)\"/\"(I)\" NGAY sau \"nội/ngoại tiếp\" — KHÔNG có chữ \"đường tròn\"\n// (vd \"tam giác ABC nội tiếp (O)\"). Phổ biến ở đề olympiad; thiếu nhánh này thì\n// circumcircle O không được tạo → arcMidpoint tham chiếu O fail (transpile).\n// Paren BẮT BUỘC (1 ký tự HOA trong ngoặc) để KHÔNG over-match \"nội tiếp\" trần.\n// Phân biệt với TRI_INSCRIBED_IN_CIRCLE/TRI_CIRCUMSCRIBES_CIRCLE: ở đó sau \"tiếp\"\n// là \"đường tròn\" → 2 nhánh không chồng (dedup theo spec:tri vẫn an toàn nếu có).\nconst TRI_INSCRIBED_IN_PAREN = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?nội\\\\s*tiếp\\\\s+(?:trong\\\\s+)?\\\\(\\\\s*([A-Z])\\\\s*\\\\)',\n 'giu',\n);\nconst TRI_CIRCUMSCRIBES_PAREN = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?ngoại\\\\s*tiếp\\\\s+\\\\(\\\\s*([A-Z])\\\\s*\\\\)',\n 'giu',\n);\n\n// --- Ký hiệu ngoặc \"(O; R)\" quét TOÀN ĐỀ (segmenter cắt ';') ------------------\n// \"(đường tròn)? (O; R) ngoại/nội tiếp tam giác XYZ\" — circle ĐỨNG TRƯỚC. R là\n// CHỮ (bán kính ký hiệu) nên circleRadius bỏ qua (cần \\d). Guard\n// (?![^)]*[A-Z]\\s*[;,]) chặn paren méo nhiều dấu chấm phẩy \"(A; B; C)\".\nconst PAREN_CENTER =\n '(?:' + CIRCLE_KW + '\\\\s*)?\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)\\\\s*';\nconst CIRCUM_TRI_PAREN = new RegExp(\n PAREN_CENTER + 'ngoại\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\nconst INCIRCLE_TRI_PAREN = new RegExp(\n PAREN_CENTER + 'nội\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\n\n// === EN patterns (issue #46 group B) ========================================\n// Semantics đối xứng VN. Phân biệt through3 (circumcircle) vs inscribedIn\n// (incircle) bằng SUBJECT (triangle/circle) + verb:\n// - triangle inscribed in circle → through3 (circle ngoại tiếp tam giác)\n// - triangle circumscribes/circumscribed about circle → inscribedIn (incircle)\n// - circle inscribed in triangle → inscribedIn (incircle)\n// - circle circumscribes/circumscribed about triangle → through3 (circumcircle)\n//\n// KHÔNG cờ 'i' (sẽ nuốt chữ thường vào group nhãn/center [A-Z]). First-letter\n// flex bằng [Tt]riangle / [Cc]ircle / [Ii]nscribed / [Cc]ircumscrib. Group\n// nhãn/center [A-Z] STRICT. Gap token = [^.]{0,N}? (non-greedy, không vượt '.').\n//\n// Center EN sau \"circle\": \"(O)\" (paren) hoặc bare \"O\" (neo (?![A-Za-z])).\nconst EN_CIRCLE_CENTER = '[Cc]ircle\\\\s+(?:\\\\(\\\\s*([A-Z])\\\\s*\\\\)|([A-Z])(?![A-Za-z]))';\nconst EN_TRI = '[Tt]riangle\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])';\n\n// SUBJECT=triangle + \"inscribed in\" circle → through3 (circumcircle).\n// \"triangle ABC (is)? inscribed in (the)? circle (O)\".\nconst EN_TRI_INSCRIBED_IN_CIRCLE = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n EN_CIRCLE_CENTER,\n 'gu',\n);\n\n// SUBJECT=triangle + \"circumscribes / circumscribed about|around\" circle → inscribedIn.\nconst EN_TRI_CIRCUMSCRIBES_CIRCLE = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n EN_CIRCLE_CENTER,\n 'gu',\n);\n\n// SUBJECT=circle + \"inscribed in\" triangle → inscribedIn (incircle).\nconst EN_CIRCLE_INSCRIBED_IN_TRI = new RegExp(\n EN_CIRCLE_CENTER +\n '[^.]{0,12}?[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// SUBJECT=circle + \"circumscribes / circumscribed about|around\" triangle → through3.\nconst EN_CIRCLE_CIRCUMSCRIBES_TRI = new RegExp(\n EN_CIRCLE_CENTER +\n '[^.]{0,12}?[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// --- EN paren whole-problem (segmenter cắt ';' trong \"(O; R)\") ----------------\n// Mirror VN PAREN: center \"(O\" bị cắt khỏi \"R)\". circle ĐỨNG TRƯỚC hoặc SAU.\n// Center = \"(\" + 1 ký tự HOA + \";\"/\",\" (KHÔNG đóng ngoặc cùng clause vì bị cắt).\n// Guard (?![^)]*[A-Z]\\s*[;,]) chặn paren méo nhiều dấu chấm phẩy.\nconst EN_PAREN_CIRCLE =\n '[Cc]ircle\\\\s+\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)\\\\s*';\n\n// \"triangle XYZ inscribed in circle (O; R)\" → through3.\nconst EN_TRI_INSCRIBED_PAREN = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n '[Cc]ircle\\\\s+\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)',\n 'gu',\n);\n\n// \"circle (O; R) circumscribes triangle XYZ\" → through3.\nconst EN_PAREN_CIRCLE_CIRCUMSCRIBES_TRI = new RegExp(\n EN_PAREN_CIRCLE +\n '[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// \"circle (I; r) inscribed in triangle XYZ\" → inscribedIn.\nconst EN_PAREN_CIRCLE_INSCRIBED_TRI = new RegExp(\n EN_PAREN_CIRCLE +\n '[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// \"triangle XYZ circumscribes circle (I; r)\" → inscribedIn.\nconst EN_TRI_CIRCUMSCRIBES_PAREN = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n '[Cc]ircle\\\\s+\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)',\n 'gu',\n);\n\n// Prefilter EN (NON-global cho .test). Chỉ \"inscribed\"/\"circumscrib\" mới quan tâm.\nconst HAS_INSCRIBE_EN = /[Ii]nscribed|[Cc]ircumscrib/u;\n\ninterface CircHit {\n index: number;\n spec: 'through3' | 'inscribedIn';\n tri: [string, string, string];\n /** tên tâm; '' nếu không khai báo (default 'O' khi emit). */\n center: string;\n}\n\nfunction pushAll(\n text: string,\n re: RegExp,\n spec: 'through3' | 'inscribedIn',\n // index của 3 group đỉnh trong match; center luôn group 1+2.\n triStart: number,\n out: CircHit[],\n): void {\n re.lastIndex = 0;\n for (const m of text.matchAll(re)) {\n const center = m[1] ?? m[2] ?? '';\n out.push({\n index: m.index ?? 0,\n spec,\n tri: [m[triStart], m[triStart + 1], m[triStart + 2]],\n center,\n });\n }\n}\n\n/**\n * Quét MỌI cấu trúc \"(đường tròn) ngoại/nội tiếp tam giác XYZ\" trong 1 clause.\n * Vùng text [start,end) đã thuộc 1 cấu trúc thì cấu trúc khác bỏ qua (tránh\n * trùng — \"tam giác XYZ nội tiếp đường tròn\" KHÔNG bị INCIRCLE_TRI quét lại).\n */\nfunction scanClause(text: string): CircHit[] {\n const hits: CircHit[] = [];\n // CIRCUM_TRI / INCIRCLE_TRI: center là group 1|2, đỉnh là group 3,4,5.\n pushAll(text, CIRCUM_TRI, 'through3', 3, hits);\n pushAll(text, INCIRCLE_TRI, 'inscribedIn', 3, hits);\n // TRI_INSCRIBED_IN_CIRCLE: đỉnh là group 1,2,3, center là group 4|5.\n TRI_INSCRIBED_IN_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(TRI_INSCRIBED_IN_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'through3',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n // TRI_CIRCUMSCRIBES_CIRCLE: tam giác ngoại tiếp đường tròn → incircle (inscribedIn).\n TRI_CIRCUMSCRIBES_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(TRI_CIRCUMSCRIBES_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'inscribedIn',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n // Dạng tắt \"(O)\"/\"(I)\" không kèm \"đường tròn\": center là group 4.\n TRI_INSCRIBED_IN_PAREN.lastIndex = 0;\n for (const m of text.matchAll(TRI_INSCRIBED_IN_PAREN)) {\n hits.push({ index: m.index ?? 0, spec: 'through3', tri: [m[1], m[2], m[3]], center: m[4] ?? '' });\n }\n TRI_CIRCUMSCRIBES_PAREN.lastIndex = 0;\n for (const m of text.matchAll(TRI_CIRCUMSCRIBES_PAREN)) {\n hits.push({ index: m.index ?? 0, spec: 'inscribedIn', tri: [m[1], m[2], m[3]], center: m[4] ?? '' });\n }\n\n // --- EN (issue #46 group B) ---------------------------------------------\n // SUBJECT=triangle (group 1,2,3) → center group 4|5.\n EN_TRI_INSCRIBED_IN_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(EN_TRI_INSCRIBED_IN_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'through3',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n EN_TRI_CIRCUMSCRIBES_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(EN_TRI_CIRCUMSCRIBES_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'inscribedIn',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n // SUBJECT=circle (center group 1|2) → triangle group 3,4,5.\n EN_CIRCLE_INSCRIBED_IN_TRI.lastIndex = 0;\n for (const m of text.matchAll(EN_CIRCLE_INSCRIBED_IN_TRI)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'inscribedIn',\n tri: [m[3], m[4], m[5]],\n center: m[1] ?? m[2] ?? '',\n });\n }\n EN_CIRCLE_CIRCUMSCRIBES_TRI.lastIndex = 0;\n for (const m of text.matchAll(EN_CIRCLE_CIRCUMSCRIBES_TRI)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'through3',\n tri: [m[3], m[4], m[5]],\n center: m[1] ?? m[2] ?? '',\n });\n }\n\n // Khử trùng: 2 hit cùng 3 đỉnh + cùng spec → giữ 1 (vd câu vừa khớp\n // CIRCUM_TRI lẫn TRI_INSCRIBED_IN_CIRCLE hiếm khi xảy ra, nhưng an toàn).\n const seen = new Set<string>();\n const dedup: CircHit[] = [];\n hits.sort((a, b) => a.index - b.index);\n for (const h of hits) {\n const key = `${h.spec}:${h.tri.join('')}`;\n if (seen.has(key)) continue;\n seen.add(key);\n dedup.push(h);\n }\n return dedup;\n}\n\ninterface ParenHit {\n spec: 'through3' | 'inscribedIn';\n tri: [string, string, string];\n center: string;\n /** text khớp trên TOÀN đề (để gán clauseId qua substring-inclusion). */\n matchedText: string;\n}\n\n/**\n * Quét TOÀN đề cho ký hiệu ngoặc \"(O; R) ngoại/nội tiếp tam giác XYZ\" — dạng bị\n * segmenter cắt ngang ';' nên per-clause không bắt được. circle ĐỨNG TRƯỚC.\n */\nfunction scanProblemParen(problem: string): ParenHit[] {\n const out: ParenHit[] = [];\n const push = (re: RegExp, spec: 'through3' | 'inscribedIn') => {\n re.lastIndex = 0;\n for (const m of problem.matchAll(re)) {\n out.push({\n spec,\n tri: [m[2], m[3], m[4]],\n center: m[1] ?? '',\n matchedText: m[0],\n });\n }\n };\n push(CIRCUM_TRI_PAREN, 'through3');\n push(INCIRCLE_TRI_PAREN, 'inscribedIn');\n\n // --- EN (issue #46 group B): center group khác vị trí tuỳ SUBJECT ----------\n // SUBJECT=triangle (group 1,2,3) → center group 4.\n const pushTriFirst = (re: RegExp, spec: 'through3' | 'inscribedIn') => {\n re.lastIndex = 0;\n for (const m of problem.matchAll(re)) {\n out.push({ spec, tri: [m[1], m[2], m[3]], center: m[4] ?? '', matchedText: m[0] });\n }\n };\n pushTriFirst(EN_TRI_INSCRIBED_PAREN, 'through3');\n pushTriFirst(EN_TRI_CIRCUMSCRIBES_PAREN, 'inscribedIn');\n // SUBJECT=circle (center group 1) → triangle group 2,3,4.\n push(EN_PAREN_CIRCLE_CIRCUMSCRIBES_TRI, 'through3');\n push(EN_PAREN_CIRCLE_INSCRIBED_TRI, 'inscribedIn');\n return out;\n}\n\nfunction intentFor(spec: 'through3' | 'inscribedIn', tri: string[], center: string) {\n const name = center || 'O';\n return spec === 'inscribedIn'\n ? drawCircle(name, 'inscribedIn', { triangle: tri })\n : drawCircle(name, 'through3', { points: tri });\n}\n\n/**\n * Mỗi clause: quét emit-all các \"(đường tròn) nội/ngoại tiếp tam giác XYZ\".\n * - circumcircle (through3): \"đường tròn ngoại tiếp tam giác ABC\",\n * \"tam giác ABC nội tiếp đường tròn (O)\".\n * - incircle (inscribedIn): \"đường tròn nội tiếp tam giác ABC\",\n * \"tam giác ABC ngoại tiếp đường tròn (I)\".\n * Cộng nhánh TOÀN đề cho ký hiệu \"(O; R) ngoại/nội tiếp tam giác\" (bị cắt ';').\n * \"ngoại/nội tiếp\" mà KHÔNG có \"tam giác XYZ\" ngay sau (vd \"tứ giác\", \"hình\n * ...\", hoặc \"nội tiếp\" trần) → KHÔNG claim → escalate AI.\n */\nexport const circleTriangleRule: LanguageRule = {\n id: 'circleTriangle',\n priority: 72,\n languages: ['vi', 'en'],\n patterns: [HAS_INSCRIBE, HAS_INSCRIBE_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n const emitted = new Set<string>(); // \"spec:tri\" — dedup cross per-clause/paren.\n\n // 1) Per-clause (VN giữ nguyên hành vi cũ; EN thêm qua HAS_INSCRIBE_EN).\n for (const c of ctx.clauses) {\n if (!HAS_INSCRIBE.test(c.text) && !HAS_INSCRIBE_EN.test(c.text)) continue;\n const hits = scanClause(c.text);\n if (hits.length === 0) continue; // có \"ngoại/nội tiếp\" nhưng không tam giác\n for (const h of hits) emitted.add(`${h.spec}:${h.tri.join('')}`);\n out.push({\n ruleId: 'circleTriangle',\n clauseIds: [c.id],\n intents: hits.map((h) => intentFor(h.spec, h.tri, h.center)),\n });\n }\n\n // 2) Toàn đề: ký hiệu \"(O; R)\" (segmenter cắt ';'). Bỏ qua nếu (spec:tri) đã\n // emit ở per-clause. clauseId = mọi clause là substring của đoạn khớp\n // (đoạn này trải qua nhiều clause do bị cắt) → coverage tính phủ cả 2.\n for (const h of scanProblemParen(ctx.problem)) {\n const key = `${h.spec}:${h.tri.join('')}`;\n if (emitted.has(key)) continue;\n emitted.add(key);\n const clauseIds = ctx.clauses\n .filter((c) => h.matchedText.includes(c.text))\n .map((c) => c.id);\n out.push({\n ruleId: 'circleTriangle',\n clauseIds,\n intents: [intentFor(h.spec, h.tri, h.center)],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/tangentFromExt.ts\n//\n// Tiếp tuyến TỪ điểm NGOÀI đường tròn (2 nhánh):\n// \"Kẻ hai tiếp tuyến từ A đến (O)\" → drawLine(t, tangentFromExt, {from:'A', circle:'O', which:'both'})\n// \"Vẽ tiếp tuyến từ điểm A tới đường tròn O\" → drawLine(t, tangentFromExt, {from:'A', circle:'O', which:'both'})\n// \"Từ A vẽ tiếp tuyến với (O)\" → drawLine(t, tangentFromExt, {from:'A', circle:'O', which:'both'})\n//\n// Phân biệt với tangentAt (\"tiếp tuyến TẠI A của (O)\") — chỗ đó dùng \"tại\",\n// còn ở đây là \"từ <điểm ngoài>\". Rule này CHỈ match \"từ\"/\"Từ ... vẽ tiếp tuyến\".\n//\n// GOTCHA: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\n// from / circle là 1 ký tự HOA; name của line default 't' (LabelZ cho phép).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawLine, addPoint } from './_shared';\n\n// Prefilter toàn đề: phải có \"tiếp tuyến\".\nconst HAS_TANGENT = /tiếp\\s*tuyến/u;\n\n// Target đường tròn: PHẢI có dấu hiệu đường tròn — \"(X)\" hoặc \"đường tròn X\".\n// KHÔNG nhận chữ HOA TRẦN (vd \"tiếp tuyến từ A đến BC\": \"BC\" là đoạn thẳng, không\n// phải đường tròn → không claim, escalate). Hai alternative → 2 capture nhóm,\n// caller lấy nhóm nào khớp.\nconst CIRCLE_TARGET = String.raw`(?:đường\\s*tròn\\s*([A-Z])(?:['′]?)|\\(\\s*([A-Z])(?:['′]?)\\s*\\))`;\n\n// \"(kẻ|vẽ) (hai)? tiếp tuyến từ (điểm)? A (đến|tới|với) <đường tròn>\"\n// - động từ kẻ/vẽ BẮT BUỘC: chặn ngữ cảnh TÍNH/giả thiết (\"Độ dài tiếp tuyến\n// từ A đến (O) bằng 5\" → không có kẻ/vẽ → không match, escalate).\n// - \"hai\"/\"một\" optional (1 hay 2 nhánh vẫn coi là tiếp tuyến từ điểm ngoài).\n// - from = 1 ký tự HOA sau \"từ (điểm)?\".\n// - giới từ đến/tới/với nối qua đường tròn (bắt buộc có dấu hiệu — CIRCLE_TARGET).\nconst FROM_FORM = new RegExp(\n String.raw`(?:[Kk]ẻ|[Vv]ẽ)\\s+(?:một\\s+|hai\\s+)?tiếp\\s*tuyến\\s+từ\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)\\s+(?:đến|tới|với)\\s+` +\n CIRCLE_TARGET,\n 'u',\n);\n\n// Biến thể đảo: \"Từ (điểm)? A ... (kẻ|vẽ) (hai)? tiếp tuyến (đến|tới|với) <đường tròn>\".\n// - kẻ|vẽ vẫn bắt buộc (đã có sẵn trong cú pháp đảo).\nconst TU_FORM = new RegExp(\n String.raw`(?<!\\p{L})[Tt]ừ\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)(?!\\p{L})[^.]{0,40}?(?:[Kk]ẻ|[Vv]ẽ)\\s+(?:một\\s+|hai\\s+)?tiếp\\s*tuyến\\s+(?:đến|tới|với)\\s+` +\n CIRCLE_TARGET,\n 'u',\n);\n\n// === EN patterns (issue #46 group B) ========================================\n// Target đường tròn EN: \"(X)\" (language-agnostic, giống VN) HOẶC \"circle X\" /\n// \"circle (X)\". KHÔNG nhận chữ HOA TRẦN (\"from A to BC\": BC là đoạn → không\n// claim → escalate). Hai alternative → 2 capture nhóm (caller lấy nhóm nào khớp).\n// - nhóm 1: ([A-Z]) sau \"circle\" (có thể bọc \"(...)\").\n// - nhóm 2: ([A-Z]) trong \"(...)\" trần (không từ \"circle\").\n// First-letter flex [Cc]; KHÔNG cờ 'i' (giữ [A-Z] strict cho nhãn).\nconst CIRCLE_TARGET_EN = String.raw`(?:[Cc]ircle\\s*\\(?\\s*([A-Z])(?:['′]?)\\s*\\)?|\\(\\s*([A-Z])(?:['′]?)\\s*\\))`;\n\n// \"(Draw|Construct) (the|two)? tangent(s)? (lines)? from (the)? A to (the)? <circle>\"\n// - động từ Draw/Construct BẮT BUỘC: chặn ngữ cảnh TÍNH (\"The length of the\n// tangent from A to (O) is 5\" → không có Draw/Construct → không match,\n// escalate). Mirror ràng buộc verb của FROM_FORM (VN).\n// - giới từ \"from <A> to <circle>\" BẮT BUỘC: phân biệt với tangentAt\n// (\"tangent ... at A\" → không có \"from ... to\" → không match ở đây).\n// - from = 1 ký tự HOA sau \"from (the)?\".\n// - circle bắt buộc có dấu hiệu (CIRCLE_TARGET_EN — \"(X)\" hoặc \"circle X\").\n// GROUP INDEX: from = nhóm 1; circle = nhóm 2 (\"circle X\") HOẶC nhóm 3 (\"(X)\").\nconst FROM_FORM_EN = new RegExp(\n String.raw`(?:[Dd]raw|[Cc]onstruct)\\s+(?:the\\s+|two\\s+|the\\s+two\\s+)?tangents?(?:\\s+lines?)?\\s+from\\s+(?:the\\s+)?([A-Z])(?:['′]?)\\s+to\\s+(?:the\\s+)?` +\n CIRCLE_TARGET_EN,\n 'u',\n);\n\n// Biến thể đảo EN: \"From (the)? A, ... (draw|construct) (the|two)? tangent(s)?\n// (lines)? to (the)? <circle>\".\n// - verb draw/construct vẫn bắt buộc (nằm sau \"From A\").\n// - \"from A ... to <circle>\" vẫn đầy đủ (from ở đầu, to trước circle).\n// GROUP INDEX: from = nhóm 1; circle = nhóm 2 (\"circle X\") HOẶC nhóm 3 (\"(X)\").\nconst FROM_INV_EN = new RegExp(\n String.raw`(?<![A-Za-z])[Ff]rom\\s+(?:the\\s+)?([A-Z])(?:['′]?)(?![A-Za-z])[^.]{0,40}?(?:[Dd]raw|[Cc]onstruct)\\s+(?:the\\s+|two\\s+|the\\s+two\\s+)?tangents?(?:\\s+lines?)?\\s+to\\s+(?:the\\s+)?` +\n CIRCLE_TARGET_EN,\n 'u',\n);\n\n// === NAMED tangent points (issue #46) =======================================\n// \"Vẽ hai tiếp tuyến AB, AC từ A đến (O)\" — B, C LÀ tiếp điểm (named). Khác với\n// nhánh UNNAMED ở trên (regex unnamed FAIL vì \"AB, AC\" chen giữa \"tiếp tuyến\" và\n// \"từ\"). Hai regex dưới bắt 2 đoạn tiếp tuyến + đường tròn trong 1 match.\n// GROUP INDEX (cả VN & EN): m[1]=chữ đầu đoạn 1 (điểm ngoài x1),\n// m[2]=tiếp điểm 1 (B), m[3]=chữ đầu đoạn 2 (x2), m[4]=tiếp điểm 2 (C),\n// m[5]/m[6] = circle (qua CIRCLE_TARGET / CIRCLE_TARGET_EN).\nconst NAMED_FROM_VN = new RegExp(\n String.raw`(?:[Kk]ẻ|[Vv]ẽ)\\s+(?:một\\s+|hai\\s+)?tiếp\\s*tuyến\\s+([A-Z])([A-Z])\\s*(?:,|và)\\s*([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?(?:đến|tới|với)\\s+` +\n CIRCLE_TARGET,\n 'u',\n);\nconst NAMED_FROM_EN = new RegExp(\n String.raw`(?:[Dd]raw|[Cc]onstruct)\\s+(?:the\\s+|two\\s+|the\\s+two\\s+)?tangents?(?:\\s+lines?)?\\s+([A-Z])([A-Z])\\s*(?:,|and)\\s*([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?to\\s+(?:the\\s+)?` +\n CIRCLE_TARGET_EN,\n 'u',\n);\n\nexport const tangentFromExtRule: LanguageRule = {\n id: 'tangentFromExt',\n priority: 65,\n languages: ['vi', 'en'],\n // EN prefilter \"tangent\" để runRules (prefilter qua patterns[], bỏ qua\n // languages) chạy match() cho đề EN thuần (không có \"tiếp tuyến\").\n patterns: [HAS_TANGENT, /[Tt]angent/u],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n // === NAMED tangent points (issue #46): \"tiếp tuyến AB, AC ... (O)\" → dựng\n // tiếp điểm B,C (tangentPointExt) cộng với 2 tiếp tuyến. from = chữ cái đầu\n // CHUNG của 2 đoạn (điểm ngoài); tiếp điểm = chữ cái thứ 2 mỗi đoạn.\n const named = NAMED_FROM_VN.exec(c.text) ?? NAMED_FROM_EN.exec(c.text);\n if (named) {\n const from = named[1];\n const tpB = named[2];\n const x2 = named[3];\n const tpC = named[4];\n const circle = named[5] ?? named[6];\n // Hợp lệ: cùng điểm ngoài (m1===m3), 2 tiếp điểm phân biệt & khác điểm ngoài.\n if (\n circle && from === x2 &&\n tpB !== from && tpC !== from && tpB !== tpC\n ) {\n out.push({\n ruleId: 'tangentFromExt',\n clauseIds: [c.id],\n intents: [\n drawLine('t', 'tangentFromExt', { from, circle, which: 'both' }),\n addPoint(tpB, { kind: 'tangentPoint', from, circle, which: 0 }),\n addPoint(tpC, { kind: 'tangentPoint', from, circle, which: 1 }),\n ],\n });\n continue; // clause handled — skip unnamed path\n }\n // not valid named form → fall through to unnamed logic (will likely escalate)\n }\n // VN trước (FROM_FORM / TU_FORM), giữ nguyên hành vi cũ; EN sau (FROM_FORM_EN\n // / FROM_INV_EN). circle bắt qua 1 trong các alternative capture group.\n const m =\n FROM_FORM.exec(c.text) ??\n TU_FORM.exec(c.text) ??\n FROM_FORM_EN.exec(c.text) ??\n FROM_INV_EN.exec(c.text);\n if (!m) continue;\n const from = m[1];\n // circle bắt qua 1 trong 2 alternative:\n // VN: \"đường tròn X\" = m[2], \"(X)\" = m[3].\n // EN: \"circle X\" = m[2], \"(X)\" = m[3] (cùng index — cả 2 dạng đều có\n // circle ở nhóm 2/3 vì from luôn là nhóm 1, CIRCLE_TARGET(_EN) có 2\n // alternative nhóm 2 & 3).\n const circle = m[2] ?? m[3];\n // Không xác định được from hoặc circle → bỏ qua (escalate AI).\n if (!from || !circle) continue;\n out.push({\n ruleId: 'tangentFromExt',\n clauseIds: [c.id],\n intents: [\n drawLine('t', 'tangentFromExt', { from, circle, which: 'both' }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/externalPoint.ts\n//\n// Điểm nằm NGOÀI đường tròn (free external point):\n// \"Lấy điểm A nằm ngoài đường tròn (O)\" → addPoint(A, {externalToCircle, circle:'O'})\n// \"Lấy điểm A ở ngoài (O)\" → addPoint(A, {externalToCircle, circle:'O'})\n// \"Gọi A là điểm nằm ngoài (O)\" → addPoint(A, {externalToCircle, circle:'O'})\n// \"Take a point A outside the circle (O).\" (EN) → addPoint(A, {externalToCircle, circle:'O'})\n//\n// Mục đích: UNBLOCK tangentFromExt render END-TO-END. tangentFromExt emit\n// drawLine(from:'A', circle:'O') nhưng KHÔNG rule nào dựng điểm A ngoài circle\n// → transpile UNKNOWN_REF A → escalate. Rule này dựng A (qua builder\n// externalToCircle, đọc tâm+bán kính từ build state, đặt A free ngoài circle).\n//\n// PRIORITY 68: sau circleRadius (75) / circleTriangle (72) để circle build\n// TRƯỚC, trước tangentFromExt (65) để A build TRƯỚC tangent. Build order:\n// circle → A → tangent (đúng phụ thuộc).\n//\n// GOTCHA \\b: ký tự Việt \"ngoài\" → KHÔNG dùng \\b. Cờ 'u' cho mọi regex.\n// `[^.A-Z]` giữa name và \"ngoài\"/\"outside\" chặn nhảy qua nhãn HOA khác / dấu chấm.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// VN: \"(Lấy|Gọi) (điểm)? A ... ngoài (đường tròn (X) | (X))\".\n// - from = nhóm 1 (1 ký tự HOA).\n// - circle = nhóm 2 (\"đường tròn X\") HOẶC nhóm 3 (\"(X)\").\n// - [^.A-Z]{0,14}? cho \"nằm\"/\"ở\" chen giữa, chặn dấu chấm / nhãn HOA khác.\nconst VN_FORM = new RegExp(\n String.raw`(?:[Ll]ấy|[Gg]ọi)\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)[^.A-Z]{0,14}?ngoài\\s+(?:đường\\s*tròn\\s*\\(?\\s*([A-Z])\\s*\\)?|\\(\\s*([A-Z])\\s*\\))`,\n 'u',\n);\n\n// EN: \"(Take|Let|Mark|Choose|Pick) (a)? (point)? A ... outside (the)? (circle (X) | (X))\".\n// - from = nhóm 1; circle = nhóm 2 (\"circle X\") HOẶC nhóm 3 (\"(X)\").\n// - [^.A-Z]{0,24}? cho \"be a point\"/\"nằm\" chen giữa, chặn dấu chấm / nhãn HOA.\nconst EN_FORM = new RegExp(\n String.raw`(?:[Tt]ake|[Ll]et|[Mm]ark|[Cc]hoose|[Pp]ick)\\s+(?:a\\s+)?(?:point\\s+)?([A-Z])(?:['′]?)[^.A-Z]{0,24}?outside\\s+(?:the\\s+)?(?:[Cc]ircle\\s*\\(?\\s*([A-Z])\\s*\\)?|\\(\\s*([A-Z])\\s*\\))`,\n 'u',\n);\n\nexport const externalPointRule: LanguageRule = {\n id: 'externalPoint',\n priority: 68,\n languages: ['vi', 'en'],\n // Prefilter toàn đề (runRules prefilter qua patterns[], BỎ QUA languages):\n // cần bắt cả VN (\"ngoài\") lẫn EN (\"outside\"). match() mới có regex chặt.\n patterns: [/ngoài/u, /[Oo]utside/u],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const m = VN_FORM.exec(c.text) ?? EN_FORM.exec(c.text);\n if (!m) continue;\n const from = m[1];\n const circle = m[2] ?? m[3];\n if (!from || !circle) continue; // escalate-safe\n out.push({\n ruleId: 'externalPoint',\n clauseIds: [c.id],\n intents: [addPoint(from, { kind: 'externalToCircle', circle })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/arcMidpoint.ts\n//\n// Điểm chính giữa cung: \"Gọi M là điểm chính giữa cung BC (không chứa A)\".\n// → add-point M {kind:'arcMidpoint', circle:'O', a:'B', b:'C', notContaining:'A'}\n//\n// circle lấy từ toàn đề (\"(O)\" / \"đường tròn (tâm) O\"); KHÔNG có circle → bỏ qua\n// (escalate AI — không thể dựng cung mà không biết đường tròn).\n//\n// notContaining (PHẢI là đỉnh thứ 3, ∉ {a,b}):\n// - \"không chứa X\" → X (chỉ nhận nếu X ∉ {a,b}; X∈{a,b} vô nghĩa → bỏ qua)\n// - không nêu nhưng có tam giác → đỉnh thứ 3 (đỉnh tam giác không thuộc cặp cung)\n// - cả hai đều không suy được → bỏ qua (escalate)\n//\n// CHỈ xử lý cú pháp \"cung (nhỏ)? <PAIR> không chứa <Z>\" (containment ÂM, cung nhỏ).\n// Vượt scope → bỏ qua (escalate, an toàn — đừng mis-render):\n// - \"cung lớn <PAIR>\" → cung lớn, ngữ nghĩa cung đối → defer\n// - \"chứa X\" (containment DƯƠNG, không có \"không\" đứng trước) → defer\n//\n// Tên điểm qua extractPointName / ký tự HOA trước \"(là) điểm chính giữa\"; không\n// trích được tên → bỏ qua (đừng bịa tên).\n//\n// EN (issue #46 group B): hỗ trợ thêm các dạng tiếng Anh tương đương —\n// \"Let M be the midpoint of arc BC not containing A\"\n// \"M is the midpoint of the (minor) arc BC\" (suy notContaining từ \"Triangle ABC\")\n// \"major arc\" → defer (mirror \"cung lớn\"); \"containing X\" dương → defer.\n// Tên điểm EN qua \"X is/be the midpoint of … arc\" (extractPointName là VN-only).\n// Collision midpoint EN (rule prio 50): KHÔNG xảy ra — midpoint EN cần\n// \"midpoint of (segment|side)? [A-Z][A-Z]\", nhưng sau \"of\" ở đây là \"arc\" (chữ\n// thường) → [A-Z] fail → midpoint không grab \"BC\".\n//\n// GOTCHA \\b: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { addPoint, drawCircle, extractPointName, pairFromToken } from './_shared';\n\n// Prefilter toàn đề: \"chính giữa cung\" hoặc \"trung điểm cung\".\nconst ARC_MID = /(?:chính\\s+giữa|trung\\s*điểm)\\s+(?:của\\s+)?cung/u;\n\n// Cụm cung + cặp đỉnh: \"điểm chính giữa cung (nhỏ|lớn) BC\".\n// \"nhỏ|lớn\" optional; \"của\" optional. Cặp đỉnh = 2 ký tự HOA liền.\nconst ARC_PAIR =\n /(?:chính\\s+giữa|trung\\s*điểm)\\s+(?:của\\s+)?cung\\s+(?:nhỏ\\s+|lớn\\s+)?([A-Z])([A-Z])/u;\n\n// Tên điểm đứng TRƯỚC cụm: \"M (là) (điểm) (chính giữa|trung điểm) cung\".\nconst NAME_BEFORE =\n /([A-Z])(?:['′]?)\\s+(?:là\\s+)?(?:điểm\\s+)?(?:chính\\s+giữa|trung\\s*điểm)\\s+(?:của\\s+)?cung/u;\n\n// \"không chứa X\" → X.\nconst NOT_CONTAINING = /không\\s+chứa\\s+([A-Z])/u;\n\n// Tam giác trong toàn đề → 3 đỉnh (dùng suy notContaining khi đề không nêu).\nconst TRI = /tam giác\\s+([A-Z])([A-Z])([A-Z])/u;\n\n// Tên đường tròn trong toàn đề: \"đường tròn (tâm) O\" / \"(O)\".\n// - \"đường tròn tâm O\" / \"đường tròn O\" → O\n// - \"(O)\" đứng riêng (1 ký tự HOA trong ngoặc, không phải cặp đỉnh / số)\nconst CIRCLE_WORDS = /đường\\s*tròn\\s*(?:\\(\\s*)?(?:tâm\\s+)?([A-Z])(?![A-Z])/u;\nconst CIRCLE_PAREN = /\\(\\s*([A-Z])\\s*\\)/u;\n\n// === EN patterns (issue #46 group B) =========================================\n// First-letter case-flex [Mm]/[Tt]; KHÔNG cờ 'i' (phá nhãn [A-Z]). Nhãn STRICT\n// [A-Z] + neo (?![A-Za-z]) cuối cặp đỉnh (chặn \"BCD\" 3 chữ → escalate-safe).\n// Prefilter EN: \"midpoint of (the)? (minor|major)? arc\".\nconst ARC_MID_EN = /[Mm]idpoint\\s+of\\s+(?:the\\s+)?(?:minor\\s+|major\\s+)?arc/u;\n// Cụm cung + cặp đỉnh EN.\nconst ARC_PAIR_EN =\n /[Mm]idpoint\\s+of\\s+(?:the\\s+)?(?:minor\\s+|major\\s+)?arc\\s+([A-Z])([A-Z])(?![A-Za-z])/u;\n// Tên đứng TRƯỚC: \"M is/be the midpoint of arc\". (EN không có lời dẫn VN; extractPointName VN-only.)\nconst NAME_BEFORE_EN =\n /([A-Z])(?:['′]?)\\s+(?:is|be)\\s+the\\s+midpoint\\s+of\\s+(?:the\\s+)?(?:minor\\s+|major\\s+)?arc/u;\n// \"not containing (the)? (point|vertex)? X\".\nconst NOT_CONTAINING_EN = /not\\s+containing\\s+(?:the\\s+)?(?:point\\s+|vertex\\s+)?([A-Z])(?![A-Za-z])/u;\n// Tam giác EN (suy notContaining khi không nêu \"not containing\").\nconst TRI_EN = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Za-z])/u;\n// Scope guard: \"major arc\" → defer (mirror VN \"cung lớn\").\nconst MAJOR_ARC_EN = /major\\s+arc/u;\n\n/** Tên đường tròn từ toàn đề; undefined nếu không tìm thấy. */\nfunction resolveCircle(problem: string): string | undefined {\n const w = CIRCLE_WORDS.exec(problem);\n if (w) return w[1];\n const p = CIRCLE_PAREN.exec(problem);\n if (p) return p[1];\n return undefined;\n}\n\n/**\n * Tên cho circumcircle NGẦM (khi đề không nêu \"(O)\"): ưu tiên 'O' (quy ước), né\n * nếu đã là token HOA đứng riêng trong đề (vd điểm O); else 'O1'/'O2'/'W'.\n */\nfunction synthCircleName(problem: string): string {\n for (const cand of ['O', 'O1', 'O2', 'W']) {\n if (!new RegExp(`(?<!\\\\p{L})${cand}(?![\\\\p{L}\\\\d])`, 'u').test(problem)) return cand;\n }\n return 'O'; // fallback (resolveCircleNameCollisions sẽ dedup nếu cần)\n}\n\n/**\n * \"Gọi M là điểm chính giữa cung nhỏ BC không chứa A\" → add-point M\n * {kind:'arcMidpoint', circle, a:'B', b:'C', notContaining:'A'}.\n *\n * Một clause khớp khi: trích được tên điểm, cặp đỉnh cung, đường tròn, và\n * notContaining (nêu \"không chứa X\" hoặc suy từ đỉnh thứ 3 của tam giác). Thiếu\n * bất kỳ thành phần nào → bỏ qua clause (escalate AI thay vì đoán sai).\n */\nexport const arcMidpointRule: LanguageRule = {\n id: 'arcMidpoint',\n priority: 60,\n languages: ['vi', 'en'],\n patterns: [ARC_MID, ARC_MID_EN],\n match(ctx) {\n const explicitCircle = resolveCircle(ctx.problem);\n const tri = TRI.exec(ctx.problem);\n const triEnM0 = TRI_EN.exec(ctx.problem);\n // Tam giác để suy circumcircle NGẦM khi đề KHÔNG nêu \"(O)\" (VN ưu tiên, EN fallback).\n const circumTri: string[] | null = tri\n ? [tri[1], tri[2], tri[3]]\n : triEnM0\n ? [triEnM0[1], triEnM0[2], triEnM0[3]]\n : null;\n // \"(O)\" tường minh thắng; else circumcircle ngầm của tam giác (tên synth).\n const circle = explicitCircle ?? (circumTri ? synthCircleName(ctx.problem) : undefined);\n if (!circle) return []; // không circle tường minh + không tam giác → escalate\n const usesCircum = !explicitCircle;\n\n const out: RuleMatch[] = [];\n // Khi dùng circumcircle ngầm, prepend drawCircle(through3) vào arcMidpoint ĐẦU\n // TIÊN dùng nó → circle emit TRƯỚC điểm (transpile resolve ref theo thứ tự).\n let circumEmitted = false;\n const withCircum = (ap: IntentT): IntentT[] => {\n if (usesCircum && !circumEmitted && circumTri) {\n circumEmitted = true;\n return [drawCircle(circle, 'through3', { points: circumTri }), ap];\n }\n return [ap];\n };\n // Circumcircle ngầm chỉ hợp lệ khi 2 đầu mút cung LÀ đỉnh tam giác.\n const arcOnCircum = (a: string, b: string): boolean =>\n !usesCircum || (!!circumTri && circumTri.includes(a) && circumTri.includes(b));\n\n for (const c of ctx.clauses) {\n if (!ARC_MID.test(c.text)) continue;\n\n // Vượt scope (chỉ xử lý \"cung (nhỏ) PAIR không chứa Z\"):\n // - \"cung lớn\" → cung đối, defer → escalate\n // - \"chứa X\" containment DƯƠNG (không có \"không\" trước) → defer → escalate\n if (/cung\\s+lớn/u.test(c.text)) continue;\n if (/chứa/u.test(c.text) && !/không\\s+chứa/u.test(c.text)) continue;\n\n const pairM = ARC_PAIR.exec(c.text);\n if (!pairM) continue;\n const pair = pairFromToken(pairM[1] + pairM[2]);\n if (pair.length !== 2) continue;\n const [a, b] = pair;\n if (!arcOnCircum(a, b)) continue; // circumcircle ngầm: cung phải là 2 đỉnh tam giác\n\n // Tên điểm: lời dẫn \"Gọi/Lấy X là …\" ưu tiên, fallback HOA trước cụm.\n const before = NAME_BEFORE.exec(c.text);\n const name = extractPointName(c.text) ?? (before ? before[1] : undefined);\n if (!name) continue; // không trích được tên → bỏ qua\n\n // notContaining: \"không chứa X\" hoặc đỉnh thứ 3 của tam giác.\n let notContaining: string | undefined;\n const nc = NOT_CONTAINING.exec(c.text);\n if (nc) {\n notContaining = nc[1];\n // notContaining = endpoint của cung (a/b) → vô nghĩa hình học → escalate.\n if (notContaining === a || notContaining === b) continue;\n } else if (tri) {\n const verts = [tri[1], tri[2], tri[3]];\n notContaining = verts.find((v) => v !== a && v !== b);\n }\n if (!notContaining) continue; // không suy được → bỏ qua\n\n out.push({\n ruleId: 'arcMidpoint',\n clauseIds: [c.id],\n intents: withCircum(addPoint(name, { kind: 'arcMidpoint', circle, a, b, notContaining })),\n });\n }\n\n // --- EN (issue #46 group B) ---------------------------------------------------\n // Tam giác EN để suy notContaining (đỉnh thứ 3) khi đề không nêu \"not containing\".\n const triEnVerts = triEnM0 ? [triEnM0[1], triEnM0[2], triEnM0[3]] : undefined;\n\n for (const c of ctx.clauses) {\n if (!ARC_MID_EN.test(c.text)) continue;\n // Vượt scope (mirror VN): \"major arc\" → cung đối, defer → escalate.\n if (MAJOR_ARC_EN.test(c.text)) continue;\n // \"containing X\" DƯƠNG (không có \"not\" trước) → defer → escalate.\n if (/containing/u.test(c.text) && !/not\\s+containing/u.test(c.text)) continue;\n\n const pairM = ARC_PAIR_EN.exec(c.text);\n if (!pairM) continue;\n const pair = pairFromToken(pairM[1] + pairM[2]);\n if (pair.length !== 2) continue;\n const [a, b] = pair;\n if (!arcOnCircum(a, b)) continue; // circumcircle ngầm: cung phải là 2 đỉnh tam giác\n\n // Tên điểm: \"M is/be the midpoint of arc\" (HOA trước). Không có → bỏ qua.\n const before = NAME_BEFORE_EN.exec(c.text);\n const name = before ? before[1] : undefined;\n if (!name) continue;\n\n // notContaining: \"not containing X\" tường minh, hoặc đỉnh thứ 3 của tam giác EN.\n let notContaining: string | undefined;\n const nc = NOT_CONTAINING_EN.exec(c.text);\n if (nc) {\n notContaining = nc[1];\n if (notContaining === a || notContaining === b) continue; // endpoint cung → vô nghĩa\n } else if (triEnVerts) {\n notContaining = triEnVerts.find((v) => v !== a && v !== b);\n }\n if (!notContaining) continue;\n\n out.push({\n ruleId: 'arcMidpoint',\n clauseIds: [c.id],\n intents: withCircum(addPoint(name, { kind: 'arcMidpoint', circle, a, b, notContaining })),\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/excenter.ts\n//\n// Tâm đường tròn bàng tiếp (excenter): \"J là tâm bàng tiếp góc A\".\n// → add-point J {kind:'excenter', of:['A','B','C'], opposite:'A'}\n//\n// excenter cần BỘ 3 đỉnh tam giác (of) + ĐỈNH ĐỐI DIỆN (opposite — góc mà đường\n// tròn bàng tiếp ứng với). DSL/intent/render đã support; rule này chỉ lo NLU.\n//\n// Tam giác: nêu trong clause → lấy; else tam giác DUY NHẤT toàn đề; nhập nhằng /\n// không có → bỏ qua (escalate). Đỉnh đối PHẢI thuộc tam giác (else escalate).\n//\n// Tên tâm: ký tự HOA đứng TRƯỚC \"(là) tâm (đường tròn)? bàng tiếp\" (cục bộ, KHÔNG\n// quét lời dẫn toàn clause). Không trích được tên → bỏ qua (đừng bịa).\n//\n// KHÔNG dùng extractPointName (_shared) ở đây: NAME_LA của nó dùng `là\\b` (ASCII\n// \\b sau 'à' không khớp) nên không bắt được \"X là …\". Rule tự neo qua NAME_BEFORE.\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt. Regex chứa ký\n// tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\n//\n// Chỉ dựng ĐIỂM tâm (excenter). \"Vẽ đường tròn bàng tiếp\" (excircle) chưa có\n// intent path → clause không đặt tên tâm sẽ KHÔNG match → escalate (an toàn).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// Prefilter toàn đề.\nconst EXCENTER_KW = /bàng\\s*tiếp/u;\n\n// Tam giác (1 lần) trong 1 đoạn text.\nconst TRI = /tam\\s*giác\\s+([A-Z])([A-Z])([A-Z])/u;\nconst TRI_G = /tam\\s*giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// Đỉnh đối diện: \"bàng tiếp (trong)? (góc|đỉnh|ứng với (đỉnh)?|đối diện (đỉnh)?) X\".\nconst OPPOSITE =\n /bàng\\s*tiếp\\s+(?:trong\\s+)?(?:góc|đỉnh|ứng\\s+với(?:\\s+đỉnh)?|đối\\s+diện(?:\\s+đỉnh)?)\\s+([A-Z])(?!\\p{L})/u;\n\n// Tên tâm đứng TRƯỚC: \"J (là)? tâm (của)? (đường tròn)? bàng tiếp\".\nconst NAME_BEFORE =\n /([A-Z])(?:['′]?)\\s+(?:là\\s+)?(?:tâm\\s+)?(?:(?:của\\s+)?đường\\s*tròn\\s+)?bàng\\s*tiếp/u;\n\n/**\n * of=[A,B,C] cho 1 clause: ưu tiên tam giác nêu trong clause; else tam giác DUY\n * NHẤT toàn đề (dedup theo bộ đỉnh). Nhiều tam giác khác nhau / không có →\n * undefined (escalate).\n */\nfunction resolveTriangleOf(clauseText: string, problem: string): string[] | undefined {\n const inClause = TRI.exec(clauseText);\n if (inClause) return [inClause[1], inClause[2], inClause[3]];\n TRI_G.lastIndex = 0;\n const all: string[] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) all.push(m[1] + m[2] + m[3]);\n const distinct = new Set(all);\n if (distinct.size === 1) {\n const t = all[0];\n return [t[0], t[1], t[2]];\n }\n return undefined;\n}\n\n/**\n * \"J là tâm bàng tiếp góc A\" → add-point J {kind:'excenter', of:[A,B,C], opposite:'A'}.\n * Thiếu đỉnh đối / tam giác / tên → bỏ qua clause (escalate AI thay vì đoán sai).\n */\nexport const excenterRule: LanguageRule = {\n id: 'excenter',\n priority: 60,\n languages: ['vi'],\n patterns: [EXCENTER_KW],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!EXCENTER_KW.test(c.text)) continue;\n\n const oppM = OPPOSITE.exec(c.text);\n if (!oppM) continue; // không xác định đỉnh đối → escalate\n const opposite = oppM[1];\n\n const of = resolveTriangleOf(c.text, ctx.problem);\n if (!of) continue; // không có/nhập nhằng tam giác → escalate\n if (!of.includes(opposite)) continue; // đỉnh đối phải thuộc tam giác\n\n const nameM = NAME_BEFORE.exec(c.text);\n const name = nameM ? nameM[1] : undefined;\n if (!name) continue; // không trích được tên → bỏ qua (đừng bịa)\n\n out.push({\n ruleId: 'excenter',\n clauseIds: [c.id],\n intents: [addPoint(name, { kind: 'excenter', of, opposite })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/parallelPerp.ts\n//\n// Đường thẳng QUA 1 điểm, song song / vuông góc với 1 đường (cặp đỉnh):\n// \"Qua A kẻ đường thẳng song song với BC\" → draw-line parallelThrough A→BC\n// \"Từ A vẽ đường thẳng vuông góc với BC\" → draw-line perpThrough A→BC\n//\n// Phân biệt với perpFoot (\"Kẻ AH vuông góc BC\" → chân H): rule này BẮT BUỘC mở\n// đầu \"Qua/Từ <P>\" (P = điểm đường thẳng đi qua, KHÔNG sinh chân). perpFoot\n// không có tiền tố \"Qua/Từ\" nên 2 rule không chồng.\n//\n// Tên line không nêu trong đề → synthesize (\"parA\"/\"prpA\"); guard chỉ track điểm\n// HOA nên line name không bị đòi. Nếu đề có \"cắt … tại N\" (giao điểm) → phần đó\n// KHÔNG được claim → coverage/guard escalate (an toàn) thay vì dựng thiếu N.\n//\n// GOTCHA \\b: dùng (?!\\p{L}) + cờ 'u' quanh ký tự Việt.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawLine } from './_shared';\n\n// \"Qua/Từ <P> [kẻ/vẽ/dựng đường thẳng (d)] song song|vuông góc [với] [cạnh|đoạn] <PAIR>\".\n// group1 = through point; group2 = kind keyword; group3+4 = cặp đỉnh đường tham chiếu.\n// [^.]{0,24}? bắc cầu cụm \"kẻ đường thẳng (d) \" nhưng KHÔNG vượt dấu '.'.\nconst RE = new RegExp(\n '(?:Qua|qua|Từ|từ)\\\\s+(?:điểm\\\\s+)?([A-Z])(?:[\\'′]?)(?!\\\\p{L})' +\n '[^.]{0,24}?(song\\\\s*song|vuông\\\\s*góc)\\\\s+(?:với\\\\s+)?(?:cạnh\\\\s+|đoạn(?:\\\\s+thẳng)?\\\\s+)?' +\n '([A-Z])([A-Z])(?!\\\\p{L})',\n 'gu',\n);\n\n// Prefilter toàn đề (NON-global cho .test).\nconst PREFILTER =\n /(?:Qua|qua|Từ|từ)\\s+(?:điểm\\s+)?[A-Z][^.]{0,24}?(?:song\\s*song|vuông\\s*góc)/u;\n\nexport const parallelPerpRule: LanguageRule = {\n id: 'parallelPerp',\n priority: 58,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n RE.lastIndex = 0;\n for (const m of c.text.matchAll(RE)) {\n const through = m[1];\n const isParallel = /song/.test(m[2]);\n const to = m[3] + m[4];\n // Song song với đường CHỨA chính điểm qua → trùng đường đó (degenerate) → bỏ.\n if (isParallel && to.includes(through)) continue;\n const kind = isParallel ? 'parallelThrough' : 'perpThrough';\n const name = (isParallel ? 'par' : 'prp') + through;\n out.push({\n ruleId: 'parallelPerp',\n clauseIds: [c.id],\n intents: [drawLine(name, kind, { through, to })],\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/reflection.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, extractPointName } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + tránh \\b.\n\n// Prefilter toàn đề: \"đối xứng\" (cho phép viết liền \"đốixứng\" hiếm gặp → giữ \\s*).\nconst REFLECT = /đối\\s*xứng/u;\n\n// Dạng A: tên điểm ĐỨNG TRƯỚC.\n// \"D đối xứng (với) H qua BC\"\n// \"D là (điểm) đối xứng (của|với) H qua (đường thẳng|cạnh|trục) <Z>\"\n// Z bắt mở (chữ cái + dấu phẩy/′), phân loại điểm/đường ở dưới.\nconst NAME_BEFORE =\n /([A-Z])(?:['′]?)\\s+(?:là\\s+)?(?:điểm\\s+)?đối\\s*xứng\\s+(?:của\\s+|với\\s+)?([A-Z])(?:['′]?)\\s+qua\\s+(?:đường\\s*thẳng\\s+|cạnh\\s+|đoạn\\s+|trục\\s+|trung\\s*điểm\\s+|điểm\\s+)?([A-Za-z][A-Za-z′']?)/u;\n\n// Dạng B: KHÔNG có tên dẫn trước \"đối xứng\" (lấy tên từ lời dẫn \"Gọi/Lấy …\").\n// \"Gọi D là điểm đối xứng của H qua BC\"\n// \"Lấy điểm đối xứng của H qua M\"\nconst NAME_AFTER =\n /(?:điểm\\s+)?đối\\s*xứng\\s+(?:của\\s+|với\\s+)?([A-Z])(?:['′]?)\\s+qua\\s+(?:đường\\s*thẳng\\s+|cạnh\\s+|đoạn\\s+|trục\\s+|trung\\s*điểm\\s+|điểm\\s+)?([A-Za-z][A-Za-z′']?)/u;\n\n// === EN (issue #46 group B) ===\n// \"<Name> is/be the reflection of <Of> (over|across|in|about|through) (the)? (line|point|segment)? <Z>\"\n// Name đứng TRƯỚC (qua \"is\"/\"be the\" — gồm \"Let D be the reflection...\"). KHÔNG cờ 'i'.\n// (?<![A-Za-z]) đảm bảo Name là nhãn đơn. Z phân loại bằng classifyThrough (reuse).\nconst REFLECT_EN =\n /(?<![A-Za-z])([A-Z])(?:['′]?)\\s+(?:is|be)\\s+the\\s+reflection\\s+of\\s+([A-Z])(?:['′]?)\\s+(?:over|across|in|about|through)\\s+(?:the\\s+)?(?:line\\s+|point\\s+|segment\\s+)?([A-Za-z][A-Za-z′']?)/u;\nconst REFLECT_EN_PRE = /[Rr]eflection/u;\n\n// Phân loại token Z (đã strip dấu phẩy/′):\n// \"M\" → điểm (1 ký tự HOA) → reflectPoint\n// \"BC\" → đường (cặp 2 ký tự HOA) → reflectLine\n// \"d\" → đường (tên đường, chữ thường) → reflectLine\nfunction classifyThrough(raw: string): { kind: 'point' | 'line'; value: string } | undefined {\n const z = raw.replace(/['′]/gu, '').trim();\n if (/^[A-Z]$/u.test(z)) return { kind: 'point', value: z };\n if (/^[A-Z][A-Z]$/u.test(z)) return { kind: 'line', value: z };\n // tên đường thẳng chữ thường (d, d1, a, xy…) → đường\n if (/^[a-z][A-Za-z0-9]*$/u.test(z)) return { kind: 'line', value: z };\n return undefined;\n}\n\n/**\n * Đối xứng (Cụm A reflection):\n * \"D đối xứng H qua BC\" → reflectLine (qua ĐƯỜNG: cặp đỉnh BC / tên đường d)\n * \"Q đối xứng P qua M\" → reflectPoint (qua ĐIỂM: 1 ký tự HOA)\n * \"D là điểm đối xứng của H qua đường thẳng d\" → reflectLine (through='d')\n *\n * name (điểm ảnh) = ký tự HOA đứng trước \"đối xứng\" (dạng A) hoặc lời dẫn\n * \"Gọi/Lấy …\" (dạng B). of = điểm gốc (X). through = Z, phân loại bằng\n * classifyThrough. Không trích đủ name / of / through hợp lệ → BỎ QUA clause\n * (đừng bịa tên) để pipeline escalate AI.\n */\nexport const reflectionRule: LanguageRule = {\n id: 'reflection',\n priority: 55,\n languages: ['vi', 'en'],\n patterns: [REFLECT, REFLECT_EN_PRE],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!REFLECT.test(c.text) && !REFLECT_EN_PRE.test(c.text)) continue;\n\n let name: string | undefined;\n let of: string | undefined;\n let throughRaw: string | undefined;\n\n const before = NAME_BEFORE.exec(c.text);\n if (before) {\n name = before[1];\n of = before[2];\n throughRaw = before[3];\n } else {\n const after = NAME_AFTER.exec(c.text);\n if (after) {\n // Không có tên đứng trước → lấy từ lời dẫn (\"Gọi D là …\").\n name = extractPointName(c.text);\n of = after[1];\n throughRaw = after[2];\n } else {\n // --- EN (issue #46 group B) — chỉ chạy khi cả 2 dạng VN fail. ---\n const en = REFLECT_EN.exec(c.text);\n if (en) {\n name = en[1];\n of = en[2];\n throughRaw = en[3];\n }\n }\n }\n\n if (!name || !of || !throughRaw) continue;\n\n const through = classifyThrough(throughRaw);\n if (!through) continue;\n\n const constraint =\n through.kind === 'point'\n ? { kind: 'reflectPoint', of, through: through.value }\n : { kind: 'reflectLine', of, through: through.value };\n\n out.push({\n ruleId: 'reflection',\n clauseIds: [c.id],\n intents: [addPoint(name, constraint)],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/pointAtDistance.ts\n//\n// Constraint METRIC: điểm trên tia kéo dài, cách mốc một khoảng cho trước.\n// C = through + d · unit(through − from) (xem spec 2026-06-06-point-at-distance)\n//\n// Phrasing phủ:\n// - \"trên tia đối của tia BA, lấy (điểm)? C sao cho BC = R\"\n// tia đối của tia BA = tia từ B ngược hướng A ⇒ hướng A→B kéo dài.\n// ⇒ from = A, through = B, điểm mới C nằm NGOÀI B.\n// - \"kéo dài AB (về phía B) lấy C sao cho BC = R\"\n// ⇒ from = A, through = B.\n// - EN (issue #46 group B):\n// \"On ray XY extended beyond Y, take D such that YD = …\" ⇒ from=X, through=Y.\n// \"Extend XY beyond Y to D such that YD = …\" ⇒ from=X, through=Y.\n// \"On the opposite ray of ray XY, take D such that XD …\" ⇒ from=Y, through=X.\n//\n// Hướng suy từ thứ tự token (from→through), KHÔNG cần field thừa. Điểm mốc đo\n// khoảng cách (through) trùng đỉnh đầu của cụm \"YZ = ...\" (Y = through, Z = tên\n// điểm mới). Ta dùng chính cặp này để chốt hướng + nguồn distance.\n//\n// distance (3 nguồn — discriminated union):\n// \"= R\" / \"= bán kính\" / \"= bán kính (O)\" → {kind:'circleRadius', circle}\n// \"= AB\" / \"= MN\" (2 ký tự HOA) → {kind:'segmentLength', p1, p2}\n// \"= 3\" / \"= 2,5\" / \"= 2 cm\" → {kind:'literal', value}\n//\n// GOTCHA \\b: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt.\n// Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// LƯU Ý: KHÔNG dùng cờ 'i' — nó làm [A-Z] khớp cả chữ thường, hỏng việc trích\n// tên điểm (đỉnh là CHỮ HOA). Clause có thể bắt đầu bằng chữ HOA (\"Kéo dài…\",\n// \"Trên tia đối…\") nên chữ cái đầu từ-khoá tiếng Việt dùng alternation [Kk]/[Tt].\n// --- Prefilter (toàn đề) ------------------------------------------------------\nconst KEYWORD = /(?:[Kk]éo\\s*dài|tia\\s*đối)/u;\n\n// --- Trigger trên clause ------------------------------------------------------\n// \"trên tia đối của tia BA\" → cặp [B, A] (B = gốc tia, A = hướng cũ). Hướng kéo\n// dài là tia đối ⇒ from = A, through = B.\nconst TIA_DOI =\n /tia\\s*đối\\s+của\\s+tia\\s+([A-Z])([A-Z])(?![A-Z])/u;\n// \"kéo dài AB\" → cặp [A, B]. Mặc định lấy điểm về phía B (đỉnh cuối) ⇒ from = A,\n// through = B. (\"về phía A\" hiếm + cần re-map; defer → bỏ qua để escalate.)\nconst KEO_DAI =\n /[Kk]éo\\s*dài\\s+(?:(?:đoạn|cạnh|tia)\\s+)?([A-Z])([A-Z])(?![A-Z])/u;\n\n// \"lấy (điểm)? C sao cho\" / \"lấy C\" / \"lấy C′\" → tên điểm mới (CAPTURE prime).\n// Issue #46 nhóm A: prime (' U+0027 / ′ U+2032) là PHẦN của tên — giữ lại để\n// \"C′\" ≠ đỉnh \"C\" (tránh addPoint dedup drop → escalate). Group 2 = prime char.\nconst TAKE_POINT =\n /lấy\\s+(?:điểm\\s+)?([A-Z])(['′]?)(?![A-Z])/u;\n\n// Normalize prime về 1 dạng: ′ (U+2032) → ' (U+0027). NameZ/serialize NAME_REGEX\n// cho phép ' nhưng KHÔNG cho phép ′ → chuẩn hoá để name \"C'\" chảy qua DSL/render\n// (label) không cần đổi schema. Trả về tên đầy đủ (chữ + prime đã normalize).\nfunction normalizePointName(letter: string, prime: string): string {\n return prime ? `${letter}'` : letter;\n}\n\n// \"về phía X\": hướng kéo dài. Mặc định through = đỉnh cuối cụm. Nếu \"về phía X\"\n// mà X KHÁC through (vd \"kéo dài AB về phía A\") → hướng đảo, rule không xử lý\n// đúng (defer) → skip để escalate.\nconst VE_PHIA = /về\\s+phía\\s+([A-Z])(?![A-Za-z])/u;\n\n// === EN (issue #46 group B) ==================================================\n// Additive — KHÔNG đụng building block VN ở trên. Nhãn STRICT [A-Z] (KHÔNG cờ\n// 'i' — sẽ nuốt chữ thường); first-letter flex của verb bằng [Ee]/[Tt]/[Mm]/…\n//\n// EN prefilter (runRules tests `patterns` against whole problem, IGNORING the\n// `languages` field — so an EN regex is REQUIRED here for EN-only problems to\n// reach match()). Broad but match() validates precisely → safe.\nconst PREFILTER_EN = /beyond|opposite\\s+ray/i;\n\n// \"ray XY extended beyond Z\" → ray X→Y extended past Z. from=X, through=Y;\n// require Z===Y (you extend past the FAR endpoint). Comma before \"extended\" ok.\nconst RAY_EXTENDED_EN =\n /ray\\s+([A-Z])([A-Z])(?![A-Z])\\s*,?\\s*extended\\s+beyond\\s+([A-Z])(?![A-Z])/u;\n// \"extend(ed)? (segment|line|side)? XY beyond Z\" (no \"ray\"). from=X, through=Y;\n// require Z===Y.\nconst EXTEND_SEG_EN =\n /[Ee]xtend(?:ed)?\\s+(?:segment\\s+|line\\s+|side\\s+)?([A-Z])([A-Z])(?![A-Z])\\s+beyond\\s+([A-Z])(?![A-Z])/u;\n// \"opposite ray of ray XY\" → mirror VN tia đối: from=Y(2nd), through=X(1st).\nconst OPPOSITE_RAY_EN =\n /opposite\\s+ray\\s+of\\s+ray\\s+([A-Z])([A-Z])(?![A-Z])/u;\n\n// New-point name (EN). \"take/mark/choose/pick D\" or \"to D\" (phrasing \"extend AB\n// beyond B TO D\"). Lookbehind (?<![A-Za-z]) stops \"to\" matching inside words\n// (into, photo). NO `i` flag — capture is [A-Z]; first-letter flex per verb.\n// group 1 = letter, group 2 = prime (mirror VN TAKE_POINT).\nconst TAKE_POINT_EN =\n /(?<![A-Za-z])(?:[Tt]ake|[Mm]ark|[Cc]hoose|[Pp]ick|to)\\s+(?:a\\s+|the\\s+)?(?:point\\s+)?([A-Z])(['′]?)(?![A-Z])/u;\n\n// Cụm chốt mốc + khoảng cách: \"BC = R\" / \"BC = AB\" / \"BC = 3\" / \"BC = 2,5 cm\".\n// Đỉnh đầu (m[1]) = mốc đo (through); đỉnh sau (m[2]) = điểm mới (Z); m[3] = prime\n// của điểm mới (CAPTURE — phải khớp tên điểm mới ở TAKE_POINT). Issue #46 nhóm A:\n// điểm mới có thể mang dấu phẩy/prime (\"BC′ = R\"); giữ prime để chốt mốc đúng.\n// Phần sau dấu \"=\" (m[4]) gom thô để parse riêng (radius / segment / số). KHÔNG\n// kết thúc trên ',' — dấu phẩy có thể là phân tách thập phân (\"2,5\"); clause đã\n// được segmentClauses tách trên dấu chấm/'; nên gom tới hết clause là an toàn.\nconst DIST_CLAUSE =\n /(?:sao\\s+cho\\s+)?([A-Z])([A-Z])(['′]?)(?![A-Z])\\s*=\\s*(.+?)\\s*(?:[.;]|$)/u;\n\n// --- Distance parsing ---------------------------------------------------------\nconst RADIUS_WORD = /(?<!\\p{L})(?:R|bán\\s*kính)(?!\\p{L})/u;\nconst CIRCLE_OF_RADIUS = /bán\\s*kính\\s*(?:\\(\\s*)?([A-Z])\\s*\\)?/u;\nconst SEGMENT_PAIR = /^\\s*([A-Z])([A-Z])(?![A-Z])\\s*$/u;\nconst NUMBER = /(\\d+(?:[.,]\\d+)?)/u;\n\n// Tâm đường tròn trong đề: \"(O;\" / \"(O)\" / \"đường tròn tâm O\" → tên circle.\nconst CIRCLE_NAME_PAREN = /\\(\\s*([A-Z])\\s*[;,)]/u;\nconst CIRCLE_NAME_WORDS = /đường\\s*tròn\\s*(?:tâm\\s+)?([A-Z])(?![A-Z])/u;\n\nfunction parseNum(raw: string): number {\n return Number(raw.replace(',', '.'));\n}\n\n/** Tên circle để gắn radius. Suy từ đề (ctx.problem); mặc định 'O'. */\nfunction resolveCircleName(problem: string): string {\n const w = CIRCLE_NAME_WORDS.exec(problem);\n if (w) return w[1];\n const p = CIRCLE_NAME_PAREN.exec(problem);\n if (p) return p[1];\n return 'O';\n}\n\ntype DistanceBase =\n | { kind: 'circleRadius'; circle: string }\n | { kind: 'segmentLength'; p1: string; p2: string }\n | { kind: 'literal'; value: number };\n\ntype Distance = DistanceBase & { scale?: number; offset?: number };\n\n// --- Hệ số/bội/offset (Issue #46 nhóm C) -------------------------------------\n// Tách \"<scale>·base ± offset\". scale = số đứng TRƯỚC base (qua dấu nhân ·/./×/*\n// hoặc dán liền \"2AB\"/\"2R\" hoặc cách \"2 AB\"). offset = \"± số\" đứng SAU base.\n// \"2R\" → scale 2, base R\n// \"2·AB\" → scale 2, base AB\n// \"R + 1\" → base R, offset +1\n// \"2R + 1\" → scale 2, base R, offset +1\n// base có thể là R/bán kính, cặp đỉnh (AB), hoặc số literal.\n//\n// Hệ số đứng trước base: \"2\", \"2·\", \"2.\", \"2×\", \"2*\", \"2 \" (số rồi base).\nconst COEF_PREFIX = /^(\\d+(?:[.,]\\d+)?)\\s*[·.×*]?\\s*(?=[A-Z]|bán)/u;\n// Offset đứng cuối: \"± số\" (chỉ số literal, không nhân thêm đại lượng).\nconst OFFSET_SUFFIX = /([+-])\\s*(\\d+(?:[.,]\\d+)?)\\s*$/u;\n// Dấu nhân CHỈ giữa 2 đại lượng (vd \"R·AB\", \"AB·MN\"): tích 2 đại lượng → mơ hồ.\n// Phát hiện: có dấu nhân mà 2 BÊN đều KHÔNG phải số → reject.\nconst MUL_TWO_QUANTITIES = /[A-Z](?:\\s*['′])?\\s*[·×*]\\s*[A-Z]/u;\n\n/** Parse phần sau dấu \"=\" → DistanceSpec hoặc undefined (không nhận dạng được). */\nfunction parseDistance(raw: string, problem: string): Distance | undefined {\n let text = raw.trim();\n\n // 0. TỪ CHỐI ngay các biểu thức KHÔNG xử lý được:\n if (/\\//u.test(text)) return undefined; // chia: \"AB/2\", \"1/2 AB\" → defer\n if (/\\blần\\b/u.test(text)) return undefined; // \"2 lần bán kính\" → defer\n if (MUL_TWO_QUANTITIES.test(text)) return undefined; // tích 2 đại lượng \"R·AB\"\n // '-' đứng đầu (giá trị âm trực tiếp \"-3\") → defer. ('-' offset xử lý ở dưới.)\n if (/^-/u.test(text)) return undefined;\n\n // 1. Tách offset \"± số\" ở cuối (literal). Không nhân thêm đại lượng.\n let offset: number | undefined;\n const off = OFFSET_SUFFIX.exec(text);\n if (off) {\n const sign = off[1] === '-' ? -1 : 1;\n offset = sign * parseNum(off[2]);\n text = text.slice(0, off.index).trim();\n }\n // Sau khi bóc offset, KHÔNG còn được phép có toán tử +/- (vd \"1 + 2 + R\" lạ).\n if (/[+]/u.test(text)) return undefined;\n if (/-\\s*\\d/u.test(text)) return undefined;\n\n // 2. Tách hệ số (scale) đứng trước base. Chỉ nhận khi PHÍA SAU là base\n // (đỉnh HOA / \"bán\"). \"3\" đơn lẻ KHÔNG khớp (→ literal value).\n let scale: number | undefined;\n const coef = COEF_PREFIX.exec(text);\n if (coef) {\n scale = parseNum(coef[1]);\n if (!(Number.isFinite(scale) && scale > 0)) return undefined;\n text = text.slice(coef[0].length).trim();\n }\n\n // Còn sót dấu nhân lẻ (vd \"·R\" do tách lỗi) → mơ hồ.\n if (/[·×*]/u.test(text)) return undefined;\n\n const withCoef = (base: DistanceBase): Distance => {\n const d: Distance = { ...base };\n if (scale !== undefined) d.scale = scale;\n if (offset !== undefined) d.offset = offset;\n return d;\n };\n\n // 3. base = bán kính: \"R\" / \"bán kính\" / \"bán kính (O)\".\n if (RADIUS_WORD.test(text)) {\n const co = CIRCLE_OF_RADIUS.exec(text);\n const circle = co ? co[1] : resolveCircleName(problem);\n return withCoef({ kind: 'circleRadius', circle });\n }\n // 4. base = đoạn = 2 ký tự HOA liền (\"AB\", \"MN\").\n const seg = SEGMENT_PAIR.exec(text);\n if (seg) return withCoef({ kind: 'segmentLength', p1: seg[1], p2: seg[2] });\n // 5. base = số literal (board units). \"2 cm\" → 2 (cm-mapping defer).\n // Lưu ý: nếu đã tách scale thì KHÔNG còn base số (scale·số vô nghĩa) → defer.\n if (scale === undefined) {\n const num = NUMBER.exec(text);\n if (num) {\n const value = parseNum(num[1]);\n if (Number.isFinite(value) && value > 0) return withCoef({ kind: 'literal', value });\n }\n }\n return undefined;\n}\n\n/**\n * \"kéo dài AB lấy C sao cho BC = R\" / \"trên tia đối của tia BA, lấy C sao cho\n * BC = R\" → add-point C kind:pointAtDistance. Hướng (from→through) suy từ token\n * cặp + mốc đo (đỉnh đầu cụm \"YZ = …\"). Không parse đủ (thiếu tên điểm mới /\n * distance không nhận dạng / mốc không khớp) → bỏ qua để escalate AI.\n *\n * EN (issue #46 group B) — mirror VN, chỉ chạy khi VN không xác định được hướng:\n * \"ray XY extended beyond Y, take D such that YD = …\" → from=X, through=Y\n * \"extend XY beyond Y to D such that YD = …\" → from=X, through=Y\n * \"opposite ray of ray XY, take D such that XD = …\" → from=Y, through=X\n */\nexport const pointAtDistanceRule: LanguageRule = {\n id: 'pointAtDistance',\n priority: 55,\n languages: ['vi', 'en'],\n patterns: [KEYWORD, PREFILTER_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n let from: string | undefined;\n let through: string | undefined;\n let name: string | undefined;\n let isEn = false;\n\n // --- Hướng VN (from → through) ---\n const doi = TIA_DOI.exec(c.text);\n if (doi) {\n // tia đối của tia BA: B = gốc, A = hướng cũ ⇒ kéo dài về B ⇒ from=A, through=B.\n from = doi[2];\n through = doi[1];\n } else {\n const kd = KEO_DAI.exec(c.text);\n if (kd) {\n // kéo dài AB (về phía B mặc định) ⇒ from=A, through=B.\n from = kd[1];\n through = kd[2];\n }\n }\n\n if (from && through) {\n // VN name (GIỮ prime, normalize ′→').\n const take = TAKE_POINT.exec(c.text);\n name = take ? normalizePointName(take[1], take[2]) : undefined;\n } else {\n // --- EN direction (additive; chỉ khi VN không xác định được hướng) ---\n const opp = OPPOSITE_RAY_EN.exec(c.text);\n const ray = RAY_EXTENDED_EN.exec(c.text);\n const ext = EXTEND_SEG_EN.exec(c.text);\n if (opp) {\n // opposite ray of ray XY → mirror VN tia đối: from=Y, through=X.\n from = opp[2];\n through = opp[1];\n } else if (ray && ray[3] === ray[2]) {\n // ray XY extended beyond Z (Z must = Y): from=X, through=Y.\n from = ray[1];\n through = ray[2];\n } else if (ext && ext[3] === ext[2]) {\n // extend XY beyond Z (Z must = Y): from=X, through=Y.\n from = ext[1];\n through = ext[2];\n }\n if (from && through) {\n isEn = true;\n const takeEn = TAKE_POINT_EN.exec(c.text);\n name = takeEn ? normalizePointName(takeEn[1], takeEn[2]) : undefined;\n }\n }\n\n if (!from || !through || !name) continue;\n\n // VE_PHIA: chỉ VN (EN không có \"về phía\"). Giữ outcome VN byte-identical.\n if (!isEn) {\n const vp = VE_PHIA.exec(c.text);\n if (vp && vp[1] !== through) continue;\n }\n\n // --- Mốc đo + khoảng cách (\"YZ = …\") — language-agnostic (DIST_CLAUSE) ---\n const dc = DIST_CLAUSE.exec(c.text);\n if (!dc) continue;\n const anchor = dc[1]; // Y = mốc đo (phải trùng through; đỉnh đơn)\n const newPt = normalizePointName(dc[2], dc[3]); // Z = điểm mới (phải trùng name)\n // Mốc đo phải là through; đỉnh sau là điểm mới ta vừa lấy (so theo tên đã\n // normalize ⇒ \"BC′\" khớp điểm \"C'\", \"BD′\" KHÔNG khớp điểm \"C'\").\n if (anchor !== through || newPt !== name) continue;\n\n const distance = parseDistance(dc[4], ctx.problem);\n if (!distance) continue;\n\n out.push({\n ruleId: 'pointAtDistance',\n clauseIds: [c.id],\n intents: [addPoint(name, { kind: 'pointAtDistance', from, through, distance })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/eulerLine.ts\n//\n// Đường thẳng Euler (issue #47, construct 1): đường thẳng đi qua 3 tâm tam giác\n// THẲNG HÀNG — trọng tâm G, trực tâm H, tâm đường tròn ngoại tiếp O. KHÔNG phải\n// kind DSL riêng — compose từ 3 tâm (centroid/orthocenter/circumcenter, đã có)\n// + kind tổng quát `lineThrough([G,H,O])`.\n//\n// Fail-safe (escalate, KHÔNG dựng sai):\n// - \"đường tròn Euler\" (đường tròn 9 điểm) → KHÔNG khớp (regex chỉ nhận\n// \"đường (thẳng) Euler\", không có \"tròn\").\n// - Tam giác đều (\"đều\") → G≡H≡O suy biến, đường Euler không xác định → bỏ qua.\n// - Không có tam giác / >1 tam giác (nhập nhằng) → bỏ qua.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, drawLine } from './_shared';\n\n// \"đường thẳng Euler\" / \"đường Euler\" — \"thẳng\" optional. KHÔNG khớp \"đường tròn\n// Euler\" (vì \"tròn\" KHÔNG phải nhánh optional \"thẳng\"). \\p{L} lookaround vì \\b\n// không khớp quanh ký tự Việt.\nconst EULER_LINE_KW = /(?<!\\p{L})đường\\s+(?:thẳng\\s+)?[Ee]uler(?!\\p{L})/u;\n\n// Tam giác (global): quét mọi tam giác nêu trong đề.\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// Tam giác đều → 3 tâm trùng → đường Euler suy biến.\nconst EQUILATERAL_KW = /(?<!\\p{L})đều(?!\\p{L})/u;\n\n/** Bộ 3 đỉnh duy nhất toàn đề; undefined nếu 0 hoặc >1 tam giác phân biệt. */\nfunction uniqueTriangle(problem: string): [string, string, string] | undefined {\n TRI_G.lastIndex = 0;\n const tris: string[][] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) {\n tris.push([m[1], m[2], m[3]]);\n }\n const distinct = new Set(tris.map((t) => t.join('')));\n if (distinct.size !== 1) return undefined;\n const t = tris[0];\n return [t[0], t[1], t[2]];\n}\n\nexport const eulerLineRule: LanguageRule = {\n id: 'eulerLine',\n priority: 68,\n languages: ['vi'],\n patterns: [EULER_LINE_KW],\n match(ctx) {\n // Suy biến tam giác đều → escalate (G≡H≡O → đường Euler không xác định).\n if (EQUILATERAL_KW.test(ctx.problem)) return [];\n\n const tri = uniqueTriangle(ctx.problem);\n if (!tri) return []; // 0 hoặc >1 tam giác → nhập nhằng → escalate.\n const [A, B, C] = tri;\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!EULER_LINE_KW.test(c.text)) continue;\n out.push({\n ruleId: 'eulerLine',\n clauseIds: [c.id],\n intents: [\n addPoint('G', { kind: 'centroid', of: [A, B, C] }),\n addPoint('H', { kind: 'orthocenter', of: [A, B, C] }),\n addPoint('O', { kind: 'circumcenter', of: [A, B, C] }),\n drawLine('euler' + A + B + C, 'lineThrough', { points: ['G', 'H', 'O'] }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/radicalAxis.ts\n//\n// Trục đẳng phương 2 đường tròn (issue #47, construct 2): đường ⊥ đường nối tâm\n// O₁O₂, mọi điểm trên nó có lũy thừa (power) bằng nhau với 2 đường tròn. KHÔNG\n// phải kind point — compose từ kind tổng quát `radicalAxis(circle1, circle2)`\n// (tham chiếu 2 CIRCLE đã được circleRadius dựng theo center letter).\n//\n// Fail-safe (escalate, KHÔNG dựng sai):\n// - Đồng tâm \"(O;3) và (O;5)\" → {O} (1 center phân biệt) → bỏ qua (suy biến,\n// trục không xác định).\n// - 0 hoặc 1 đường tròn có bán kính → không đủ 2 → bỏ qua.\n// - >2 đường tròn → nhập nhằng (cặp nào?) → bỏ qua.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawLine } from './_shared';\n\n// \"trục đẳng phương\" / \"đẳng phương\" — \"trục\" optional. \\p{L} lookaround vì \\b\n// không khớp quanh ký tự Việt.\nconst RADICAL_KW = /(?<!\\p{L})(?:trục\\s+)?đẳng\\s*phương(?!\\p{L})/u;\n\n// Đường tròn CÓ BÁN KÍNH (số hoặc ký hiệu R/r) — khớp những gì circleRadius\n// dựng qua centerRadius. \"(O; 3)\" / \"(I, 2.5)\" / \"(O; R)\". Global: nhiều đường\n// tròn / đề. Group 1 = center letter.\nconst CIRCLE_R_G = /\\(\\s*([A-Z])\\s*[;,]\\s*(?:\\d|[Rr])/gu;\n\n/** Các center letter phân biệt của đường tròn-có-bán-kính nêu trong đề. */\nfunction circleCentersWithRadius(problem: string): string[] {\n CIRCLE_R_G.lastIndex = 0;\n const centers = new Set<string>();\n let m: RegExpExecArray | null;\n while ((m = CIRCLE_R_G.exec(problem)) !== null) {\n centers.add(m[1]);\n }\n return [...centers];\n}\n\nexport const radicalAxisRule: LanguageRule = {\n id: 'radicalAxis',\n priority: 66,\n languages: ['vi'],\n patterns: [RADICAL_KW],\n match(ctx) {\n const centers = circleCentersWithRadius(ctx.problem);\n // Cần ĐÚNG 2 đường tròn phân biệt. Đồng tâm → 1 center → escalate. >2 → mơ hồ.\n if (centers.length !== 2) return [];\n const [c1, c2] = centers;\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!RADICAL_KW.test(c.text)) continue;\n out.push({\n ruleId: 'radicalAxis',\n clauseIds: [c.id],\n intents: [drawLine('rad' + c1 + c2, 'radicalAxis', { circle1: c1, circle2: c2 })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/simson.ts\n//\n// Đường thẳng Simson (issue #47, construct 3): P trên đường tròn ngoại tiếp tam\n// giác ABC → 3 chân vuông góc hạ từ P xuống 3 cạnh (BC, CA, AB) THẲNG HÀNG\n// (định lý Simson). KHÔNG kind DSL riêng — compose:\n// - P = onCircle (glider trên đường tròn ngoại tiếp, theta cố định 0.7).\n// - 3 chân = perpFoot (chiếu trực giao xuống đường vô hạn BC/CA/AB).\n// - đường Simson = lineThrough([chân1, chân2, chân3]).\n//\n// Fail-safe (escalate, KHÔNG dựng sai):\n// - Không có đường tròn ngoại tiếp khai báo → KHÔNG đặt được P → bỏ qua.\n// - 0 hoặc >1 tam giác phân biệt (nhập nhằng) → bỏ qua.\n// - P trùng đỉnh (Simson của A) → 3 chân suy biến → bỏ qua.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, drawLine } from './_shared';\n\n// \"Simson\" — danh từ riêng. \\b không khớp quanh ký tự ASCII letter ổn, nhưng\n// dùng lookaround [A-Za-z] để chắc chắn không khớp trong từ khác.\nconst SIMSON_KW = /(?<![A-Za-z])[Ss]imson(?![A-Za-z])/u;\n\n// Tam giác (global): quét mọi tam giác nêu trong đề.\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// Tên tâm đường tròn ngoại tiếp: \"(O)\" — dạng ngoặc 1 chữ HOA.\nconst CIRCLE_CENTER = /\\(\\s*([A-Z])\\s*\\)/u;\n\n// P của Simson: \"Simson của (điểm) P\".\nconst SIMSON_OF = /[Ss]imson\\s+của\\s+(?:điểm\\s+)?([A-Z])(?![A-Za-z])/u;\n\n/** Bộ 3 đỉnh duy nhất toàn đề; undefined nếu 0 hoặc >1 tam giác phân biệt. */\nfunction uniqueTriangle(problem: string): [string, string, string] | undefined {\n TRI_G.lastIndex = 0;\n const tris: string[][] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) {\n tris.push([m[1], m[2], m[3]]);\n }\n const distinct = new Set(tris.map((t) => t.join('')));\n if (distinct.size !== 1) return undefined;\n const t = tris[0];\n return [t[0], t[1], t[2]];\n}\n\nexport const simsonRule: LanguageRule = {\n id: 'simson',\n priority: 64,\n languages: ['vi'],\n patterns: [SIMSON_KW],\n match(ctx) {\n const tri = uniqueTriangle(ctx.problem);\n if (!tri) return []; // 0 hoặc >1 tam giác → nhập nhằng → escalate.\n const [A, B, C] = tri;\n\n // Đường tròn ngoại tiếp PHẢI được khai báo (vd \"(O)\") — circleTriangle dựng\n // circle tên theo chữ trong \"(O)\". Thiếu → KHÔNG đặt được P → escalate.\n const cm = CIRCLE_CENTER.exec(ctx.problem);\n if (!cm) return [];\n const O = cm[1];\n\n // P của Simson.\n const pm = SIMSON_OF.exec(ctx.problem);\n if (!pm) return []; // không xác định được P → escalate.\n const P = pm[1];\n\n // Suy biến: P là 1 đỉnh tam giác → 3 chân trùng → đường Simson suy biến.\n if (P === A || P === B || P === C) return [];\n\n const f1 = 'S' + A + B + C + '1';\n const f2 = 'S' + A + B + C + '2';\n const f3 = 'S' + A + B + C + '3';\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!SIMSON_KW.test(c.text)) continue;\n out.push({\n ruleId: 'simson',\n clauseIds: [c.id],\n intents: [\n addPoint(P, { kind: 'onCircle', circle: O, theta: 0.7 }),\n addPoint(f1, { kind: 'perpFoot', from: P, onLine: B + C }),\n addPoint(f2, { kind: 'perpFoot', from: P, onLine: C + A }),\n addPoint(f3, { kind: 'perpFoot', from: P, onLine: A + B }),\n drawLine('simson' + P, 'lineThrough', { points: [f1, f2, f3] }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/ninePoint.ts\n//\n// Đường tròn chín điểm / đường tròn Euler (issue #47, construct 4): đường tròn qua\n// 3 trung điểm cạnh (= cũng qua 3 chân đường cao + 3 trung điểm đỉnh-trực tâm;\n// bán kính R/2). Dựng = circle3 qua 3 TRUNG ĐIỂM CẠNH — TRÁNH radius-scaling.\n// Compose midpoint×3 + circle3, KHÔNG kind DSL mới.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, drawCircle } from './_shared';\n\n// \"đường tròn chín điểm\" / \"đường tròn Euler\" / \"chín điểm\". KHÔNG khớp \"đường\n// thẳng Euler\" (yêu cầu \"tròn\" trước Euler — đó là đường thẳng Euler, construct 1).\nconst NINE_KW = /(?<!\\p{L})(?:đường\\s*tròn\\s+Euler|(?:đường\\s*tròn\\s+)?chín\\s*điểm)(?!\\p{L})/u;\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\nfunction uniqueTriangle(problem: string): [string, string, string] | undefined {\n TRI_G.lastIndex = 0;\n const tris: string[][] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) tris.push([m[1], m[2], m[3]]);\n const distinct = new Set(tris.map((t) => t.join('')));\n if (distinct.size !== 1) return undefined;\n const t = tris[0];\n return [t[0], t[1], t[2]];\n}\n\nexport const ninePointRule: LanguageRule = {\n id: 'ninePoint',\n priority: 63,\n languages: ['vi'],\n patterns: [NINE_KW],\n match(ctx) {\n const tri = uniqueTriangle(ctx.problem);\n if (!tri) return []; // 0 hoặc >1 tam giác → escalate.\n const [A, B, C] = tri;\n const mAB = 'M' + A + B, mBC = 'M' + B + C, mCA = 'M' + C + A;\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!NINE_KW.test(c.text)) continue;\n out.push({\n ruleId: 'ninePoint',\n clauseIds: [c.id],\n intents: [\n addPoint(mAB, { kind: 'midpoint', of: A + B }),\n addPoint(mBC, { kind: 'midpoint', of: B + C }),\n addPoint(mCA, { kind: 'midpoint', of: C + A }),\n drawCircle('N9', 'through3', { points: [mAB, mBC, mCA] }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/diameterCirclePairwise.ts\n//\n// Đề \"đường tròn đường kính đôi một cắt nhau lần thứ hai\" (whole-problem construct):\n//\n// Cho đường tròn (O) và ba dây cung AB, AC, AD bất kì. Các đường tròn đường\n// kính AB, AC, AD đôi một cắt nhau lần thứ hai tại M, N, P.\n//\n// Bản chất: (đ.kính AX)∩(đ.kính AY) lần 2 = chân vuông góc hạ từ A xuống XY\n// (∠ nhìn AX,AY = 90°). M,N,P = 3 chân Simson của A với ΔBCD. Đề gốc chỉ là\n// GIẢ THIẾT → hình tối giản: (O)+O, A/B/C/D, dây AX, 3 đường tròn đường kính,\n// M/N/P (giao điểm thứ hai, loại điểm chung A).\n//\n// Fail-safe (escalate, KHÔNG dựng sai): thiếu tâm \"(O)\"; <2 đường kính chung\n// apex; đầu mút/kết quả trùng; số tên kết quả ≠ số đường kính.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, drawCircle, DUONG_KW } from './_shared';\n\n// Tâm đường tròn: \"(O)\" — ngoặc 1 chữ HOA.\nconst CIRCLE_CENTER = /\\(\\s*([A-Z])\\s*\\)/u;\n// Prefilter: phải có \"đường kính\" + dấu hiệu \"đôi một\"/\"cắt nhau\".\nconst KW_DIAMETER = new RegExp(DUONG_KW + '\\\\s*kính', 'u');\nconst KW_PAIRWISE = /đôi một|cắt nhau/u;\n\n// Góc đặt điểm (radian) — apex trên cao, các đầu mút còn lại rải cung dưới ở\n// vị trí TỔNG QUÁT (tránh suy biến chân vuông góc trùng nhau).\nconst APEX_THETA = 2.0;\nconst OTHER_THETAS = [5.5, 4.0, 0.6, 3.3, 1.1, 5.0] as const;\n\ninterface Parsed {\n center: string;\n apex: string;\n others: string[];\n results: string[];\n}\n\nfunction parse(problem: string): Parsed | undefined {\n const cm = CIRCLE_CENTER.exec(problem);\n if (!cm) return undefined;\n const center = cm[1];\n\n // Vùng sau \"đường kính\" tới khi gặp \"đôi một\"/\"cắt nhau\" (cùng câu).\n const dm = new RegExp(DUONG_KW + '\\\\s*kính\\\\s+([^.;\\n]*)', 'u').exec(problem);\n if (!dm) return undefined;\n let region = dm[1];\n const cut = region.search(/đôi một|cắt nhau/u);\n if (cut >= 0) region = region.slice(0, cut);\n const pairs = region.match(/[A-Z][A-Z]/g) ?? [];\n if (pairs.length < 2) return undefined;\n\n // apex = chữ xuất hiện trong MỌI cặp.\n const counts = new Map<string, number>();\n for (const pr of pairs) {\n counts.set(pr[0], (counts.get(pr[0]) ?? 0) + 1);\n counts.set(pr[1], (counts.get(pr[1]) ?? 0) + 1);\n }\n const apexEntries = [...counts].filter(([, n]) => n === pairs.length);\n if (apexEntries.length !== 1) return undefined; // 0 → không chung; >1 → nhập nhằng\n const apex = apexEntries[0][0];\n const others = pairs.map((pr) => (pr[0] === apex ? pr[1] : pr[0]));\n if (new Set(others).size !== others.length) return undefined; // đầu mút trùng\n if (others.includes(apex)) return undefined;\n\n // Tên kết quả sau \"tại\": các chữ HOA đơn lẻ (M, N, P, ...).\n const rm = /\\btại\\s+([A-Z][^.;\\n]*)/u.exec(problem);\n if (!rm) return undefined;\n const results = rm[1].match(/\\b[A-Z]\\b/g) ?? [];\n // \"đôi một cắt nhau\" của n đường kính chung apex = TẤT CẢ C(n,2) cặp → C(n,2)\n // giao điểm. Số tên kết quả phải khớp đúng (n=3 → 3; n=4 → 6; ...).\n const numPairs = (others.length * (others.length - 1)) / 2;\n if (results.length !== numPairs) return undefined;\n if (new Set(results).size !== results.length) return undefined;\n\n return { center, apex, others, results };\n}\n\nexport const diameterCirclePairwiseRule: LanguageRule = {\n id: 'diameter-circle-pairwise',\n priority: 66,\n languages: ['vi'],\n patterns: [KW_DIAMETER],\n match(ctx) {\n if (!KW_PAIRWISE.test(ctx.problem)) return [];\n const p = parse(ctx.problem);\n if (!p) return [];\n const { center, apex, others, results } = p;\n\n const circOf = (other: string) => `k${apex}${other}`;\n const oCircle = `k${center}`; // tên entity đường tròn (O) (khác điểm tâm O)\n\n // Tất cả cặp (i<j) theo thứ tự từ điển — \"đôi một\" = mọi cặp đường kính.\n const allPairs: Array<[number, number]> = [];\n for (let i = 0; i < others.length; i++)\n for (let j = i + 1; j < others.length; j++) allPairs.push([i, j]);\n\n const intents = [\n // (O): tâm `center` (free) + bán kính cố định.\n drawCircle(oCircle, 'centerRadius', { center, radius: 4 }),\n // apex + các đầu mút = glider trên (O), vị trí tổng quát.\n addPoint(apex, { kind: 'onCircle', circle: oCircle, theta: APEX_THETA }),\n ...others.map((o, i) =>\n addPoint(o, { kind: 'onCircle', circle: oCircle, theta: OTHER_THETAS[i % OTHER_THETAS.length] }),\n ),\n // Dây cung apex–đầu mút.\n ...others.map((o) => connect(apex, o, 'segment')),\n // Đường tròn đường kính apex–đầu mút.\n ...others.map((o) => drawCircle(circOf(o), 'diameter', { endpoints: [apex, o] })),\n // Giao điểm thứ hai của TỪNG cặp đường tròn đường kính, loại điểm chung apex.\n ...results.map((r, k) =>\n addPoint(r, {\n kind: 'circleSecondIntersection',\n c1: circOf(others[allPairs[k][0]]),\n c2: circOf(others[allPairs[k][1]]),\n exclude: apex,\n }),\n ),\n ];\n\n const out: RuleMatch[] = [{\n ruleId: 'diameter-circle-pairwise',\n // Whole-problem construct: claim mọi clause để coverage gate đầy đủ.\n clauseIds: ctx.clauses.map((c) => c.id),\n intents,\n }];\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/angleBisectorFoot.ts\n//\n// Chân đường phân giác (trong/ngoài) hạ từ một đỉnh xuống cạnh đối:\n// \"D là chân đường phân giác từ A\" → onLine = cạnh đối A (suy từ tam giác)\n// \"D là chân đường phân giác trong kẻ từ A đến BC\" → onLine = BC (nêu rõ)\n// \"D là chân phân giác góc A\" → onLine = cạnh đối A\n// \"D là chân đường phân giác ngoài từ A\" → externalAngleBisectorFoot\n// → add-point D {kind:'angleBisectorFoot', from:'A', onLine:'BC'} (builder dựng\n// tia phân giác ∠(onLine[0])-from-(onLine[1]) ∩ đoạn onLine).\n//\n// Phân biệt (KHÔNG chồng rule khác):\n// - cevian (\"phân giác AD\" — đỉnh+chân dạng cặp HOA NGAY sau \"phân giác\"): rule\n// này BẮT BUỘC chữ \"chân\" mở đầu cụm → cevian không khớp.\n// - perpFoot (\"chân đường vuông góc / cao\"): keyword khác (\"vuông góc\"/\"cao\").\n// - angleBisectorAngle (\"phân giác góc A\" — vẽ tia VISIBLE, không foot): rule\n// đó tự né khi có \"chân\" đứng trước (guard CHAN_BEFORE bên angleBisectorAngle).\n//\n// Cần TAM GIÁC để suy cạnh đối khi đề KHÔNG nêu cạnh (\"đến BC\"); nêu rõ thì dùng\n// luôn. Tên chân (HOA) bind cục bộ qua \"X là\" NGAY TRƯỚC cụm. Thiếu tên / không\n// suy được cạnh đối → bỏ qua clause (escalate AI thay vì đoán sai).\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt (\"đ\",\"ề\",\"ạ\"…).\n// Regex chứa ký tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// Tam giác toàn đề (suy cạnh đối). Bổ ngữ \"vuông|cân|đều|nhọn|tù\" optional.\nconst TRI = /tam\\s*giác(?:\\s+(?:vuông|cân|đều|nhọn|tù))?\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\n\n// onLine token: tên đường 1 ký tự HOA HOẶC cặp đỉnh 2 ký tự HOA. Tiền tố tuỳ chọn.\nconst LINE = '(?:đường\\\\s*thẳng\\\\s+|cạnh\\\\s+|đoạn\\\\s+)?([A-Z]{1,2})(?![A-Z])';\n// Giới từ dẫn tới cạnh đáy.\nconst PREP_TO = '(?:đến|tới|xuống|trên|ra)';\n// Đỉnh: \"từ (đỉnh)? X\" | \"của góc X\" | \"góc X\" | \"tại (đỉnh)? X\" | \"đỉnh X\".\nconst VERTEX =\n '(?:từ\\\\s+(?:đỉnh\\\\s+)?|của\\\\s+góc\\\\s+|góc\\\\s+|tại\\\\s+(?:đỉnh\\\\s+)?|đỉnh\\\\s+)([A-Z])(?![A-Z])';\n\n// \"chân (của)? (đường|tia)? phân giác (trong|ngoài)? (hạ|kẻ|vẽ|dựng)? VERTEX (PREP_TO LINE)?\".\n// group1 = trong|ngoài (optional); group2 = vertex; group3 = onLine (optional).\nconst CORE = new RegExp(\n 'chân\\\\s+(?:của\\\\s+)?(?:đường\\\\s*|tia\\\\s+)?phân\\\\s*giác\\\\s+(?:(trong|ngoài)\\\\s+)?' +\n '(?:(?:hạ|kẻ|vẽ|dựng)\\\\s+)?' +\n VERTEX +\n `(?:\\\\s+${PREP_TO}\\\\s+${LINE})?`,\n 'gu',\n);\n\n// Tên chân đứng TRƯỚC: \"X là \" NGAY TRƯỚC cụm \"chân … phân giác\".\nconst NAME_BEFORE = /([A-Z])(?:['′]?)\\s+là\\s+$/u;\n\n// Prefilter toàn đề.\nconst PREFILTER = /chân\\s+(?:của\\s+)?(?:đường\\s*|tia\\s+)?phân\\s*giác/u;\n\n/** Cạnh đối diện đỉnh V trong tam giác = 2 đỉnh còn lại, join token (vd \"BC\"). */\nfunction opposite(tri: readonly string[], vertex: string): string | undefined {\n const rest = tri.filter((v) => v !== vertex);\n return rest.length === 2 ? rest[0] + rest[1] : undefined;\n}\n\n/**\n * Mỗi clause → 0..n add-point angleBisectorFoot / externalAngleBisectorFoot.\n * onLine ưu tiên cạnh nêu rõ (\"đến BC\"); else suy cạnh đối từ tam giác. Tên chân\n * bind cục bộ. Thiếu tên / không suy được cạnh → bỏ qua (escalate).\n */\nexport const angleBisectorFootRule: LanguageRule = {\n id: 'angleBisectorFoot',\n priority: 63,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const triM = TRI.exec(ctx.problem);\n const tri = triM ? [triM[1], triM[2], triM[3]] : null;\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n CORE.lastIndex = 0;\n for (const m of c.text.matchAll(CORE)) {\n const external = m[1] === 'ngoài';\n const vertex = m[2];\n let onLine: string | undefined = m[3]; // cạnh nêu rõ (optional)\n if (!onLine) {\n if (!tri || !tri.includes(vertex)) continue; // không suy được cạnh đối → escalate\n onLine = opposite(tri, vertex);\n }\n if (!onLine) continue; // không có cạnh (nêu rõ/suy ra) → escalate\n // Tên chân: \"X là\" NGAY TRƯỚC cụm; không có → escalate (đừng bịa).\n const nm = NAME_BEFORE.exec(c.text.slice(0, m.index));\n if (!nm) continue;\n const name = nm[1];\n if (onLine.includes(name)) continue; // chân trùng đầu mút cạnh đáy → degenerate\n const kind = external ? 'externalAngleBisectorFoot' : 'angleBisectorFoot';\n out.push({\n ruleId: 'angleBisectorFoot',\n clauseIds: [c.id],\n intents: [addPoint(name, { kind, from: vertex, onLine })],\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/intersection.ts\n//\n// Giao điểm GENERIC của 2 đường thẳng/đoạn cho bởi CẶP ĐỈNH (2 ký tự HOA):\n// \"D là giao điểm của AB và CE\" → tên TRƯỚC (\"X là …\")\n// \"AM cắt CN tại K\" → tên SAU (\"… tại D\")\n// \"AC và BD cắt nhau tại O\" → tên SAU, dạng \"cắt nhau\"\n// → add-point D {kind:'intersection', of:['AB','CE']} (builder ensure 2 segment\n// rồi lấy giao). Mỗi ref = 1 đường qua 2 điểm đã có; thiếu điểm → transpile-fail\n// → escalate (fail-safe).\n//\n// CHỈ nhận ref CẶP ĐỈNH \"AB\" (2 ký tự HOA). KHÔNG nhận:\n// - giao 2 ĐƯỜNG TRÒN \"(O) và (O')\" → kind circleIntersection (rule khác/defer);\n// ref \"(O)\" có ngoặc nên [A-Z]{2} không khớp → tự loại.\n// - line∩circle \"AB cắt (O) tại M\" → secondIntersection (defer); \"(O)\" không\n// phải cặp đỉnh → tự loại.\n// - \"đôi một cắt nhau\" (diameterCirclePairwise) → \"đôi một\" chen giữa cặp đỉnh\n// và \"cắt nhau\" phá khớp dạng C; dạng dùng dấu phẩy (không \"và\") cũng không khớp.\n//\n// Guard degenerate (fail-safe — thà escalate còn hơn dựng điểm vô nghĩa):\n// - 4 đầu mút phải PHÂN BIỆT: chia sẻ đỉnh → 2 đường gặp tại đỉnh chung (không\n// phải điểm mới) → bỏ qua.\n// - tên điểm cần dựng KHÔNG được nằm trong ref (định nghĩa vòng) → bỏ qua.\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt. Regex chứa ký\n// tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { addPoint, DUONG_KW } from './_shared';\n\n// Ref = cặp đỉnh \"AB\" (đúng 2 ký tự HOA, cho phép khoảng trắng ở giữa \"A B\", neo (?![A-Z]) chặn cụm 3+).\n// Tiền tố \"đường thẳng|đoạn|tia|cạnh\" optional.\nconst REF =\n '(?:' +\n DUONG_KW +\n '\\\\s*thẳng\\\\s+|đoạn(?:\\\\s+thẳng)?\\\\s+|tia\\\\s+|cạnh\\\\s+)?([A-Z]\\\\s*[A-Z])(?![A-Z])';\nconst CONN = '(?:và|với)';\n\n// A: \"giao điểm (của)? REF1 (và|với) REF2\" — tên đứng TRƯỚC qua \"X là\".\nconst GIAO_DIEM = new RegExp(`giao\\\\s*điểm\\\\s+(?:của\\\\s+)?${REF}\\\\s*${CONN}\\\\s*${REF}`, 'gu');\n// B: \"REF1 cắt REF2 tại D\" — tên SAU.\nconst CAT_TAI = new RegExp(`${REF}\\\\s+cắt\\\\s+${REF}\\\\s+tại\\\\s+([A-Z])(?![A-Z])`, 'gu');\n// C: \"REF1 (và|với) REF2 (cắt|giao) nhau tại D\" — tên SAU. REF2 NGAY trước \"cắt\n// nhau\" → \"đôi một\" (diameterCirclePairwise) chen vào sẽ phá khớp.\nconst CAT_NHAU = new RegExp(\n `${REF}\\\\s*${CONN}\\\\s*${REF}\\\\s+(?:cắt|giao)\\\\s+nhau\\\\s+tại\\\\s+([A-Z])(?![A-Z])`,\n 'gu',\n);\n// D: \"E, F lần lượt là giao điểm của AB và CD, của AD và BC\" → zip 2 tên với 2 cặp.\nconst DISTRIB_TWO = new RegExp(\n `([A-Z])\\\\s*,\\\\s*([A-Z])\\\\s+lần\\\\s*lượt\\\\s+là\\\\s+giao\\\\s*điểm\\\\s+của\\\\s+${REF}\\\\s*${CONN}\\\\s*${REF}\\\\s*,\\\\s*của\\\\s+${REF}\\\\s*${CONN}\\\\s*${REF}`,\n 'gu',\n);\n\n// Tên điểm đứng TRƯỚC (pattern A): \"X là \" NGAY TRƯỚC \"giao điểm\".\nconst NAME_BEFORE = /([A-Z])(?:['′]?)\\s+là\\s+$/u;\n\n// Prefilter toàn đề.\nconst PREFILTER = /giao\\s*điểm|cắt|giao\\s+nhau/u;\n\n/**\n * Build intent intersection nếu hợp lệ: 4 đầu mút phân biệt (không chia sẻ đỉnh)\n * + tên không nằm trong ref. Ngược lại trả null (escalate).\n */\nfunction makeIntent(name: string, ref1: string, ref2: string): IntentT | null {\n ref1 = ref1.replace(/\\s+/g, '');\n ref2 = ref2.replace(/\\s+/g, '');\n const ends = [ref1[0], ref1[1], ref2[0], ref2[1]];\n if (new Set(ends).size !== 4) return null; // chia sẻ đỉnh / ref trùng → degenerate\n if (ends.includes(name)) return null; // ref chứa chính điểm cần dựng → vô nghĩa\n return addPoint(name, { kind: 'intersection', of: [ref1, ref2] });\n}\n\nexport const intersectionRule: LanguageRule = {\n id: 'intersection',\n // THẤP HƠN mọi rule tạo điểm (midpoint=50 thấp nhất, perpFoot/cevian/center…\n // đều ≥50): intentsToDsl xử lý intent THEO THỨ TỰ priority DESC (không topo-sort)\n // → các điểm đầu mút (vd M,N trung điểm trong \"AM cắt CN tại K\") phải được dựng\n // TRƯỚC khi intersection tham chiếu chúng. Đặt 45 (>connect 40) để chạy sau cùng.\n priority: 45,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const seen = new Set<string>(); // tên đã claim trong clause (tránh trùng tên)\n const emit = (name: string, ref1: string, ref2: string) => {\n if (seen.has(name)) return;\n const intent = makeIntent(name, ref1, ref2);\n if (!intent) return;\n seen.add(name);\n out.push({ ruleId: 'intersection', clauseIds: [c.id], intents: [intent] });\n };\n\n DISTRIB_TWO.lastIndex = 0;\n for (const m of c.text.matchAll(DISTRIB_TWO)) {\n emit(m[1], m[3], m[4]);\n emit(m[2], m[5], m[6]);\n }\n\n // A: tên TRƯỚC — \"X là giao điểm của REF1 và REF2\".\n GIAO_DIEM.lastIndex = 0;\n for (const m of c.text.matchAll(GIAO_DIEM)) {\n const nm = NAME_BEFORE.exec(c.text.slice(0, m.index));\n if (nm) emit(nm[1], m[1], m[2]);\n }\n // B: \"REF1 cắt REF2 tại D\".\n CAT_TAI.lastIndex = 0;\n for (const m of c.text.matchAll(CAT_TAI)) emit(m[3], m[1], m[2]);\n // C: \"REF1 và REF2 cắt nhau tại D\".\n CAT_NHAU.lastIndex = 0;\n for (const m of c.text.matchAll(CAT_NHAU)) emit(m[3], m[1], m[2]);\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/chord.ts\n//\n// Dây cung của đường tròn (chord):\n// \"Cho đường tròn (O), dây AB\" → circle O + A,B ∈ (O) + đoạn AB\n// \"đường tròn tâm O. Dây cung MN\" → circle O + M,N ∈ (O) + đoạn MN\n// \"AB là dây của (O)\" → reverse\n// → drawCircle(O, centerRadius default) + onCircle A,B + connect A-B (dây).\n//\n// \"(O)\" KHÔNG có bán kính (circleRadius cố ý BỎ QUA \"(O)\" trơ). Dây cần MỘT đường\n// tròn để minh hoạ → emit circleCR tâm O bán kính CANONICAL (SYMBOLIC_RADIUS), y\n// như cách xử lý \"(O; R)\" ký hiệu. 2 đầu mút dây là glider onCircle (theta phân\n// biệt) → nằm ĐÚNG trên đường tròn; đoạn nối = dây.\n//\n// Nếu đường tròn O đã được rule khác (circleRadius) dựng với bán kính cụ thể →\n// addShape idempotent theo TÊN + circleRadius priority cao hơn ⇒ định nghĩa cụ\n// thể THẮNG, circle ở đây bị bỏ (không chồng). onCircle/connect vẫn dùng O đó.\n//\n// Circle emit TRƯỚC (RuleMatch đầu) để onCircle tham chiếu O đã tồn tại (transpile\n// xử lý theo thứ tự). Claim cả clause khai báo đường tròn để coverage không sót.\n//\n// Thiếu đường tròn / đầu mút dây trùng tâm / cặp trùng → bỏ qua (escalate).\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt. Regex chứa ký\n// tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { Clause } from '../deterministic/coverage';\nimport { addPoint, connect, drawCircle, CIRCLE_KW } from './_shared';\nimport { SYMBOLIC_RADIUS } from './circleRadius';\n\n// Tên đường tròn toàn đề: \"đường tròn (tâm) O\" / \"(O)\".\n// Hỗ trợ cả tên chữ (alpha, omega...).\nconst CIRCLE_WORDS = new RegExp(CIRCLE_KW + '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?![A-Z])', 'u');\nconst CIRCLE_PAREN = /\\(\\s*([^\\\\s;,).:]+)\\s*\\)/u;\n\n// \"dây (cung)? AB\" (forward) / \"AB là (một)? dây (cung)?\" (reverse). Cặp đỉnh 2\n// ký tự HOA liền, neo (?![A-Z]) chặn cụm 3+.\n// [Dd]ây: \"Dây\" HOA đầu câu (sau dấu '.') cũng khớp; nhãn cặp đỉnh vẫn STRICT HOA.\nconst CHORD_FWD = /[Dd]ây\\s+(?:cung\\s+)?([A-Z])([A-Z])(?![A-Z])/gu;\nconst CHORD_REV = /([A-Z])([A-Z])(?![A-Z])\\s+là\\s+(?:một\\s+)?dây(?:\\s+cung)?(?!\\p{L})/gu;\n\n// Glider angle cho 2 đầu mút dây (radian) — phân biệt để A≠B, dây trải phần trên.\nconst THETA_A = 2.3;\nconst THETA_B = 0.7;\n\n// Prefilter toàn đề (\"Dây\" HOA đầu câu cũng khớp).\nconst PREFILTER = /[Dd]ây/u;\n\n/** Clause id chứa khai báo đường tròn (CIRCLE_WORDS hoặc \"(O)\"). */\nfunction findCircleClauseId(clauses: readonly Clause[], circle: string): number | undefined {\n const frag = new RegExp(CIRCLE_KW + `|\\\\(\\\\s*${circle}\\\\s*\\\\)`, 'u');\n for (const c of clauses) if (frag.test(c.text)) return c.id;\n return undefined;\n}\n\n/**\n * Resolve tên đường tròn từ toàn đề; undefined nếu không có.\n */\nfunction resolveCircle(problem: string): string | undefined {\n const w = CIRCLE_WORDS.exec(problem);\n if (w) return w[1];\n const p = CIRCLE_PAREN.exec(problem);\n if (p) return p[1];\n return undefined;\n}\n\nexport const chordRule: LanguageRule = {\n id: 'chord',\n // Dưới circleRadius (75) — nếu circle O có bán kính cụ thể, định nghĩa đó thắng.\n priority: 52,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const circle = resolveCircle(ctx.problem);\n if (!circle) return []; // không có đường tròn → escalate\n\n // Gom các dây hợp lệ.\n interface Chord {\n clauseId: number;\n a: string;\n b: string;\n }\n const chords: Chord[] = [];\n const seen = new Set<string>(); // \"a|b\" (chuẩn hoá thứ tự) tránh trùng\n for (const c of ctx.clauses) {\n const collect = (re: RegExp) => {\n re.lastIndex = 0;\n for (const m of c.text.matchAll(re)) {\n const a = m[1];\n const b = m[2];\n if (a === b) continue; // cặp trùng → degenerate\n if (a === circle || b === circle) continue; // đầu mút trùng tâm → degenerate\n const key = [a, b].sort().join('|');\n if (seen.has(key)) continue;\n seen.add(key);\n chords.push({ clauseId: c.id, a, b });\n }\n };\n collect(CHORD_FWD);\n collect(CHORD_REV);\n }\n if (chords.length === 0) return []; // không trích được dây → escalate\n\n const out: RuleMatch[] = [];\n // 1) Đường tròn (centerRadius default) — TRƯỚC, claim clause khai báo đường\n // tròn để coverage không sót clause \"Cho đường tròn (O)\".\n const circleClauseId = findCircleClauseId(ctx.clauses, circle);\n out.push({\n ruleId: 'chord',\n clauseIds: circleClauseId === undefined ? [] : [circleClauseId],\n intents: [drawCircle(circle, 'centerRadius', { center: circle, radius: SYMBOLIC_RADIUS })],\n });\n // 2) Mỗi dây: A,B glider onCircle (theta phân biệt) + đoạn nối.\n for (const ch of chords) {\n out.push({\n ruleId: 'chord',\n clauseIds: [ch.clauseId],\n intents: [\n addPoint(ch.a, { kind: 'onCircle', circle, theta: THETA_A }),\n addPoint(ch.b, { kind: 'onCircle', circle, theta: THETA_B }),\n connect(ch.a, ch.b, 'segment'),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/incircleTangency.ts\n//\n// Tiếp điểm của đường tròn nội tiếp với các cạnh tam giác:\n// \"Đường tròn (I) nội tiếp tam giác ABC tiếp xúc với các cạnh BC, CA, AB\n// tại các điểm D, E, G\"\n// → D/E/G = tangencyPoint(circle I, onLine BC/CA/AB).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\nimport type { IntentT } from '../intent';\nimport type { Clause } from '../deterministic/coverage';\n\nconst PREFILTER = /tiếp\\s*xúc/u;\n\nconst INCIRCLE_IN_CLAUSE = /đường\\s*tròn\\s*(?:\\(\\s*([A-Z])\\s*\\)|tâm\\s+([A-Z]))?\\s*nội\\s*tiếp\\s+tam\\s*giác\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/iu;\n\nconst SIDE_POINT_LIST = /tiếp\\s*xúc\\s+(?:với\\s+)?(?:các\\s+)?(?:cạnh|đoạn)\\s+([A-Z]{2}(?:\\s*,\\s*[A-Z]{2})*)\\s+(?:lần\\s*lượt\\s+)?tại\\s+(?:các\\s+)?(?:điểm\\s+)?([A-Z](?:\\s*,\\s*[A-Z])*)(?![A-Za-z])/iu;\n\nfunction splitCsv(blob: string): string[] {\n return blob\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction normalizeSpaces(text: string): string {\n return text.replace(/\\s+/gu, ' ').trim();\n}\n\nfunction logicalChunks(problem: string, clauses: readonly Clause[]): Array<{ text: string; clauseIds: number[] }> {\n return problem\n .split(/[.;]+/u)\n .map((text) => normalizeSpaces(text))\n .filter(Boolean)\n .map((text) => ({\n text,\n clauseIds: clauses\n .filter((c) => text.includes(normalizeSpaces(c.text)))\n .map((c) => c.id),\n }));\n}\n\nfunction parseIncircleName(text: string): string | undefined {\n const m = INCIRCLE_IN_CLAUSE.exec(text);\n if (!m) return undefined;\n return m[1] ?? m[2] ?? 'O';\n}\n\nfunction parseTangencies(text: string, circle: string): IntentT[] {\n const m = SIDE_POINT_LIST.exec(text);\n if (!m) return [];\n\n const sides = splitCsv(m[1]);\n const names = splitCsv(m[2]);\n if (sides.length === 0 || sides.length !== names.length) return [];\n\n return names.map((name, i) => (\n addPoint(name, { kind: 'tangencyPoint', circle, onLine: sides[i] })\n ));\n}\n\nexport const incircleTangencyRule: LanguageRule = {\n id: 'incircleTangency',\n priority: 71,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const chunk of logicalChunks(ctx.problem, ctx.clauses)) {\n const circle = parseIncircleName(chunk.text);\n if (!circle) continue;\n\n const intents = parseTangencies(chunk.text, circle);\n if (intents.length === 0) continue;\n\n out.push({ ruleId: 'incircleTangency', clauseIds: chunk.clauseIds, intents });\n }\n return out;\n },\n};\n","import type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, drawCircle, drawShape, CIRCLE_KW, DUONG_KW } from './_shared';\n\nconst TRI = /tam\\s*giác(?:[^A-Z.;\\n]*)\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\nconst ALTITUDES = /các\\s+đường\\s*cao\\s+([A-Z])([A-Z])\\s*,\\s*([A-Z])([A-Z])(?![A-Z])/u;\nconst DIAMETER_INTERSECTION = new RegExp(\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])\\\\s+và\\\\s+' +\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])[^.;\\n]*?tại\\\\s+các\\\\s+điểm\\\\s+([A-Z])\\\\s*,\\\\s*([A-Z])(?![A-Z])',\n 'u',\n);\nconst SEGMENT_CIRCLE = new RegExp(\n '[Đđ]oạn\\\\s+thẳng\\\\s+([A-Z])([A-Z])\\\\s+cắt\\\\s+' +\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])\\\\s+tại\\\\s+điểm\\\\s+([A-Z])(?![A-Z])',\n 'gu',\n);\nconst LINE_LINE =\n /[Cc]ác\\s+đường\\s+thẳng\\s+([A-Z])([A-Z])\\s+và\\s+([A-Z])([A-Z])\\s+cắt\\s+nhau\\s+tại\\s+([A-Z])(?![A-Z])/u;\n\nfunction opposite(triangle: readonly string[], apex: string): string | undefined {\n const rest = triangle.filter((v) => v !== apex);\n return rest.length === 2 ? rest[0] + rest[1] : undefined;\n}\n\nexport const altitudeDiameterCirclesRule: LanguageRule = {\n id: 'altitude-diameter-circles',\n priority: 67,\n languages: ['vi'],\n patterns: [new RegExp(DUONG_KW + '\\\\s*cao', 'u'), new RegExp(DUONG_KW + '\\\\s*kính', 'u')],\n match(ctx) {\n const tri = TRI.exec(ctx.problem);\n const alts = ALTITUDES.exec(ctx.problem);\n const circles = DIAMETER_INTERSECTION.exec(ctx.problem);\n if (!tri || !alts || !circles) return [];\n\n const triangle = [tri[1], tri[2], tri[3]] as const;\n const altPairs = [\n [alts[1], alts[2]],\n [alts[3], alts[4]],\n ] as const;\n\n const altitudeIntents = [];\n for (const [apex, foot] of altPairs) {\n if (!triangle.includes(apex) || triangle.includes(foot)) return [];\n const opp = opposite(triangle, apex);\n if (!opp) return [];\n altitudeIntents.push(\n addPoint(foot, { kind: 'perpFoot', from: apex, onLine: opp }),\n connect(apex, foot, 'segment'),\n );\n }\n\n const dia1 = circles[1] + circles[2];\n const dia2 = circles[3] + circles[4];\n const known = new Set(altPairs.map(([a, f]) => `${a}${f}`));\n if (!known.has(dia1) || !known.has(dia2) || dia1 === dia2) return [];\n\n const c1 = `k${dia1}`;\n const c2 = `k${dia2}`;\n const x = circles[5];\n const y = circles[6];\n if (x === y) return [];\n\n const segCircles = [...ctx.problem.matchAll(SEGMENT_CIRCLE)];\n const extraPointIntents = [];\n for (const m of segCircles) {\n const line = `${m[1]}${m[2]}`;\n const dia = `${m[3]}${m[4]}`;\n const point = m[5];\n if (line === dia || point === line[0] || point === line[1]) return [];\n const circle = dia === dia1 ? c1 : dia === dia2 ? c2 : undefined;\n if (!circle) return [];\n extraPointIntents.push(\n addPoint(point, { kind: 'intersection', of: [line, circle], branch: 0 }),\n );\n }\n\n const lineLine = LINE_LINE.exec(ctx.problem);\n if (lineLine) {\n extraPointIntents.push(\n addPoint(lineLine[5], {\n kind: 'intersection',\n of: [`${lineLine[1]}${lineLine[2]}`, `${lineLine[3]}${lineLine[4]}`],\n }),\n );\n }\n\n const intents = [\n drawShape('triangle', [...triangle], 'any'),\n ...altitudeIntents,\n drawCircle(c1, 'diameter', { endpoints: [dia1[0], dia1[1]] }),\n drawCircle(c2, 'diameter', { endpoints: [dia2[0], dia2[1]] }),\n addPoint(x, { kind: 'circleIntersection', c1, c2, which: 0 }),\n addPoint(y, { kind: 'circleIntersection', c1, c2, which: 1 }),\n ...extraPointIntents,\n ];\n\n const out: RuleMatch[] = [{\n ruleId: 'altitude-diameter-circles',\n clauseIds: ctx.clauses.map((c) => c.id),\n intents,\n }];\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/diameterCircleCutsSides.ts\n//\n// \"Đường tròn đường kính BC cắt AB, AC tại M và N\" — đường tròn đường kính một\n// cạnh cắt hai cạnh kề tại các điểm phái sinh (phân phối 1-1):\n//\n// Cho tam giác ABC nhọn, đường tròn đường kính BC cắt AB, AC tại M và N.\n//\n// Bản chất: đường tròn đường kính PQ đi qua P, Q. Cạnh AB (chứa B ∈ đường kính)\n// cắt đường tròn tại B và một điểm thứ hai M (= chân đường cao hạ từ C, ∠BMC=90°\n// Thales). Vì luôn biết điểm chung (đỉnh dùng chung giữa cạnh và đường kính), ta\n// dựng M bằng `secondIntersection` (JSXGraph otherintersection loại điểm chung) —\n// robust hơn `intersection`+branch (không phụ thuộc thứ tự index JSXGraph).\n//\n// Phân phối: \"cắt L1, L2 tại X, Y\" → zip L1↔X, L2↔Y (kèm biến thể \"lần lượt\",\n// nối \"và\", tiền tố \"cạnh\"/\"các cạnh\"). Đường tròn KHÔNG tự dựng tam giác (triangle\n// rule lo) — chỉ emit đường tròn + các giao điểm.\n//\n// Fail-safe (escalate, thà thiếu hơn dựng sai):\n// - số cạnh ≠ số điểm → bỏ qua.\n// - cạnh không chia sẻ ĐÚNG 1 đỉnh với đường kính (0 → không biết điểm chung;\n// 2 → cạnh trùng đường kính, suy biến) → bỏ qua.\n// - tên điểm trùng đỉnh cạnh/đường kính (định nghĩa vòng) → bỏ qua.\n//\n// GOTCHA \\b: \\b của JS theo ASCII. Vùng tên điểm (\"M và N\", \"M, N\") các chữ HOA\n// luôn cách bởi dấu cách/phẩy nên \\b[A-Z]\\b an toàn; vẫn dùng cờ 'u'.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { addPoint, drawCircle, CIRCLE_KW, DUONG_KW } from './_shared';\n\n// Anchor \"đường tròn đường kính PQ cắt <cạnh…> (lần lượt)? tại <điểm…>\".\n// lineRegion lazy tới \"tại\" đầu tiên; pointRegion tới hết clause (không . ; \\n).\nconst PATTERN = new RegExp(\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])(?![A-Z])\\\\s+cắt\\\\s+([^.;\\\\n]*?)\\\\s+(?:lần\\\\s*lượt\\\\s+)?tại\\\\s+([^.;\\n]*)',\n 'u',\n);\n\nconst PREFILTER = new RegExp(DUONG_KW + '\\\\s*kính', 'u');\n\n/** Đỉnh chung DUY NHẤT giữa cạnh \"AB\" và đường kính \"BC\" (vd \"B\"). */\nfunction sharedVertex(line: string, dia: string): string | undefined {\n const shared = [line[0], line[1]].filter((ch) => dia.includes(ch));\n return shared.length === 1 ? shared[0] : undefined;\n}\n\nexport const diameterCircleCutsSidesRule: LanguageRule = {\n // THẤP HƠN triangle (100): cần A,B,C dựng trước khi secondIntersection tham\n // chiếu cạnh/đỉnh. Đặt 66 (cùng họ diameterCirclePairwise) — đủ thấp so với 100.\n id: 'diameter-circle-cuts-sides',\n priority: 66,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const m = PATTERN.exec(c.text);\n if (!m) continue;\n\n const d0 = m[1];\n const d1 = m[2];\n const dia = d0 + d1; // \"BC\"\n const lines = m[3].match(/[A-Z][A-Z](?![A-Z])/gu) ?? [];\n const points = m[4].match(/\\b[A-Z]\\b/gu) ?? [];\n\n // Phân phối 1-1: cần ≥1 cạnh và số cạnh == số điểm.\n if (lines.length === 0 || lines.length !== points.length) continue;\n\n const circle = `k${dia}`;\n const intents: IntentT[] = [\n drawCircle(circle, 'diameter', { endpoints: [d0, d1] }),\n ];\n\n let ok = true;\n const seen = new Set<string>();\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const pt = points[i];\n const other = sharedVertex(line, dia);\n // Cần đúng 1 đỉnh chung (điểm đã biết trên cả cạnh lẫn đường tròn).\n if (!other) { ok = false; break; }\n // Tên điểm phải MỚI, không trùng đỉnh cạnh/đường kính.\n if (line.includes(pt) || dia.includes(pt) || seen.has(pt)) { ok = false; break; }\n seen.add(pt);\n intents.push(addPoint(pt, { kind: 'secondIntersection', line, circle, other }));\n }\n if (!ok) continue;\n\n out.push({ ruleId: 'diameter-circle-cuts-sides', clauseIds: [c.id], intents });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/registry.ts\n//\n// Đăng ký rule + engine chạy theo priority. Thêm construct mới = import module\n// + thêm vào ALL_RULES (không sửa engine).\nimport type { LanguageRule, RuleContext, RuleMatch } from './_types';\nimport { triangleRule } from './triangle';\nimport { quadRule } from './quad';\nimport { connectRule } from './connect';\nimport { midpointRule } from './midpoint';\nimport { perpBisectorRule } from './perpBisector';\nimport { cevianRule } from './cevian';\nimport { angleBisectorAngleRule } from './angleBisectorAngle';\nimport { centersRule } from './centers';\nimport { perpFootRule } from './perpFoot';\nimport { circleRadiusRule } from './circleRadius';\nimport { circleTriangleRule } from './circleTriangle';\nimport { tangentFromExtRule } from './tangentFromExt';\nimport { externalPointRule } from './externalPoint';\nimport { arcMidpointRule } from './arcMidpoint';\nimport { excenterRule } from './excenter';\nimport { parallelPerpRule } from './parallelPerp';\nimport { reflectionRule } from './reflection';\nimport { pointAtDistanceRule } from './pointAtDistance';\nimport { eulerLineRule } from './eulerLine';\nimport { radicalAxisRule } from './radicalAxis';\nimport { simsonRule } from './simson';\nimport { ninePointRule } from './ninePoint';\nimport { diameterCirclePairwiseRule } from './diameterCirclePairwise';\nimport { angleBisectorFootRule } from './angleBisectorFoot';\nimport { intersectionRule } from './intersection';\nimport { chordRule } from './chord';\nimport { incircleTangencyRule } from './incircleTangency';\nimport { altitudeDiameterCirclesRule } from './altitudeDiameterCircles';\nimport { diameterCircleCutsSidesRule } from './diameterCircleCutsSides';\n\nconst RULES: readonly LanguageRule[] = [\n triangleRule,\n quadRule,\n connectRule,\n midpointRule,\n perpBisectorRule,\n cevianRule,\n angleBisectorAngleRule,\n centersRule,\n perpFootRule,\n circleRadiusRule,\n circleTriangleRule,\n tangentFromExtRule,\n externalPointRule,\n arcMidpointRule,\n excenterRule,\n parallelPerpRule,\n reflectionRule,\n pointAtDistanceRule,\n eulerLineRule,\n radicalAxisRule,\n simsonRule,\n ninePointRule,\n diameterCirclePairwiseRule,\n angleBisectorFootRule,\n intersectionRule,\n chordRule,\n incircleTangencyRule,\n altitudeDiameterCirclesRule,\n diameterCircleCutsSidesRule,\n];\n\n/** Sắp xếp priority giảm dần (cao chạy trước) — tính 1 lần ở module load. */\nexport const ALL_RULES: readonly LanguageRule[] = [...RULES].sort(\n (a, b) => b.priority - a.priority,\n);\n\nexport function runRules(ctx: RuleContext): RuleMatch[] {\n const matches: RuleMatch[] = [];\n for (const rule of ALL_RULES) {\n if (!rule.patterns.some((p) => p.test(ctx.problem))) continue;\n matches.push(...rule.match(ctx));\n }\n return matches;\n}\n","// src/stamps/geometry-2d/ai/deterministic/runDeterministicIntents.ts\n//\n// Track A orchestrator: rule engine → IntentT[] + coverage gate.\n// Chỉ lo NLU; gate transpile/verify do router (buildFigureIntent) áp dụng sau.\nimport type { IntentT } from '../intent';\nimport { segmentClauses, computeCoverage, type Clause, type CoverageReport } from './coverage';\nimport { runRules } from '../rules/registry';\n\nexport type DetIntentResult =\n | { ok: true; intents: IntentT[]; coverage: CoverageReport }\n | {\n ok: false;\n reason: 'incomplete-coverage' | 'no-match';\n coverage: CoverageReport;\n };\n\ninterface Collected {\n /** Intent từ MỌI clause có rule claim, deduped theo JSON. */\n intents: IntentT[];\n coverage: CoverageReport;\n matchCount: number;\n}\n\n// Segment → rules → coverage → dedup. Dùng chung cho gate đầy đủ\n// (runDeterministicIntents) lẫn partial (tryPartialDeterministic).\n// Dedupe intent y hệt nhau: nhiều rule cùng tham chiếu 1 hình (vd \"tam giác ABC\"\n// xuất hiện ở nhiều clause → triangle rule emit lặp; centers/cevian cũng cần nó).\nfunction collectDeterministic(problem: string): Collected {\n const clauses = segmentClauses(problem);\n const matches = runRules({ problem, clauses });\n const coverage = computeCoverage(clauses, matches);\n\n const seen = new Set<string>();\n const intents = matches\n .flatMap((m) => m.intents)\n .filter((i) => {\n const key = JSON.stringify(i);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n return { intents, coverage, matchCount: matches.length };\n}\n\nexport function runDeterministicIntents(problem: string): DetIntentResult {\n const { intents, coverage, matchCount } = collectDeterministic(problem);\n\n if (matchCount === 0) return { ok: false, reason: 'no-match', coverage };\n if (!coverage.complete) return { ok: false, reason: 'incomplete-coverage', coverage };\n return { ok: true, intents, coverage };\n}\n\nexport interface PartialDeterministicResult {\n /** Intent deterministic từ các clause đã được rule claim (deduped). */\n detIntents: IntentT[];\n /** Clause geo CHƯA được phủ — phần LLM cần bù (hybrid Phase 2). */\n uncovered: Clause[];\n coverage: CoverageReport;\n /**\n * true khi deterministic phủ MỘT PHẦN: có rule match + ≥1 intent NHƯNG coverage\n * CHƯA đầy đủ. Đây là điều kiện kích hoạt hybrid (Phase 2 gọi LLM bù `uncovered`\n * rồi mergeIntents). false khi: complete (Track A lo đủ) hoặc no-match/0 intent\n * (full LLM Track B).\n */\n hasPartial: boolean;\n}\n\n/**\n * Deterministic-only (KHÔNG LLM): thu intent phần đã phủ + clause còn thiếu, kể\n * cả khi coverage incomplete. Nền cho hybrid partial-coverage — Phase 2 sẽ gọi\n * LLM bù `uncovered` rồi `mergeIntents(detIntents, llmIntents)`.\n */\nexport function tryPartialDeterministic(problem: string): PartialDeterministicResult {\n const { intents, coverage, matchCount } = collectDeterministic(problem);\n return {\n detIntents: intents,\n uncovered: coverage.uncovered,\n coverage,\n hasPartial: matchCount > 0 && !coverage.complete && intents.length > 0,\n };\n}\n","// src/stamps/geometry-2d/ai/deterministic/guards.ts\n//\n// Hai guard fail-safe cho deterministic-first: nếu DSL dựng được KHÔNG trung thành\n// với đề, router escalate AI thay vì render hình sai/thiếu. Bổ sung cho coverage\n// clause-level (vốn coarse, dễ bỏ lọt khi 1 clause chứa nhiều construct).\nimport type { DslInputT } from '../../dsl/schema';\nimport type { IntentT } from '../intent';\n\n// ── Guard 1: named-entity present ────────────────────────────────────────────\n// Mọi đỉnh/điểm được ĐẶT TÊN hay KHAI BÁO trong đề phải tồn tại trong DSL.\n// KHÔNG dùng \\b (ASCII) quanh ký tự Việt.\n\n// Tên điểm dẫn nhập 1 ký tự HOA: \"Gọi M\", \"lấy điểm D\", \"cắt … tại D\", \"N là …\",\n// \"H, K lần lượt\", \"và P là\".\n// Issue #46 nhóm A: prime (' U+0027 / ′ U+2032) là PHẦN của tên (\"D′\" ≠ \"D\").\n// Group prime đứng ngay sau chữ cái — collect bằng letter + normalize(prime) để\n// expected-name khớp DSL (rule pointAtDistance giữ prime → DSL có \"D'\").\nconst NAMED_INTRO = /(?:Gọi|gọi|Lấy|lấy|Dựng|dựng|Đặt|đặt|tại|điểm|và)\\s+(?:điểm\\s+)?([A-Z])(['′]?)(?![A-Za-z])/gu;\n// LƯU Ý: KHÔNG dùng `là\\b` — `\\b` của JS theo ASCII, mà 'à' (U+00E0) là\n// non-word-char ASCII → `\\b` sau 'là' KHÔNG khớp khi theo sau là space/dấu câu\n// → pattern chết, bỏ sót mọi \"X là <construct>\" (bug silent-incomplete). Dùng\n// lookahead non-letter Unicode (?!\\p{L}) để neo cuối \"là\".\nconst NAMED_LA = /([A-Z])(['′]?)(?![A-Za-z])\\s+là(?!\\p{L})/gu;\nconst NAMED_LANLUOT = /([A-Z])(['′]?)(?![A-Za-z])\\s*,\\s*([A-Z])(['′]?)(?![A-Za-z])\\s+lần lượt/gu;\n\n// Ghép chữ cái + prime đã normalize (′→') thành tên đầy đủ. Đồng bộ với\n// rules/pointAtDistance.ts normalizePointName — giữ naming layer nhất quán.\nfunction joinPrime(letter: string | undefined, prime: string | undefined): string | undefined {\n if (!letter) return undefined;\n return prime ? `${letter}'` : letter;\n}\n\n// Đỉnh của hình khai báo: \"tam giác ABC\", \"tứ giác ABCD\", \"hình vuông/… ABCD\".\n// Bắt cụm 3-4 ký tự HOA LIỀN ngay sau tên hình (mỗi đỉnh phải có trong DSL).\nconst SHAPE_TRI = /tam giác\\s+([A-Z]{3})(?![A-Z])/gu;\nconst SHAPE_QUAD = /(?:tứ giác|hình\\s+(?:vuông|chữ nhật|bình hành|thoi|thang))\\s+([A-Z]{4})(?![A-Z])/gu;\n\nexport interface NamedEntityReport {\n ok: boolean;\n missing: string[];\n}\n\nfunction collectExpectedNames(problem: string): Set<string> {\n const names = new Set<string>();\n // Mỗi entry [letterGroup, primeGroup]: tên = letter + normalize(prime).\n const add = (re: RegExp, groups: [number, number][]) => {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(problem)) !== null) {\n for (const [lg, pg] of groups) {\n const name = joinPrime(m[lg], m[pg]);\n if (name) names.add(name);\n }\n }\n };\n add(NAMED_INTRO, [[1, 2]]);\n add(NAMED_LA, [[1, 2]]);\n add(NAMED_LANLUOT, [[1, 2], [3, 4]]);\n // Đỉnh hình: tách cụm 3/4 ký tự thành từng đỉnh.\n for (const re of [SHAPE_TRI, SHAPE_QUAD]) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(problem)) !== null) {\n for (const ch of m[1]) names.add(ch);\n }\n }\n return names;\n}\n\nexport function allNamedEntitiesPresent(problem: string, dsl: DslInputT): NamedEntityReport {\n const present = new Set<string>();\n for (const p of dsl.points) present.add(p.name);\n for (const s of dsl.shapes) present.add(s.name);\n\n const missing: string[] = [];\n for (const name of collectExpectedNames(problem)) {\n if (!present.has(name)) missing.push(name);\n }\n return { ok: missing.length === 0, missing };\n}\n\n// ── Guard 2: intent → DSL fidelity ───────────────────────────────────────────\n// Mỗi add-point intent dựng điểm phái sinh (không phải 'free') PHẢI hiện diện\n// trong DSL đúng dạng. Builder idempotent DROP add-point khi tên trùng đỉnh sẵn\n// có (vd \"đường cao AB\" → foot B trùng vertex B) → điểm để 'free' → guard bắt.\n\nexport interface FidelityReport {\n ok: boolean;\n dropped: string[];\n}\n\nexport function verifyIntentFidelity(intents: readonly IntentT[], dsl: DslInputT): FidelityReport {\n const byName = new Map<string, { kind: string }>();\n for (const p of dsl.points) byName.set(p.name, p as unknown as { kind: string });\n\n const dropped: string[] = [];\n for (const intent of intents) {\n if (intent.op !== 'add-point') continue;\n const kind = (intent as { constraint?: { kind?: string } }).constraint?.kind;\n // free point không phải construct phái sinh → skip fidelity.\n // externalToCircle CỐ TÌNH dựng FREE point ngoài circle (như fixture canonical\n // tangent-from-external-named.ts): builder đặt A kind 'free' tại coord ngoài\n // circle, KHÔNG phải điểm phái sinh đặc thù bị drop. Nếu builder fail-safe skip\n // (circle thiếu / tâm không free) → A missing → guard allNamedEntitiesPresent\n // bắt (named-missing). Vì vậy bỏ externalToCircle khỏi fidelity check.\n if (!kind || kind === 'free' || kind === 'externalToCircle') continue;\n const name = (intent as { name: string }).name;\n const pt = byName.get(name);\n // Thiếu hẳn, hoặc bị builder hạ về 'free' (đã bị drop bởi vertex trùng tên).\n if (!pt || pt.kind === 'free') dropped.push(name);\n }\n return { ok: dropped.length === 0, dropped };\n}\n","// src/stamps/geometry-2d/ai/deterministic/tryDeterministicFigure.ts\n//\n// Track A đầy đủ: rule NLU → coverage gate → normalize → resolve circle collisions\n// → build DSL → transpile → verifyGeometry → named-entity guard. Trả figure SẴN\n// RENDER nếu qua HẾT 4 lớp gate; ngược lại { ok:false } để router escalate AI.\n//\n// Tách khỏi buildFigureIntent để test độc lập toàn bộ logic quyết định.\nimport type { IntentT } from '../intent';\nimport type { DslInputT } from '../../dsl/schema';\nimport type { TranspileResult } from '../../dsl/transpile/errors';\nimport type { VerifyReport } from '../verify';\nimport type { CoverageReport } from './coverage';\nimport { runDeterministicIntents } from './runDeterministicIntents';\nimport { allNamedEntitiesPresent, verifyIntentFidelity } from './guards';\nimport { normalizeIntents } from '../normalizeIntent';\nimport { resolveCircleNameCollisions } from '../resolveCircleNames';\nimport { intentsToDsl } from '../intentToDsl';\nimport { transpile } from '../../dsl';\nimport { verifyGeometry } from '../verify';\n\nexport type DeterministicReason =\n | 'no-match'\n | 'incomplete-coverage'\n | 'build-throw'\n | 'transpile-throw'\n | 'transpile-fail'\n | 'verify-fail'\n | 'named-missing'\n | 'intent-dropped';\n\nexport interface DeterministicFigure {\n intents: IntentT[];\n dsl: DslInputT;\n transpile: Extract<TranspileResult, { ok: true }>;\n verify: VerifyReport;\n coverage: CoverageReport;\n}\n\nexport type TryDeterministicResult =\n | { ok: true; figure: DeterministicFigure }\n | { ok: false; reason: DeterministicReason; detail?: string; coverage?: CoverageReport };\n\nexport function tryDeterministicFigure(problem: string): TryDeterministicResult {\n const det = runDeterministicIntents(problem);\n if (!det.ok) return { ok: false, reason: det.reason, coverage: det.coverage };\n\n // Cùng các stage chuẩn hoá như Track B (LLM) để 2 path hội tụ.\n const intents = resolveCircleNameCollisions(normalizeIntents(det.intents, problem));\n\n let dsl: DslInputT;\n try {\n dsl = intentsToDsl(intents);\n } catch (e) {\n return { ok: false, reason: 'build-throw', detail: errMsg(e), coverage: det.coverage };\n }\n\n let tResult: TranspileResult;\n try {\n tResult = transpile(dsl);\n } catch (e) {\n return { ok: false, reason: 'transpile-throw', detail: errMsg(e), coverage: det.coverage };\n }\n if (!tResult.ok) {\n return {\n ok: false,\n reason: 'transpile-fail',\n detail: tResult.errors.map((x) => `${x.code}:${x.message}`).join('; '),\n coverage: det.coverage,\n };\n }\n\n const vReport = verifyGeometry(intents, dsl);\n if (!vReport.ok) {\n return { ok: false, reason: 'verify-fail', coverage: det.coverage };\n }\n\n // Guard 1: tên xuất hiện/khai báo trong đề phải có trong DSL (chống drop construct).\n const named = allNamedEntitiesPresent(problem, dsl);\n if (!named.ok) {\n return { ok: false, reason: 'named-missing', detail: named.missing.join(','), coverage: det.coverage };\n }\n\n // Guard 2: add-point phái sinh phải dựng trung thành (không bị builder drop vì\n // trùng tên đỉnh sẵn có → điểm thực tế là 'free' thay vì construct).\n const fidelity = verifyIntentFidelity(intents, dsl);\n if (!fidelity.ok) {\n return { ok: false, reason: 'intent-dropped', detail: fidelity.dropped.join(','), coverage: det.coverage };\n }\n\n return {\n ok: true,\n figure: { intents, dsl, transpile: tResult, verify: vReport, coverage: det.coverage },\n };\n}\n\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n","// src/stamps/geometry-2d/ai/deterministic/describeMiss.ts\n//\n// Dịch lý do deterministic miss (mã kỹ thuật) → câu tiếng Việt dễ hiểu cho\n// chế độ deterministicOnly (\"dùng tạm rule base, tắt LLM\"). Phân 2 nhóm để người\n// tối ưu rule base phân biệt ngay:\n// - \"chưa phủ\" (no-match / incomplete-coverage / named-missing) → CẦN THÊM RULE.\n// - \"rule khớp nhưng dựng lỗi\" (build/transpile/verify/intent-dropped) → có thể LỖI RULE.\n// Hàm thuần, không I/O — message này được gán vào IntentFailureResult.message và\n// nổi lên AiFigureUiResult để consumer (hoctotbachkhoa) hiển thị / ghi log.\nimport type { DeterministicReason } from './tryDeterministicFigure';\nimport type { CoverageReport } from './coverage';\n\nexport interface DeterministicMiss {\n reason: DeterministicReason;\n /** Chi tiết kỹ thuật theo reason (tên thiếu, mã lỗi transpile, …). */\n detail?: string;\n /** Báo cáo coverage — dùng `uncovered[].text` để nêu cụm đề chưa phủ. */\n coverage?: CoverageReport;\n}\n\n/** \", \" sau detail nếu có (else chuỗi rỗng) — tránh \"(undefined)\". */\nfunction detailSuffix(detail?: string): string {\n const d = detail?.trim();\n return d ? `: ${d}` : '';\n}\n\n/** \"D,E\" → \"D, E\" (thêm khoảng trắng sau phẩy cho dễ đọc). */\nfunction formatNames(detail?: string): string {\n const names = (detail ?? '')\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n return names.length > 0 ? names.join(', ') : 'một số đối tượng';\n}\n\nexport function describeDeterministicMiss(miss: DeterministicMiss): string {\n const { reason, detail, coverage } = miss;\n switch (reason) {\n // === Nhóm \"chưa phủ\" → cần bổ sung rule ===\n case 'no-match':\n return 'Rule base chưa nhận ra cấu trúc hình học nào trong đề (cần bổ sung rule cho dạng này).';\n case 'incomplete-coverage': {\n const parts = (coverage?.uncovered ?? []).map((c) => `«${c.text}»`);\n if (parts.length === 0) {\n return 'Rule base mới phủ được một phần đề (cần bổ sung rule cho phần còn lại).';\n }\n return `Rule base mới phủ được một phần đề. Chưa dựng được: ${parts.join('; ')} (cần bổ sung rule).`;\n }\n case 'named-missing':\n return `Đề nhắc tới ${formatNames(detail)} nhưng rule base chưa dựng được (cần bổ sung rule).`;\n\n // === Nhóm \"rule khớp nhưng dựng lỗi\" → có thể lỗi rule ===\n case 'build-throw':\n return `Rule đã khớp nhưng dựng hình thất bại — có thể lỗi rule${detailSuffix(detail)}.`;\n case 'transpile-throw':\n case 'transpile-fail':\n return `Rule đã khớp nhưng biên dịch hình lỗi — có thể lỗi rule${detailSuffix(detail)}.`;\n case 'verify-fail':\n return 'Rule dựng được hình nhưng sai kiểm tra hình học — có thể lỗi rule.';\n case 'intent-dropped':\n return `Rule khớp nhưng một số điểm phái sinh bị bỏ (${formatNames(detail)}) — có thể lỗi rule.`;\n\n default: {\n // Exhaustive guard: thêm reason mới mà quên xử lý → type error tại compile.\n const _never: never = reason;\n return `Rule base chưa dựng được (${String(_never)}).`;\n }\n }\n}\n","// src/stamps/geometry-2d/ai/providers/anthropic.ts\n//\n// AIProvider impl cho Anthropic Claude. Internal: dùng tool_use với single\n// tool \"emit_figure_envelope\" input_schema = envelope JSON Schema → ép Claude\n// emit JSON đúng shape. Map response → ProviderOutput envelope.\n//\n// Khác bản trước (provider.ts): bỏ dual-tool (build_figure + refuse) — Claude\n// hoàn toàn xử lý được decision/refuse trong cùng 1 envelope.\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport type {\n AIProvider,\n ImagePart,\n ProviderOutput,\n ProviderRequest,\n ProviderTokenUsage,\n VisionRequest,\n} from './types';\n\nconst TOOL_NAME = 'emit_figure_envelope';\nconst VISION_TOOL_NAME = 'extract_problem_envelope';\n\nexport interface AnthropicProviderOptions {\n apiKey: string;\n /** Cache system prompt qua Anthropic prompt-caching (mặc định bật). */\n enableCaching?: boolean;\n}\n\nexport class AnthropicProvider implements AIProvider {\n readonly name = 'anthropic';\n readonly defaultModel = 'claude-opus-4-7';\n\n constructor(private readonly opts: AnthropicProviderOptions) {\n if (!opts.apiKey) throw new Error('AnthropicProvider: apiKey bắt buộc');\n }\n\n async call(req: ProviderRequest): Promise<ProviderOutput> {\n const enableCaching = this.opts.enableCaching !== false;\n const systemBlock = enableCaching\n ? { type: 'text' as const, text: req.systemPrompt, cache_control: { type: 'ephemeral' as const } }\n : { type: 'text' as const, text: req.systemPrompt };\n\n const tool = {\n name: TOOL_NAME,\n description:\n 'Emit envelope JSON cho phép vẽ hình hoặc từ chối. ' +\n 'decision=\"build\" kèm figure (DSL hình học); decision=\"refuse\" kèm reason.',\n input_schema: req.schema,\n };\n\n const client = new Anthropic({ apiKey: this.opts.apiKey });\n let resp: Anthropic.Messages.Message;\n try {\n resp = await client.messages.create(\n {\n model: req.model,\n max_tokens: req.maxTokens,\n system: [systemBlock],\n tools: [tool as never],\n tool_choice: { type: 'tool', name: TOOL_NAME },\n messages: [{ role: 'user', content: req.userPrompt }],\n },\n req.signal ? { signal: req.signal } : undefined,\n );\n } catch (e) {\n const err = e as { message?: string; status?: number };\n return {\n kind: 'error',\n message: err.message ?? 'Lỗi gọi Anthropic API',\n ...(err.status !== undefined ? { status: err.status } : {}),\n };\n }\n\n const usage = toUsage(resp.usage);\n const toolUse = resp.content.find((c) => c.type === 'tool_use');\n if (!toolUse || toolUse.type !== 'tool_use') {\n return {\n kind: 'error',\n message: 'Claude không gọi tool. stop_reason=' + resp.stop_reason,\n };\n }\n if (toolUse.name !== TOOL_NAME) {\n return {\n kind: 'error',\n message: `Tool không xác định: \"${toolUse.name}\"`,\n };\n }\n return { kind: 'json', data: toolUse.input, usage };\n }\n\n async extractText(req: VisionRequest): Promise<ProviderOutput> {\n const model = req.model ?? this.defaultModel;\n const enableCaching = this.opts.enableCaching !== false;\n const systemBlock = enableCaching\n ? { type: 'text' as const, text: req.systemPrompt, cache_control: { type: 'ephemeral' as const } }\n : { type: 'text' as const, text: req.systemPrompt };\n\n const tool = {\n name: VISION_TOOL_NAME,\n description: 'Trích đề bài hình học từ ảnh, hoặc từ chối nếu không phải đề toán.',\n input_schema: req.schema,\n };\n\n const imageBlocks = req.images.map((img: ImagePart) => ({\n type: 'image' as const,\n source: {\n type: 'base64' as const,\n media_type: img.mediaType,\n data: img.base64,\n },\n }));\n\n const client = new Anthropic({ apiKey: this.opts.apiKey });\n let resp: Anthropic.Messages.Message;\n try {\n resp = await client.messages.create(\n {\n model,\n max_tokens: req.maxTokens,\n system: [systemBlock],\n tools: [tool as never],\n tool_choice: { type: 'tool', name: VISION_TOOL_NAME },\n messages: [\n {\n role: 'user',\n content: [...imageBlocks, { type: 'text', text: req.userPrompt }],\n },\n ],\n },\n req.signal ? { signal: req.signal } : undefined,\n );\n } catch (e) {\n const err = e as { message?: string; status?: number };\n return {\n kind: 'error',\n message: err.message ?? 'Lỗi gọi Anthropic Vision API',\n ...(err.status !== undefined ? { status: err.status } : {}),\n };\n }\n\n const usage = toUsage(resp.usage);\n const toolUse = resp.content.find((c) => c.type === 'tool_use');\n if (!toolUse || toolUse.type !== 'tool_use') {\n return { kind: 'error', message: 'Claude không gọi vision tool. stop_reason=' + resp.stop_reason };\n }\n if (toolUse.name !== VISION_TOOL_NAME) {\n return { kind: 'error', message: `Claude gọi sai tool: ${toolUse.name}` };\n }\n return { kind: 'json', data: toolUse.input, usage };\n }\n}\n\nfunction toUsage(u: Anthropic.Messages.Usage): ProviderTokenUsage {\n return {\n inputTokens: u.input_tokens,\n outputTokens: u.output_tokens,\n cacheReadTokens: u.cache_read_input_tokens ?? 0,\n cacheCreationTokens: u.cache_creation_input_tokens ?? 0,\n };\n}\n","// src/stamps/geometry-2d/ai/providers/claude-agent-sdk.ts\n//\n// AIProvider impl dùng @anthropic-ai/claude-agent-sdk (official Anthropic SDK\n// wrap Claude Code binary). OAuth subscription path — bill vào Pro/Max/Team\n// thay vì API key console. KHÔNG vi phạm ToS (SDK chính chủ).\n//\n// Setup:\n// $ npm install -g @anthropic-ai/claude-code\n// $ claude setup-token # browser auth → sk-ant-oat01-...\n// $ export CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...\n// $ unset ANTHROPIC_API_KEY # nếu đã set ở project khác (sẽ shadow OAuth)\n//\n// So với ClaudeCliProvider (spawn `claude -p` subprocess):\n// - Latency thấp hơn nhiều (~10-30s vs 1-2 phút) — không boot full Claude Code context\n// - Streaming-first (in-process async iterator)\n// - Cùng subscription billing path\n\nimport type { AIProvider, ProviderOutput, ProviderRequest } from './types';\n\nconst DEFAULT_MODEL = 'claude-sonnet-4-6';\n\nconst SCHEMA_CACHE = new WeakMap<object, string>();\n\nfunction memoSchemaJson(schema: object): string {\n let s = SCHEMA_CACHE.get(schema);\n if (s) return s;\n s = JSON.stringify(schema, null, 2);\n SCHEMA_CACHE.set(schema, s);\n return s;\n}\n\nexport interface ClaudeAgentSdkProviderOptions {\n /** OAuth token. Fallback: env CLAUDE_CODE_OAUTH_TOKEN. */\n oauthToken?: string;\n defaultModel?: string;\n /** Inject custom query impl cho test mock. */\n queryImpl?: ClaudeAgentSdkQueryFn;\n}\n\n/** Shape của `query` từ @anthropic-ai/claude-agent-sdk — cho test mock. */\nexport type ClaudeAgentSdkQueryFn = (args: {\n prompt: string;\n options: {\n systemPrompt?: string;\n allowedTools?: string[];\n model?: string;\n abortSignal?: AbortSignal;\n };\n}) => AsyncIterable<ClaudeAgentSdkMessage>;\n\nexport type ClaudeAgentSdkMessage =\n | {\n type: 'assistant';\n message: { content: Array<{ type: 'text'; text: string } | { type: string }> };\n }\n | {\n type: 'result';\n subtype: 'success' | 'error_during_execution' | string;\n duration_ms?: number;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n }\n | { type: 'system'; [k: string]: unknown }\n | { type: string; [k: string]: unknown };\n\nexport class ClaudeAgentSdkProvider implements AIProvider {\n readonly name = 'claude-agent-sdk';\n readonly defaultModel: string;\n private readonly oauthToken: string | undefined;\n private readonly queryImpl: ClaudeAgentSdkQueryFn | null;\n\n constructor(opts: ClaudeAgentSdkProviderOptions = {}) {\n this.defaultModel = opts.defaultModel ?? DEFAULT_MODEL;\n this.oauthToken = opts.oauthToken;\n this.queryImpl = opts.queryImpl ?? null;\n }\n\n private async resolveQuery(): Promise<ClaudeAgentSdkQueryFn> {\n if (this.queryImpl) return this.queryImpl;\n // Lazy import: chỉ load SDK khi thực sự cần. SDK requires Node (spawn).\n const mod = (await import('@anthropic-ai/claude-agent-sdk')) as {\n query: ClaudeAgentSdkQueryFn;\n };\n return mod.query;\n }\n\n async call(req: ProviderRequest): Promise<ProviderOutput> {\n // Inject OAuth token vào env nếu provider có. SDK đọc CLAUDE_CODE_OAUTH_TOKEN.\n if (this.oauthToken) {\n process.env.CLAUDE_CODE_OAUTH_TOKEN = this.oauthToken;\n }\n\n let query: ClaudeAgentSdkQueryFn;\n try {\n query = await this.resolveQuery();\n } catch (e) {\n return {\n kind: 'error',\n message:\n 'ClaudeAgentSdkProvider: SDK không khả dụng. ' +\n ((e as { message?: string }).message ?? ''),\n };\n }\n\n // Constraint output qua system prompt — Agent SDK không có --json-schema flag,\n // dùng prompt-instruct + parse JSON post-hoc. Sonnet 4.6 follow format tốt.\n const schemaText = memoSchemaJson(req.schema as object);\n const constrainedSystem = `${req.systemPrompt}\n\nQUAN TRỌNG: Output PHẢI là valid JSON đúng schema sau. KHÔNG markdown wrapper, KHÔNG prose giải thích, CHỈ raw JSON:\n\n${schemaText}`;\n\n let assistantText = '';\n let usageInput = 0;\n let usageOutput = 0;\n let cacheRead = 0;\n let cacheCreation = 0;\n\n try {\n for await (const msg of query({\n prompt: req.userPrompt,\n options: {\n systemPrompt: constrainedSystem,\n allowedTools: [],\n model: req.model ?? this.defaultModel,\n ...(req.signal ? { abortSignal: req.signal } : {}),\n },\n })) {\n if (msg.type === 'assistant') {\n const message = (msg as { message: { content: Array<unknown> } }).message;\n for (const block of message.content) {\n const b = block as { type?: string; text?: string };\n if (b.type === 'text' && typeof b.text === 'string') {\n assistantText += b.text;\n if (req.onToken) {\n try { req.onToken(b.text); } catch { /* swallow */ }\n }\n }\n }\n } else if (msg.type === 'result') {\n const r = msg as {\n subtype?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n if (r.subtype && r.subtype !== 'success') {\n return {\n kind: 'error',\n message: `ClaudeAgentSdkProvider: result subtype=${r.subtype}`,\n };\n }\n if (r.usage) {\n usageInput = r.usage.input_tokens ?? 0;\n usageOutput = r.usage.output_tokens ?? 0;\n cacheRead = r.usage.cache_read_input_tokens ?? 0;\n cacheCreation = r.usage.cache_creation_input_tokens ?? 0;\n }\n }\n }\n } catch (e) {\n return {\n kind: 'error',\n message:\n 'ClaudeAgentSdkProvider: query() throw: ' +\n ((e as { message?: string }).message ?? '?'),\n };\n }\n\n if (!assistantText.trim()) {\n return {\n kind: 'error',\n message: 'ClaudeAgentSdkProvider: assistant trả response rỗng.',\n };\n }\n\n // Strip markdown fence nếu Sonnet vẫn add (defensive).\n let cleaned = assistantText.trim();\n cleaned = cleaned.replace(/^```(?:json)?\\s*\\n?/i, '').replace(/\\n?\\s*```\\s*$/, '');\n\n let data: unknown;\n try {\n data = JSON.parse(cleaned);\n } catch (e) {\n return {\n kind: 'error',\n message:\n 'ClaudeAgentSdkProvider: output không parse JSON: ' +\n ((e as { message?: string }).message ?? '?') +\n '. Output preview: ' +\n cleaned.slice(0, 200),\n };\n }\n\n return {\n kind: 'json',\n data,\n usage: {\n inputTokens: usageInput,\n outputTokens: usageOutput,\n cacheReadTokens: cacheRead,\n cacheCreationTokens: cacheCreation,\n },\n };\n }\n}\n","// src/stamps/geometry-2d/ai/providers/claude-cli.ts\n//\n// AIProvider impl qua `claude` CLI subprocess (Claude Code) — dev/eval only.\n// Tận dụng OAuth subscription Claude Pro/Max/Team đã đăng nhập sẵn ở máy,\n// charge vào quota subscription thay vì API console credits.\n//\n// LƯU Ý: Theo Anthropic ToS (cập nhật 02/2026), OAuth token từ subscription\n// chỉ legal cho Claude Code CLI / claude.ai. KHÔNG dùng provider này trong\n// production third-party app — chỉ dùng cho dev/eval local. Production phải\n// dùng AnthropicProvider với API key từ console.anthropic.com.\n//\n// CLI flags dùng:\n// --print batch mode (stdin → stdout)\n// --output-format json single-result JSON envelope\n// --json-schema <schema> structured-output constraint\n// --tools \"\" disable built-in Bash/Read/Write/Edit/...\n// --append-system-prompt inject DSL system prompt\n// --model <id> model id (alias 'sonnet'/'opus' hoặc full)\n// --max-budget-usd <usd> cost cap per call (safety)\n//\n// Parse `structured_output` field từ stdout JSON (không phải `result` —\n// `result` empty khi có --json-schema).\n\nimport type {\n AIProvider,\n ProviderOutput,\n ProviderRequest,\n ProviderTokenUsage,\n} from './types';\n\n// Lazy node:child_process — tránh bundle vào browser build (provider này\n// chỉ chạy ở Node env dev/eval).\ntype SpawnFn = typeof import('node:child_process').spawn;\n\nexport interface ClaudeCliProviderOptions {\n /** Binary path. Default 'claude'. Override qua env CLAUDE_CLI_BIN. */\n bin?: string;\n /** Default model id khi request không truyền. Default 'claude-sonnet-4-6'. */\n defaultModel?: string;\n /** Cost cap per call (USD). Default 0.50. */\n maxBudgetUsd?: number;\n /** Custom spawn impl (test mock). */\n spawnImpl?: SpawnFn;\n}\n\ninterface ClaudeCliResultEnvelope {\n type: 'result';\n subtype: 'success' | 'error_during_execution' | 'error_max_turns' | string;\n is_error: boolean;\n api_error_status?: string | null;\n result?: string;\n structured_output?: unknown;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n total_cost_usd?: number;\n}\n\nconst DEFAULT_BIN = 'claude';\nconst DEFAULT_MODEL = 'claude-sonnet-4-6';\nconst DEFAULT_MAX_BUDGET_USD = 0.5;\n\nexport class ClaudeCliProvider implements AIProvider {\n readonly name = 'claude-cli';\n readonly defaultModel: string;\n private readonly bin: string;\n private readonly maxBudgetUsd: number;\n private readonly spawnImpl: SpawnFn | null;\n\n constructor(opts: ClaudeCliProviderOptions = {}) {\n this.bin = opts.bin ?? DEFAULT_BIN;\n this.defaultModel = opts.defaultModel ?? DEFAULT_MODEL;\n this.maxBudgetUsd = opts.maxBudgetUsd ?? DEFAULT_MAX_BUDGET_USD;\n this.spawnImpl = opts.spawnImpl ?? null;\n }\n\n private async resolveSpawn(): Promise<SpawnFn> {\n if (this.spawnImpl) return this.spawnImpl;\n const mod = await import('node:child_process');\n return mod.spawn;\n }\n\n async call(req: ProviderRequest): Promise<ProviderOutput> {\n let spawn: SpawnFn;\n try {\n spawn = await this.resolveSpawn();\n } catch (e) {\n return {\n kind: 'error',\n message:\n 'ClaudeCliProvider: node:child_process không khả dụng (chỉ chạy được ở Node env). ' +\n ((e as { message?: string }).message ?? ''),\n };\n }\n\n const args = [\n '--print',\n '--output-format', 'json',\n '--json-schema', JSON.stringify(req.schema),\n '--append-system-prompt', req.systemPrompt,\n '--tools', '',\n '--model', req.model,\n '--max-budget-usd', String(this.maxBudgetUsd),\n ];\n\n return new Promise<ProviderOutput>((resolve) => {\n let child;\n try {\n child = spawn(this.bin, args, { stdio: ['pipe', 'pipe', 'pipe'] });\n } catch (e) {\n resolve({\n kind: 'error',\n message:\n `ClaudeCliProvider: spawn '${this.bin}' thất bại. ` +\n ((e as { message?: string }).message ?? 'Kiểm tra claude CLI đã cài chưa.'),\n });\n return;\n }\n\n let stdout = '';\n let stderr = '';\n let settled = false;\n const settle = (out: ProviderOutput) => {\n if (settled) return;\n settled = true;\n resolve(out);\n };\n\n const onAbort = () => {\n child.kill('SIGTERM');\n settle({ kind: 'error', message: 'ClaudeCliProvider: aborted' });\n };\n if (req.signal) {\n if (req.signal.aborted) {\n onAbort();\n return;\n }\n req.signal.addEventListener('abort', onAbort, { once: true });\n }\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n\n child.on('error', (e: Error) => {\n settle({\n kind: 'error',\n message: `ClaudeCliProvider: subprocess error: ${e.message}`,\n });\n });\n\n child.on('close', (code: number | null) => {\n if (settled) return;\n if (code !== 0) {\n settle({\n kind: 'error',\n message:\n `ClaudeCliProvider: exit code ${code}. stderr: ${stderr.trim() || '(empty)'}`,\n ...(typeof code === 'number' ? { status: code } : {}),\n });\n return;\n }\n\n let env: ClaudeCliResultEnvelope;\n try {\n env = JSON.parse(stdout.trim()) as ClaudeCliResultEnvelope;\n } catch (e) {\n settle({\n kind: 'error',\n message:\n 'ClaudeCliProvider: stdout không parse được JSON: ' +\n ((e as { message?: string }).message ?? '?'),\n });\n return;\n }\n\n if (env.is_error) {\n settle({\n kind: 'error',\n message:\n `ClaudeCliProvider: CLI báo lỗi (subtype=${env.subtype}, api_status=${env.api_error_status ?? 'n/a'})`,\n });\n return;\n }\n\n if (env.structured_output === undefined || env.structured_output === null) {\n settle({\n kind: 'error',\n message:\n 'ClaudeCliProvider: thiếu structured_output trong response. ' +\n `result=\"${(env.result ?? '').slice(0, 200)}\"`,\n });\n return;\n }\n\n const usage = toUsage(env.usage);\n settle({ kind: 'json', data: env.structured_output, usage });\n });\n\n // User prompt qua stdin (cleaner than arg cho prompt dài + escape).\n try {\n child.stdin?.write(req.userPrompt);\n child.stdin?.end();\n } catch (e) {\n settle({\n kind: 'error',\n message:\n 'ClaudeCliProvider: ghi stdin thất bại: ' +\n ((e as { message?: string }).message ?? '?'),\n });\n }\n });\n }\n}\n\nfunction toUsage(u: ClaudeCliResultEnvelope['usage']): ProviderTokenUsage {\n return {\n inputTokens: u?.input_tokens ?? 0,\n outputTokens: u?.output_tokens ?? 0,\n cacheReadTokens: u?.cache_read_input_tokens ?? 0,\n cacheCreationTokens: u?.cache_creation_input_tokens ?? 0,\n };\n}\n","// src/stamps/geometry-2d/ai/providers/ollama.ts\n//\n// AIProvider impl cho Ollama local. Dùng /api/chat với `format: <jsonSchema>`\n// (Ollama v0.5+ — structured outputs). Model emit JSON đúng schema, parse +\n// trả về envelope.\n//\n// Setup local:\n// $ ollama pull gemma3:4b # ~3.3GB Q4\n// $ ollama serve # mặc định port 11434\n//\n// Override base URL qua env `OLLAMA_BASE_URL` (test env / remote ollama).\n\nimport type {\n AIProvider,\n ProviderOutput,\n ProviderRequest,\n ProviderTokenUsage,\n VisionRequest,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'http://localhost:11434';\nconst DEFAULT_MODEL = 'gemma3:4b';\n\nexport interface OllamaProviderOptions {\n /** Endpoint base URL, default http://localhost:11434. */\n baseUrl?: string;\n /** Default model id nếu request không truyền. */\n defaultModel?: string;\n /** Custom fetch impl (dùng cho test mock). */\n fetchImpl?: typeof fetch;\n}\n\ninterface OllamaChatResponse {\n model: string;\n message: { role: 'assistant'; content: string };\n done: boolean;\n prompt_eval_count?: number;\n eval_count?: number;\n total_duration?: number;\n}\n\nexport class OllamaProvider implements AIProvider {\n readonly name = 'ollama';\n readonly defaultModel: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof fetch | null;\n\n constructor(opts: OllamaProviderOptions = {}) {\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '');\n this.defaultModel = opts.defaultModel ?? DEFAULT_MODEL;\n // Lazy resolve: jsdom test env không có global fetch; consumer chỉ cần\n // fetch ở runtime khi gọi .call(). Custom impl ưu tiên (test mock).\n this.fetchImpl = opts.fetchImpl ?? null;\n }\n\n private resolveFetch(): typeof fetch {\n if (this.fetchImpl) return this.fetchImpl;\n if (typeof fetch === 'undefined') {\n throw new Error(\n 'OllamaProvider: global `fetch` không khả dụng. Truyền `fetchImpl` qua constructor hoặc chạy ở Node 18+ / browser.',\n );\n }\n return fetch;\n }\n\n async call(req: ProviderRequest): Promise<ProviderOutput> {\n const body = {\n model: req.model,\n messages: [\n { role: 'system', content: req.systemPrompt },\n { role: 'user', content: req.userPrompt },\n ],\n format: req.schema,\n stream: true,\n options: { num_predict: req.maxTokens, temperature: 0.2 },\n };\n\n let doFetch: typeof fetch;\n try {\n doFetch = this.resolveFetch();\n } catch (e) {\n const err = e as { message?: string };\n return { kind: 'error', message: err.message ?? 'fetch không khả dụng' };\n }\n\n let resp: Response;\n try {\n resp = await doFetch(`${this.baseUrl}/api/chat`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n signal: req.signal,\n });\n } catch (e) {\n const err = e as { message?: string };\n return {\n kind: 'error',\n message: err.message ?? `Không kết nối được Ollama ở ${this.baseUrl}`,\n };\n }\n\n if (!resp.ok || !resp.body) {\n let detail = '';\n try { detail = await resp.text(); } catch { /* ignore */ }\n return {\n kind: 'error',\n message: `Ollama HTTP ${resp.status}: ${detail || resp.statusText}`,\n status: resp.status,\n };\n }\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let content = '';\n let promptEvalCount = 0;\n let evalCount = 0;\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let nl;\n while ((nl = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, nl).trim();\n buffer = buffer.slice(nl + 1);\n if (!line) continue;\n try {\n const chunk = JSON.parse(line) as {\n message?: { content?: string };\n done?: boolean;\n prompt_eval_count?: number;\n eval_count?: number;\n };\n if (chunk.message?.content) {\n content += chunk.message.content;\n if (req.onToken) {\n try { req.onToken(chunk.message.content); } catch { /* swallow */ }\n }\n }\n if (chunk.done) {\n promptEvalCount = chunk.prompt_eval_count ?? promptEvalCount;\n evalCount = chunk.eval_count ?? evalCount;\n }\n } catch { /* skip malformed line */ }\n }\n }\n\n const trimmed = content.trim();\n if (!trimmed) return { kind: 'error', message: 'Ollama trả message.content rỗng' };\n\n let data: unknown;\n try {\n data = JSON.parse(trimmed);\n } catch (e) {\n const err = e as { message?: string };\n return {\n kind: 'error',\n message: 'Ollama content không parse được JSON: ' + (err.message ?? '?'),\n };\n }\n\n return {\n kind: 'json',\n data,\n usage: {\n inputTokens: promptEvalCount,\n outputTokens: evalCount,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n },\n };\n }\n\n // Vision: gửi ảnh qua images[] field trong message (Ollama multimodal API).\n // Model cần hỗ trợ vision (gemma3, llava, ...). Output vẫn là JSON envelope.\n async extractText(req: VisionRequest): Promise<ProviderOutput> {\n const model = req.model ?? this.defaultModel;\n const body = {\n model,\n messages: [\n { role: 'system', content: req.systemPrompt },\n {\n role: 'user',\n content: req.userPrompt,\n images: req.images.map((i) => i.base64),\n },\n ],\n format: req.schema,\n stream: false,\n options: { num_predict: req.maxTokens, temperature: 0.2 },\n };\n\n let doFetch: typeof fetch;\n try {\n doFetch = this.resolveFetch();\n } catch (e) {\n return { kind: 'error', message: (e as { message?: string }).message ?? 'fetch không khả dụng' };\n }\n\n let resp: Response;\n try {\n resp = await doFetch(`${this.baseUrl}/api/chat`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n signal: req.signal,\n });\n } catch (e) {\n return {\n kind: 'error',\n message: (e as { message?: string }).message ?? `Không kết nối được Ollama ở ${this.baseUrl}`,\n };\n }\n\n if (!resp.ok) {\n let detail = '';\n try { detail = await resp.text(); } catch { /* ignore */ }\n return {\n kind: 'error',\n message: `Ollama Vision HTTP ${resp.status}: ${detail || resp.statusText}`,\n status: resp.status,\n };\n }\n\n let json: OllamaChatResponse;\n try {\n json = (await resp.json()) as OllamaChatResponse;\n } catch (e) {\n return { kind: 'error', message: 'Ollama vision response không phải JSON: ' + ((e as { message?: string }).message ?? '?') };\n }\n\n const content = json.message?.content?.trim();\n if (!content) return { kind: 'error', message: 'Ollama vision trả content rỗng' };\n\n let data: unknown;\n try {\n data = JSON.parse(content);\n } catch (e) {\n return { kind: 'error', message: 'Ollama vision content không parse JSON: ' + ((e as { message?: string }).message ?? '?') };\n }\n\n const usage: ProviderTokenUsage = {\n inputTokens: json.prompt_eval_count ?? 0,\n outputTokens: json.eval_count ?? 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n };\n return { kind: 'json', data, usage };\n }\n}\n","// src/stamps/geometry-2d/ai/providers/index.ts\n//\n// Public exports + selectProvider() factory dựa trên env hoặc explicit opts.\n//\n// Quy tắc chọn provider (high → low priority):\n// 1. opts.provider — instance đã build sẵn (test/custom)\n// 2. opts.apiKey — auto-route Anthropic (backward-compat caller cũ)\n// 3. env WHITEBOARD_AI_PROVIDER\n// - \"claude-agent-sdk\" (default): @anthropic-ai/claude-agent-sdk + OAuth subscription Pro/Max/Team\n// - \"anthropic\": cần env ANTHROPIC_API_KEY (pay-per-token console)\n// - \"claude-cli\": spawn `claude -p` subprocess (legacy, chậm hơn)\n// - \"ollama\": local, không cần key, đọc OLLAMA_BASE_URL tùy chọn\n\nimport { AnthropicProvider } from './anthropic';\nimport { ClaudeAgentSdkProvider } from './claude-agent-sdk';\nimport { ClaudeCliProvider } from './claude-cli';\nimport { OllamaProvider } from './ollama';\nimport type { AIProvider } from './types';\n\nexport type { AIProvider, ProviderOutput, ProviderRequest, ProviderTokenUsage } from './types';\nexport { AnthropicProvider } from './anthropic';\nexport { ClaudeAgentSdkProvider } from './claude-agent-sdk';\nexport { ClaudeCliProvider } from './claude-cli';\nexport { OllamaProvider } from './ollama';\n\nexport interface SelectProviderOptions {\n /** Provider instance dùng trực tiếp (override mọi env). */\n provider?: AIProvider;\n /** Anthropic API key. Khi truyền → auto chọn AnthropicProvider. */\n apiKey?: string;\n /** Anthropic prompt-caching, default true (chỉ áp dụng provider Anthropic). */\n enableCaching?: boolean;\n /** Ollama endpoint override. */\n ollamaBaseUrl?: string;\n /** Ollama model override (vd \"gemma3:1b\"). */\n ollamaDefaultModel?: string;\n /** Claude CLI binary path override (default 'claude'). */\n claudeCliBin?: string;\n /** Claude CLI default model override. */\n claudeCliDefaultModel?: string;\n /** Claude CLI max budget USD per call override. */\n claudeCliMaxBudgetUsd?: number;\n /** Claude Agent SDK OAuth token (subscription path). Fallback env CLAUDE_CODE_OAUTH_TOKEN. */\n claudeAgentSdkOauthToken?: string;\n /** Claude Agent SDK default model. */\n claudeAgentSdkDefaultModel?: string;\n /** Test env: env vars getter (default process.env). */\n env?: Record<string, string | undefined>;\n}\n\nexport function selectProvider(opts: SelectProviderOptions = {}): AIProvider {\n if (opts.provider) return opts.provider;\n if (opts.apiKey) {\n return new AnthropicProvider({\n apiKey: opts.apiKey,\n enableCaching: opts.enableCaching,\n });\n }\n\n const env = opts.env ?? readEnv();\n const wanted = (env.WHITEBOARD_AI_PROVIDER ?? 'claude-agent-sdk').toLowerCase();\n\n if (wanted === 'anthropic') {\n const key = env.ANTHROPIC_API_KEY;\n if (!key) {\n throw new Error(\n 'selectProvider: WHITEBOARD_AI_PROVIDER=anthropic nhưng thiếu env ANTHROPIC_API_KEY',\n );\n }\n return new AnthropicProvider({ apiKey: key, enableCaching: opts.enableCaching });\n }\n\n if (wanted === 'claude-cli') {\n const budgetEnv = env.CLAUDE_CLI_MAX_BUDGET_USD;\n const budgetNum = budgetEnv !== undefined ? Number(budgetEnv) : undefined;\n return new ClaudeCliProvider({\n bin: opts.claudeCliBin ?? env.CLAUDE_CLI_BIN,\n defaultModel: opts.claudeCliDefaultModel ?? env.CLAUDE_CLI_MODEL,\n maxBudgetUsd:\n opts.claudeCliMaxBudgetUsd ??\n (budgetNum !== undefined && Number.isFinite(budgetNum) ? budgetNum : undefined),\n });\n }\n\n if (wanted === 'claude-agent-sdk') {\n return new ClaudeAgentSdkProvider({\n oauthToken: opts.claudeAgentSdkOauthToken ?? env.CLAUDE_CODE_OAUTH_TOKEN,\n defaultModel:\n opts.claudeAgentSdkDefaultModel ?? env.CLAUDE_AGENT_SDK_MODEL,\n });\n }\n\n if (wanted === 'ollama') {\n return new OllamaProvider({\n baseUrl: opts.ollamaBaseUrl ?? env.OLLAMA_BASE_URL,\n defaultModel: opts.ollamaDefaultModel ?? env.OLLAMA_DEFAULT_MODEL,\n });\n }\n\n throw new Error(\n `selectProvider: WHITEBOARD_AI_PROVIDER=\"${wanted}\" không hợp lệ (anthropic|claude-cli|claude-agent-sdk|ollama)`,\n );\n}\n\nfunction readEnv(): Record<string, string | undefined> {\n // process.env không tồn tại ở pure browser; ở Node/Next.js server route thì OK.\n if (typeof process !== 'undefined' && process.env) {\n return process.env as Record<string, string | undefined>;\n }\n return {};\n}\n","// src/stamps/geometry-2d/ai/buildFigureIntent.ts\n//\n// 4-stage pipeline orchestrator (new path, parallel to buildFigure.ts):\n// Stage 1: AI extract Intent[] (provider.call with intent prompt + schema)\n// Stage 2: intentsToDsl() (deterministic)\n// Stage 3: transpile(DSL) (existing)\n// Stage 4: verifyGeometry() (deterministic geometric check)\n//\n// Trả về GenerateResult tương tự buildFigure.ts để consumer dùng được cả 2 path.\n\nimport { transpile } from '../dsl';\nimport type { TranspileResult } from '../dsl';\nimport { intentsToDsl, IntentBuilderError } from './intentToDsl';\nimport { buildIntentSystemPrompt } from './intentPrompt';\nimport { IntentEnvelopeZ, type IntentEnvelopeT, type IntentT } from './intent';\nimport { intentEnvelopeJsonSchema } from './intentEnvelope';\nimport { normalizeIntents } from './normalizeIntent';\nimport { resolveCircleNameCollisions } from './resolveCircleNames';\nimport { completeRightAngle } from './completeRightAngle';\nimport { verifyGeometry, type VerifyReport } from './verify';\nimport { tryDeterministicFigure } from './deterministic/tryDeterministicFigure';\nimport { describeDeterministicMiss } from './deterministic/describeMiss';\nimport {\n selectProvider,\n type AIProvider,\n type ProviderTokenUsage,\n type SelectProviderOptions,\n} from './providers';\n\nconst DEFAULT_MAX_TOKENS = 4096;\nconst ZERO_USAGE: IntentTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n};\n\nexport interface GenerateIntentOptions extends SelectProviderOptions {\n model?: string;\n maxTokens?: number;\n signal?: AbortSignal;\n /**\n * Track A deterministic-first (mặc định bật). Thử rule engine trước; chỉ gọi\n * LLM (Track B) khi deterministic không phủ đủ / không dựng được. Đặt false để\n * ép luôn dùng LLM (vd so sánh eval, debug).\n */\n useDeterministic?: boolean;\n /**\n * CHỈ deterministic — KHÔNG fallback LLM. Track A miss → trả failure\n * `deterministic_miss` (kèm lý do) thay vì gọi Track B. Dùng khi tối ưu rule\n * base: muốn THẤY đề nào rule chưa phủ (không tốn token, không che lấp gap).\n * Ưu tiên hơn `useDeterministic` (true ⇒ luôn chạy Track A, không bao giờ LLM).\n */\n deterministicOnly?: boolean;\n}\n\nexport interface IntentTokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n}\n\nexport interface IntentSuccessResult {\n ok: true;\n intents: readonly IntentT[];\n dsl: ReturnType<typeof intentsToDsl>;\n transpile: Extract<TranspileResult, { ok: true }>;\n verify: VerifyReport;\n usage: IntentTokenUsage;\n provider: string;\n}\n\nexport interface IntentFailureResult {\n ok: false;\n reason:\n | 'refused'\n | 'parse_error'\n | 'builder_error'\n | 'transpile_error'\n | 'verify_error'\n | 'provider_error'\n | 'deterministic_miss';\n message: string;\n intents?: readonly IntentT[];\n dsl?: ReturnType<typeof intentsToDsl>;\n usage?: IntentTokenUsage;\n provider?: string;\n}\n\nexport type IntentGenerateResult = IntentSuccessResult | IntentFailureResult;\n\nexport async function generateFigureIntent(\n problem: string,\n opts: GenerateIntentOptions = {},\n): Promise<IntentGenerateResult> {\n // === Track A: deterministic-first ===\n // Rule engine + 4 lớp gate (coverage/transpile/verify/named-entity). Đề dễ→trung\n // bình dựng tại đây, KHÔNG gọi LLM. Đề khó / phủ thiếu → fall through Track B\n // (trừ khi deterministicOnly → trả deterministic_miss).\n // deterministicOnly ép chạy Track A kể cả khi useDeterministic=false.\n if (opts.useDeterministic !== false || opts.deterministicOnly) {\n const det = tryDeterministicFigure(problem);\n if (det.ok) {\n return {\n ok: true,\n intents: det.figure.intents,\n dsl: det.figure.dsl,\n transpile: det.figure.transpile,\n verify: det.figure.verify,\n usage: ZERO_USAGE,\n provider: 'deterministic',\n };\n }\n // deterministicOnly: KHÔNG fallback LLM → trả failure kèm lý do (det.reason)\n // để người tối ưu rule base thấy gap. (no-match / incomplete-coverage /\n // transpile-fail / named-missing / verify-fail / …)\n if (opts.deterministicOnly) {\n return {\n ok: false,\n reason: 'deterministic_miss',\n message: describeDeterministicMiss(det),\n usage: ZERO_USAGE,\n provider: 'deterministic',\n };\n }\n // không hit → tiếp tục Track B (LLM)\n }\n\n // === Track B: LLM ===\n const provider: AIProvider = selectProvider(opts);\n const model = opts.model ?? provider.defaultModel;\n const maxTokens = opts.maxTokens ?? DEFAULT_MAX_TOKENS;\n const systemPrompt = buildIntentSystemPrompt();\n const schema = intentEnvelopeJsonSchema();\n\n const result = await provider.call({\n systemPrompt,\n userPrompt: problem,\n schema,\n model,\n maxTokens,\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n\n if (result.kind === 'error') {\n return {\n ok: false,\n reason: 'provider_error',\n message: result.message,\n provider: provider.name,\n };\n }\n\n const usage = toUsage(result.usage);\n\n // Parse envelope\n let envelope: IntentEnvelopeT;\n try {\n envelope = IntentEnvelopeZ.parse(result.data);\n } catch (e) {\n const err = e as { message?: string };\n return {\n ok: false,\n reason: 'parse_error',\n message: `Envelope không parse được: ${err.message ?? '?'}`,\n usage,\n provider: provider.name,\n };\n }\n\n if (envelope.decision === 'refuse') {\n return {\n ok: false,\n reason: 'refused',\n message: envelope.reason ?? 'AI từ chối không nêu lý do',\n usage,\n provider: provider.name,\n };\n }\n\n // Stage 1.5a: variant normalization (rule-based — fix common LLM biases về\n // variant naming, vd \"cân tại A\" → isoceles-BC theo canonical, rectangle\n // \"wide\" → \"standard\" mặc định). API contract: caller nhận variant đã chuẩn\n // hoá vì đây là known-canonical correction, không phải semantic change.\n const intents = normalizeIntents(envelope.intents!, problem);\n\n // Stage 1.5b: preprocess naming collisions (circle name dùng làm point ref).\n // Notation Việt \"(O)\" thường ám chỉ TÂM (point) chứ không phải tên circle —\n // preprocessor inject add-point center + rename circle để tránh KIND_MISMATCH.\n const collisionFixed = resolveCircleNameCollisions(intents);\n\n // Stage 1.5c: deterministic inject \"góc vuông nhìn đoạn\" (∠a-M-b = 90°).\n // LLM hay miss insight dựng đường tròn đường kính — inject từ regex đề.\n const processedIntents = completeRightAngle(collisionFixed, problem);\n\n // Stage 2: deterministic build\n let dsl: ReturnType<typeof intentsToDsl>;\n try {\n dsl = intentsToDsl(processedIntents);\n } catch (e) {\n const err = e as IntentBuilderError;\n return {\n ok: false,\n reason: 'builder_error',\n message: err.message,\n intents,\n usage,\n provider: provider.name,\n };\n }\n\n // Stage 3: transpile. `transpile()` thường trả {ok:false} cho known error,\n // nhưng vẫn có throw uncaught (vd \"emit: id not assigned for X\") khi DSL có\n // shape ref chưa-assigned. Catch để giữ intents + dsl cho debug downstream.\n let tResult: TranspileResult;\n try {\n tResult = transpile(dsl);\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n ok: false,\n reason: 'transpile_error',\n message: `transpile throw: ${message}`,\n intents,\n dsl,\n usage,\n provider: provider.name,\n };\n }\n if (!tResult.ok) {\n return {\n ok: false,\n reason: 'transpile_error',\n message: tResult.errors.map((e) => `${e.code}: ${e.message}`).join('; '),\n intents,\n dsl,\n usage,\n provider: provider.name,\n };\n }\n\n // Stage 4: geometric verify\n const vReport = verifyGeometry(intents, dsl);\n\n return {\n ok: true,\n intents,\n dsl,\n transpile: tResult,\n verify: vReport,\n usage,\n provider: provider.name,\n };\n}\n\nfunction toUsage(u: ProviderTokenUsage | undefined): IntentTokenUsage {\n return {\n inputTokens: u?.inputTokens ?? 0,\n outputTokens: u?.outputTokens ?? 0,\n ...(u?.cacheReadTokens != null ? { cacheReadTokens: u.cacheReadTokens } : {}),\n ...(u?.cacheCreationTokens != null ? { cacheCreationTokens: u.cacheCreationTokens } : {}),\n };\n}\n","// Façade HTTP transport cho rule-engine intent pipeline (generateFigureIntent).\n// Map IntentGenerateResult → AiFigureUiResult ({ ok, state }) — shape mà\n// <Whiteboard generateGeometryFigure> + playground route dùng trực tiếp.\n//\n// 2026-06-09: repurpose từ path buildFigure (free-form DSL, đã xoá) sang intent\n// pipeline. generateFigureIntent TỰ làm deterministic rules-first\n// (tryDeterministicFigure → 21 rule + 4 gate) rồi mới LLM fallback, nên façade\n// chỉ cần map kết quả. Contract AiFigureUiResult GIỮ NGUYÊN → consumer\n// (playground, hoctotbachkhoa) không phải đổi route, tự hưởng rule engine khi upgrade.\n\nimport type { AiFigureUiResult } from '../../shared/types';\nimport {\n generateFigureIntent,\n type GenerateIntentOptions,\n type IntentGenerateResult,\n} from './buildFigureIntent';\n\nexport interface HandleGenerateFigureInput {\n /** Đề bài tiếng Việt từ teacher. */\n problem: string;\n}\n\nexport interface HandleGenerateFigureOptions extends GenerateIntentOptions {\n /**\n * Telemetry hook: gọi cho MỖI attempt với IntentGenerateResult nội bộ trước\n * khi map sang AiFigureUiResult — consumer dùng để log usage/cost/error.\n * Không throw từ logger (swallow để không vỡ response).\n *\n * @param result IntentGenerateResult của attempt\n * @param attempt 1-indexed (1 = lần đầu, 2 = retry, ...)\n */\n onResult?: (result: IntentGenerateResult, attempt: number) => void;\n /**\n * Số attempt tối đa khi build error (transpile/builder). Default 2 (1 retry).\n * LLM stochastic → lần 2 thường khá hơn. Clamp [1,5].\n */\n maxAttempts?: number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 2;\n\n/**\n * Gọi rule-engine intent pipeline và trả về `AiFigureUiResult` mà\n * `<Whiteboard generateGeometryFigure>` chấp nhận trực tiếp.\n *\n * Track A (deterministic rules) chạy trong `generateFigureIntent` — đề dễ→trung\n * bình dựng KHÔNG tốn token. Miss → Track B (LLM intent).\n *\n * Auto-retry: chỉ retry khi `transpile_error`/`builder_error` (AI emit hình\n * structurally sai — model stochastic có cơ hội khá hơn lần 2). KHÔNG retry\n * `refused` (cố ý), `parse_error` (sai schema), `provider_error` (network/config).\n *\n * Server-side caller giữ `IntentGenerateResult` đầy đủ qua `onResult` cho\n * telemetry/logging.\n */\nexport async function handleGenerateFigure(\n input: HandleGenerateFigureInput,\n opts: HandleGenerateFigureOptions = {},\n): Promise<AiFigureUiResult> {\n if (!input.problem.trim()) {\n return { ok: false, message: 'Đề bài rỗng' };\n }\n\n const { onResult, maxAttempts: rawMax, ...genOpts } = opts;\n const maxAttempts = clampAttempts(rawMax ?? DEFAULT_MAX_ATTEMPTS);\n\n let last: IntentGenerateResult | null = null;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const r = await generateFigureIntent(input.problem, genOpts);\n last = r;\n if (onResult) {\n try { onResult(r, attempt); } catch { /* swallow telemetry errors */ }\n }\n if (r.ok) return { ok: true, state: r.transpile.state };\n if ((r.reason === 'transpile_error' || r.reason === 'builder_error') && attempt < maxAttempts) {\n continue;\n }\n break;\n }\n return mapErrorToUi(last!);\n}\n\nfunction clampAttempts(n: number): number {\n if (!Number.isFinite(n)) return DEFAULT_MAX_ATTEMPTS;\n return Math.max(1, Math.min(5, Math.floor(n)));\n}\n\nfunction mapErrorToUi(result: IntentGenerateResult): AiFigureUiResult {\n if (result.ok) return { ok: true, state: result.transpile.state };\n\n switch (result.reason) {\n case 'refused':\n return { ok: false, message: result.message };\n case 'parse_error':\n return {\n ok: false,\n message: 'AI trả về dữ liệu không hợp lệ. Vui lòng thử lại hoặc diễn đạt lại đề bài.',\n };\n case 'builder_error':\n case 'transpile_error':\n case 'verify_error':\n return {\n ok: false,\n message:\n 'AI tạo hình không hợp lệ (đã thử lại). Vui lòng tách thành 1 yêu cầu/lần hoặc diễn đạt khác.',\n };\n case 'deterministic_miss':\n // Chế độ chỉ-deterministic (đang tối ưu rule base, đã tắt LLM fallback):\n // `message` đã là câu tiếng Việt dễ hiểu từ describeDeterministicMiss\n // (nêu rõ cần bổ sung rule / có thể lỗi rule + phần đề chưa phủ) → trả\n // thẳng cho UI/log, không bọc jargon.\n return { ok: false, message: result.message };\n case 'provider_error':\n default:\n return { ok: false, message: result.message };\n }\n}\n","// src/stamps/geometry-2d/ai/envelope.ts\n//\n// Envelope schema chung cho mọi AI provider. AI luôn emit:\n// { decision: 'build', figure: <DslInput> }\n// { decision: 'refuse', reason: '...' }\n//\n// Anthropic dùng tool_use với tool đơn ('emit_figure_envelope') input đúng\n// schema này. Ollama (Gemma) dùng `format: <schema>` constrained output.\n//\n// Ưu điểm: 1 schema, 1 prompt, parse + validate ở 1 chỗ. Provider chỉ chịu\n// trách nhiệm gửi/nhận; orchestrator (buildFigure) xử lý logic.\n\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { DslInput, type DslInputT } from '../dsl';\n\nexport const FigureEnvelopeZ = z\n .object({\n decision: z.enum(['build', 'refuse']),\n // figure: DslInput khi build; bỏ qua khi refuse.\n figure: DslInput.optional(),\n // reason: lý do từ chối (Việt) khi refuse; bỏ qua khi build.\n reason: z.string().optional(),\n })\n .refine(\n (e) => (e.decision === 'build' ? e.figure != null : e.reason != null && e.reason.length > 0),\n {\n message:\n 'decision=build cần `figure`; decision=refuse cần `reason` không rỗng',\n },\n );\n\nexport type FigureEnvelopeT = z.infer<typeof FigureEnvelopeZ>;\n\n// JSON Schema bản phẳng — pass cho Anthropic tool input_schema + Ollama format.\n// Note: refine() chỉ run ở Zod runtime; JSON Schema không representable. Provider\n// constraint output ở \"any of decision/figure/reason\"; orchestrator parse +\n// validate qua FigureEnvelopeZ để bắt vi phạm refine.\nexport function envelopeJsonSchema(): Record<string, unknown> {\n return zodToJsonSchema(FigureEnvelopeZ, {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n }) as Record<string, unknown>;\n}\n\n/** Helper: ép envelope build hợp lệ về DslInputT (sau khi đã validate). */\nexport function envelopeBuildDsl(env: FigureEnvelopeT): DslInputT {\n if (env.decision !== 'build' || env.figure == null) {\n throw new Error('envelopeBuildDsl: envelope không phải decision=build hoặc thiếu figure');\n }\n // Zod infer cho DslInput rộng `{[x: string]: any}[]` (discriminatedUnion từ\n // registry với schemas erased `ZodObject<any>`); runtime parse đã validate,\n // safe widen sang DslInputT (xem comment trong schema.ts).\n return env.figure as unknown as DslInputT;\n}\n","// src/stamps/geometry-2d/ai/refineEnvelope.ts\n//\n// Envelope schema cho multi-step refine. AI emit 1 trong 3:\n// { decision: 'add', figure: <DSL delta> }\n// { decision: 'replace', figure: <DSL full> }\n// { decision: 'refuse', reason: '...' }\n//\n// Tách hẳn khỏi FigureEnvelopeZ (build) — decision space khác (3 thay vì 2),\n// semantics khác (delta vs full), prompt khác.\n\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { DslInput } from '../dsl';\n\nexport const FigureRefineEnvelopeZ = z\n .object({\n decision: z.enum(['add', 'replace', 'refuse']),\n figure: DslInput.optional(),\n reason: z.string().optional(),\n })\n .refine(\n (e) =>\n e.decision === 'refuse'\n ? e.reason != null && e.reason.length > 0\n : e.figure != null,\n {\n message:\n 'decision=add/replace cần `figure`; decision=refuse cần `reason` không rỗng',\n },\n );\n\nexport type FigureRefineEnvelopeT = z.infer<typeof FigureRefineEnvelopeZ>;\n\nexport function refineEnvelopeJsonSchema(): Record<string, unknown> {\n return zodToJsonSchema(FigureRefineEnvelopeZ, {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n }) as Record<string, unknown>;\n}\n","// src/stamps/geometry-2d/ai/refineFixtures.ts\n//\n// Refine fixtures: { name, currentDsl, instruction, expectedEnvelope }\n// Dùng cho:\n// - 6-8 đầu: few-shot trong refinePrompt\n// - Tất cả 10: integration smoke test (gated)\n//\n// Pattern: currentDsl đại diện state đã có (sau build trước), instruction là\n// chỉ thị bổ sung. expectedEnvelope là ground truth AI nên emit.\n\nimport type { DslInputT } from '../dsl/schema';\nimport type { FigureRefineEnvelopeT } from './refineEnvelope';\n\nexport interface RefineFixture {\n name: string;\n currentDsl: DslInputT;\n instruction: string;\n expectedEnvelope: FigureRefineEnvelopeT;\n}\n\nconst triangleABC: DslInputT = {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: 0, y: 3 },\n { name: 'B', kind: 'free', x: -2, y: 0 },\n { name: 'C', kind: 'free', x: 3, y: 0 },\n ],\n shapes: [{ name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] }],\n};\n\nconst rightTriangleAtA: DslInputT = {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: 0, y: 0 },\n { name: 'B', kind: 'free', x: 4, y: 0 },\n { name: 'C', kind: 'free', x: 0, y: 3 },\n ],\n shapes: [{ name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] }],\n};\n\nconst parallelogramABCD: DslInputT = {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: -2, y: 0 },\n { name: 'B', kind: 'free', x: 3, y: 0 },\n { name: 'C', kind: 'free', x: 4, y: 2 },\n { name: 'D', kind: 'free', x: -1, y: 2 },\n ],\n shapes: [{ name: 'ABCD', kind: 'polygon', vertices: ['A', 'B', 'C', 'D'] }],\n};\n\nconst circleOnA: DslInputT = {\n version: 1,\n points: [\n { name: 'O', kind: 'free', x: 0, y: 0 },\n { name: 'A', kind: 'free', x: 3, y: 0 },\n ],\n shapes: [{ name: 'omega', kind: 'circleCP', center: 'O', surfacePoint: 'A' }],\n};\n\nexport const REFINE_FIXTURES: RefineFixture[] = [\n {\n name: 'triangle-add-midpoint',\n currentDsl: triangleABC,\n instruction: 'Thêm trung điểm M của BC',\n expectedEnvelope: {\n decision: 'add',\n figure: {\n version: 1,\n points: [{ name: 'M', kind: 'midpoint', p1: 'B', p2: 'C' }],\n shapes: [{ name: 'AM', kind: 'segment', p1: 'A', p2: 'M' }],\n },\n },\n },\n {\n name: 'triangle-add-altitude',\n currentDsl: triangleABC,\n instruction: 'Dựng đường cao AH xuống BC',\n expectedEnvelope: {\n decision: 'add',\n figure: {\n version: 1,\n points: [{ name: 'H', kind: 'perpFoot', from: 'A', onLine: 'BC_line' }],\n shapes: [\n { name: 'BC_line', kind: 'line', p1: 'B', p2: 'C' },\n { name: 'AH', kind: 'segment', p1: 'A', p2: 'H' },\n ],\n },\n },\n },\n {\n name: 'triangle-add-circumcircle',\n currentDsl: triangleABC,\n instruction: 'Vẽ đường tròn ngoại tiếp tam giác ABC',\n expectedEnvelope: {\n decision: 'add',\n figure: {\n version: 1,\n points: [{ name: 'O', kind: 'circumcenter', vertices: ['A', 'B', 'C'] }],\n shapes: [{ name: 'omega', kind: 'circle3', p1: 'A', p2: 'B', p3: 'C' }],\n },\n },\n },\n {\n name: 'right-triangle-add-centroid',\n currentDsl: rightTriangleAtA,\n instruction: 'Thêm trọng tâm G của tam giác',\n expectedEnvelope: {\n decision: 'add',\n figure: {\n version: 1,\n points: [{ name: 'G', kind: 'centroid', vertices: ['A', 'B', 'C'] }],\n shapes: [],\n },\n },\n },\n {\n name: 'parallelogram-add-diagonals',\n currentDsl: parallelogramABCD,\n instruction: 'Vẽ hai đường chéo AC, BD và giao điểm O',\n expectedEnvelope: {\n decision: 'add',\n figure: {\n version: 1,\n points: [{ name: 'O', kind: 'intersection', ref1: 'AC', ref2: 'BD' }],\n shapes: [\n { name: 'AC', kind: 'segment', p1: 'A', p2: 'C' },\n { name: 'BD', kind: 'segment', p1: 'B', p2: 'D' },\n ],\n },\n },\n },\n {\n name: 'circle-add-tangent',\n currentDsl: circleOnA,\n instruction: 'Kẻ tiếp tuyến tại A của đường tròn',\n expectedEnvelope: {\n decision: 'add',\n figure: {\n version: 1,\n points: [],\n shapes: [{ name: 't', kind: 'tangent', throughPoint: 'A', toCircle: 'omega' }],\n },\n },\n },\n {\n name: 'triangle-replace-equilateral',\n currentDsl: triangleABC,\n instruction: 'Bỏ tam giác này, vẽ tam giác đều ABC thay vào',\n expectedEnvelope: {\n decision: 'replace',\n figure: {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: 0, y: 2 },\n { name: 'B', kind: 'free', x: -1.732, y: -1 },\n { name: 'C', kind: 'free', x: 1.732, y: -1 },\n ],\n shapes: [{ name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] }],\n },\n },\n },\n {\n name: 'triangle-replace-rhombus',\n currentDsl: triangleABC,\n instruction: 'Đổi sang hình thoi ABCD',\n expectedEnvelope: {\n decision: 'replace',\n figure: {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: -2, y: 0 },\n { name: 'B', kind: 'free', x: 0, y: 1.5 },\n { name: 'C', kind: 'free', x: 2, y: 0 },\n { name: 'D', kind: 'free', x: 0, y: -1.5 },\n ],\n shapes: [{ name: 'ABCD', kind: 'polygon', vertices: ['A', 'B', 'C', 'D'] }],\n },\n },\n },\n {\n name: 'refuse-calculation',\n currentDsl: triangleABC,\n instruction: 'Tính diện tích tam giác ABC',\n expectedEnvelope: {\n decision: 'refuse',\n reason: 'Yêu cầu tính toán, không phải vẽ hình.',\n },\n },\n {\n name: 'refuse-3d',\n currentDsl: triangleABC,\n instruction: 'Vẽ hình chóp SABC với S nằm trên tam giác',\n expectedEnvelope: {\n decision: 'refuse',\n reason: 'Hình 3D ngoài phạm vi geometry-2d.',\n },\n },\n];\n\n/** 8 fixture đầu dùng cho few-shot prompt (bỏ 2 refuse cuối để prompt không bias refuse). */\nexport const REFINE_PROMPT_FIXTURES = REFINE_FIXTURES.slice(0, 8);\n","// src/stamps/geometry-2d/ai/refinePrompt.ts\n//\n// System prompt cho refine mode. Inject currentDsl JSON + list tên đã dùng\n// để AI emit delta hợp lệ. Few-shot examples từ REFINE_PROMPT_FIXTURES.\n\nimport type { DslInputT } from '../dsl/schema';\nimport { REFINE_PROMPT_FIXTURES } from './refineFixtures';\n\nfunction namesOf(dsl: DslInputT): { points: string[]; shapes: string[] } {\n return {\n points: dsl.points.map((p) => p.name),\n shapes: dsl.shapes.map((s) => s.name),\n };\n}\n\nexport function buildRefineSystemPrompt(currentDsl: DslInputT): string {\n const names = namesOf(currentDsl);\n const examples = REFINE_PROMPT_FIXTURES.map((f, i) => {\n const env = f.expectedEnvelope;\n return `### Ví dụ ${i + 1}\n**Hình hiện tại:**\n${JSON.stringify(f.currentDsl, null, 2)}\n**Yêu cầu chỉnh sửa:** ${f.instruction}\n**Output:**\n${JSON.stringify(env, null, 2)}`;\n }).join('\\n\\n');\n\n return `Bạn là trợ lý vẽ hình học 2D. Học sinh đã có HÌNH HIỆN TẠI và muốn THÊM/SỬA.\n\n## Hình hiện tại (DSL JSON)\n${JSON.stringify(currentDsl, null, 2)}\n\n## Tên đã dùng (KHÔNG được redefine)\npoints: ${names.points.join(', ') || '(chưa có)'}\nshapes: ${names.shapes.join(', ') || '(chưa có)'}\n\n## Nhiệm vụ\nĐọc YÊU CẦU CHỈNH SỬA → emit JSON envelope đúng 1 trong 3 dạng:\n\n { \"decision\": \"add\", \"figure\": <DSL chỉ chứa entity MỚI> }\n { \"decision\": \"replace\", \"figure\": <DSL hoàn chỉnh thay thế hình cũ> }\n { \"decision\": \"refuse\", \"reason\": \"lý do tiếng Việt\" }\n\n## Khi nào dùng decision nào?\n- **\"add\"**: user muốn THÊM primitive vào hình hiện tại (vd: \"thêm trung điểm M của BC\", \"dựng đường cao AH\").\n → figure chỉ chứa point/shape MỚI. Ref tên cũ (A, B, C, …) là OK. KHÔNG redefine tên cũ.\n- **\"replace\"**: user muốn vẽ LẠI hoặc đổi sang hình khác hẳn (vd: \"vẽ tam giác đều thay vào\", \"bỏ tam giác, dựng hình thoi\").\n → figure đầy đủ như prompt mới (giống mode build).\n- **\"refuse\"**: yêu cầu ngoài phạm vi (3D, lượng giác / tính toán đại số KHÔNG kèm mô tả hình, biến hình lớp 11+). Mệnh lệnh \"Chứng minh\"/\"Tính\" KHÔNG tự động refuse — nếu kèm mô tả hình thì dùng add/replace bình thường.\n\n## Quy tắc decision=add\n1. Mọi name MỚI KHÔNG được trùng với tên đã dùng ở trên. Trùng → đặt khác (M', M1, …).\n2. ƯU TIÊN derived points: midpoint, perpFoot, intersection, circumcenter, incenter, centroid, orthocenter.\n3. Ref tới tên cũ (A, B, C) là OK — AI biết các tên đó tồn tại.\n4. KHÔNG copy lại entity cũ vào figure delta (delta chỉ chứa cái MỚI).\n\n## Anti-pattern (BẮT BUỘC tránh)\n- KHÔNG redefine tên đã dùng (A, B, C đã có → KHÔNG đặt lại).\n- KHÔNG ref tới tên chưa có ngoài \"Tên đã dùng\" + tên vừa định nghĩa trong delta.\n- KHÔNG emit add với figure chứa cả entity cũ (đó là replace).\n\n## Primitives sẵn có\n**Points:** free, midpoint, onSegment, onLine, onCircle, perpFoot, circumcenter, incenter, centroid, orthocenter, intersection\n**Shapes:** segment, line, ray, polygon, perpendicular, parallel, perpBisector, angleBisector, tangent, circleCP, circle3\n\n## ${REFINE_PROMPT_FIXTURES.length} ví dụ\n\n${examples}\n\nTrả về CHỈ 1 JSON object đúng schema. Không có lời dẫn, không markdown fence.`;\n}\n","// src/stamps/geometry-2d/ai/buildFigureDelta.ts\n//\n// Orchestrator cho multi-step refine. Mirror buildFigure.ts với differences:\n// - Schema: FigureRefineEnvelopeZ (3 decision: add/replace/refuse)\n// - Prompt: buildRefineSystemPrompt(currentDsl)\n// - Merge: decision=add concat currentDsl + delta → transpile()\n// decision=replace transpile envelope.figure alone\n// - Errors: lift DUPLICATE_NAME → name_collision, UNKNOWN_REF → unresolved_ref\n\nimport type { State as SceneState } from '../../../core/scene/types';\nimport type { DslInputT, TranspileError } from '../dsl';\nimport { transpile } from '../dsl';\nimport {\n FigureRefineEnvelopeZ,\n refineEnvelopeJsonSchema,\n} from './refineEnvelope';\nimport { buildRefineSystemPrompt } from './refinePrompt';\nimport {\n selectProvider,\n type AIProvider,\n type ProviderTokenUsage,\n type SelectProviderOptions,\n} from './providers';\n\nconst DEFAULT_MAX_TOKENS = 8192;\n\nexport interface GenerateDeltaOptions extends SelectProviderOptions {\n model?: string;\n maxTokens?: number;\n signal?: AbortSignal;\n maxAttempts?: number;\n}\n\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n}\n\nexport type GenerateDeltaResult =\n | {\n ok: true;\n state: SceneState;\n mergedDsl: DslInputT;\n mode: 'add' | 'replace';\n usage: TokenUsage;\n provider: string;\n }\n | { ok: false; reason: 'refused'; message: string; usage?: TokenUsage; provider?: string }\n | { ok: false; reason: 'parse_error'; message: string; raw?: unknown; usage?: TokenUsage; provider?: string }\n | {\n ok: false;\n reason: 'transpile_error';\n message: string;\n errors: TranspileError[];\n dsl: unknown;\n usage?: TokenUsage;\n provider?: string;\n }\n | {\n ok: false;\n reason: 'name_collision';\n message: string;\n collisions: string[];\n errors: TranspileError[];\n dsl: unknown;\n usage?: TokenUsage;\n provider?: string;\n }\n | {\n ok: false;\n reason: 'unresolved_ref';\n message: string;\n refs: string[];\n errors: TranspileError[];\n dsl: unknown;\n usage?: TokenUsage;\n provider?: string;\n }\n | { ok: false; reason: 'api_error'; message: string; status?: number; provider?: string };\n\nexport interface GenerateFigureDeltaInput {\n problem: string;\n currentDsl: DslInputT;\n}\n\nexport async function generateFigureDelta(\n input: GenerateFigureDeltaInput,\n opts: GenerateDeltaOptions = {},\n): Promise<GenerateDeltaResult> {\n const { problem, currentDsl } = input;\n\n if (!problem || !problem.trim()) {\n return { ok: false, reason: 'api_error', message: 'Đề bài rỗng' };\n }\n\n let provider: AIProvider;\n try {\n provider = selectProvider(opts);\n } catch (e) {\n const err = e as { message?: string };\n return { ok: false, reason: 'api_error', message: err.message ?? 'Không chọn được provider' };\n }\n\n const systemPrompt = buildRefineSystemPrompt(currentDsl);\n const schema = refineEnvelopeJsonSchema();\n\n const out = await provider.call({\n systemPrompt,\n userPrompt: problem,\n schema,\n model: opts.model ?? provider.defaultModel,\n maxTokens: opts.maxTokens ?? DEFAULT_MAX_TOKENS,\n signal: opts.signal,\n });\n\n if (out.kind === 'error') {\n return {\n ok: false,\n reason: 'api_error',\n message: out.message,\n ...(out.status !== undefined ? { status: out.status } : {}),\n provider: provider.name,\n };\n }\n\n const usage = toUsage(out.usage);\n\n const parsed = FigureRefineEnvelopeZ.safeParse(out.data);\n if (!parsed.success) {\n return {\n ok: false,\n reason: 'parse_error',\n message: 'Envelope không khớp schema: ' + parsed.error.issues.map((i) => i.message).join('; '),\n raw: out.data,\n usage,\n provider: provider.name,\n };\n }\n\n const env = parsed.data;\n\n if (env.decision === 'refuse') {\n return {\n ok: false,\n reason: 'refused',\n message: env.reason ?? 'AI từ chối không nêu lý do',\n usage,\n provider: provider.name,\n };\n }\n\n if (env.decision === 'replace') {\n const figure = env.figure! as unknown as DslInputT;\n const tResult = transpile(figure);\n if (!tResult.ok) {\n return liftTranspileError(tResult.errors, figure, usage, provider.name);\n }\n return {\n ok: true,\n state: tResult.state,\n mergedDsl: figure,\n mode: 'replace',\n usage,\n provider: provider.name,\n };\n }\n\n // decision === 'add'\n const delta = env.figure! as unknown as DslInputT;\n const merged: DslInputT = {\n version: 1,\n points: [...currentDsl.points, ...delta.points],\n shapes: [...currentDsl.shapes, ...delta.shapes],\n };\n\n const tResult = transpile(merged);\n if (!tResult.ok) {\n return liftTranspileError(tResult.errors, merged, usage, provider.name);\n }\n\n return {\n ok: true,\n state: tResult.state,\n mergedDsl: merged,\n mode: 'add',\n usage,\n provider: provider.name,\n };\n}\n\nfunction liftTranspileError(\n errors: TranspileError[],\n dsl: DslInputT,\n usage: TokenUsage,\n providerName: string,\n): GenerateDeltaResult {\n const dupes = errors.filter((e) => e.code === 'DUPLICATE_NAME');\n if (dupes.length > 0) {\n const collisions = Array.from(new Set(dupes.flatMap((e) => e.path ?? []).filter(Boolean)));\n return {\n ok: false,\n reason: 'name_collision',\n message:\n 'AI tạo entity trùng tên với hình hiện tại: ' +\n (collisions.length > 0 ? collisions.join(', ') : 'không xác định'),\n collisions,\n errors,\n dsl,\n usage,\n provider: providerName,\n };\n }\n\n const unresolved = errors.filter((e) => e.code === 'UNKNOWN_REF');\n if (unresolved.length > 0) {\n const refs = Array.from(new Set(unresolved.flatMap((e) => e.path ?? []).filter(Boolean)));\n return {\n ok: false,\n reason: 'unresolved_ref',\n message:\n 'AI tham chiếu tên không có: ' +\n (refs.length > 0 ? refs.join(', ') : 'không xác định'),\n refs,\n errors,\n dsl,\n usage,\n provider: providerName,\n };\n }\n\n return {\n ok: false,\n reason: 'transpile_error',\n message: 'DSL từ AI không hợp lệ',\n errors,\n dsl,\n usage,\n provider: providerName,\n };\n}\n\nfunction toUsage(u: ProviderTokenUsage | undefined): TokenUsage {\n return {\n inputTokens: u?.inputTokens ?? 0,\n outputTokens: u?.outputTokens ?? 0,\n cacheReadTokens: u?.cacheReadTokens ?? 0,\n cacheCreationTokens: u?.cacheCreationTokens ?? 0,\n };\n}\n","// src/stamps/geometry-2d/ai/handleGenerateFigureDelta.ts\n//\n// Façade cho generateFigureDelta. Mirror handleGenerateFigure.ts với:\n// - Input thêm currentDsl\n// - Map name_collision + unresolved_ref → friendly Vietnamese message\n// - Retry chỉ với transpile_error (như handleGenerateFigure)\n\nimport type { AiFigureUiResult } from '../../shared/types';\nimport type { DslInputT } from '../dsl';\nimport {\n generateFigureDelta,\n type GenerateDeltaOptions,\n type GenerateDeltaResult,\n} from './buildFigureDelta';\n\nexport interface HandleGenerateFigureDeltaInput {\n problem: string;\n currentDsl: DslInputT;\n}\n\nexport interface HandleGenerateFigureDeltaOptions extends GenerateDeltaOptions {\n onResult?: (result: GenerateDeltaResult, attempt: number) => void;\n maxAttempts?: number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 2;\n\nexport async function handleGenerateFigureDelta(\n input: HandleGenerateFigureDeltaInput,\n opts: HandleGenerateFigureDeltaOptions = {},\n): Promise<AiFigureUiResult> {\n const { onResult, maxAttempts: rawMax, ...generateOpts } = opts;\n const maxAttempts = clampAttempts(rawMax ?? DEFAULT_MAX_ATTEMPTS);\n\n let lastResult: GenerateDeltaResult | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const result = await generateFigureDelta(input, generateOpts);\n lastResult = result;\n\n if (onResult) {\n try {\n onResult(result, attempt);\n } catch {\n // Không cho lỗi telemetry vỡ HTTP response.\n }\n }\n\n if (result.ok) {\n return { ok: true, state: result.state };\n }\n\n if (result.reason === 'transpile_error' && attempt < maxAttempts) {\n continue;\n }\n\n break;\n }\n\n return mapErrorToUi(lastResult!);\n}\n\nfunction clampAttempts(n: number): number {\n if (!Number.isFinite(n)) return DEFAULT_MAX_ATTEMPTS;\n return Math.max(1, Math.min(5, Math.floor(n)));\n}\n\nfunction mapErrorToUi(result: GenerateDeltaResult): AiFigureUiResult {\n if (result.ok) return { ok: true, state: result.state };\n\n switch (result.reason) {\n case 'refused':\n return { ok: false, message: result.message };\n case 'parse_error':\n return {\n ok: false,\n message: 'AI trả về dữ liệu không hợp lệ. Vui lòng thử lại hoặc diễn đạt lại.',\n };\n case 'transpile_error':\n return {\n ok: false,\n message:\n 'AI tạo hình không hợp lệ (đã thử lại). Vui lòng tách thành 1 yêu cầu/lần hoặc diễn đạt khác.',\n };\n case 'name_collision':\n return {\n ok: false,\n message: `AI tạo điểm trùng tên với hình hiện tại (${result.collisions.join(', ')}). Vui lòng diễn đạt lại.`,\n };\n case 'unresolved_ref':\n return {\n ok: false,\n message: `AI tham chiếu sai tên đối tượng (${result.refs.join(', ')}). Vui lòng diễn đạt lại.`,\n };\n case 'api_error':\n default:\n return { ok: false, message: result.message };\n }\n}\n","// src/stamps/geometry-2d/ai/handleGenerateFigureIntent.ts\n//\n// Façade cho HTTP transport — wrap generateFigureIntent với error mapping\n// tới AiFigureIntentUiResult (pattern giống handleGenerateFigure cũ).\n\nimport { generateFigureIntent, type GenerateIntentOptions } from './buildFigureIntent';\nimport type { IntentT } from './intent';\nimport type { DslInputT } from '../dsl/schema';\n\nexport interface HandleGenerateFigureIntentOptions extends GenerateIntentOptions {}\n\nexport interface HandleGenerateFigureIntentInput {\n problem: string;\n}\n\nexport type AiFigureIntentUiResult =\n | {\n kind: 'success';\n dsl: DslInputT;\n intents: readonly IntentT[];\n svg?: string;\n usage: { inputTokens: number; outputTokens: number };\n }\n | {\n kind: 'refused';\n message: string;\n }\n | {\n kind: 'error';\n code: string;\n message: string;\n };\n\nexport async function handleGenerateFigureIntent(\n problem: string,\n opts: HandleGenerateFigureIntentOptions = {},\n): Promise<AiFigureIntentUiResult> {\n try {\n const r = await generateFigureIntent(problem, opts);\n if (r.ok) {\n return {\n kind: 'success',\n dsl: r.dsl,\n intents: r.intents,\n usage: {\n inputTokens: r.usage.inputTokens,\n outputTokens: r.usage.outputTokens,\n },\n };\n }\n if (r.reason === 'refused') {\n return { kind: 'refused', message: r.message };\n }\n return { kind: 'error', code: r.reason, message: r.message };\n } catch (e) {\n return {\n kind: 'error',\n code: 'unexpected',\n message: e instanceof Error ? e.message : String(e),\n };\n }\n}\n","// src/stamps/geometry-2d/ai/mergeIntents.ts\n//\n// Hybrid partial-coverage (Phase 1): gộp intent deterministic + intent LLM bù\n// phần clause chưa phủ. Hai quy tắc:\n// 1. Dedup exact (cùng JSON).\n// 2. Deterministic SỞ HỮU tên (đỉnh draw-shape / name add-point/draw-circle/\n// draw-line) → LLM KHÔNG được định nghĩa lại tên đó (drop bản LLM, det thắng).\n// intent tham chiếu (connect…) KHÔNG sở hữu tên → luôn giữ.\n//\n// Det luôn đứng trước, LLM (đã lọc) nối sau — giữ thứ tự dựng.\nimport type { IntentT } from './intent';\n\n/** Tên mà 1 intent ĐỊNH NGHĨA (tạo mới). connect/ref → [] (chỉ tham chiếu). */\nfunction intentOwnedNames(intent: IntentT): string[] {\n const i = intent as unknown as { op: string; labels?: unknown; name?: unknown };\n if (i.op === 'draw-shape') {\n return Array.isArray(i.labels) ? (i.labels as string[]) : [];\n }\n // add-point / draw-circle / draw-line đều có `name` định danh entity mới.\n if (typeof i.name === 'string') return [i.name];\n return [];\n}\n\n/**\n * Gộp intent deterministic (det) + intent LLM bù (llm). Det giữ nguyên; mỗi\n * intent LLM bị loại nếu: trùng JSON với intent đã có, HOẶC định nghĩa lại tên\n * mà det đã sở hữu (det thắng — phần deterministic đã đúng, đừng để LLM ghi đè).\n */\nexport function mergeIntents(det: readonly IntentT[], llm: readonly IntentT[]): IntentT[] {\n const detOwned = new Set<string>();\n for (const i of det) for (const n of intentOwnedNames(i)) detOwned.add(n);\n\n const seen = new Set<string>(det.map((i) => JSON.stringify(i)));\n const out: IntentT[] = [...det];\n\n for (const i of llm) {\n const key = JSON.stringify(i);\n if (seen.has(key)) continue; // trùng exact\n const owned = intentOwnedNames(i);\n if (owned.some((n) => detOwned.has(n))) continue; // redefine tên det → drop\n seen.add(key);\n out.push(i);\n }\n return out;\n}\n","// src/stamps/geometry-2d/ai/vision/envelope.ts\n//\n// Envelope schema cho OCR output. AI vision luôn emit:\n// { decision: 'extract', text: '...', confidence?: 'high'|'low' }\n// { decision: 'refuse', reason: '...' }\n//\n// Schema flatten được pass cho cả Anthropic tool input_schema + Ollama format.\n\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nexport const VisionEnvelopeZ = z\n .object({\n decision: z.enum(['extract', 'refuse']),\n text: z.string().optional(),\n confidence: z.enum(['high', 'low']).optional(),\n reason: z.string().optional(),\n })\n .refine(\n (e) =>\n e.decision === 'extract'\n ? e.text != null && e.text.length > 0\n : e.reason != null && e.reason.length > 0,\n { message: 'extract cần text không rỗng; refuse cần reason không rỗng' },\n );\n\nexport type VisionEnvelopeT = z.infer<typeof VisionEnvelopeZ>;\n\nexport function visionEnvelopeJsonSchema(): Record<string, unknown> {\n return zodToJsonSchema(VisionEnvelopeZ, {\n $refStrategy: 'none',\n target: 'jsonSchema7',\n }) as Record<string, unknown>;\n}\n","// src/stamps/geometry-2d/ai/vision/prompt.ts\n//\n// Prompt OCR chuyên đề toán hình học tiếng Việt. Giữ ký hiệu Unicode toán.\n\nexport function buildVisionSystemPrompt(): string {\n return [\n 'Bạn là OCR chuyên đọc đề toán hình học tiếng Việt từ ảnh.',\n '',\n 'NHIỆM VỤ:',\n '1. Đọc text trong ảnh, trả về phần ĐỀ BÀI (lời văn + công thức inline).',\n '2. GIỮ NGUYÊN các ký hiệu toán Unicode: Δ ⊥ ∥ ° ⊙ π → ≤ ≥ ∈ ∉ ∩ ∪.',\n '3. BỎ QUA hình vẽ minh hoạ — chỉ trả phần text.',\n '4. Nếu ảnh KHÔNG phải đề toán hình học (vd: văn học, ảnh đời thường, code, công thức không liên quan): decision=\"refuse\" với reason cụ thể bằng tiếng Việt.',\n '5. Đánh giá confidence:',\n ' - \"high\": ≥ 80% ký tự đọc rõ ràng, không nghi ngờ.',\n ' - \"low\": ảnh mờ, có chữ không chắc chắn, hoặc < 80% ký tự confident.',\n '',\n 'OUTPUT: JSON theo schema sau, không markdown, không giải thích thêm.',\n ' { \"decision\": \"extract\", \"text\": \"...\", \"confidence\": \"high\"|\"low\" }',\n ' { \"decision\": \"refuse\", \"reason\": \"...\" }',\n '',\n 'VÍ DỤ extract success:',\n ' { \"decision\": \"extract\", \"text\": \"Cho tam giác ABC vuông tại A. Kẻ đường cao AH ⊥ BC. Chứng minh AH² = BH · CH.\", \"confidence\": \"high\" }',\n '',\n 'VÍ DỤ refuse:',\n ' { \"decision\": \"refuse\", \"reason\": \"Ảnh không phải đề toán — đây là một đoạn văn về Truyện Kiều.\" }',\n ].join('\\n');\n}\n\nexport const VISION_USER_PROMPT = 'Đọc đề bài hình học trong ảnh sau.';\n","// src/stamps/geometry-2d/ai/vision/tesseract.ts\n//\n// Tesseract.js wrapper cho client-side OCR đề toán. Default vie+eng, terminate\n// worker sau mỗi call (không cache v1). Lazy import giữ bundle slim.\n\nimport type { ImagePart } from '../providers/types';\n\nexport interface TesseractOcrOptions {\n /** Tesseract language code. Default 'vie+eng' cho đề toán VN. */\n lang?: string;\n signal?: AbortSignal;\n}\n\nexport interface TesseractOcrResult {\n text: string;\n /** Confidence 0–100 (Tesseract scale). */\n confidence: number;\n}\n\nconst DEFAULT_LANG = 'vie+eng';\n\nexport async function runTesseractOcr(\n image: ImagePart,\n opts: TesseractOcrOptions = {},\n): Promise<TesseractOcrResult> {\n if (opts.signal?.aborted) {\n const err = new Error('Tesseract OCR aborted');\n err.name = 'AbortError';\n throw err;\n }\n\n const { createWorker } = await import('tesseract.js');\n const lang = opts.lang ?? DEFAULT_LANG;\n const worker = await createWorker(lang);\n\n try {\n const dataUrl = `data:${image.mediaType};base64,${image.base64}`;\n const { data } = await worker.recognize(dataUrl);\n return { text: data.text, confidence: data.confidence };\n } finally {\n await worker.terminate();\n }\n}\n","// src/stamps/geometry-2d/ai/vision/extractProblem.ts\n//\n// Orchestrator vision → text. Hỗ trợ 2 engine:\n// - 'tesseract' (default): client-side OCR, offline, không cần Ollama/API key.\n// - 'llm': Vision LLM qua AIProvider.extractText() (Ollama/Anthropic) — fallback\n// cho handwriting / math symbols.\n\nimport { selectProvider, type SelectProviderOptions } from '../providers';\nimport type { AIProvider, ImagePart, VisionRequest } from '../providers/types';\nimport { VisionEnvelopeZ, visionEnvelopeJsonSchema } from './envelope';\nimport { buildVisionSystemPrompt, VISION_USER_PROMPT } from './prompt';\nimport { runTesseractOcr } from './tesseract';\n\n// Ngưỡng: text ngắn hơn thì force confidence=low bất kể engine report gì.\nconst MIN_HIGH_CONFIDENCE_CHARS = 10;\nconst MAX_TEXT_CHARS = 2000;\n// Tesseract confidence (0-100): ≥ ngưỡng này coi như high.\nconst TESSERACT_HIGH_CONFIDENCE_THRESHOLD = 70;\n\nexport type VisionEngine = 'tesseract' | 'llm';\n\nexport interface ExtractProblemOptions extends SelectProviderOptions {\n /** OCR engine. Default 'tesseract' (client-side, không cần network). */\n engine?: VisionEngine;\n /** Tesseract language (chỉ áp dụng khi engine='tesseract'). Default 'vie+eng'. */\n tesseractLang?: string;\n /** Override model OCR cho LLM path. Priority cao hơn env. */\n visionModel?: string;\n /** Max tokens cho LLM response. Default 1024. */\n maxTokens?: number;\n /** Env getter override (cho test). */\n env?: Record<string, string | undefined>;\n signal?: AbortSignal;\n}\n\nexport interface ExtractProblemSuccess {\n ok: true;\n text: string;\n confidence: 'high' | 'low';\n usage: { inputTokens: number; outputTokens: number };\n}\n\nexport interface ExtractProblemFailure {\n ok: false;\n reason: 'not-math' | 'unreadable' | 'empty' | 'unsupported';\n message: string;\n}\n\nexport type ExtractProblemOutcome = ExtractProblemSuccess | ExtractProblemFailure;\n\n/** Pick vision model theo priority: opts → env → provider.defaultModel. */\nexport function pickVisionModel(\n providerDefault: string,\n opts: { visionModel?: string },\n env: Record<string, string | undefined>,\n): string {\n return opts.visionModel ?? env.WHITEBOARD_AI_VISION_MODEL ?? providerDefault;\n}\n\nexport async function extractProblemFromImage(\n image: ImagePart,\n opts: ExtractProblemOptions = {},\n): Promise<ExtractProblemOutcome> {\n const engine: VisionEngine = opts.engine ?? 'tesseract';\n if (engine === 'tesseract') {\n return extractViaTesseract(image, opts);\n }\n return extractViaLlm(image, opts);\n}\n\nasync function extractViaTesseract(\n image: ImagePart,\n opts: ExtractProblemOptions,\n): Promise<ExtractProblemOutcome> {\n let raw: { text: string; confidence: number };\n try {\n raw = await runTesseractOcr(image, {\n ...(opts.tesseractLang ? { lang: opts.tesseractLang } : {}),\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n } catch (e) {\n const err = e as { message?: string };\n return {\n ok: false,\n reason: 'unreadable',\n message: 'Tesseract OCR fail: ' + (err.message ?? '?'),\n };\n }\n\n const text = postProcess(raw.text);\n if (text.length === 0) {\n return { ok: false, reason: 'empty', message: 'Tesseract không trích được text.' };\n }\n\n const tooShort = text.length < MIN_HIGH_CONFIDENCE_CHARS;\n const lowConf = raw.confidence < TESSERACT_HIGH_CONFIDENCE_THRESHOLD;\n const confidence: 'high' | 'low' = tooShort || lowConf ? 'low' : 'high';\n\n return {\n ok: true,\n text,\n confidence,\n usage: { inputTokens: 0, outputTokens: 0 },\n };\n}\n\nasync function extractViaLlm(\n image: ImagePart,\n opts: ExtractProblemOptions,\n): Promise<ExtractProblemOutcome> {\n const provider: AIProvider = opts.provider ?? selectProvider(opts);\n if (!provider.extractText) {\n return {\n ok: false,\n reason: 'unsupported',\n message: `Provider \"${provider.name}\" không hỗ trợ đọc ảnh.`,\n };\n }\n\n const env = opts.env ?? readEnv();\n const model = pickVisionModel(provider.defaultModel, opts, env);\n const req: VisionRequest = {\n systemPrompt: buildVisionSystemPrompt(),\n userPrompt: VISION_USER_PROMPT,\n schema: visionEnvelopeJsonSchema(),\n images: [image],\n model,\n maxTokens: opts.maxTokens ?? 1024,\n ...(opts.signal ? { signal: opts.signal } : {}),\n };\n\n const out = await provider.extractText(req);\n if (out.kind === 'error') {\n return { ok: false, reason: 'unreadable', message: out.message };\n }\n\n const parsed = VisionEnvelopeZ.safeParse(out.data);\n if (!parsed.success) {\n return {\n ok: false,\n reason: 'empty',\n message: 'Không parse được output OCR: ' + parsed.error.message,\n };\n }\n\n const env_ = parsed.data;\n if (env_.decision === 'refuse') {\n return {\n ok: false,\n reason: 'not-math',\n message: env_.reason ?? 'Ảnh không phải đề toán.',\n };\n }\n\n const rawText = env_.text ?? '';\n const text = postProcess(rawText);\n if (text.length === 0) {\n return { ok: false, reason: 'empty', message: 'OCR không trích được text.' };\n }\n\n const tooShort = text.length < MIN_HIGH_CONFIDENCE_CHARS;\n const confidence: 'high' | 'low' =\n env_.confidence === 'low' || tooShort ? 'low' : 'high';\n\n const usage = out.usage ?? { inputTokens: 0, outputTokens: 0 };\n return {\n ok: true,\n text,\n confidence,\n usage: { inputTokens: usage.inputTokens, outputTokens: usage.outputTokens },\n };\n}\n\nfunction postProcess(raw: string): string {\n let t = raw.trim();\n t = t.replace(/\\*\\*(.+?)\\*\\*/g, '$1');\n t = t.replace(/\\*(.+?)\\*/g, '$1');\n t = t.replace(/_(.+?)_/g, '$1');\n t = t.replace(/```[\\s\\S]*?```/g, '').replace(/`([^`]+)`/g, '$1');\n t = t.replace(/\\s+/g, ' ').trim();\n t = t.normalize('NFC');\n if (t.length > MAX_TEXT_CHARS) t = t.slice(0, MAX_TEXT_CHARS);\n return t;\n}\n\nfunction readEnv(): Record<string, string | undefined> {\n if (typeof process !== 'undefined' && process.env) {\n return process.env as Record<string, string | undefined>;\n }\n return {};\n}\n","// src/stamps/geometry-2d/ai/handleExtractProblem.ts\n//\n// Façade UI-friendly cho extractProblemFromImage. Map outcome → UI result kind.\n\nimport {\n extractProblemFromImage,\n type ExtractProblemOptions,\n} from './vision/extractProblem';\nimport type { ImagePart } from './providers/types';\n\nexport interface HandleExtractProblemOptions extends ExtractProblemOptions {}\n\nexport type ExtractUiResult =\n | {\n kind: 'success';\n text: string;\n usage: { inputTokens: number; outputTokens: number };\n }\n | {\n kind: 'low-confidence';\n text: string;\n warning: string;\n usage: { inputTokens: number; outputTokens: number };\n }\n | {\n kind: 'refused';\n reason: 'not-math';\n message: string;\n }\n | {\n kind: 'error';\n code: 'network' | 'unsupported' | 'unexpected' | 'empty';\n message: string;\n };\n\nexport async function handleExtractProblem(\n image: ImagePart,\n opts: HandleExtractProblemOptions = {},\n): Promise<ExtractUiResult> {\n try {\n const r = await extractProblemFromImage(image, opts);\n if (r.ok) {\n if (r.confidence === 'low') {\n return {\n kind: 'low-confidence',\n text: r.text,\n warning: 'OCR có thể không chính xác, kiểm tra trước khi vẽ.',\n usage: r.usage,\n };\n }\n return { kind: 'success', text: r.text, usage: r.usage };\n }\n if (r.reason === 'not-math') {\n return { kind: 'refused', reason: 'not-math', message: r.message };\n }\n if (r.reason === 'unsupported') {\n return { kind: 'error', code: 'unsupported', message: r.message };\n }\n if (r.reason === 'unreadable') {\n return { kind: 'error', code: 'network', message: r.message };\n }\n return { kind: 'error', code: 'empty', message: r.message };\n } catch (e) {\n return {\n kind: 'error',\n code: 'unexpected',\n message: e instanceof Error ? e.message : String(e),\n };\n }\n}\n","// src/stamps/geometry-2d/ai/vision/preprocess.ts\n//\n// Pure-ish browser utilities cho image: validate, infer media type, downscale,\n// encode base64. fileToImagePart() là entry point chính cho UI.\n\nimport type { ImagePart } from '../providers/types';\n\nexport const MAX_EDGE_PX = 2048;\nexport const MAX_RAW_BYTES = 10 * 1024 * 1024; // 10 MB\nexport const MAX_ENCODED_BYTES = 3 * 1024 * 1024; // 3 MB blob threshold; base64 inflate ~33% → ~4 MB string, safely under Anthropic 5 MB image limit\n\nconst ALLOWED_TYPES = ['image/png', 'image/jpeg', 'image/webp'] as const;\ntype AllowedType = (typeof ALLOWED_TYPES)[number];\n\nexport type ValidationResult =\n | { ok: true; mediaType: AllowedType }\n | { ok: false; code: 'invalid-format' | 'too-large'; message: string };\n\nexport function inferMediaType(file: File): AllowedType | null {\n const t = file.type.toLowerCase();\n if ((ALLOWED_TYPES as readonly string[]).includes(t)) return t as AllowedType;\n return null;\n}\n\nexport function validateFile(file: File): ValidationResult {\n const mt = inferMediaType(file);\n if (mt == null) {\n return {\n ok: false,\n code: 'invalid-format',\n message: 'Chỉ hỗ trợ PNG, JPEG, WEBP.',\n };\n }\n if (file.size > MAX_RAW_BYTES) {\n return {\n ok: false,\n code: 'too-large',\n message: `Ảnh quá lớn (> ${Math.round(MAX_RAW_BYTES / 1024 / 1024)} MB). Crop hoặc resize trước.`,\n };\n }\n return { ok: true, mediaType: mt };\n}\n\n/**\n * Convert File → ImagePart. Auto-downscale nếu max edge > MAX_EDGE_PX.\n * Throws nếu file invalid hoặc decode fail.\n */\nexport async function fileToImagePart(file: File): Promise<ImagePart> {\n const v = validateFile(file);\n if (!v.ok) throw new Error(v.message);\n\n // Decode + có thể downscale qua canvas.\n const bitmap = await createImageBitmap(file);\n const { width, height } = bitmap;\n const maxEdge = Math.max(width, height);\n const scale = maxEdge > MAX_EDGE_PX ? MAX_EDGE_PX / maxEdge : 1;\n const targetW = Math.round(width * scale);\n const targetH = Math.round(height * scale);\n\n const canvas =\n typeof OffscreenCanvas !== 'undefined'\n ? new OffscreenCanvas(targetW, targetH)\n : Object.assign(document.createElement('canvas'), { width: targetW, height: targetH });\n const ctx = canvas.getContext('2d') as\n | CanvasRenderingContext2D\n | OffscreenCanvasRenderingContext2D\n | null;\n if (!ctx) throw new Error('Không tạo được canvas 2D context');\n ctx.drawImage(bitmap, 0, 0, targetW, targetH);\n bitmap.close();\n\n // Encode: PNG nếu input PNG, JPEG cho jpeg/webp.\n let outputType: AllowedType =\n v.mediaType === 'image/png' ? 'image/png' : 'image/jpeg';\n let finalBlob = await canvasToBlob(canvas, outputType, 0.92);\n\n // Nếu vẫn quá cap encoded → fallback JPEG quality 0.7 (kể cả PNG → JPEG,\n // vì OCR không cần alpha và JPEG nén tốt hơn nhiều).\n if (finalBlob.size > MAX_ENCODED_BYTES) {\n outputType = 'image/jpeg';\n finalBlob = await canvasToBlob(canvas, 'image/jpeg', 0.7);\n }\n\n const base64 = await blobToBase64(finalBlob);\n return { mediaType: outputType, base64 };\n}\n\nasync function canvasToBlob(\n canvas: HTMLCanvasElement | OffscreenCanvas,\n type: AllowedType,\n quality: number,\n): Promise<Blob> {\n if ('convertToBlob' in canvas) {\n return canvas.convertToBlob({ type, quality });\n }\n return new Promise((resolve, reject) => {\n (canvas as HTMLCanvasElement).toBlob(\n (b) => (b ? resolve(b) : reject(new Error('Canvas encode fail'))),\n type,\n quality,\n );\n });\n}\n\nasync function blobToBase64(blob: Blob): Promise<string> {\n const buf = await blob.arrayBuffer();\n // btoa cần string → dùng chunked conversion cho Uint8Array.\n let binary = '';\n const bytes = new Uint8Array(buf);\n const chunk = 0x8000;\n for (let i = 0; i < bytes.length; i += chunk) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunk));\n }\n return typeof btoa === 'function' ? btoa(binary) : Buffer.from(binary, 'binary').toString('base64');\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/stamps/geometry-2d/ai/deterministic/vocabulary.ts","../src/stamps/geometry-2d/ai/deterministic/coverage.ts","../src/stamps/geometry-2d/ai/rules/_shared.ts","../src/stamps/geometry-2d/ai/rules/triangle.ts","../src/stamps/geometry-2d/ai/rules/quad.ts","../src/stamps/geometry-2d/ai/rules/connect.ts","../src/stamps/geometry-2d/ai/rules/midpoint.ts","../src/stamps/geometry-2d/ai/rules/perpBisector.ts","../src/stamps/geometry-2d/ai/rules/cevian.ts","../src/stamps/geometry-2d/ai/rules/angleBisectorAngle.ts","../src/stamps/geometry-2d/ai/rules/centers.ts","../src/stamps/geometry-2d/ai/rules/perpFoot.ts","../src/stamps/geometry-2d/ai/rules/circleRadius.ts","../src/stamps/geometry-2d/ai/rules/circleTriangle.ts","../src/stamps/geometry-2d/ai/rules/tangentFromExt.ts","../src/stamps/geometry-2d/ai/rules/externalPoint.ts","../src/stamps/geometry-2d/ai/rules/arcMidpoint.ts","../src/stamps/geometry-2d/ai/rules/excenter.ts","../src/stamps/geometry-2d/ai/rules/parallelPerp.ts","../src/stamps/geometry-2d/ai/rules/reflection.ts","../src/stamps/geometry-2d/ai/rules/pointAtDistance.ts","../src/stamps/geometry-2d/ai/rules/eulerLine.ts","../src/stamps/geometry-2d/ai/rules/radicalAxis.ts","../src/stamps/geometry-2d/ai/rules/simson.ts","../src/stamps/geometry-2d/ai/rules/ninePoint.ts","../src/stamps/geometry-2d/ai/rules/diameterCirclePairwise.ts","../src/stamps/geometry-2d/ai/rules/angleBisectorFoot.ts","../src/stamps/geometry-2d/ai/rules/intersection.ts","../src/stamps/geometry-2d/ai/rules/chord.ts","../src/stamps/geometry-2d/ai/rules/incircleTangency.ts","../src/stamps/geometry-2d/ai/rules/altitudeDiameterCircles.ts","../src/stamps/geometry-2d/ai/rules/diameterCircleCutsSides.ts","../src/stamps/geometry-2d/ai/rules/registry.ts","../src/stamps/geometry-2d/ai/deterministic/runDeterministicIntents.ts","../src/stamps/geometry-2d/ai/deterministic/guards.ts","../src/stamps/geometry-2d/ai/normalizeIntent.ts","../src/stamps/geometry-2d/ai/resolveCircleNames.ts","../src/stamps/geometry-2d/ai/repairCircleIntersections.ts","../src/stamps/geometry-2d/dsl/names.ts","../src/stamps/geometry-2d/dsl/kinds/_types.ts","../src/stamps/geometry-2d/dsl/kinds/_shared.ts","../src/stamps/geometry-2d/dsl/kinds/points/free.ts","../src/stamps/geometry-2d/dsl/kinds/points/midpoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/onSegment.ts","../src/stamps/geometry-2d/dsl/kinds/points/onLine.ts","../src/stamps/geometry-2d/dsl/kinds/points/onCircle.ts","../src/stamps/geometry-2d/dsl/kinds/points/perpFoot.ts","../src/stamps/geometry-2d/dsl/kinds/points/circumcenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/incenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/centroid.ts","../src/stamps/geometry-2d/dsl/kinds/points/orthocenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/intersection.ts","../src/stamps/geometry-2d/dsl/kinds/lines/segment.ts","../src/stamps/geometry-2d/dsl/kinds/lines/line.ts","../src/stamps/geometry-2d/dsl/kinds/lines/ray.ts","../src/stamps/geometry-2d/dsl/kinds/lines/perpendicular.ts","../src/stamps/geometry-2d/dsl/kinds/lines/parallel.ts","../src/stamps/geometry-2d/dsl/kinds/lines/perpBisector.ts","../src/stamps/geometry-2d/dsl/kinds/lines/angleBisector.ts","../src/stamps/geometry-2d/dsl/kinds/lines/lineThrough.ts","../src/stamps/geometry-2d/dsl/kinds/lines/radicalAxis.ts","../src/stamps/geometry-2d/dsl/kinds/lines/tangent.ts","../src/stamps/geometry-2d/dsl/kinds/polygons/polygon.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circleCP.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circle3.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circleDiameter.ts","../src/stamps/geometry-2d/dsl/kinds/points/secondIntersection.ts","../src/stamps/geometry-2d/dsl/kinds/points/circleIntersection.ts","../src/stamps/geometry-2d/dsl/kinds/points/circleSecondIntersection.ts","../src/stamps/geometry-2d/dsl/kinds/points/tangencyPoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/tangentPointExt.ts","../src/stamps/geometry-2d/dsl/kinds/circles/circleCR.ts","../src/stamps/geometry-2d/dsl/kinds/circles/incircle.ts","../src/stamps/geometry-2d/dsl/kinds/circles/excircle.ts","../src/stamps/geometry-2d/dsl/kinds/points/arcMidpoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/excenter.ts","../src/stamps/geometry-2d/dsl/kinds/points/reflectPoint.ts","../src/stamps/geometry-2d/dsl/kinds/points/reflectLine.ts","../src/stamps/geometry-2d/dsl/kinds/points/pointAtDistance.ts","../src/stamps/geometry-2d/dsl/registry.ts","../src/stamps/geometry-2d/dsl/transpile/errors.ts","../src/stamps/geometry-2d/dsl/transpile/refs.ts","../src/stamps/geometry-2d/ai/layout/disjointOffset.ts","../src/stamps/geometry-2d/ai/intent-builders/_types.ts","../src/stamps/geometry-2d/ai/intent-builders/shared.ts","../src/stamps/geometry-2d/ai/intent-builders/draw-shape.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/midpoint.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/perpFoot.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/centers.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/intersections.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/tangency.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/onSegment-free.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/angleBisectorFoot.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/externalAngleBisectorFoot.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/rightAngleViewing.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/arcMidpoint.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/reflect.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/pointAtDistance.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/externalToCircle.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/onCircle.ts","../src/stamps/geometry-2d/ai/intent-builders/add-point/index.ts","../src/stamps/geometry-2d/ai/intent-builders/connect.ts","../src/stamps/geometry-2d/ai/intent-builders/draw-circle.ts","../src/stamps/geometry-2d/ai/intent-builders/draw-line.ts","../src/stamps/geometry-2d/ai/intent-builders/mark-shape.ts","../src/stamps/geometry-2d/ai/intent-builders/registry.ts","../src/stamps/geometry-2d/ai/intentToDsl.ts","../src/stamps/geometry-2d/dsl/schema.ts","../src/core/scene/types.ts","../src/stamps/geometry-2d/dsl/transpile/symbols.ts","../src/stamps/geometry-2d/dsl/transpile/cycles.ts","../src/stamps/geometry-2d/dsl/transpile/topology.ts","../src/stamps/geometry-2d/dsl/transpile/ids.ts","../src/stamps/geometry-2d/dsl/transpile.ts","../src/stamps/geometry-2d/ai/verify.ts","../src/stamps/geometry-2d/ai/deterministic/tryDeterministicFigure.ts","../src/stamps/geometry-2d/ai/deterministic/describeMiss.ts","../src/stamps/geometry-2d/ai/buildFigureIntent.ts","../src/stamps/geometry-2d/ai/handleGenerateFigure.ts","../src/stamps/geometry-2d/ai/envelope.ts","../src/stamps/geometry-2d/ai/intent.ts","../src/stamps/geometry-2d/ai/intentEnvelope.ts","../src/stamps/geometry-2d/ai/intentPrompt.ts","../src/stamps/geometry-2d/ai/handleGenerateFigureIntent.ts","../src/stamps/geometry-2d/ai/mergeIntents.ts"],"names":["others","PREFILTER","TRI","TRI_EN","TRI_G","TRI_EN_G","dm","CENTER","scanClause","from","circle","NAME_BEFORE","NAME_BEFORE_EN","opposite","z","PREFILTER_EN","parseNum","t","uniqueTriangle","CIRCLE_CENTER","LINE","CIRCLE_WORDS","CIRCLE_PAREN","resolveCircle","collect","addPoint","zodToJsonSchema"],"mappings":";;;;;;AAKO,IAAM,iBAAA,GAAuC;AAAA;AAAA,EAElD,aAAA;AAAA,EAAY,8BAAA;AAAA,EAAc,8BAAA;AAAA,EAAc,4BAAA;AAAA,EAAiB,kBAAA;AAAA,EACzD,yBAAA;AAAA,EAAkB,cAAA;AAAA,EAAa,eAAA;AAAA,EAAc,iBAAA;AAAA;AAAA,EAE7C,mBAAA;AAAA,EAAa,iBAAA;AAAA,EAAW,eAAA;AAAA;AAAA,EAExB,gBAAA;AAAA,EAAY,QAAA;AAAA,EAAO,8BAAA;AAAA,EAAc,8BAAA;AAAA;AAAA,EAEjC,gBAAA;AAAA;AAAA,EAEA,sBAAA;AAAA,EAAc,kCAAA;AAAA,EAAkB,kCAAA;AAAA,EAAkB,oBAAA;AAAA,EAClD,mBAAA;AAAA,EAAa,kBAAA;AAAA,EAAY,2BAAA;AAAA,EAAgB,6BAAA;AAAA;AAAA,EAEzC,0BAAA;AAAA,EAAa,0BAAA;AAAA,EAAa,kBAAA;AAAA,EAAe,iBAAA;AAAA,EAAa,iBAAA;AAAA;AAAA,EAEtD,sBAAA;AAAA,EAAc,0BAAA;AAAA,EAAa,kBAAA;AAAA,EAC3B,oBAAA;AAAA,EAAY,sBAAA;AAAA;AAAA;AAAA;AAAA,EAIZ,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA,iCAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,wBAAA;AAAA;AAAA,EAEA,WAAA;AAAA,EAAa,iBAAA;AAAA,EAAa,qBAAA;AAAA,EAAa,UAAA;AAAA,EAAO,iCAAA;AAAA,EAAe,iCAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM7D,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA;AAAA;AAAA;AAAA,EAIA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAA;AAAA,EACA,YAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAA;AAAA,EACA,YAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAA;AAAA,EACA,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAA;AAAA,EACA,UAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AACF,CAAA;AAEO,SAAS,sBAAsB,IAAA,EAAsB;AAC1D,EAAA,MAAM,KAAA,GAAQ,KAAK,WAAA,EAAY;AAC/B,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,MAAM,iBAAA,EAAmB;AAClC,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,MAAM,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,EAAA,EAAI,IAAI,CAAA;AAChC,MAAA,IAAI,IAAI,CAAA,EAAG;AACX,MAAA,KAAA,EAAA;AACA,MAAA,IAAA,GAAO,IAAI,EAAA,CAAG,MAAA;AAAA,IAChB;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;;;AC3HO,SAAS,eAAe,OAAA,EAA2B;AAMxD,EAAA,OAAO,OAAA,CACJ,KAAA;AAAA,IACC;AAAA,GACF,CACC,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA,CAC1B,GAAA,CAAI,CAAC,IAAA,EAAM,EAAA,MAAQ,EAAE,EAAA,EAAI,IAAA,EAAM,WAAA,EAAa,qBAAA,CAAsB,IAAI,CAAA,GAAI,CAAA,EAAE,CAAE,CAAA;AACnF;AAEO,SAAS,eAAA,CACd,SACA,OAAA,EACgB;AAChB,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,KAAA,MAAW,CAAA,IAAK,SAAS,KAAA,MAAW,EAAA,IAAM,EAAE,SAAA,EAAW,OAAA,CAAQ,IAAI,EAAE,CAAA;AAErE,EAAA,MAAM,aAAa,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,WAAW,CAAA;AACtD,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,MAAA,CAAO,CAAC,CAAA,KAAM,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA;AAC7D,EAAA,MAAM,gBAAA,GAAmB,UAAA,CACtB,MAAA,CAAO,CAAC,MAAM,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,EAAE,CAAC,CAAA,CAC/B,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAElB,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,SAAA,CAAU,MAAA,KAAW,CAAA,IAAK,WAAW,MAAA,GAAS,CAAA;AAAA,IACxD,gBAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAO,UAAA,CAAW,MAAA,KAAW,IAAI,CAAA,GAAI,gBAAA,CAAiB,SAAS,UAAA,CAAW;AAAA,GAC5E;AACF;;;ACtDO,SAAS,SAAA,CACd,KAAA,EACA,MAAA,EACA,OAAA,GAAU,OACV,cAAA,EACS;AACT,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,YAAA;AAAA,IACJ,KAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,GAA0C;AAAC,GAC7C;AACF;AAEO,SAAS,QAAA,CAAS,MAAc,UAAA,EAA8C;AACnF,EAAA,OAAO,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,UAAA,EAAW;AAC7C;AAEO,SAAS,OAAA,CAAQ,IAAA,EAAc,EAAA,EAAY,KAAA,GAAQ,SAAA,EAAoB;AAC5E,EAAA,OAAO,EAAE,EAAA,EAAI,SAAA,EAAW,IAAA,EAAM,IAAI,KAAA,EAAM;AAC1C;AAEO,SAAS,UAAA,CACd,IAAA,EACA,IAAA,EACA,KAAA,GAAiC,EAAC,EACzB;AACT,EAAA,OAAO,EAAE,EAAA,EAAI,aAAA,EAAe,IAAA,EAAM,IAAA,EAAM,GAAG,KAAA,EAAM;AACnD;AAEO,SAAS,QAAA,CACd,IAAA,EACA,IAAA,EACA,KAAA,GAAiC,EAAC,EACzB;AACT,EAAA,OAAO,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,IAAA,EAAM,GAAG,KAAA,EAAM;AACjD;AAGO,SAAS,SAAA,CAAU,OAAe,MAAA,EAA2B;AAClE,EAAA,OAAO,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,MAAA,EAAO;AAC3C;AAIA,IAAM,UAAA,GACJ,uEAAA;AACF,IAAM,OAAA,GAAU,4BAAA;AAST,SAAS,iBAAiB,UAAA,EAAwC;AACvE,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA;AACxC,EAAA,IAAI,KAAA,EAAO,OAAO,KAAA,CAAM,CAAC,CAAA;AACzB,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,IAAA,CAAK,UAAU,CAAA;AAClC,EAAA,IAAI,EAAA,EAAI,OAAO,EAAA,CAAG,CAAC,CAAA;AACnB,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,cAAc,KAAA,EAAyB;AACrD,EAAA,MAAM,CAAA,GAAI,mBAAA,CAAoB,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAC/C,EAAA,OAAO,CAAA,GAAI,CAAC,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,EAAC;AAC7B;AAQO,IAAM,WAAA,GAAc,6EAAA;AAGpB,IAAM,QAAA,GAAW,sCAAA;AAGjB,IAAM,YAAY,QAAA,GAAW,aAAA;;;AChFpC,IAAM,KAAA,GAAQ,oEAAA;AACd,IAAM,QAAA,GAAW,oCAAA;AACjB,IAAM,MAAA,GAAS,kCAAA;AAGf,IAAM,WAAA,GAAc,yBAAA;AAOpB,IAAM,QAAA,GACJ,8GAAA;AAEF,IAAM,WAAA,GAAc,0DAAA;AAEpB,IAAM,UAAA,GAAa,uCAAA;AAEnB,IAAM,cAAA,GAAiB,0CAAA;AACvB,IAAM,YAAA,GAAe,wCAAA;AAGrB,SAAS,WAAW,IAAA,EAA8C;AAChE,EAAA,IAAI,CAAC,MAAM,OAAO,MAAA;AAClB,EAAA,MAAM,CAAA,GAAI,KAAK,WAAA,EAAY;AAC3B,EAAA,IAAI,CAAA,KAAM,eAAe,OAAO,aAAA;AAChC,EAAA,IAAI,CAAA,KAAM,OAAA,IAAW,CAAA,KAAM,cAAA,EAAgB,OAAO,OAAA;AAClD,EAAA,IAAI,CAAA,KAAM,aAAa,OAAO,WAAA;AAC9B,EAAA,OAAO,MAAA;AACT;AA0BA,IAAM,YAAA,GAAe,CAAC,YAAA,EAAc,YAAA,EAAc,YAAY,CAAA;AAC9D,IAAM,UAAA,GAAa,CAAC,aAAA,EAAe,aAAA,EAAe,aAAa,CAAA;AAW/D,IAAM,QAAA,GAAW,CAAA;AACjB,IAAM,YAAA,GAAe,GAAA;AAGrB,IAAM,aAAA,GACJ,sGAAA;AAEF,IAAM,IAAA,GAAO,2CAAA;AAGb,SAAS,oBAAoB,MAAA,EAAoC;AAC/D,EAAA,MAAM,CAAA,GAAI,aAAA,CAAc,IAAA,CAAK,MAAM,CAAA;AACnC,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,OAAO,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AACjC;AAGA,SAAS,aAAA,CAAc,MAAA,EAAgB,IAAA,EAAcA,OAAAA,EAA0B;AAC7E,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA;AAC1B,EAAA,IAAI,CAAA,EAAG;AACL,IAAA,MAAM,EAAA,GAAK,EAAE,CAAC,CAAA;AACd,IAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAC,CAAA,KAAM,OAAO,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,KAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,GAAI,MAAA;AACzD,IAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAC,CAAA,KAAM,OAAO,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,KAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,GAAI,MAAA;AACzD,IAAA,IAAI,EAAA,IAAM,MAAMA,OAAAA,CAAO,QAAA,CAAS,EAAE,CAAA,IAAKA,OAAAA,CAAO,QAAA,CAAS,EAAE,CAAA,EAAG;AAC1D,MAAA,OAAO,EAAA,KAAO,MAAM,EAAA,GAAK,EAAA;AAAA,IAC3B;AAAA,EACF;AACA,EAAA,OAAOA,QAAO,CAAC,CAAA;AACjB;AAMA,SAAS,aAAA,CACP,MAAA,EACA,OAAA,EACA,aAAA,EACA,MAAA,EACkB;AAClB,EAAA,MAAM,IAAA,GAAO,OAAO,OAAO,CAAA;AAC3B,EAAA,MAAMA,UAAS,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAM,MAAM,OAAO,CAAA;AACpD,EAAA,MAAM,KAAK,aAAA,IAAiB,GAAA;AAC5B,EAAA,IAAI,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,MAAA,EAAQ,IAAA,EAAMA,OAAM,CAAA;AACnD,EAAA,MAAM,OAAA,GAAUA,QAAO,CAAC,CAAA,KAAM,WAAWA,OAAAA,CAAO,CAAC,CAAA,GAAIA,OAAAA,CAAO,CAAC,CAAA;AAC7D,EAAA,OAAO;AAAA,IACL,QAAA,CAAS,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,CAAC,CAAC,QAAA,EAAU,CAAC,CAAA,EAAG,CAAA;AAAA;AAAA,IACvD,QAAA,CAAS,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAI,CAAC,QAAA,EAAU,CAAC,CAAA,EAAG,CAAA;AAAA,IACrD,QAAA,CAAS,IAAI,EAAE,IAAA,EAAM,YAAY,EAAA,EAAI,QAAA,GAAW,SAAS,CAAA;AAAA;AAAA,IACzD,UAAA,CAAW,IAAI,eAAA,EAAiB,EAAE,QAAQ,EAAA,EAAI,OAAA,EAAS,UAAU,CAAA;AAAA,IACjE,QAAA,CAAS,MAAM,EAAE,IAAA,EAAM,YAAY,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,YAAA,EAAc,CAAA;AAAA;AAAA,IACpE,SAAA,CAAU,YAAY,MAAM;AAAA,GAC9B;AACF;AAEA,SAAS,UAAA,CAAW,KAAa,MAAA,EAAwB;AACvD,EAAA,OAAO,GAAA,CAAI,SAAS,IAAA,GAAO,YAAA,CAAa,KAAK,MAAM,CAAA,GAAI,YAAA,CAAa,GAAA,EAAK,MAAM,CAAA;AACjF;AAEA,SAAS,YAAA,CAAa,KAAa,MAAA,EAAwB;AACzD,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,GAAA;AAEzB,EAAA,IAAI,SAAS,eAAA,IAAS,WAAA,CAAY,IAAA,CAAK,MAAM,GAAG,OAAO,aAAA;AAEvD,EAAA,MAAM,EAAA,GAAK,QAAA,CAAS,IAAA,CAAK,MAAM,CAAA;AAC/B,EAAA,IAAI,EAAA,EAAI;AACN,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,EAAA,CAAG,CAAC,CAAC,CAAA;AAC9B,IAAA,IAAI,CAAA,IAAK,CAAA,EAAG,OAAO,YAAA,CAAa,CAAC,CAAA;AAAA,EACnC;AAEA,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAC9B,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,CAAA;AAC/B,IAAA,IAAI,CAAA,IAAK,CAAA,EAAG,OAAO,UAAA,CAAW,CAAC,CAAA;AAAA,EACjC;AAEA,EAAA,OAAO,KAAA;AACT;AASA,SAAS,YAAA,CAAa,KAAa,MAAA,EAAwB;AACzD,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,GAAA;AACzB,EAAA,IAAI,SAAS,aAAA,IAAiB,cAAA,CAAe,IAAA,CAAK,MAAM,GAAG,OAAO,aAAA;AAIlE,EAAA,MAAM,EAAA,GAAK,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA;AAClC,EAAA,IAAI,EAAA,EAAI;AACN,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,EAAA,CAAG,CAAC,CAAC,CAAA;AAC9B,IAAA,IAAI,CAAA,IAAK,CAAA,EAAG,OAAO,YAAA,CAAa,CAAC,CAAA;AAAA,EACnC;AAIA,EAAA,MAAM,MAAA,GAAS,IAAA,KAAS,WAAA,IAAe,YAAA,CAAa,KAAK,MAAM,CAAA;AAC/D,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,MAAM,EAAA,GAAK,UAAA,CAAW,IAAA,CAAK,MAAM,CAAA;AACjC,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,MAAM,CAAA,GAAI,MAAA,CAAO,OAAA,CAAQ,EAAA,CAAG,CAAC,CAAC,CAAA;AAC9B,MAAA,IAAI,CAAA,IAAK,CAAA,EAAG,OAAO,UAAA,CAAW,CAAC,CAAA;AAAA,IACjC;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAYO,IAAM,YAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,UAAA;AAAA,EACJ,QAAA,EAAU,GAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAAC,KAAA,EAAO,QAAQ,CAAA;AAAA,EAC1B,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,OAAiB,EAAC;AAExB,MAAA,KAAA,CAAM,SAAA,GAAY,CAAA;AAClB,MAAA,IAAI,CAAA;AACJ,MAAA,OAAA,CAAQ,IAAI,KAAA,CAAM,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AACxC,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACR,IAAA,EAAM,EAAE,CAAC,CAAA;AAAA,UACT,IAAA,EAAM,IAAA;AAAA,UACN,MAAA,EAAQ,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,UACzB,OAAO,CAAA,CAAE,KAAA;AAAA,UACT,GAAA,EAAK,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE;AAAA,SACrB,CAAA;AAAA,MACH;AAEA,MAAA,QAAA,CAAS,SAAA,GAAY,CAAA;AACrB,MAAA,OAAA,CAAQ,IAAI,QAAA,CAAS,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AAC3C,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACR,IAAA,EAAM,UAAA,CAAW,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,UACrB,IAAA,EAAM,IAAA;AAAA,UACN,MAAA,EAAQ,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,UACzB,OAAO,CAAA,CAAE,KAAA;AAAA,UACT,GAAA,EAAK,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE;AAAA,SACrB,CAAA;AAAA,MACH;AAEA,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AAIvB,MAAA,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAErC,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,CAAC,KAAK,GAAA,KAAQ;AACzC,QAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,GAAM,CAAC,CAAA;AACzB,QAAA,MAAM,SAAA,GAAY,IAAA,GAAO,IAAA,CAAK,KAAA,GAAQ,EAAE,IAAA,CAAK,MAAA;AAC7C,QAAA,MAAM,SAAS,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,KAAK,SAAS,CAAA;AAC9C,QAAA,MAAM,OAAA,GAAU,UAAA,CAAW,GAAA,EAAK,MAAM,CAAA;AAKtC,QAAA,MAAM,QAAA,GAAW,YAAA,CAAa,OAAA,CAAQ,OAAO,CAAA;AAC7C,QAAA,IAAI,YAAY,CAAA,EAAG;AACjB,UAAA,MAAM,UAAA,GAAa,oBAAoB,MAAM,CAAA;AAC7C,UAAA,IAAI,eAAe,MAAA,EAAW;AAC5B,YAAA,MAAM,SAAS,aAAA,CAAc,GAAA,CAAI,MAAA,EAAQ,QAAA,EAAU,YAAY,MAAM,CAAA;AACrE,YAAA,IAAI,QAAQ,OAAO,MAAA;AAAA,UACrB;AAAA,QACF;AACA,QAAA,OAAO,CAAC,SAAA,CAAU,UAAA,EAAY,GAAA,CAAI,MAAA,EAAQ,OAAO,CAAC,CAAA;AAAA,MACpD,CAAC,CAAA;AAED,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,UAAA,EAAY,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA;AAAA,IAC7D;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AC/PA,IAAM,IAAA,GAAO,uCAAA;AAcb,IAAM,KAAA,GAAoB;AAAA;AAAA,EAExB;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,gCAAA,GAA6B,MAAM,IAAI,CAAA;AAAA,IACxD,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,kCAAA,GAA+B,MAAM,IAAI,CAAA;AAAA,IAC1D,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA;AAAA;AAAA,EAGA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,sBAAA,GAAsB,MAAM,IAAI,CAAA;AAAA,IACjD,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,yBAAA,GAAsB,MAAM,IAAI,CAAA;AAAA,IACjD,KAAA,EAAO,QAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,sCAAA,GAA4B,MAAM,IAAI,CAAA;AAAA,IACvD,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,mCAAA,GAA6B,MAAM,IAAI,CAAA;AAAA,IACxD,KAAA,EAAO,eAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,qBAAA,GAAqB,MAAM,IAAI,CAAA;AAAA,IAChD,KAAA,EAAO,SAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,yCAAA,GAA+B,MAAM,IAAI,CAAA;AAAA,IAC1D,KAAA,EAAO,eAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,mDAAA,GAAsD,MAAM,IAAI,CAAA;AAAA,IACjF,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,+CAAA,GAAkD,MAAM,IAAI,CAAA;AAAA,IAC7E,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,mCAAA,GAAsC,MAAM,IAAI,CAAA;AAAA,IACjE,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,eAAA,GAAkB,MAAM,IAAI,CAAA;AAAA,IAC7C,KAAA,EAAO,QAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,kBAAA,GAAqB,MAAM,IAAI,CAAA;AAAA,IAChD,KAAA,EAAO,WAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,sBAAA,GAAyB,MAAM,IAAI,CAAA;AAAA,IACpD,KAAA,EAAO,eAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,gBAAA,GAAmB,MAAM,IAAI,CAAA;AAAA,IAC9C,KAAA,EAAO,SAAA;AAAA,IACP,OAAA,EAAS;AAAA,GACX;AAAA,EACA;AAAA,IACE,IAAA,EAAM,IAAI,MAAA,CAAO,sBAAA,GAAyB,MAAM,IAAI,CAAA;AAAA,IACpD,KAAA,EAAO,eAAA;AAAA,IACP,OAAA,EAAS;AAAA;AAEb,CAAA;AAGA,IAAM,SAAA,GACJ,6JAAA;AAIF,IAAM,WAAA,GAAc,iBAAA;AACpB,IAAM,SAAA,GAAY,yBAAA;AAGlB,IAAM,UAAA,GAAa,mBAAA;AAgBnB,SAAS,WAAW,IAAA,EAAqB;AACvC,EAAA,MAAM,UAAiB,EAAC;AACxB,EAAA,MAAM,QAAiC,EAAC;AAExC,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,EAAe,GAAA,KAC/B,MAAM,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,KAAA,GAAQ,CAAA,IAAK,MAAM,CAAC,CAAA;AAE7C,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,CAAA,CAAE,KAAK,SAAA,GAAY,CAAA;AACnB,IAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,CAAA,CAAE,IAAI,CAAA,EAAG;AACrC,MAAA,MAAM,KAAA,GAAQ,EAAE,KAAA,IAAS,CAAA;AACzB,MAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA;AACzB,MAAA,IAAI,QAAA,CAAS,KAAA,EAAO,GAAG,CAAA,EAAG;AAC1B,MAAA,KAAA,CAAM,IAAA,CAAK,CAAC,KAAA,EAAO,GAAG,CAAC,CAAA;AAEvB,MAAA,IAAI,UAAU,CAAA,CAAE,OAAA;AAGhB,MAAA,IAAI,CAAA,CAAE,KAAA,KAAU,WAAA,IAAe,CAAA,CAAE,YAAY,SAAA,EAAW;AACtD,QAAA,IAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAA,EAAK,MAAM,EAAE,CAAA;AACnC,QAAA,MAAM,IAAA,GAAO,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA;AACjC,QAAA,IAAI,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,KAAK,KAAK,CAAA;AACzC,QAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAG,OAAA,GAAU,OAAA;AAAA,aAAA,IAC7B,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,EAAG,OAAA,GAAU,UAAA;AAAA,MAC3C;AACA,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,KAAA,EAAO,KAAA;AAAA,QACP,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,OAAA;AAAA,QACA,MAAA,EAAQ,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,QAC/B,QAAA,EAAU;AAAA,OACX,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACxC,EAAA,OAAO,OAAA;AACT;AA6BA,IAAM,kBAAA,GAAkD;AAAA,EACtD,CAAC,IAAI,CAAC,CAAA;AAAA,EACN,CAAC,GAAG,CAAC,CAAA;AAAA,EACL,CAAC,GAAG,EAAE,CAAA;AAAA,EACN,CAAC,IAAI,EAAE;AACT,CAAA;AAGA,IAAM,aAAA,GAAgB,IAAA,CAAK,KAAA,CAAM,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,kBAAA,CAAmB,CAAC,CAAA,CAAE,CAAC,CAAC,CAAA;AACnF,IAAM,qBAAwC,kBAAA,CAAmB,GAAA;AAAA,EAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MACzE,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC;AACjB,CAAA;AAGA,IAAM,MAAA,GAAS,8CAAA;AAIf,IAAM,2BAA2B,IAAI,MAAA;AAAA,EACnC,wKAAA,GACE,MAAA;AAAA,EACF;AACF,CAAA;AAIA,IAAM,4BAA4B,IAAI,MAAA;AAAA,EACpC,mDACE,MAAA,GACA,uGAAA;AAAA,EACF;AACF,CAAA;AAIA,IAAM,aAAA,GAAgB,+DAAA;AAQtB,SAAS,aAAA,CAAc,KAAkB,UAAA,EAAmC;AAC1E,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAC9B,EAAA,aAAA,CAAc,SAAA,GAAY,CAAA;AAC1B,EAAA,KAAA,MAAW,CAAA,IAAK,GAAA,CAAI,OAAA,CAAQ,QAAA,CAAS,aAAa,CAAA,EAAG;AACnD,IAAA,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AACd,IAAA,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AACd,IAAA,KAAA,CAAM,GAAA,CAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,EAChB;AACA,EAAA,MAAM,OAAA,GAAU,UAAA,CAAW,IAAA,CAAK,EAAE,CAAA;AAClC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,IAAA,KAAA,MAAW,CAAA,IAAK,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,EAAG;AAClC,MAAA,IAAI,CAAA,CAAE,MAAA,CAAO,IAAA,CAAK,EAAE,MAAM,OAAA,EAAS;AACnC,MAAA,KAAA,MAAW,GAAA,IAAO,CAAA,CAAE,MAAA,EAAQ,KAAA,CAAM,IAAI,GAAG,CAAA;AAAA,IAC3C;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAMA,SAAS,YAAA,CAAa,MAAc,GAAA,EAA8B;AAEhE,EAAA,MAAM,IAAI,wBAAA,CAAyB,IAAA,CAAK,KAAK,KAAA,CAAM,GAAA,CAAI,QAAQ,CAAC,CAAA;AAChE,EAAA,IAAI,GAAG,OAAO,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AAE9B,EAAA,MAAM,CAAA,GAAI,0BAA0B,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,EAAG,GAAA,CAAI,KAAK,CAAC,CAAA;AACjE,EAAA,IAAI,GAAG,OAAO,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AAC9B,EAAA,OAAO,MAAA;AACT;AAiBO,IAAM,QAAA,GAAyB;AAAA,EACpC,EAAA,EAAI,MAAA;AAAA,EACJ,QAAA,EAAU,GAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAAC,SAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,KAAA,MAAW,GAAA,IAAO,UAAA,CAAW,CAAA,CAAE,IAAI,CAAA,EAAG;AACpC,QAAA,IAAI,OAAA,GAAU,CAAC,SAAA,CAAU,GAAA,CAAI,OAAO,GAAA,CAAI,MAAA,EAAQ,GAAA,CAAI,OAAO,CAAC,CAAA;AAE5D,QAAA,IAAI,GAAA,CAAI,UAAU,eAAA,EAAiB;AACjC,UAAA,MAAM,MAAA,GAAS,YAAA,CAAa,CAAA,CAAE,IAAA,EAAM,GAAG,CAAA;AACvC,UAAA,IAAI,WAAW,MAAA,EAAW;AAExB,YAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,GAAA,EAAK,GAAA,CAAI,MAAM,CAAA;AAC3C,YAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,IAAA,CAAK,CAAC,GAAA,KAAQ,KAAA,CAAM,GAAA,CAAI,GAAG,CAAC,CAAA;AACtD,YAAA,IAAI,CAAC,MAAA,EAAQ;AACX,cAAA,MAAM,aAAa,MAAA,IAAU,GAAA;AAM7B,cAAA,OAAA,GAAU;AAAA,gBACR,UAAA,CAAW,YAAY,cAAA,EAAgB;AAAA,kBACrC,MAAA,EAAQ,UAAA;AAAA,kBACR,MAAA,EAAQ;AAAA,iBACT,CAAA;AAAA,gBACD,GAAG,IAAI,MAAA,CAAO,GAAA;AAAA,kBAAI,CAAC,GAAA,EAAK,CAAA,KACtB,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,UAAA,EAAY,KAAA,EAAO,kBAAA,CAAmB,CAAC,GAAG;AAAA,iBACtF;AAAA,gBACA,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,GAAA,CAAI,MAAM;AAAA,eACjC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,MAAA;AAAA,UACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,UAChB;AAAA,SACD,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACvUA,IAAM,OAAA,GAAU,iDAAA;AAEhB,IAAM,MAAA,GAAS,iDAAA;AAMf,IAAM,cAAA,GAAiB,sBAAA;AAEvB,IAAM,MAAA,GAAS,iEAAA;AAEf,IAAM,MAAA,GACJ,iFAAA;AAeF,IAAM,WAAA,GAAc,wDAAA;AAEpB,IAAM,YAAA,GAAe,qDAAA;AASrB,IAAM,oBAAA,GAAuB,6DAAA;AAU7B,IAAM,WAAA,GAAc,wEAAA;AACpB,IAAM,sBAAA,GAAyB,0BAAA;AAE/B,IAAM,YAAA,GAAe,oEAAA;AAErB,IAAM,WAAA,GACJ,yFAAA;AAKF,IAAM,YAAA,GAAe,qDAAA;AAErB,SAAS,QACP,EAAA,EACA,IAAA,EACA,KAAA,EACA,IAAA,EACA,KAGA,gBAAA,EACM;AACN,EAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACnC,IAAA,IAAI,gBAAA,IAAoB,iBAAiB,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG;AACrE,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAE,WAAA,EAAY;AAC3B,IAAA,MAAM,CAAA,GAAI,CAAA,CAAE,CAAC,CAAA,CAAE,WAAA,EAAY;AAG3B,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,CAAA;AACpB,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,KAAK,CAAC,CAAA;AAAA,EAC/B;AACF;AAOO,IAAM,WAAA,GAA4B;AAAA,EACvC,EAAA,EAAI,SAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU;AAAA,IACR,OAAA;AAAA,IAAS,MAAA;AAAA,IAAQ,MAAA;AAAA,IAAQ,MAAA;AAAA,IACzB,WAAA;AAAA,IAAa,YAAA;AAAA,IAAc,WAAA;AAAA,IAAa,YAAA;AAAA,IAAc,WAAA;AAAA,IAAa;AAAA,GACrE;AAAA,EACA,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,SAAsB,EAAC;AAC7B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,UAAqB,EAAC;AAG5B,MAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAG7B,MAAA,OAAA,CAAQ,OAAA,EAAS,CAAA,CAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,OAAO,CAAA;AAG9C,MAAA,OAAA,CAAQ,QAAQ,CAAA,CAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,SAAS,cAAc,CAAA;AAC5D,MAAA,OAAA,CAAQ,MAAA,EAAQ,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,MAAM,OAAO,CAAA;AAChD,MAAA,OAAA,CAAQ,MAAA,EAAQ,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,MAAM,OAAO,CAAA;AAIhD,MAAA,OAAA,CAAQ,aAAa,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,SAAS,oBAAoB,CAAA;AAC3E,MAAA,OAAA,CAAQ,cAAc,CAAA,CAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,SAAS,oBAAoB,CAAA;AACzE,MAAA,OAAA,CAAQ,aAAa,CAAA,CAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,SAAS,sBAAsB,CAAA;AACzE,MAAA,OAAA,CAAQ,YAAA,EAAc,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,MAAM,OAAO,CAAA;AACtD,MAAA,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,MAAM,OAAO,CAAA;AACrD,MAAA,OAAA,CAAQ,YAAA,EAAc,CAAA,CAAE,IAAA,EAAM,SAAA,EAAW,MAAM,OAAO,CAAA;AACtD,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA;AAAA,MAC/D;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;;;AC/IA,IAAM,QAAA,GAAW,eAAA;AAMjB,IAAM,gBAAgB,IAAI,MAAA;AAAA,EACxB,4FAAqE,WAAW,CAAA,wBAAA,CAAA;AAAA,EAChF;AACF,CAAA;AAIA,IAAM,eAAe,IAAI,MAAA;AAAA,EACvB,mEAA+C,WAAW,CAAA,wBAAA,CAAA;AAAA,EAC1D;AACF,CAAA;AAMA,IAAM,UAAU,IAAI,MAAA;AAAA,EAClB,2LAAmI,WAAW,CAAA,wFAAA,CAAA;AAAA,EAC9I;AACF,CAAA;AAGA,SAAS,UAAU,GAAA,EAAiC;AAClD,EAAA,MAAM,CAAA,GAAI,kBAAA,CAAmB,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAC5C,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,OAAO,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,EAAG,EAAE,CAAC,CAAC,CAAA,CAAA,CAAA,GAAM,CAAA,CAAE,CAAC,CAAA;AAChC;AAIA,IAAM,WAAA,GAAc,cAAA;AAEpB,IAAM,cAAA,GAAiB,2BAAA;AAKvB,IAAM,mBAAmB,IAAI,MAAA;AAAA,EAC3B,kEAA6D,cAAc,CAAA,0BAAA,CAAA;AAAA,EAC3E;AACF,CAAA;AAGA,IAAM,kBAAkB,IAAI,MAAA;AAAA,EAC1B,iDAA4C,cAAc,CAAA,0BAAA,CAAA;AAAA,EAC1D;AACF,CAAA;AAaO,IAAM,YAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,UAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAAC,QAAA,EAAU,WAAW,CAAA;AAAA,EAChC,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAClC,MAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACrC,MAAA,IAAI,CAAC,KAAA,IAAS,CAAC,KAAA,EAAO;AAEtB,MAAA,MAAM,IAAA,GAAO,CAAC,IAAA,EAAc,SAAA,EAAmB,QAAA,KAAqB;AAClE,QAAA,MAAM,IAAA,GAAO,cAAc,SAAS,CAAA;AACpC,QAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAChC,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,UAAA;AAAA,UACR,SAAA,EAAW,CAAC,QAAQ,CAAA;AAAA,UACpB,OAAA,EAAS,CAAC,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,IAAA,CAAK,IAAA,CAAK,EAAE,CAAA,EAAG,CAAC;AAAA,SAClE,CAAA;AAAA,MACH,CAAA;AAEA,MAAA,IAAI,KAAA,EAAO;AAGT,QAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAC9B,QAAA,IAAI,EAAA,EAAI;AACN,UAAA,MAAM,QAAQ,EAAA,CAAG,CAAC,EACf,KAAA,CAAM,GAAG,EACT,GAAA,CAAI,CAAC,MAAM,SAAA,CAAU,CAAC,CAAC,CAAA,CACvB,MAAA,CAAO,CAAC,CAAA,KAAmB,CAAC,CAAC,CAAC,CAAA;AACjC,UAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,CAAC,CAAA,CACf,MAAM,mBAAmB,CAAA,CACzB,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,OAAO,OAAO,CAAA;AACjB,UAAA,IAAI,MAAM,MAAA,IAAU,CAAA,IAAK,KAAA,CAAM,MAAA,KAAW,MAAM,MAAA,EAAQ;AACtD,YAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,EAAE,EAAE,CAAA;AACpE,YAAA;AAAA,UACF;AAAA,QACF;AAIA,QAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AAIjC,QAAA,aAAA,CAAc,SAAA,GAAY,CAAA;AAC1B,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,EAAG;AAC9C,UAAA,MAAM,QAAQ,CAAA,CAAE,IAAA,CAAK,QAAQ,OAAA,EAAS,CAAA,CAAE,SAAS,CAAC,CAAA;AAClD,UAAA,IAAI,KAAA,IAAS,CAAA,EAAG,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AAClC,UAAA,IAAA,CAAK,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,EAAE,CAAA;AAAA,QAC9B;AAGA,QAAA,YAAA,CAAa,SAAA,GAAY,CAAA;AACzB,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA,EAAG;AAC7C,UAAA,MAAM,KAAA,GAAQ,EAAE,KAAA,IAAS,CAAA;AACzB,UAAA,IAAI,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG;AACzB,UAAA,IAAA,CAAK,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,EAAE,CAAA;AAAA,QAC9B;AAAA,MACF;AAMA,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,gBAAA,CAAiB,SAAA,GAAY,CAAA;AAC7B,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,gBAAgB,CAAA,EAAG;AACjD,UAAA,IAAA,CAAK,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,EAAE,CAAA;AAAA,QAC9B;AACA,QAAA,eAAA,CAAgB,SAAA,GAAY,CAAA;AAC5B,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,eAAe,CAAA,EAAG;AAChD,UAAA,IAAA,CAAK,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,EAAE,CAAA;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACxIA,IAAM,aAAA,GACJ,wFAAA;AAWF,IAAM,YAAA,GACJ,2MAAA;AAGF,IAAMC,UAAAA,GAAY,eAAA;AAKlB,IAAM,gBAAA,GACJ,2FAAA;AACF,IAAM,oBAAA,GAAuB,8BAAA;AAWtB,IAAM,gBAAA,GAAiC;AAAA,EAC5C,EAAA,EAAI,cAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAACA,UAAAA,EAAW,oBAAoB,CAAA;AAAA,EAC1C,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,aAAA,CAAc,SAAA,GAAY,CAAA;AAC1B,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,aAAa,CAAA,EAAG;AAC9C,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,CAAA,CAAE,CAAC,CAAC,CAAA;AAC/B,QAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,cAAA;AAAA,UACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,UAChB,OAAA,EAAS,CAAC,OAAA,CAAQ,IAAA,CAAK,CAAC,GAAG,IAAA,CAAK,CAAC,CAAA,EAAG,cAAc,CAAC;AAAA,SACpD,CAAA;AAAA,MACH;AAMA,MAAA,YAAA,CAAa,SAAA,GAAY,CAAA;AACzB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA,EAAG;AAC7C,QAAA,MAAM,EAAA,GAAK,aAAA,CAAc,CAAA,CAAE,CAAC,CAAC,CAAA;AAC7B,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,CAAA,CAAE,CAAC,CAAC,CAAA;AAC/B,QAAA,MAAM,CAAA,GAAI,EAAE,CAAC,CAAA;AACb,QAAA,IAAI,EAAA,CAAG,MAAA,KAAW,CAAA,IAAK,IAAA,CAAK,WAAW,CAAA,EAAG;AAE1C,QAAA,IAAA,qBAAQ,GAAA,CAAI,CAAC,GAAG,CAAC,CAAA,EAAG,GAAG,CAAC,CAAA,EAAG,KAAK,CAAC,CAAA,EAAG,KAAK,CAAC,CAAC,CAAC,CAAA,EAAE,GAAA,CAAI,CAAC,CAAA,EAAG;AACtD,QAAA,MAAM,MAAA,GAAS,MAAM,EAAA,CAAG,CAAC,CAAC,CAAA,EAAG,EAAA,CAAG,CAAC,CAAC,CAAA,CAAA;AAClC,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,cAAA;AAAA,UACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,UAChB,OAAA,EAAS;AAAA,YACP,QAAQ,EAAA,CAAG,CAAC,GAAG,EAAA,CAAG,CAAC,GAAG,cAAc,CAAA;AAAA,YACpC,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,CAAC,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG;AAAA;AAC1D,SACD,CAAA;AAAA,MACH;AAGA,MAAA,gBAAA,CAAiB,SAAA,GAAY,CAAA;AAC7B,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,gBAAgB,CAAA,EAAG;AACjD,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,CAAA,CAAE,CAAC,CAAC,CAAA;AAC/B,QAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,cAAA;AAAA,UACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,UAChB,OAAA,EAAS,CAAC,OAAA,CAAQ,IAAA,CAAK,CAAC,GAAG,IAAA,CAAK,CAAC,CAAA,EAAG,cAAc,CAAC;AAAA,SACpD,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACnFA,IAAM,GAAA,GAAM,sEAAA;AAQZ,IAAM,MAAA,GAAS,+CAAA;AAUf,IAAM,eAAA,GAAoF;AAAA,EACxF;AAAA,IACE,IAAA,EAAM,UAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,4EAAA;AAAA,MACA,4CAAA;AAAA,MACA,yDAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,yCAAA;AAAA;AAAA,MAEA;AAAA;AACF,GACF;AAAA,EACA;AAAA,IACE,IAAA,EAAM,QAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,wEAAA;AAAA,MACA,8CAAA;AAAA,MACA,2DAAA;AAAA;AAAA,MAEA,uCAAA;AAAA,MACA;AAAA;AACF,GACF;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAME,IAAA,EAAM,UAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,0GAAA;AAAA,MACA,yGAAA;AAAA,MACA,sGAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,oHAAA;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA;AACF,GACF;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAME,IAAA,EAAM,kBAAA;AAAA,IACN,QAAA,EAAU;AAAA,MACR,qGAAA;AAAA,MACA,oGAAA;AAAA,MACA;AAAA;AACF;AAEJ,CAAA;AAMA,IAAMA,UAAAA,GAAY;AAAA,EAChB,iBAAA;AAAA,EACA,mBAAA;AAAA,EACA,iBAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA;AACF,CAAA;AAGA,SAAS,QAAA,CAAS,KAAwB,MAAA,EAAoC;AAC5E,EAAA,MAAM,OAAO,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,MAAM,CAAA;AAC3C,EAAA,OAAO,IAAA,CAAK,WAAW,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA;AACjD;AAeO,IAAM,UAAA,GAA2B;AAAA,EACtC,EAAA,EAAI,QAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAUA,UAAAA;AAAA,EACV,MAAM,GAAA,EAAK;AAGT,IAAA,MAAM,QAAA,GAAW,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AACrC,IAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAC1C,IAAA,MAAM,GAAA,GAAM,QAAA,GACR,CAAC,QAAA,CAAS,CAAC,GAAG,QAAA,CAAS,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,IACtC,UAAA,GACE,CAAC,UAAA,CAAW,CAAC,CAAA,EAAG,UAAA,CAAW,CAAC,CAAA,EAAG,UAAA,CAAW,CAAC,CAAC,CAAA,GAC5C,IAAA;AACN,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAKlB,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,KAAA,MAAW,MAAM,eAAA,EAAiB;AAChC,QAAA,KAAA,MAAW,EAAA,IAAM,GAAG,QAAA,EAAU;AAC5B,UAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,UAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,EAAG;AACnC,YAAA,MAAM,IAAA,GAAO,EAAE,CAAC,CAAA;AAChB,YAAA,MAAM,IAAA,GAAO,EAAE,CAAC,CAAA;AAEhB,YAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,IAAI,CAAA,EAAG;AAIzB,YAAA,IAAI,GAAA,CAAI,QAAA,CAAS,IAAI,CAAA,EAAG;AACxB,YAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,EAAK,IAAI,CAAA;AAC9B,YAAA,IAAI,CAAC,GAAA,EAAK;AAEV,YAAA,MAAM,MAAM,CAAA,EAAG,IAAI,IAAI,IAAI,CAAA,CAAA,EAAI,GAAG,IAAI,CAAA,CAAA;AACtC,YAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,YAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,YAAA,UAAA,CAAW,IAAA,CAAK,EAAE,QAAA,EAAU,CAAA,CAAE,EAAA,EAAI,IAAA,EAAM,EAAA,CAAG,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,GAAA,EAAK,CAAA;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAMA,IAAA,MAAM,SAAA,uBAAgB,GAAA,EAAoB;AAC1C,IAAA,KAAA,MAAW,EAAA,IAAM,UAAA,EAAY,SAAA,CAAU,GAAA,CAAI,EAAA,CAAG,IAAA,EAAA,CAAO,SAAA,CAAU,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAErF,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,MAAM,UAAA,EAAY;AAC3B,MAAA,IAAA,CAAK,UAAU,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA,IAAK,KAAK,CAAA,EAAG;AAEvC,MAAA,IAAI,WAAA;AACJ,MAAA,IAAI,EAAA,CAAG,SAAS,UAAA,EAAY;AAC1B,QAAA,WAAA,GAAc,QAAA,CAAS,EAAA,CAAG,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,EAAA,CAAG,IAAA,EAAM,MAAA,EAAQ,EAAA,CAAG,GAAA,EAAK,CAAA;AAAA,MACrF,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,QAAA,EAAU;AAC/B,QAAA,WAAA,GAAc,QAAA,CAAS,GAAG,IAAA,EAAM,EAAE,MAAM,UAAA,EAAY,EAAA,EAAI,EAAA,CAAG,GAAA,EAAK,CAAA;AAAA,MAClE,CAAA,MAAA,IAAW,EAAA,CAAG,IAAA,KAAS,kBAAA,EAAoB;AACzC,QAAA,WAAA,GAAc,QAAA,CAAS,GAAG,IAAA,EAAM;AAAA,UAC9B,IAAA,EAAM,2BAAA;AAAA,UACN,MAAM,EAAA,CAAG,IAAA;AAAA,UACT,QAAQ,EAAA,CAAG;AAAA,SACZ,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,WAAA,GAAc,QAAA,CAAS,GAAG,IAAA,EAAM;AAAA,UAC9B,IAAA,EAAM,mBAAA;AAAA,UACN,MAAM,EAAA,CAAG,IAAA;AAAA,UACT,QAAQ,EAAA,CAAG;AAAA,SACZ,CAAA;AAAA,MACH;AAEA,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,QAAA;AAAA,QACR,SAAA,EAAW,CAAC,EAAA,CAAG,QAAQ,CAAA;AAAA,QACvB,OAAA,EAAS,CAAC,WAAA,EAAa,OAAA,CAAQ,GAAG,IAAA,EAAM,EAAA,CAAG,IAAA,EAAM,SAAS,CAAC;AAAA,OAC5D,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AC/MA,IAAMC,IAAAA,GAAM,sEAAA;AAMZ,IAAMC,OAAAA,GAAS,+CAAA;AAKf,IAAMF,UAAAA,GAAY;AAAA,EAChB,iBAAA;AAAA,EACA,MAAA;AAAA,EACA,sBAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAIA,IAAM,MAAA,GACJ,0EAAA;AAEF,IAAM,MAAA,GACJ,4DAAA;AAKF,IAAM,WAAA,GAAc,0CAAA;AAWpB,IAAM,WAAA,GACJ,iFAAA;AACF,IAAM,WAAA,GACJ,6DAAA;AAGF,IAAM,WAAA,GACJ,mEAAA;AAGF,SAAS,MAAA,CAAO,KAAwB,MAAA,EAA0B;AAChE,EAAA,OAAO,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,MAAM,CAAA;AACvC;AAcO,IAAM,sBAAA,GAAuC;AAAA,EAClD,EAAA,EAAI,oBAAA;AAAA;AAAA;AAAA,EAGJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAUA,UAAAA;AAAA,EACV,MAAM,GAAA,EAAK;AAIT,IAAA,MAAM,QAAA,GAAWC,IAAAA,CAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AACrC,IAAA,MAAM,UAAA,GAAaC,OAAAA,CAAO,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAC1C,IAAA,MAAM,GAAA,GAAM,QAAA,GACR,CAAC,QAAA,CAAS,CAAC,GAAG,QAAA,CAAS,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,IACtC,UAAA,GACE,CAAC,UAAA,CAAW,CAAC,CAAA,EAAG,UAAA,CAAW,CAAC,CAAA,EAAG,UAAA,CAAW,CAAC,CAAC,CAAA,GAC5C,IAAA;AAEN,IAAA,MAAM,OAAc,EAAC;AACrB,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAE7B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAE3B,MAAA,MAAA,CAAO,SAAA,GAAY,CAAA;AACnB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG;AACvC,QAAA,IAAI,WAAA,CAAY,KAAK,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG;AAChD,QAAA,MAAM,CAAC,EAAA,EAAI,MAAA,EAAQ,EAAE,IAAI,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAC1C,QAAA,MAAM,MAAM,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,MAAM,IAAI,EAAE,CAAA,CAAA;AACjC,QAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,QAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,QAAA,IAAA,CAAK,IAAA,CAAK,EAAE,QAAA,EAAU,CAAA,CAAE,IAAI,EAAA,EAAI,MAAA,EAAQ,IAAI,CAAA;AAAA,MAC9C;AAKA,MAAA,MAAA,CAAO,SAAA,GAAY,CAAA;AACnB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,EAAG;AACvC,QAAA,IAAI,WAAA,CAAY,KAAK,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG;AAChD,QAAA,MAAM,MAAA,GAAS,EAAE,CAAC,CAAA;AAClB,QAAA,IAAI,CAAC,GAAA,EAAK;AACV,QAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3B,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,EAAK,MAAM,CAAA;AAC/B,QAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,QAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,IAAA;AACjB,QAAA,MAAM,MAAM,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,MAAM,IAAI,EAAE,CAAA,CAAA;AACjC,QAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,QAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,QAAA,IAAA,CAAK,IAAA,CAAK,EAAE,QAAA,EAAU,CAAA,CAAE,IAAI,EAAA,EAAI,MAAA,EAAQ,IAAI,CAAA;AAAA,MAC9C;AAIA,MAAA,KAAA,MAAW,EAAA,IAAM,CAAC,WAAA,EAAa,WAAW,CAAA,EAAG;AAC3C,QAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,EAAG;AACnC,UAAA,MAAM,CAAC,EAAA,EAAI,MAAA,EAAQ,EAAE,IAAI,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAC1C,UAAA,MAAM,MAAM,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,MAAM,IAAI,EAAE,CAAA,CAAA;AACjC,UAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,UAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,UAAA,IAAA,CAAK,IAAA,CAAK,EAAE,QAAA,EAAU,CAAA,CAAE,IAAI,EAAA,EAAI,MAAA,EAAQ,IAAI,CAAA;AAAA,QAC9C;AAAA,MACF;AAGA,MAAA,WAAA,CAAY,SAAA,GAAY,CAAA;AACxB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA,EAAG;AAC5C,QAAA,MAAM,MAAA,GAAS,EAAE,CAAC,CAAA;AAClB,QAAA,IAAI,CAAC,GAAA,EAAK;AACV,QAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AAC3B,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,EAAK,MAAM,CAAA;AAC/B,QAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,QAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,IAAA;AACjB,QAAA,MAAM,MAAM,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,MAAM,IAAI,EAAE,CAAA,CAAA;AACjC,QAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,QAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,QAAA,IAAA,CAAK,IAAA,CAAK,EAAE,QAAA,EAAU,CAAA,CAAE,IAAI,EAAA,EAAI,MAAA,EAAQ,IAAI,CAAA;AAAA,MAC9C;AAAA,IACF;AAEA,IAAA,OAAO,IAAA,CAAK,GAAA,CAAe,CAAC,CAAA,MAAO;AAAA,MACjC,MAAA,EAAQ,oBAAA;AAAA,MACR,SAAA,EAAW,CAAC,CAAA,CAAE,QAAQ,CAAA;AAAA,MACtB,OAAA,EAAS;AAAA,QACP,QAAA,CAAS,CAAA,GAAA,EAAM,CAAA,CAAE,EAAE,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA,EAAG,CAAA,CAAE,EAAE,CAAA,CAAA,EAAI,eAAA,EAAiB;AAAA,UACxD,IAAI,CAAA,CAAE,EAAA;AAAA,UACN,QAAQ,CAAA,CAAE,MAAA;AAAA,UACV,IAAI,CAAA,CAAE;AAAA,SACP;AAAA;AACH,KACF,CAAE,CAAA;AAAA,EACJ;AACF,CAAA;;;ACvKA,IAAMC,MAAAA,GAAQ,oCAAA;AAMd,IAAMC,SAAAA,GAAW,gDAAA;AAIjB,IAAM,WAAA,GAAc,iCAAA;AAEpB,IAAM,QAAA,GAAW,gCAAA;AAEjB,IAAM,SAAA,GAAY,kCAAA;AAElB,IAAM,WAAA,GAAc,gCAAA;AAEpB,IAAM,eAAA,GAAkB,wCAAA;AAOxB,IAAM,cAAA,GAAiB,uCAAA;AACvB,IAAM,WAAA,GAAc,iDAAA;AACpB,IAAM,YAAA,GAAe,kDAAA;AACrB,IAAM,cAAA,GAAiB,8CAAA;AAGvB,SAAS,SAAA,CAAU,MAAc,EAAA,EAAgC;AAC/D,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA;AACtB,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,CAAA,CAAE,QAAQ,CAAA,CAAE,CAAC,EAAE,MAAM,CAAA;AAE7C,EAAA,MAAM,KAAA,GAAQ,oDAAA,CAAqD,IAAA,CAAK,IAAI,CAAA;AAC5E,EAAA,OAAO,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA;AAC5B;AAGA,SAAS,UAAA,CAAW,MAAc,EAAA,EAAgC;AAChE,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA;AACtB,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,KAAK,CAAA;AAEpC,EAAA,MAAM,EAAA,GAAK,kCAAA,CAAmC,IAAA,CAAK,MAAM,CAAA;AACzD,EAAA,OAAO,EAAA,GAAK,EAAA,CAAG,CAAC,CAAA,GAAI,MAAA;AACtB;AAEA,SAAS,WAAA,CAAY,MAAc,EAAA,EAAgC;AACjE,EAAA,OAAO,WAAW,IAAA,EAAM,EAAE,CAAA,IAAK,SAAA,CAAU,MAAM,EAAE,CAAA;AACnD;AAIA,SAAS,iBAAA,CAAkB,MAAc,EAAA,EAAgC;AACvE,EAAA,MAAM,MAAA,GAAS,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AACxC,EAAA,IAAI,MAAA,EAAQ,OAAO,MAAA,CAAO,CAAC,CAAA;AAC3B,EAAA,OAAO,SAAA,CAAU,MAAM,EAAE,CAAA;AAC3B;AAMA,SAAS,YAAA,CAAa,MAAc,EAAA,EAAgC;AAClE,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA;AACtB,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,KAAK,CAAA;AAEpC,EAAA,MAAM,EAAA,GAAK,6CAAA,CAA8C,IAAA,CAAK,MAAM,CAAA;AACpE,EAAA,OAAO,EAAA,GAAK,EAAA,CAAG,CAAC,CAAA,GAAI,MAAA;AACtB;AAMA,SAAS,WAAA,CAAY,MAAc,EAAA,EAAgC;AACjE,EAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA;AACtB,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,CAAA,CAAE,QAAQ,CAAA,CAAE,CAAC,EAAE,MAAM,CAAA;AAC7C,EAAA,MAAM,KAAA,GAAQ,0BAAA,CAA2B,IAAA,CAAK,IAAI,CAAA;AAClD,EAAA,OAAO,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA;AAC5B;AAEA,SAAS,aAAA,CAAc,MAAc,EAAA,EAAgC;AACnE,EAAA,OAAO,aAAa,IAAA,EAAM,EAAE,CAAA,IAAK,WAAA,CAAY,MAAM,EAAE,CAAA;AACvD;AAaA,SAAS,aAAa,IAAA,EAAwB;AAC5C,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAAD,OAAM,SAAA,GAAY,CAAA;AAClB,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,CAAA,GAAIA,MAAAA,CAAM,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACtC,IAAA,IAAA,CAAK,KAAK,EAAE,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAC,GAAG,KAAA,EAAO,CAAA,CAAE,OAAO,CAAA;AAAA,EACvD;AACA,EAAAC,UAAS,SAAA,GAAY,CAAA;AACrB,EAAA,OAAA,CAAQ,CAAA,GAAIA,SAAAA,CAAS,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACzC,IAAA,IAAA,CAAK,KAAK,EAAE,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAC,GAAG,KAAA,EAAO,CAAA,CAAE,OAAO,CAAA;AAAA,EACvD;AACA,EAAA,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACrC,EAAA,OAAO,IAAA;AACT;AAMA,SAAS,YAAY,IAAA,EAA0B;AAC7C,EAAA,OAAO,aAAa,IAAI,CAAA,CAAE,IAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AAC5C;AASA,SAAS,eAAA,CACP,UAAA,EACA,OAAA,EACA,gBAAA,EACsB;AACtB,EAAA,MAAM,QAAA,GAAW,aAAa,UAAU,CAAA;AACxC,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AAGvB,IAAA,IAAI,IAAA;AACJ,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,MAAA,MAAM,MAAM,CAAA,CAAE,KAAA;AAEd,MAAA,MAAM,QAAQ,GAAA,IAAO,OAAA;AACrB,MAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,MAAM,OAAO,CAAA,IAAK,QAAQ,CAAA,GAAI,GAAA,CAAA;AACpD,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,GAAO,IAAA,CAAK,IAAA,SAAa,EAAE,GAAA,EAAK,CAAA,CAAE,GAAA,EAAK,IAAA,EAAK;AAAA,IAC3D;AACA,IAAA,OAAO,IAAA,EAAM,GAAA;AAAA,EACf;AACA,EAAA,OAAO,gBAAA;AACT;AAMO,IAAM,WAAA,GAA4B;AAAA,EACvC,EAAA,EAAI,SAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU;AAAA,IACR,WAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA,WAAA;AAAA,IACA,YAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA,MAAM,GAAA,EAAK;AAIT,IAAA,MAAM,MAAA,GAAS,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA;AACtC,IAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAC,CAAA;AACtD,IAAA,MAAM,mBAAmB,QAAA,CAAS,IAAA,KAAS,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAI,MAAA;AAG3D,IAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,EAAc,EAAA,KAAqC;AAChE,MAAA,MAAM,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA;AACtB,MAAA,MAAM,OAAA,GAAU,CAAA,GAAI,CAAA,CAAE,KAAA,GAAQ,CAAA;AAC9B,MAAA,OAAO,eAAA,CAAgB,IAAA,EAAM,OAAA,EAAS,gBAAgB,CAAA;AAAA,IACxD,CAAA;AAEA,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,UAAU,EAAC;AAEjB,MAAA,IAAI,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC5B,QAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAA,CAAE,IAAA,EAAM,WAAW,CAAA;AAC5C,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,WAAW,CAAA;AACpC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,CAAC,CAAA;AAAA,MACvE;AACA,MAAA,IAAI,QAAA,CAAS,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AACzB,QAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAA,CAAE,IAAA,EAAM,QAAQ,CAAA;AACzC,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,QAAQ,CAAA;AACjC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,CAAC,CAAA;AAAA,MAC1E;AAGA,MAAA,IAAI,SAAA,CAAU,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC1B,QAAA,MAAM,IAAA,GAAO,iBAAA,CAAkB,CAAA,CAAE,IAAA,EAAM,SAAS,CAAA;AAChD,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,SAAS,CAAA;AAClC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,CAAC,CAAA;AAAA,MAC3E,CAAA,MAAA,IAAW,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AACnC,QAAA,MAAM,IAAA,GAAO,iBAAA,CAAkB,CAAA,CAAE,IAAA,EAAM,WAAW,CAAA;AAClD,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,WAAW,CAAA;AACpC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,CAAC,CAAA;AAAA,MACvE;AAOA,MAAA,IAAI,cAAA,CAAe,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC/B,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,CAAA,CAAE,IAAA,EAAM,cAAc,CAAA;AACjD,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,cAAc,CAAA;AACvC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,CAAC,CAAA;AAAA,MACvE;AACA,MAAA,IAAI,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC5B,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,CAAA,CAAE,IAAA,EAAM,WAAW,CAAA;AAC9C,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,WAAW,CAAA;AACpC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,CAAC,CAAA;AAAA,MAC1E;AACA,MAAA,IAAI,YAAA,CAAa,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC7B,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,CAAA,CAAE,IAAA,EAAM,YAAY,CAAA;AAC/C,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,YAAY,CAAA;AACrC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,CAAC,CAAA;AAAA,MAC3E;AACA,MAAA,IAAI,cAAA,CAAe,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC/B,QAAA,MAAM,IAAA,GAAO,aAAA,CAAc,CAAA,CAAE,IAAA,EAAM,cAAc,CAAA;AACjD,QAAA,MAAM,EAAA,GAAK,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,cAAc,CAAA;AACvC,QAAA,IAAI,IAAA,IAAQ,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,CAAC,CAAA;AAAA,MACvE;AAEA,MAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,QAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA;AAAA,MAC5D;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AC3OA,IAAMJ,aAAY,IAAI,MAAA;AAAA,EACpB,uDACE,QAAA,GACA,0DAAA;AAAA,EACF;AACF,CAAA;AAIA,IAAM,YAAA,GAAe,qCAAA;AAIrB,IAAM,IAAA,GAAO,QAAQ,QAAA,GAAW,4EAAA;AAChC,IAAM,IAAA,GAAO,sDAAA;AAGb,IAAM,SAAA,GAAY,CAAA,gFAAA,EAAgE,IAAI,CAAA,IAAA,EAAO,IAAI,CAAA,CAAA;AAEjG,IAAM,YAAY,CAAA,4BAAA,EAAuB,QAAQ,CAAA,mHAAA,EAAuF,IAAI,OAAO,IAAI,CAAA,CAAA;AAIvJ,IAAM,UAAU,IAAI,MAAA;AAAA,EAClB,oGAAwE,SAAS,CAAA,CAAA,EAAI,SAAS,CAAA,sDAAA,EAA4C,IAAI,OAAO,IAAI,CAAA,CAAA;AAAA,EACzJ;AACF,CAAA;AAIA,IAAM,MAAA,GAAS,IAAI,MAAA,CAAO,CAAA,GAAA,EAAM,SAAS,CAAA,KAAA,EAAQ,SAAS,KAAK,IAAI,CAAA;AAOnE,IAAM,UAAA,GAAa,wDAAA;AACnB,IAAM,UAAA,GAAa,gDAAA;AACnB,IAAM,eAAe,IAAI,MAAA;AAAA,EACvB,aACE,0MAAA,GAEA,UAAA;AAAA,EACF;AACF,CAAA;AACA,IAAM,eAAe,IAAI,MAAA;AAAA,EACvB,aACE,+RAAA,GAEA,UAAA;AAAA,EACF;AACF,CAAA;AAGA,SAAS,WAAW,IAAA,EAAwB;AAC1C,EAAA,OAAO,KACJ,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,IAAA,MAAM,EAAA,GAAK,kBAAA,CAAmB,IAAA,CAAK,CAAA,CAAE,MAAM,CAAA;AAC3C,IAAA,OAAO,EAAA,GAAM,EAAA,CAAG,CAAC,CAAA,GAAI,CAAA,EAAG,EAAA,CAAG,CAAC,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA,CAAG,CAAC,CAAA,GAAK,EAAA;AAAA,EAC9C,CAAC,CAAA,CACA,MAAA,CAAO,OAAO,CAAA;AACnB;AAQA,IAAM,YAAY,IAAI,MAAA;AAAA,EACpB,CAAA,qQAAA,CAAA;AAAA,EACA;AACF,CAAA;AAGA,IAAM,UAAA,GAAa,8BAAA;AAEnB,IAAM,WAAA,GAAc,4BAAA;AAQpB,IAAM,OAAA,GAAU,yDAAA;AAIhB,IAAM,YAAA,GAAe,uEAAuE,OAAO,CAAA,CAAA;AAGnG,IAAM,YAAA,GAAe,gGAAgG,OAAO,CAAA,CAAA;AAI5H,IAAM,SAAA,GAAY,IAAI,MAAA,CAAO,CAAA,GAAA,EAAM,YAAY,CAAA,KAAA,EAAQ,YAAY,KAAK,IAAI,CAAA;AAQ5E,IAAM,eAAe,IAAI,MAAA;AAAA,EACvB,CAAA,mKAAA,CAAA;AAAA,EACA;AACF,CAAA;AAIA,IAAM,cAAA,GAAiB,8CAAA;AAavB,SAAS,UAAU,IAAA,EAAsB;AACvC,EAAA,MAAM,MAAc,EAAC;AACrB,EAAA,MAAM,WAAoC,EAAC;AAK3C,EAAA,KAAA,MAAW,EAAA,IAAM,CAAC,YAAA,EAAc,YAAY,CAAA,EAAG;AAC7C,IAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,IAAA,KAAA,MAAWK,GAAAA,IAAM,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,EAAG;AAClC,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAWA,GAAAA,CAAG,CAAC,CAAC,CAAA;AAC9B,MAAA,MAAM,IAAA,GAAOA,IAAG,CAAC,CAAA;AACjB,MAAA,MAAM,KAAA,GAAQA,GAAAA,CAAG,CAAC,CAAA,CAAE,MAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,OAAO,OAAO,CAAA;AAClE,MAAA,IAAI,MAAM,MAAA,GAAS,CAAA,IAAK,KAAA,CAAM,MAAA,KAAW,MAAM,MAAA,EAAQ;AAGvD,MAAA,KAAA,CAAM,QAAQ,CAAC,IAAA,EAAM,CAAA,KAAM,GAAA,CAAI,KAAK,EAAE,IAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,MAAM,CAAC,CAAA,EAAG,WAAA,EAAa,IAAA,EAAM,CAAC,CAAA;AACxF,MAAA,QAAA,CAAS,IAAA,CAAK,CAACA,GAAAA,CAAG,KAAA,IAAS,CAAA,EAAA,CAAIA,GAAAA,CAAG,KAAA,IAAS,CAAA,IAAKA,GAAAA,CAAG,CAAC,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,IAC/D;AAAA,EACF;AAGA,EAAA,OAAA,CAAQ,SAAA,GAAY,CAAA;AACpB,EAAA,IAAI,EAAA;AACJ,EAAA,OAAA,CAAQ,EAAA,GAAK,OAAA,CAAQ,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACzC,IAAA,IAAI,UAAA,CAAW,KAAK,IAAA,CAAK,KAAA,CAAM,GAAG,EAAA,CAAG,KAAK,CAAC,CAAA,EAAG;AAC9C,IAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,CAAC,CAAA,IAAK,GAAG,CAAC,CAAA;AAC3B,IAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,CAAC,CAAA,IAAK,GAAG,CAAC,CAAA;AAC3B,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,IAAA,EAAM,EAAA,CAAG,CAAC,GAAG,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,CAAA;AACpD,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,IAAA,EAAM,EAAA,CAAG,CAAC,CAAA,EAAG,IAAA,EAAM,EAAA,CAAG,CAAC,CAAA,EAAG,MAAA,EAAQ,EAAA,CAAG,CAAC,GAAG,CAAA;AACpD,IAAA,QAAA,CAAS,IAAA,CAAK,CAAC,EAAA,CAAG,KAAA,EAAO,EAAA,CAAG,QAAQ,EAAA,CAAG,CAAC,CAAA,CAAE,MAAM,CAAC,CAAA;AAAA,EACnD;AAGA,EAAA,MAAA,CAAO,SAAA,GAAY,CAAA;AACnB,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AACvC,IAAA,MAAM,QAAQ,CAAA,CAAE,KAAA;AAChB,IAAA,IAAI,QAAA,CAAS,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,KAAA,IAAS,CAAA,IAAK,KAAA,GAAQ,CAAC,CAAA,EAAG;AACxD,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAClC,IAAA,IAAI,UAAA,CAAW,IAAA,CAAK,MAAM,CAAA,EAAG;AAC7B,IAAA,MAAM,EAAA,GAAK,WAAA,CAAY,IAAA,CAAK,MAAM,CAAA;AAClC,IAAA,IAAI,CAAC,EAAA,EAAI;AACT,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,IAAA,EAAM,EAAA,CAAG,CAAC,CAAA,EAAG,IAAA,EAAM,EAAE,CAAC,CAAA,IAAK,EAAE,CAAC,CAAA,EAAG,QAAQ,CAAA,CAAE,CAAC,KAAK,CAAA,CAAE,CAAC,GAAG,CAAA;AAAA,EACpE;AAGA,EAAA,SAAA,CAAU,SAAA,GAAY,CAAA;AACtB,EAAA,IAAI,EAAA;AACJ,EAAA,OAAA,CAAQ,EAAA,GAAK,SAAA,CAAU,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AAC3C,IAAA,MAAM,IAAA,GAAO,GAAG,CAAC,CAAA;AACjB,IAAA,MAAM,IAAA,GAAO,GAAG,CAAC,CAAA;AACjB,IAAA,MAAM,MAAA,GAAS,GAAG,CAAC,CAAA;AACnB,IAAA,MAAM,EAAA,GAAK,GAAG,CAAC,CAAA;AACf,IAAA,IAAI,EAAA,IAAM,OAAO,IAAA,EAAM;AACvB,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3B,IAAA,GAAA,CAAI,KAAK,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,QAAQ,CAAA;AAAA,EACvC;AAKA,EAAA,SAAA,CAAU,SAAA,GAAY,CAAA;AACtB,EAAA,IAAI,EAAA;AACJ,EAAA,OAAA,CAAQ,EAAA,GAAK,SAAA,CAAU,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AAC3C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,GAAG,KAAK,CAAA;AACrC,IAAA,MAAM,EAAA,GAAK,cAAA,CAAe,IAAA,CAAK,MAAM,CAAA;AACrC,IAAA,IAAI,CAAC,EAAA,EAAI;AACT,IAAA,MAAM,IAAA,GAAO,EAAA,CAAG,CAAC,CAAA,IAAK,GAAG,CAAC,CAAA;AAC1B,IAAA,MAAM,MAAA,GAAS,EAAA,CAAG,CAAC,CAAA,IAAK,GAAG,CAAC,CAAA;AAC5B,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,IAAA,EAAM,EAAA,CAAG,CAAC,CAAA,EAAG,IAAA,EAAM,QAAQ,CAAA;AAAA,EACxC;AAIA,EAAA,YAAA,CAAa,SAAA,GAAY,CAAA;AACzB,EAAA,IAAI,EAAA;AACJ,EAAA,OAAA,CAAQ,EAAA,GAAK,YAAA,CAAa,IAAA,CAAK,IAAI,OAAO,IAAA,EAAM;AAC9C,IAAA,MAAM,IAAA,GAAO,GAAG,CAAC,CAAA;AACjB,IAAA,MAAM,IAAA,GAAO,GAAG,CAAC,CAAA;AACjB,IAAA,MAAM,MAAA,GAAS,GAAG,CAAC,CAAA;AACnB,IAAA,MAAM,EAAA,GAAK,GAAG,CAAC,CAAA;AACf,IAAA,IAAI,EAAA,IAAM,OAAO,IAAA,EAAM;AACvB,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3B,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,IAAA,EAAM,IAAA,EAAM,MAAM,MAAA,EAAQ,WAAA,EAAa,MAAM,CAAA;AAAA,EAC1D;AACA,EAAA,OAAO,GAAA;AACT;AAMO,IAAM,YAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,UAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAACL,UAAAA,EAAW,YAAY,CAAA;AAAA,EAClC,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAC7B,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AAIvB,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA,KAAM;AAClC,QAAA,MAAM,GAAA,GAAM,QAAA,CAAS,CAAA,CAAE,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,MAAA,EAAQ,CAAA,CAAE,QAAQ,CAAA;AACjF,QAAA,OAAO,CAAA,CAAE,WAAA,GAAc,CAAC,GAAA,EAAK,OAAA,CAAQ,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,SAAS,CAAC,CAAA,GAAI,CAAC,GAAG,CAAA;AAAA,MACzE,CAAC,CAAA;AACD,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,UAAA,EAAY,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA;AAAA,IAC7D;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AClOA,IAAM,wBAAwB,IAAI,MAAA;AAAA,EAChC,SAAA,GACE,gJAAA;AAAA,EACF;AACF,CAAA;AAIA,IAAM,mBAAmB,IAAI,MAAA;AAAA,EAC3B,SAAA,GAAY,wFAAA;AAAA,EACZ;AACF,CAAA;AAKA,IAAM,aAAA,GAAgB,sCAAA;AAGtB,IAAM,qBAAA,GAAwB,gDAAA;AAOvB,IAAM,eAAA,GAAkB,CAAA;AAK/B,IAAM,4BAAA,GAA+B,mCAAA;AAQrC,IAAM,+BAA+B,IAAI,MAAA;AAAA,EACvC,SAAA,GACE,6IAAA;AAAA,EACF;AACF,CAAA;AAWA,IAAM,gBAAA,GACJ,gGAAA;AACF,IAAM,MAAA,GAAS,2BAAA;AAIf,IAAM,iBAAiB,IAAI,MAAA;AAAA,EACzB,mBAAmB,MAAA,GAAS,+BAAA;AAAA,EAC5B;AACF,CAAA;AAKA,IAAM,wBAAwB,IAAI,MAAA;AAAA,EAChC,mBAAmB,MAAA,GAAS,4BAAA;AAAA,EAC5B;AACF,CAAA;AAIA,IAAM,sBAAsB,IAAI,MAAA;AAAA,EAC9B,mBAAmB,MAAA,GAAS,2CAAA;AAAA,EAC5B;AACF,CAAA;AAGA,IAAM,YAAA,GAAe,IAAI,MAAA,CAAO,gBAAA,EAAkB,GAAG,CAAA;AAGrD,SAAS,SAAS,GAAA,EAAqB;AACrC,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,GAAG,CAAC,CAAA;AACrC;AAQA,SAAS,wBAAA,CAAyB,SAAiB,MAAA,EAAyB;AAK1E,EAAA,MAAM,GAAA,GAAM,+EAAA;AAGZ,EAAA,MAAM,QAAQ,IAAI,MAAA;AAAA,IAChB,CAAA,EAAG,GAAG,CAAA,yEAAA,EAA0D,MAAM,CAAA,SAAA,CAAA;AAAA,IACtE;AAAA,GACF;AAKA,EAAA,MAAM,SAAS,IAAI,MAAA;AAAA,IACjB,CAAA,OAAA,EAAU,MAAM,CAAA,4BAAA,EAA+B,GAAG,CAAA,CAAA;AAAA,IAClD;AAAA,GACF;AACA,EAAA,OAAO,MAAM,IAAA,CAAK,OAAO,CAAA,IAAK,MAAA,CAAO,KAAK,OAAO,CAAA;AACnD;AAGA,SAAS,iBAAA,CACP,SACA,MAAA,EACoB;AACpB,EAAA,MAAM,OAAO,IAAI,MAAA,CAAO,CAAA,OAAA,EAAU,MAAM,aAAa,GAAG,CAAA;AACxD,EAAA,KAAA,MAAW,CAAA,IAAK,SAAS,IAAI,IAAA,CAAK,KAAK,CAAA,CAAE,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,EAAA;AACzD,EAAA,OAAO,MAAA;AACT;AAEO,IAAM,gBAAA,GAAiC;AAAA,EAC5C,EAAA,EAAI,cAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU;AAAA,IACR,qBAAA;AAAA,IACA,gBAAA;AAAA,IACA,yBAAA;AAAA,IACA,gCAAA;AAAA;AAAA,IACA,gCAAA;AAAA;AAAA,IACA;AAAA;AAAA,GACF;AAAA,EACA,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAG1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAI3B,MAAA,MAAM,YAAA,GAAe,aAAA,CAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAC9C,MAAA,IAAI,CAAC,YAAA,EAAc;AACjB,QAAA,gBAAA,CAAiB,SAAA,GAAY,CAAA;AAC7B,QAAA,IAAI,EAAA;AACJ,QAAA,OAAA,CAAQ,KAAK,gBAAA,CAAiB,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AACpD,UAAA,MAAM,MAAA,GAAS,GAAG,CAAC,CAAA;AACnB,UAAA,MAAM,OAAA,GAAU,GAAG,CAAC,CAAA;AACpB,UAAA,GAAA,CAAI,IAAA,CAAK;AAAA,YACP,MAAA,EAAQ,cAAA;AAAA,YACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,YAChB,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,iBAAiB,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAC;AAAA,WACnE,CAAA;AAAA,QACH;AAAA,MACF;AAKA,MAAA,qBAAA,CAAsB,SAAA,GAAY,CAAA;AAClC,MAAA,IAAI,GAAA;AACJ,MAAA,OAAA,CAAQ,MAAM,qBAAA,CAAsB,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AAC1D,QAAA,MAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AACpB,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,CAAC,CAAC,CAAA;AAC9B,QAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC7C,QAAA,IAAI,wBAAA,CAAyB,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA,EAAG;AACnD,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,cAAA;AAAA,UACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,UAChB,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,gBAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAC;AAAA,SACjE,CAAA;AAAA,MACH;AAKA,MAAA,IAAI,CAAC,uBAAA,CAAwB,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AACzC,QAAA,4BAAA,CAA6B,SAAA,GAAY,CAAA;AACzC,QAAA,IAAI,GAAA;AACJ,QAAA,OAAA,CAAQ,MAAM,4BAAA,CAA6B,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AACjE,UAAA,MAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AACpB,UAAA,IAAI,wBAAA,CAAyB,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA,EAAG;AACnD,UAAA,GAAA,CAAI,IAAA,CAAK;AAAA,YACP,MAAA,EAAQ,cAAA;AAAA,YACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,YAChB,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,cAAA,EAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,eAAA,EAAiB,CAAC;AAAA,WAClF,CAAA;AAAA,QACH;AAAA,MACF;AAKA,MAAA,IAAI,CAAC,gCAAA,CAAiC,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAElD,QAAA,mBAAA,CAAoB,SAAA,GAAY,CAAA;AAChC,QAAA,IAAI,GAAA;AACJ,QAAA,OAAA,CAAQ,MAAM,mBAAA,CAAoB,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AACxD,UAAA,MAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AACpB,UAAA,MAAM,OAAA,GAAU,IAAI,CAAC,CAAA;AACrB,UAAA,GAAA,CAAI,IAAA,CAAK;AAAA,YACP,MAAA,EAAQ,cAAA;AAAA,YACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,YAChB,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,iBAAiB,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAC;AAAA,WACnE,CAAA;AAAA,QACH;AAGA,QAAA,cAAA,CAAe,SAAA,GAAY,CAAA;AAC3B,QAAA,IAAI,GAAA;AACJ,QAAA,OAAA,CAAQ,MAAM,cAAA,CAAe,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AACnD,UAAA,MAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AACpB,UAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,CAAC,CAAC,CAAA;AAC9B,UAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC7C,UAAA,GAAA,CAAI,IAAA,CAAK;AAAA,YACP,MAAA,EAAQ,cAAA;AAAA,YACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,YAChB,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,gBAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAC;AAAA,WACjE,CAAA;AAAA,QACH;AAGA,QAAA,qBAAA,CAAsB,SAAA,GAAY,CAAA;AAClC,QAAA,IAAI,GAAA;AACJ,QAAA,OAAA,CAAQ,MAAM,qBAAA,CAAsB,IAAA,CAAK,CAAA,CAAE,IAAI,OAAO,IAAA,EAAM;AAC1D,UAAA,MAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AACpB,UAAA,GAAA,CAAI,IAAA,CAAK;AAAA,YACP,MAAA,EAAQ,cAAA;AAAA,YACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,YAChB,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,cAAA,EAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,eAAA,EAAiB,CAAC;AAAA,WAClF,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,IAAA,qBAAA,CAAsB,SAAA,GAAY,CAAA;AAClC,IAAA,IAAI,EAAA;AACJ,IAAA,OAAA,CAAQ,KAAK,qBAAA,CAAsB,IAAA,CAAK,GAAA,CAAI,OAAO,OAAO,IAAA,EAAM;AAC9D,MAAA,MAAM,MAAA,GAAS,GAAG,CAAC,CAAA;AACnB,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,EAAA,CAAG,CAAC,CAAC,CAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC7C,MAAA,IAAI,wBAAA,CAAyB,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA,EAAG;AACnD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA;AACtD,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,cAAA;AAAA,QACR,WAAW,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,CAAC,QAAQ,CAAA;AAAA,QAClD,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,gBAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,CAAC;AAAA,OACjE,CAAA;AAAA,IACH;AAKA,IAAA,4BAAA,CAA6B,SAAA,GAAY,CAAA;AACzC,IAAA,IAAI,GAAA;AACJ,IAAA,OAAA,CAAQ,MAAM,4BAAA,CAA6B,IAAA,CAAK,GAAA,CAAI,OAAO,OAAO,IAAA,EAAM;AACtE,MAAA,MAAM,MAAA,GAAS,IAAI,CAAC,CAAA;AACpB,MAAA,IAAI,wBAAA,CAAyB,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA,EAAG;AACnD,MAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA;AACtD,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,cAAA;AAAA,QACR,WAAW,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,CAAC,QAAQ,CAAA;AAAA,QAClD,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,cAAA,EAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,eAAA,EAAiB,CAAC;AAAA,OAClF,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACnSA,IAAM,YAAA,GAAe,2CAAA;AAKrB,IAAMM,OAAAA,GAAS,qDAAA;AAOf,IAAM,aAAa,IAAI,MAAA;AAAA,EACrB,SAAA,GAAY,SACVA,OAAAA,GACA,iFAAA;AAAA,EACF;AACF,CAAA;AAGA,IAAM,eAAe,IAAI,MAAA;AAAA,EACvB,SAAA,GAAY,SACVA,OAAAA,GACA,+EAAA;AAAA,EACF;AACF,CAAA;AAIA,IAAM,0BAA0B,IAAI,MAAA;AAAA,EAClC,oGAAA,GACE,YACA,MAAA,GACAA,OAAAA;AAAA,EACF;AACF,CAAA;AAOA,IAAM,2BAA2B,IAAI,MAAA;AAAA,EACnC,wFAAA,GACE,YACA,MAAA,GACAA,OAAAA;AAAA,EACF;AACF,CAAA;AAQA,IAAM,yBAAyB,IAAI,MAAA;AAAA,EACjC,yHAAA;AAAA,EACA;AACF,CAAA;AACA,IAAM,0BAA0B,IAAI,MAAA;AAAA,EAClC,6GAAA;AAAA,EACA;AACF,CAAA;AAMA,IAAM,YAAA,GACJ,QAAQ,SAAA,GAAY,sEAAA;AACtB,IAAM,mBAAmB,IAAI,MAAA;AAAA,EAC3B,YAAA,GAAe,6EAAA;AAAA,EACf;AACF,CAAA;AACA,IAAM,qBAAqB,IAAI,MAAA;AAAA,EAC7B,YAAA,GAAe,2EAAA;AAAA,EACf;AACF,CAAA;AAeA,IAAM,gBAAA,GAAmB,4DAAA;AACzB,IAAM,MAAA,GAAS,+CAAA;AAIf,IAAM,6BAA6B,IAAI,MAAA;AAAA,EACrC,SACE,+CAAA,GACA,gBAAA;AAAA,EACF;AACF,CAAA;AAGA,IAAM,8BAA8B,IAAI,MAAA;AAAA,EACtC,SACE,iEAAA,GACA,gBAAA;AAAA,EACF;AACF,CAAA;AAGA,IAAM,6BAA6B,IAAI,MAAA;AAAA,EACrC,mBACE,+CAAA,GACA,MAAA;AAAA,EACF;AACF,CAAA;AAGA,IAAM,8BAA8B,IAAI,MAAA;AAAA,EACtC,mBACE,iEAAA,GACA,MAAA;AAAA,EACF;AACF,CAAA;AAMA,IAAM,eAAA,GACJ,6EAAA;AAGF,IAAM,yBAAyB,IAAI,MAAA;AAAA,EACjC,MAAA,GACE,sHAAA;AAAA,EAEF;AACF,CAAA;AAGA,IAAM,oCAAoC,IAAI,MAAA;AAAA,EAC5C,kBACE,sDAAA,GACA,MAAA;AAAA,EACF;AACF,CAAA;AAGA,IAAM,gCAAgC,IAAI,MAAA;AAAA,EACxC,kBACE,oCAAA,GACA,MAAA;AAAA,EACF;AACF,CAAA;AAGA,IAAM,6BAA6B,IAAI,MAAA;AAAA,EACrC,MAAA,GACE,wIAAA;AAAA,EAEF;AACF,CAAA;AAGA,IAAM,eAAA,GAAkB,8BAAA;AAUxB,SAAS,OAAA,CACP,IAAA,EACA,EAAA,EACA,IAAA,EAEA,UACA,GAAA,EACM;AACN,EAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,EAAG;AACjC,IAAA,MAAM,SAAS,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AAC/B,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MACP,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,IAAA;AAAA,MACA,GAAA,EAAK,CAAC,CAAA,CAAE,QAAQ,CAAA,EAAG,CAAA,CAAE,QAAA,GAAW,CAAC,CAAA,EAAG,CAAA,CAAE,QAAA,GAAW,CAAC,CAAC,CAAA;AAAA,MACnD;AAAA,KACD,CAAA;AAAA,EACH;AACF;AAOA,SAASC,YAAW,IAAA,EAAyB;AAC3C,EAAA,MAAM,OAAkB,EAAC;AAEzB,EAAA,OAAA,CAAQ,IAAA,EAAM,UAAA,EAAY,UAAA,EAAY,CAAA,EAAG,IAAI,CAAA;AAC7C,EAAA,OAAA,CAAQ,IAAA,EAAM,YAAA,EAAc,aAAA,EAAe,CAAA,EAAG,IAAI,CAAA;AAElD,EAAA,uBAAA,CAAwB,SAAA,GAAY,CAAA;AACpC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,uBAAuB,CAAA,EAAG;AACtD,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,IAAA,EAAM,UAAA;AAAA,MACN,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACtB,QAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK;AAAA,KACzB,CAAA;AAAA,EACH;AAEA,EAAA,wBAAA,CAAyB,SAAA,GAAY,CAAA;AACrC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,wBAAwB,CAAA,EAAG;AACvD,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,IAAA,EAAM,aAAA;AAAA,MACN,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACtB,QAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK;AAAA,KACzB,CAAA;AAAA,EACH;AAEA,EAAA,sBAAA,CAAuB,SAAA,GAAY,CAAA;AACnC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,sBAAsB,CAAA,EAAG;AACrD,IAAA,IAAA,CAAK,IAAA,CAAK,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,IAAS,GAAG,IAAA,EAAM,UAAA,EAAY,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA,EAAI,CAAA;AAAA,EAClG;AACA,EAAA,uBAAA,CAAwB,SAAA,GAAY,CAAA;AACpC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,uBAAuB,CAAA,EAAG;AACtD,IAAA,IAAA,CAAK,IAAA,CAAK,EAAE,KAAA,EAAO,CAAA,CAAE,KAAA,IAAS,GAAG,IAAA,EAAM,aAAA,EAAe,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA,EAAI,CAAA;AAAA,EACrG;AAIA,EAAA,0BAAA,CAA2B,SAAA,GAAY,CAAA;AACvC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,0BAA0B,CAAA,EAAG;AACzD,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,IAAA,EAAM,UAAA;AAAA,MACN,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACtB,QAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK;AAAA,KACzB,CAAA;AAAA,EACH;AACA,EAAA,2BAAA,CAA4B,SAAA,GAAY,CAAA;AACxC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,2BAA2B,CAAA,EAAG;AAC1D,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,IAAA,EAAM,aAAA;AAAA,MACN,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACtB,QAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK;AAAA,KACzB,CAAA;AAAA,EACH;AAEA,EAAA,0BAAA,CAA2B,SAAA,GAAY,CAAA;AACvC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,0BAA0B,CAAA,EAAG;AACzD,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,IAAA,EAAM,aAAA;AAAA,MACN,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACtB,QAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK;AAAA,KACzB,CAAA;AAAA,EACH;AACA,EAAA,2BAAA,CAA4B,SAAA,GAAY,CAAA;AACxC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,2BAA2B,CAAA,EAAG;AAC1D,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,KAAA,EAAO,EAAE,KAAA,IAAS,CAAA;AAAA,MAClB,IAAA,EAAM,UAAA;AAAA,MACN,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACtB,QAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK;AAAA,KACzB,CAAA;AAAA,EACH;AAIA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,MAAM,QAAmB,EAAC;AAC1B,EAAA,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AACrC,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,MAAM,GAAA,GAAM,GAAG,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,GAAA,CAAI,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AACvC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,IAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACd;AACA,EAAA,OAAO,KAAA;AACT;AAcA,SAAS,iBAAiB,OAAA,EAA6B;AACrD,EAAA,MAAM,MAAkB,EAAC;AACzB,EAAA,MAAM,IAAA,GAAO,CAAC,EAAA,EAAY,IAAA,KAAqC;AAC7D,IAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,IAAA,KAAA,MAAW,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,EAAE,CAAA,EAAG;AACpC,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,IAAA;AAAA,QACA,GAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,QACtB,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AAAA,QAChB,WAAA,EAAa,EAAE,CAAC;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AACA,EAAA,IAAA,CAAK,kBAAkB,UAAU,CAAA;AACjC,EAAA,IAAA,CAAK,oBAAoB,aAAa,CAAA;AAItC,EAAA,MAAM,YAAA,GAAe,CAAC,EAAA,EAAY,IAAA,KAAqC;AACrE,IAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,IAAA,KAAA,MAAW,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,EAAE,CAAA,EAAG;AACpC,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,IAAA,EAAM,GAAA,EAAK,CAAC,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,MAAA,EAAQ,CAAA,CAAE,CAAC,CAAA,IAAK,IAAI,WAAA,EAAa,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA;AAAA,IACnF;AAAA,EACF,CAAA;AACA,EAAA,YAAA,CAAa,wBAAwB,UAAU,CAAA;AAC/C,EAAA,YAAA,CAAa,4BAA4B,aAAa,CAAA;AAEtD,EAAA,IAAA,CAAK,mCAAmC,UAAU,CAAA;AAClD,EAAA,IAAA,CAAK,+BAA+B,aAAa,CAAA;AACjD,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,SAAA,CAAU,IAAA,EAAkC,GAAA,EAAe,MAAA,EAAgB;AAClF,EAAA,MAAM,OAAO,MAAA,IAAU,GAAA;AACvB,EAAA,OAAO,SAAS,aAAA,GACZ,UAAA,CAAW,IAAA,EAAM,aAAA,EAAe,EAAE,QAAA,EAAU,GAAA,EAAK,CAAA,GACjD,WAAW,IAAA,EAAM,UAAA,EAAY,EAAE,MAAA,EAAQ,KAAK,CAAA;AAClD;AAYO,IAAM,kBAAA,GAAmC;AAAA,EAC9C,EAAA,EAAI,gBAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAAC,YAAA,EAAc,eAAe,CAAA;AAAA,EACxC,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAGhC,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,YAAA,CAAa,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IAAK,CAAC,eAAA,CAAgB,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AACjE,MAAA,MAAM,IAAA,GAAOA,WAAAA,CAAW,CAAA,CAAE,IAAI,CAAA;AAC9B,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,MAAA,KAAA,MAAW,CAAA,IAAK,IAAA,EAAM,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,CAAA,CAAE,GAAA,CAAI,IAAA,CAAK,EAAE,CAAC,CAAA,CAAE,CAAA;AAC/D,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,gBAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,SAAA,CAAU,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,GAAA,EAAK,CAAA,CAAE,MAAM,CAAC;AAAA,OAC5D,CAAA;AAAA,IACH;AAKA,IAAA,KAAA,MAAW,CAAA,IAAK,gBAAA,CAAiB,GAAA,CAAI,OAAO,CAAA,EAAG;AAC7C,MAAA,MAAM,GAAA,GAAM,GAAG,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,GAAA,CAAI,IAAA,CAAK,EAAE,CAAC,CAAA,CAAA;AACvC,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,EAAG;AACtB,MAAA,OAAA,CAAQ,IAAI,GAAG,CAAA;AACf,MAAA,MAAM,YAAY,GAAA,CAAI,OAAA,CACnB,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,WAAA,CAAY,QAAA,CAAS,CAAA,CAAE,IAAI,CAAC,CAAA,CAC5C,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAClB,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,gBAAA;AAAA,QACR,SAAA;AAAA,QACA,OAAA,EAAS,CAAC,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA,CAAE,GAAA,EAAK,CAAA,CAAE,MAAM,CAAC;AAAA,OAC7C,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACjZA,IAAM,WAAA,GAAc,eAAA;AAMpB,IAAM,gBAAgB,MAAA,CAAO,GAAA,CAAA,8DAAA,CAAA;AAQ7B,IAAM,YAAY,IAAI,MAAA;AAAA,EACpB,OAAO,GAAA,CAAA,yGAAA,CAAA,GACL,aAAA;AAAA,EACF;AACF,CAAA;AAIA,IAAM,UAAU,IAAI,MAAA;AAAA,EAClB,OAAO,GAAA,CAAA,uIAAA,CAAA,GACL,aAAA;AAAA,EACF;AACF,CAAA;AASA,IAAM,mBAAmB,MAAA,CAAO,GAAA,CAAA,uEAAA,CAAA;AAWhC,IAAM,eAAe,IAAI,MAAA;AAAA,EACvB,OAAO,GAAA,CAAA,yIAAA,CAAA,GACL,gBAAA;AAAA,EACF;AACF,CAAA;AAOA,IAAM,cAAc,IAAI,MAAA;AAAA,EACtB,OAAO,GAAA,CAAA,6KAAA,CAAA,GACL,gBAAA;AAAA,EACF;AACF,CAAA;AASA,IAAM,gBAAgB,IAAI,MAAA;AAAA,EACxB,OAAO,GAAA,CAAA,mIAAA,CAAA,GACL,aAAA;AAAA,EACF;AACF,CAAA;AACA,IAAM,gBAAgB,IAAI,MAAA;AAAA,EACxB,OAAO,GAAA,CAAA,mKAAA,CAAA,GACL,gBAAA;AAAA,EACF;AACF,CAAA;AAEO,IAAM,kBAAA,GAAmC;AAAA,EAC9C,EAAA,EAAI,gBAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA;AAAA;AAAA,EAGtB,QAAA,EAAU,CAAC,WAAA,EAAa,aAAa,CAAA;AAAA,EACrC,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAI3B,MAAA,MAAM,KAAA,GAAQ,cAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IAAK,aAAA,CAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACrE,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,MAAMC,KAAAA,GAAO,MAAM,CAAC,CAAA;AACpB,QAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,QAAA,MAAM,EAAA,GAAK,MAAM,CAAC,CAAA;AAClB,QAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,QAAA,MAAMC,OAAAA,GAAS,KAAA,CAAM,CAAC,CAAA,IAAK,MAAM,CAAC,CAAA;AAElC,QAAA,IACEA,OAAAA,IAAUD,UAAS,EAAA,IACnB,GAAA,KAAQA,SAAQ,GAAA,KAAQA,KAAAA,IAAQ,QAAQ,GAAA,EACxC;AACA,UAAA,GAAA,CAAI,IAAA,CAAK;AAAA,YACP,MAAA,EAAQ,gBAAA;AAAA,YACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,YAChB,OAAA,EAAS;AAAA,cACP,QAAA,CAAS,GAAA,EAAK,gBAAA,EAAkB,EAAE,IAAA,EAAAA,OAAM,MAAA,EAAAC,OAAAA,EAAQ,KAAA,EAAO,MAAA,EAAQ,CAAA;AAAA,cAC/D,QAAA,CAAS,GAAA,EAAK,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAAD,KAAAA,EAAM,MAAA,EAAAC,OAAAA,EAAQ,KAAA,EAAO,CAAA,EAAG,CAAA;AAAA,cAC9D,QAAA,CAAS,GAAA,EAAK,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAA,EAAAD,KAAAA,EAAM,MAAA,EAAAC,OAAAA,EAAQ,KAAA,EAAO,CAAA,EAAG;AAAA;AAChE,WACD,CAAA;AACD,UAAA;AAAA,QACF;AAAA,MAEF;AAGA,MAAA,MAAM,IACJ,SAAA,CAAU,IAAA,CAAK,EAAE,IAAI,CAAA,IACrB,QAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IACnB,YAAA,CAAa,KAAK,CAAA,CAAE,IAAI,KACxB,WAAA,CAAY,IAAA,CAAK,EAAE,IAAI,CAAA;AACzB,MAAA,IAAI,CAAC,CAAA,EAAG;AACR,MAAA,MAAM,IAAA,GAAO,EAAE,CAAC,CAAA;AAMhB,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,CAAC,CAAA,IAAK,EAAE,CAAC,CAAA;AAE1B,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,EAAQ;AACtB,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,gBAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS;AAAA,UACP,QAAA,CAAS,KAAK,gBAAA,EAAkB,EAAE,MAAM,MAAA,EAAQ,KAAA,EAAO,QAAQ;AAAA;AACjE,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACzIA,IAAM,UAAU,IAAI,MAAA;AAAA,EAClB,MAAA,CAAO,GAAA,CAAA,8HAAA,CAAA;AAAA,EACP;AACF,CAAA;AAKA,IAAM,UAAU,IAAI,MAAA;AAAA,EAClB,MAAA,CAAO,GAAA,CAAA,6KAAA,CAAA;AAAA,EACP;AACF,CAAA;AAEO,IAAM,iBAAA,GAAkC;AAAA,EAC7C,EAAA,EAAI,eAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA;AAAA;AAAA,EAGtB,QAAA,EAAU,CAAC,QAAA,EAAU,aAAa,CAAA;AAAA,EAClC,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,CAAA,GAAI,QAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IAAK,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACrD,MAAA,IAAI,CAAC,CAAA,EAAG;AACR,MAAA,MAAM,IAAA,GAAO,EAAE,CAAC,CAAA;AAChB,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,CAAC,CAAA,IAAK,EAAE,CAAC,CAAA;AAC1B,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,EAAQ;AACtB,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,eAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,CAAC,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,kBAAA,EAAoB,MAAA,EAAQ,CAAC;AAAA,OAC/D,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACzBA,IAAM,OAAA,GAAU,kDAAA;AAIhB,IAAM,QAAA,GACJ,qFAAA;AAGF,IAAMC,YAAAA,GACJ,2FAAA;AAGF,IAAM,cAAA,GAAiB,yBAAA;AAGvB,IAAMT,IAAAA,GAAM,mCAAA;AAKZ,IAAM,YAAA,GAAe,uDAAA;AACrB,IAAM,YAAA,GAAe,oBAAA;AAMrB,IAAM,UAAA,GAAa,0DAAA;AAEnB,IAAM,WAAA,GACJ,uFAAA;AAEF,IAAMU,eAAAA,GACJ,4FAAA;AAEF,IAAM,iBAAA,GAAoB,2EAAA;AAE1B,IAAMT,OAAAA,GAAS,kDAAA;AAEf,IAAM,YAAA,GAAe,cAAA;AAGrB,SAAS,cAAc,OAAA,EAAqC;AAC1D,EAAA,MAAM,CAAA,GAAI,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACnC,EAAA,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC,CAAA;AACjB,EAAA,MAAM,CAAA,GAAI,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACnC,EAAA,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC,CAAA;AACjB,EAAA,OAAO,MAAA;AACT;AAMA,SAAS,gBAAgB,OAAA,EAAyB;AAChD,EAAA,KAAA,MAAW,QAAQ,CAAC,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,GAAG,CAAA,EAAG;AACzC,IAAA,IAAI,CAAC,IAAI,MAAA,CAAO,CAAA,WAAA,EAAc,IAAI,CAAA,eAAA,CAAA,EAAmB,GAAG,CAAA,CAAE,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,IAAA;AAAA,EAClF;AACA,EAAA,OAAO,GAAA;AACT;AAUO,IAAM,eAAA,GAAgC;AAAA,EAC3C,EAAA,EAAI,aAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAAC,OAAA,EAAS,UAAU,CAAA;AAAA,EAC9B,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,cAAA,GAAiB,aAAA,CAAc,GAAA,CAAI,OAAO,CAAA;AAChD,IAAA,MAAM,GAAA,GAAMD,IAAAA,CAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAChC,IAAA,MAAM,OAAA,GAAUC,OAAAA,CAAO,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAEvC,IAAA,MAAM,SAAA,GAA6B,GAAA,GAC/B,CAAC,GAAA,CAAI,CAAC,GAAG,GAAA,CAAI,CAAC,CAAA,EAAG,GAAA,CAAI,CAAC,CAAC,IACvB,OAAA,GACE,CAAC,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAC,CAAA,GACnC,IAAA;AAEN,IAAA,MAAM,SAAS,cAAA,KAAmB,SAAA,GAAY,eAAA,CAAgB,GAAA,CAAI,OAAO,CAAA,GAAI,MAAA,CAAA;AAC7E,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AACrB,IAAA,MAAM,aAAa,CAAC,cAAA;AAEpB,IAAA,MAAM,MAAmB,EAAC;AAG1B,IAAA,IAAI,aAAA,GAAgB,KAAA;AACpB,IAAA,MAAM,UAAA,GAAa,CAAC,EAAA,KAA2B;AAC7C,MAAA,IAAI,UAAA,IAAc,CAAC,aAAA,IAAiB,SAAA,EAAW;AAC7C,QAAA,aAAA,GAAgB,IAAA;AAChB,QAAA,OAAO,CAAC,WAAW,MAAA,EAAQ,UAAA,EAAY,EAAE,MAAA,EAAQ,SAAA,EAAW,CAAA,EAAG,EAAE,CAAA;AAAA,MACnE;AACA,MAAA,OAAO,CAAC,EAAE,CAAA;AAAA,IACZ,CAAA;AAEA,IAAA,MAAM,WAAA,GAAc,CAAC,CAAA,EAAW,CAAA,KAC9B,CAAC,UAAA,IAAe,CAAC,CAAC,SAAA,IAAa,UAAU,QAAA,CAAS,CAAC,CAAA,IAAK,SAAA,CAAU,SAAS,CAAC,CAAA;AAE9E,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAK3B,MAAA,IAAI,aAAA,CAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAChC,MAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IAAK,CAAC,eAAA,CAAgB,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAE3D,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAClC,MAAA,IAAI,CAAC,KAAA,EAAO;AACZ,MAAA,MAAM,OAAO,aAAA,CAAc,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AAC9C,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,MAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA;AACf,MAAA,IAAI,CAAC,WAAA,CAAY,CAAA,EAAG,CAAC,CAAA,EAAG;AAGxB,MAAA,MAAM,MAAA,GAASQ,YAAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACtC,MAAA,MAAM,IAAA,GAAO,iBAAiB,CAAA,CAAE,IAAI,MAAM,MAAA,GAAS,MAAA,CAAO,CAAC,CAAA,GAAI,MAAA,CAAA;AAC/D,MAAA,IAAI,CAAC,IAAA,EAAM;AAGX,MAAA,IAAI,aAAA;AACJ,MAAA,MAAM,EAAA,GAAK,cAAA,CAAe,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACrC,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,aAAA,GAAgB,GAAG,CAAC,CAAA;AAEpB,QAAA,IAAI,aAAA,KAAkB,CAAA,IAAK,aAAA,KAAkB,CAAA,EAAG;AAAA,MAClD,WAAW,GAAA,EAAK;AACd,QAAA,MAAM,KAAA,GAAQ,CAAC,GAAA,CAAI,CAAC,CAAA,EAAG,IAAI,CAAC,CAAA,EAAG,GAAA,CAAI,CAAC,CAAC,CAAA;AACrC,QAAA,aAAA,GAAgB,MAAM,IAAA,CAAK,CAAC,MAAM,CAAA,KAAM,CAAA,IAAK,MAAM,CAAC,CAAA;AAAA,MACtD;AACA,MAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,aAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,UAAA,CAAW,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,aAAA,EAAe,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG,aAAA,EAAe,CAAC;AAAA,OACzF,CAAA;AAAA,IACH;AAIA,IAAA,MAAM,UAAA,GAAa,OAAA,GAAU,CAAC,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAC,CAAA,GAAI,MAAA;AAEpE,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAE9B,MAAA,IAAI,YAAA,CAAa,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAE/B,MAAA,IAAI,aAAA,CAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IAAK,CAAC,mBAAA,CAAoB,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAErE,MAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACrC,MAAA,IAAI,CAAC,KAAA,EAAO;AACZ,MAAA,MAAM,OAAO,aAAA,CAAc,KAAA,CAAM,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AAC9C,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACvB,MAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,IAAA;AACf,MAAA,IAAI,CAAC,WAAA,CAAY,CAAA,EAAG,CAAC,CAAA,EAAG;AAGxB,MAAA,MAAM,MAAA,GAASC,eAAAA,CAAe,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACzC,MAAA,MAAM,IAAA,GAAO,MAAA,GAAS,MAAA,CAAO,CAAC,CAAA,GAAI,MAAA;AAClC,MAAA,IAAI,CAAC,IAAA,EAAM;AAGX,MAAA,IAAI,aAAA;AACJ,MAAA,MAAM,EAAA,GAAK,iBAAA,CAAkB,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACxC,MAAA,IAAI,EAAA,EAAI;AACN,QAAA,aAAA,GAAgB,GAAG,CAAC,CAAA;AACpB,QAAA,IAAI,aAAA,KAAkB,CAAA,IAAK,aAAA,KAAkB,CAAA,EAAG;AAAA,MAClD,WAAW,UAAA,EAAY;AACrB,QAAA,aAAA,GAAgB,WAAW,IAAA,CAAK,CAAC,MAAM,CAAA,KAAM,CAAA,IAAK,MAAM,CAAC,CAAA;AAAA,MAC3D;AACA,MAAA,IAAI,CAAC,aAAA,EAAe;AAEpB,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,aAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,UAAA,CAAW,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,aAAA,EAAe,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG,aAAA,EAAe,CAAC;AAAA,OACzF,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACtMA,IAAM,WAAA,GAAc,cAAA;AAGpB,IAAMV,IAAAA,GAAM,qCAAA;AACZ,IAAME,MAAAA,GAAQ,sCAAA;AAGd,IAAM,QAAA,GACJ,0GAAA;AAGF,IAAMO,YAAAA,GACJ,qFAAA;AAOF,SAAS,iBAAA,CAAkB,YAAoB,OAAA,EAAuC;AACpF,EAAA,MAAM,QAAA,GAAWT,IAAAA,CAAI,IAAA,CAAK,UAAU,CAAA;AACpC,EAAA,IAAI,QAAA,EAAU,OAAO,CAAC,QAAA,CAAS,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,CAAA,EAAG,QAAA,CAAS,CAAC,CAAC,CAAA;AAC3D,EAAAE,OAAM,SAAA,GAAY,CAAA;AAClB,EAAA,MAAM,MAAgB,EAAC;AACvB,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,OAAO,CAAA,MAAO,MAAM,GAAA,CAAI,IAAA,CAAK,CAAA,CAAE,CAAC,IAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AACtE,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,GAAG,CAAA;AAC5B,EAAA,IAAI,QAAA,CAAS,SAAS,CAAA,EAAG;AACvB,IAAA,MAAM,CAAA,GAAI,IAAI,CAAC,CAAA;AACf,IAAA,OAAO,CAAC,EAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,MAAA;AACT;AAMO,IAAM,YAAA,GAA6B;AAAA,EACxC,EAAA,EAAI,UAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,WAAW,CAAA;AAAA,EACtB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAE/B,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACjC,MAAA,IAAI,CAAC,IAAA,EAAM;AACX,MAAA,MAAMS,SAAAA,GAAW,KAAK,CAAC,CAAA;AAEvB,MAAA,MAAM,EAAA,GAAK,iBAAA,CAAkB,CAAA,CAAE,IAAA,EAAM,IAAI,OAAO,CAAA;AAChD,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,IAAI,CAAC,EAAA,CAAG,QAAA,CAASA,SAAQ,CAAA,EAAG;AAE5B,MAAA,MAAM,KAAA,GAAQF,YAAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACrC,MAAA,MAAM,IAAA,GAAO,KAAA,GAAQ,KAAA,CAAM,CAAC,CAAA,GAAI,MAAA;AAChC,MAAA,IAAI,CAAC,IAAA,EAAM;AAEX,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,UAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,CAAC,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,QAAA,EAAAE,SAAAA,EAAU,CAAC;AAAA,OAC7D,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACzEA,IAAM,KAAK,IAAI,MAAA;AAAA,EACb,wOAAA;AAAA,EAGA;AACF,CAAA;AAGA,IAAMZ,UAAAA,GACJ,8EAAA;AAEK,IAAM,gBAAA,GAAiC;AAAA,EAC5C,EAAA,EAAI,cAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAACA,UAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,EAAG;AACnC,QAAA,MAAM,OAAA,GAAU,EAAE,CAAC,CAAA;AACnB,QAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,CAAC,CAAC,CAAA;AACnC,QAAA,MAAM,EAAA,GAAK,CAAA,CAAE,CAAC,CAAA,GAAI,EAAE,CAAC,CAAA;AAErB,QAAA,IAAI,UAAA,IAAc,EAAA,CAAG,QAAA,CAAS,OAAO,CAAA,EAAG;AACxC,QAAA,MAAM,IAAA,GAAO,aAAa,iBAAA,GAAoB,aAAA;AAC9C,QAAA,MAAM,IAAA,GAAA,CAAQ,UAAA,GAAa,KAAA,GAAQ,KAAA,IAAS,OAAA;AAC5C,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,cAAA;AAAA,UACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,UAChB,OAAA,EAAS,CAAC,QAAA,CAAS,IAAA,EAAM,MAAM,EAAE,OAAA,EAAS,EAAA,EAAI,CAAC;AAAA,SAChD,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AClDA,IAAM,OAAA,GAAU,aAAA;AAMhB,IAAMU,YAAAA,GACJ,8LAAA;AAKF,IAAM,UAAA,GACJ,iKAAA;AAMF,IAAM,UAAA,GACJ,6LAAA;AACF,IAAM,cAAA,GAAiB,gBAAA;AAMvB,SAAS,gBAAgB,GAAA,EAAoE;AAC3F,EAAA,MAAMG,MAAI,GAAA,CAAI,OAAA,CAAQ,QAAA,EAAU,EAAE,EAAE,IAAA,EAAK;AACzC,EAAA,IAAI,UAAA,CAAW,KAAKA,GAAC,CAAA,SAAU,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAOA,GAAAA,EAAE;AACzD,EAAA,IAAI,eAAA,CAAgB,KAAKA,GAAC,CAAA,SAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAOA,GAAAA,EAAE;AAE7D,EAAA,IAAI,sBAAA,CAAuB,KAAKA,GAAC,CAAA,SAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAOA,GAAAA,EAAE;AACpE,EAAA,OAAO,MAAA;AACT;AAaO,IAAM,cAAA,GAA+B;AAAA,EAC1C,EAAA,EAAI,YAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAAC,OAAA,EAAS,cAAc,CAAA;AAAA,EAClC,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,IAAK,CAAC,cAAA,CAAe,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAE3D,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI,EAAA;AACJ,MAAA,IAAI,UAAA;AAEJ,MAAA,MAAM,MAAA,GAASH,YAAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACtC,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,IAAA,GAAO,OAAO,CAAC,CAAA;AACf,QAAA,EAAA,GAAK,OAAO,CAAC,CAAA;AACb,QAAA,UAAA,GAAa,OAAO,CAAC,CAAA;AAAA,MACvB,CAAA,MAAO;AACL,QAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACpC,QAAA,IAAI,KAAA,EAAO;AAET,UAAA,IAAA,GAAO,gBAAA,CAAiB,EAAE,IAAI,CAAA;AAC9B,UAAA,EAAA,GAAK,MAAM,CAAC,CAAA;AACZ,UAAA,UAAA,GAAa,MAAM,CAAC,CAAA;AAAA,QACtB,CAAA,MAAO;AAEL,UAAA,MAAM,EAAA,GAAK,UAAA,CAAW,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACjC,UAAA,IAAI,EAAA,EAAI;AACN,YAAA,IAAA,GAAO,GAAG,CAAC,CAAA;AACX,YAAA,EAAA,GAAK,GAAG,CAAC,CAAA;AACT,YAAA,UAAA,GAAa,GAAG,CAAC,CAAA;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,EAAA,IAAM,CAAC,UAAA,EAAY;AAEjC,MAAA,MAAM,OAAA,GAAU,gBAAgB,UAAU,CAAA;AAC1C,MAAA,IAAI,CAAC,OAAA,EAAS;AAEd,MAAA,MAAM,aACJ,OAAA,CAAQ,IAAA,KAAS,UACb,EAAE,IAAA,EAAM,gBAAgB,EAAA,EAAI,OAAA,EAAS,OAAA,CAAQ,KAAA,KAC7C,EAAE,IAAA,EAAM,eAAe,EAAA,EAAI,OAAA,EAAS,QAAQ,KAAA,EAAM;AAExD,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,YAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,CAAC,QAAA,CAAS,IAAA,EAAM,UAAU,CAAC;AAAA,OACrC,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AC5EA,IAAM,OAAA,GAAU,6BAAA;AAKhB,IAAM,OAAA,GACJ,kDAAA;AAGF,IAAM,OAAA,GACJ,kEAAA;AAKF,IAAM,UAAA,GACJ,4CAAA;AAKF,SAAS,kBAAA,CAAmB,QAAgB,KAAA,EAAuB;AACjE,EAAA,OAAO,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,CAAA,CAAA,GAAM,MAAA;AAChC;AAKA,IAAM,OAAA,GAAU,kCAAA;AAShB,IAAMI,aAAAA,GAAe,wBAAA;AAIrB,IAAM,eAAA,GACJ,4EAAA;AAGF,IAAM,aAAA,GACJ,wGAAA;AAEF,IAAM,eAAA,GACJ,sDAAA;AAMF,IAAM,aAAA,GACJ,+GAAA;AASF,IAAM,WAAA,GACJ,2EAAA;AAGF,IAAM,WAAA,GAAc,sCAAA;AACpB,IAAM,gBAAA,GAAmB,uCAAA;AACzB,IAAM,YAAA,GAAe,kCAAA;AACrB,IAAM,MAAA,GAAS,oBAAA;AAGf,IAAM,iBAAA,GAAoB,uBAAA;AAC1B,IAAM,iBAAA,GAAoB,6CAAA;AAE1B,SAASC,UAAS,GAAA,EAAqB;AACrC,EAAA,OAAO,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,GAAG,CAAC,CAAA;AACrC;AAGA,SAAS,kBAAkB,OAAA,EAAyB;AAClD,EAAA,MAAM,CAAA,GAAI,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA;AACxC,EAAA,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC,CAAA;AACjB,EAAA,MAAM,CAAA,GAAI,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA;AACxC,EAAA,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC,CAAA;AACjB,EAAA,OAAO,GAAA;AACT;AAmBA,IAAM,WAAA,GAAc,+CAAA;AAEpB,IAAM,aAAA,GAAgB,iCAAA;AAGtB,IAAM,kBAAA,GAAqB,oCAAA;AAG3B,SAAS,aAAA,CAAc,KAAa,OAAA,EAAuC;AACzE,EAAA,IAAI,IAAA,GAAO,IAAI,IAAA,EAAK;AAGpB,EAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AAC7B,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AAClC,EAAA,IAAI,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AAE1C,EAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AAG7B,EAAA,IAAI,MAAA;AACJ,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA;AACnC,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,CAAC,CAAA,KAAM,MAAM,EAAA,GAAK,CAAA;AACnC,IAAA,MAAA,GAAS,IAAA,GAAOA,SAAAA,CAAS,GAAA,CAAI,CAAC,CAAC,CAAA;AAC/B,IAAA,IAAA,GAAO,KAAK,KAAA,CAAM,CAAA,EAAG,GAAA,CAAI,KAAK,EAAE,IAAA,EAAK;AAAA,EACvC;AAEA,EAAA,IAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AAC9B,EAAA,IAAI,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AAIjC,EAAA,IAAI,KAAA;AACJ,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA;AAClC,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,KAAA,GAAQA,SAAAA,CAAS,IAAA,CAAK,CAAC,CAAC,CAAA;AACxB,IAAA,IAAI,EAAE,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,GAAQ,IAAI,OAAO,MAAA;AACnD,IAAA,IAAA,GAAO,KAAK,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,CAAE,MAAM,EAAE,IAAA,EAAK;AAAA,EACzC;AAGA,EAAA,IAAI,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AAEhC,EAAA,MAAM,QAAA,GAAW,CAAC,IAAA,KAAiC;AACjD,IAAA,MAAM,CAAA,GAAc,EAAE,GAAG,IAAA,EAAK;AAC9B,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,CAAA,CAAE,KAAA,GAAQ,KAAA;AACnC,IAAA,IAAI,MAAA,KAAW,MAAA,EAAW,CAAA,CAAE,MAAA,GAAS,MAAA;AACrC,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAGA,EAAA,IAAI,WAAA,CAAY,IAAA,CAAK,IAAI,CAAA,EAAG;AAC1B,IAAA,MAAM,EAAA,GAAK,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AACrC,IAAA,MAAM,SAAS,EAAA,GAAK,EAAA,CAAG,CAAC,CAAA,GAAI,kBAAkB,OAAO,CAAA;AACrD,IAAA,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,cAAA,EAAgB,QAAQ,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,GAAA,GAAM,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA;AAClC,EAAA,IAAI,GAAA,EAAK,OAAO,QAAA,CAAS,EAAE,MAAM,eAAA,EAAiB,EAAA,EAAI,GAAA,CAAI,CAAC,CAAA,EAAG,EAAA,EAAI,GAAA,CAAI,CAAC,GAAG,CAAA;AAG1E,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AAC5B,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,MAAM,KAAA,GAAQA,SAAAA,CAAS,GAAA,CAAI,CAAC,CAAC,CAAA;AAC7B,MAAA,IAAI,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,GAAQ,CAAA,EAAG,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,CAAA;AAAA,IACrF;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAaO,IAAM,mBAAA,GAAoC;AAAA,EAC/C,EAAA,EAAI,iBAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAA,EAAM,IAAI,CAAA;AAAA,EACtB,QAAA,EAAU,CAAC,OAAA,EAASD,aAAY,CAAA;AAAA,EAChC,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI,IAAA;AACJ,MAAA,IAAI,IAAA,GAAO,KAAA;AAGX,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAC/B,MAAA,IAAI,GAAA,EAAK;AAEP,QAAA,IAAA,GAAO,IAAI,CAAC,CAAA;AACZ,QAAA,OAAA,GAAU,IAAI,CAAC,CAAA;AAAA,MACjB,CAAA,MAAO;AACL,QAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAC9B,QAAA,IAAI,EAAA,EAAI;AAEN,UAAA,IAAA,GAAO,GAAG,CAAC,CAAA;AACX,UAAA,OAAA,GAAU,GAAG,CAAC,CAAA;AAAA,QAChB;AAAA,MACF;AAEA,MAAA,IAAI,QAAQ,OAAA,EAAS;AAEnB,QAAA,MAAM,IAAA,GAAO,UAAA,CAAW,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACnC,QAAA,IAAA,GAAO,IAAA,GAAO,mBAAmB,IAAA,CAAK,CAAC,GAAG,IAAA,CAAK,CAAC,CAAC,CAAA,GAAI,MAAA;AAAA,MACvD,CAAA,MAAO;AAEL,QAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACvC,QAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACvC,QAAA,MAAM,GAAA,GAAM,aAAA,CAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACrC,QAAA,IAAI,GAAA,EAAK;AAEP,UAAA,IAAA,GAAO,IAAI,CAAC,CAAA;AACZ,UAAA,OAAA,GAAU,IAAI,CAAC,CAAA;AAAA,QACjB,WAAW,GAAA,IAAO,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,CAAC,CAAA,EAAG;AAEnC,UAAA,IAAA,GAAO,IAAI,CAAC,CAAA;AACZ,UAAA,OAAA,GAAU,IAAI,CAAC,CAAA;AAAA,QACjB,WAAW,GAAA,IAAO,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,CAAC,CAAA,EAAG;AAEnC,UAAA,IAAA,GAAO,IAAI,CAAC,CAAA;AACZ,UAAA,OAAA,GAAU,IAAI,CAAC,CAAA;AAAA,QACjB;AACA,QAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,UAAA,IAAA,GAAO,IAAA;AACP,UAAA,MAAM,MAAA,GAAS,aAAA,CAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AACxC,UAAA,IAAA,GAAO,MAAA,GAAS,mBAAmB,MAAA,CAAO,CAAC,GAAG,MAAA,CAAO,CAAC,CAAC,CAAA,GAAI,MAAA;AAAA,QAC7D;AAAA,MACF;AAEA,MAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,OAAA,IAAW,CAAC,IAAA,EAAM;AAGhC,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAC9B,QAAA,IAAI,EAAA,IAAM,EAAA,CAAG,CAAC,CAAA,KAAM,OAAA,EAAS;AAAA,MAC/B;AAGA,MAAA,MAAM,EAAA,GAAK,WAAA,CAAY,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAClC,MAAA,IAAI,CAAC,EAAA,EAAI;AACT,MAAA,MAAM,MAAA,GAAS,GAAG,CAAC,CAAA;AACnB,MAAA,MAAM,QAAQ,kBAAA,CAAmB,EAAA,CAAG,CAAC,CAAA,EAAG,EAAA,CAAG,CAAC,CAAC,CAAA;AAG7C,MAAA,IAAI,MAAA,KAAW,OAAA,IAAW,KAAA,KAAU,IAAA,EAAM;AAE1C,MAAA,MAAM,WAAW,aAAA,CAAc,EAAA,CAAG,CAAC,CAAA,EAAG,IAAI,OAAO,CAAA;AACjD,MAAA,IAAI,CAAC,QAAA,EAAU;AAEf,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,iBAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,CAAC,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,CAAC;AAAA,OAC/E,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACnSA,IAAM,aAAA,GAAgB,mDAAA;AAGtB,IAAMX,MAAAA,GAAQ,oCAAA;AAGd,IAAM,cAAA,GAAiB,yBAAA;AAGvB,SAAS,eAAe,OAAA,EAAuD;AAC7E,EAAAA,OAAM,SAAA,GAAY,CAAA;AAClB,EAAA,MAAM,OAAmB,EAAC;AAC1B,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,CAAA,GAAIA,MAAAA,CAAM,IAAA,CAAK,OAAO,OAAO,IAAA,EAAM;AACzC,IAAA,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAACa,EAAAA,KAAMA,EAAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAC,CAAA;AACpD,EAAA,IAAI,QAAA,CAAS,IAAA,KAAS,CAAA,EAAG,OAAO,MAAA;AAChC,EAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,EAAA,OAAO,CAAC,EAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAC1B;AAEO,IAAM,aAAA,GAA8B;AAAA,EACzC,EAAA,EAAI,WAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,aAAa,CAAA;AAAA,EACxB,MAAM,GAAA,EAAK;AAET,IAAA,IAAI,eAAe,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,SAAU,EAAC;AAE9C,IAAA,MAAM,GAAA,GAAM,cAAA,CAAe,GAAA,CAAI,OAAO,CAAA;AACtC,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAClB,IAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA;AAElB,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AACjC,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,WAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS;AAAA,UACP,QAAA,CAAS,GAAA,EAAK,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA;AAAA,UACjD,QAAA,CAAS,GAAA,EAAK,EAAE,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA;AAAA,UACpD,QAAA,CAAS,GAAA,EAAK,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA;AAAA,UACrD,QAAA,CAAS,OAAA,GAAU,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,aAAA,EAAe,EAAE,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,GAAG;AAAA;AAC1E,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACpDA,IAAM,UAAA,GAAa,+CAAA;AAKnB,IAAM,UAAA,GAAa,qCAAA;AAGnB,SAAS,wBAAwB,OAAA,EAA2B;AAC1D,EAAA,UAAA,CAAW,SAAA,GAAY,CAAA;AACvB,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,CAAA,GAAI,UAAA,CAAW,IAAA,CAAK,OAAO,OAAO,IAAA,EAAM;AAC9C,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,EAClB;AACA,EAAA,OAAO,CAAC,GAAG,OAAO,CAAA;AACpB;AAEO,IAAM,eAAA,GAAgC;AAAA,EAC3C,EAAA,EAAI,aAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,UAAU,CAAA;AAAA,EACrB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,OAAA,GAAU,uBAAA,CAAwB,GAAA,CAAI,OAAO,CAAA;AAEnD,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAClC,IAAA,MAAM,CAAC,EAAA,EAAI,EAAE,CAAA,GAAI,OAAA;AAEjB,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC9B,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,aAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS,CAAC,QAAA,CAAS,KAAA,GAAQ,EAAA,GAAK,EAAA,EAAI,aAAA,EAAe,EAAE,OAAA,EAAS,EAAA,EAAI,OAAA,EAAS,EAAA,EAAI,CAAC;AAAA,OACjF,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACvCA,IAAM,SAAA,GAAY,qCAAA;AAGlB,IAAMb,MAAAA,GAAQ,oCAAA;AAGd,IAAM,aAAA,GAAgB,oBAAA;AAGtB,IAAM,SAAA,GAAY,oDAAA;AAGlB,SAASc,gBAAe,OAAA,EAAuD;AAC7E,EAAAd,OAAM,SAAA,GAAY,CAAA;AAClB,EAAA,MAAM,OAAmB,EAAC;AAC1B,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,CAAA,GAAIA,MAAAA,CAAM,IAAA,CAAK,OAAO,OAAO,IAAA,EAAM;AACzC,IAAA,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAACa,EAAAA,KAAMA,EAAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAC,CAAA;AACpD,EAAA,IAAI,QAAA,CAAS,IAAA,KAAS,CAAA,EAAG,OAAO,MAAA;AAChC,EAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,EAAA,OAAO,CAAC,EAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAC1B;AAEO,IAAM,UAAA,GAA2B;AAAA,EACtC,EAAA,EAAI,QAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,SAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,GAAA,GAAMC,eAAAA,CAAe,GAAA,CAAI,OAAO,CAAA;AACtC,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAClB,IAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA;AAIlB,IAAA,MAAM,EAAA,GAAK,aAAA,CAAc,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AACzC,IAAA,IAAI,CAAC,EAAA,EAAI,OAAO,EAAC;AACjB,IAAA,MAAM,CAAA,GAAI,GAAG,CAAC,CAAA;AAGd,IAAA,MAAM,EAAA,GAAK,SAAA,CAAU,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AACrC,IAAA,IAAI,CAAC,EAAA,EAAI,OAAO,EAAC;AACjB,IAAA,MAAM,CAAA,GAAI,GAAG,CAAC,CAAA;AAGd,IAAA,IAAI,MAAM,CAAA,IAAK,CAAA,KAAM,KAAK,CAAA,KAAM,CAAA,SAAU,EAAC;AAE3C,IAAA,MAAM,EAAA,GAAK,GAAA,GAAM,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,GAAA;AAC7B,IAAA,MAAM,EAAA,GAAK,GAAA,GAAM,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,GAAA;AAC7B,IAAA,MAAM,EAAA,GAAK,GAAA,GAAM,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,GAAA;AAE7B,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC7B,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,QAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS;AAAA,UACP,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,YAAY,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,GAAA,EAAK,CAAA;AAAA,UACvD,QAAA,CAAS,EAAA,EAAI,EAAE,IAAA,EAAM,UAAA,EAAY,MAAM,CAAA,EAAG,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAG,CAAA;AAAA,UACzD,QAAA,CAAS,EAAA,EAAI,EAAE,IAAA,EAAM,UAAA,EAAY,MAAM,CAAA,EAAG,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAG,CAAA;AAAA,UACzD,QAAA,CAAS,EAAA,EAAI,EAAE,IAAA,EAAM,UAAA,EAAY,MAAM,CAAA,EAAG,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAG,CAAA;AAAA,UACzD,QAAA,CAAS,QAAA,GAAW,CAAA,EAAG,aAAA,EAAe,EAAE,MAAA,EAAQ,CAAC,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA,EAAG;AAAA;AAChE,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AC7EA,IAAM,OAAA,GAAU,8EAAA;AAChB,IAAMd,MAAAA,GAAQ,oCAAA;AAEd,SAASc,gBAAe,OAAA,EAAuD;AAC7E,EAAAd,OAAM,SAAA,GAAY,CAAA;AAClB,EAAA,MAAM,OAAmB,EAAC;AAC1B,EAAA,IAAI,CAAA;AACJ,EAAA,OAAA,CAAQ,IAAIA,MAAAA,CAAM,IAAA,CAAK,OAAO,CAAA,MAAO,IAAA,OAAW,IAAA,CAAK,CAAC,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AACvE,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,CAACa,EAAAA,KAAMA,EAAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAC,CAAA;AACpD,EAAA,IAAI,QAAA,CAAS,IAAA,KAAS,CAAA,EAAG,OAAO,MAAA;AAChC,EAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,EAAA,OAAO,CAAC,EAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAC1B;AAEO,IAAM,aAAA,GAA8B;AAAA,EACzC,EAAA,EAAI,WAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,OAAO,CAAA;AAAA,EAClB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,GAAA,GAAMC,eAAAA,CAAe,GAAA,CAAI,OAAO,CAAA;AACtC,IAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAClB,IAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA;AAClB,IAAA,MAAM,GAAA,GAAM,GAAA,GAAM,CAAA,GAAI,CAAA,EAAG,GAAA,GAAM,MAAM,CAAA,GAAI,CAAA,EAAG,GAAA,GAAM,GAAA,GAAM,CAAA,GAAI,CAAA;AAC5D,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,EAAG;AAC3B,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,WAAA;AAAA,QACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,QAChB,OAAA,EAAS;AAAA,UACP,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,YAAY,EAAA,EAAI,CAAA,GAAI,GAAG,CAAA;AAAA,UAC7C,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,YAAY,EAAA,EAAI,CAAA,GAAI,GAAG,CAAA;AAAA,UAC7C,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,YAAY,EAAA,EAAI,CAAA,GAAI,GAAG,CAAA;AAAA,UAC7C,UAAA,CAAW,IAAA,EAAM,UAAA,EAAY,EAAE,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG;AAAA;AAC1D,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACjCA,IAAMC,cAAAA,GAAgB,oBAAA;AAEtB,IAAM,WAAA,GAAc,IAAI,MAAA,CAAO,QAAA,GAAW,eAAY,GAAG,CAAA;AACzD,IAAM,WAAA,GAAc,mBAAA;AAIpB,IAAM,UAAA,GAAa,CAAA;AACnB,IAAM,eAAe,CAAC,GAAA,EAAK,GAAK,GAAA,EAAK,GAAA,EAAK,KAAK,CAAG,CAAA;AASlD,SAAS,MAAM,OAAA,EAAqC;AAClD,EAAA,MAAM,EAAA,GAAKA,cAAAA,CAAc,IAAA,CAAK,OAAO,CAAA;AACrC,EAAA,IAAI,CAAC,IAAI,OAAO,MAAA;AAChB,EAAA,MAAM,MAAA,GAAS,GAAG,CAAC,CAAA;AAGnB,EAAA,MAAM,EAAA,GAAK,IAAI,MAAA,CAAO,QAAA,GAAW,6BAA0B,GAAG,CAAA,CAAE,KAAK,OAAO,CAAA;AAC5E,EAAA,IAAI,CAAC,IAAI,OAAO,MAAA;AAChB,EAAA,IAAI,MAAA,GAAS,GAAG,CAAC,CAAA;AACjB,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,CAAO,mBAAmB,CAAA;AAC7C,EAAA,IAAI,OAAO,CAAA,EAAG,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,GAAG,GAAG,CAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,aAAa,KAAK,EAAC;AAC9C,EAAA,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,OAAO,MAAA;AAG7B,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,MAAW,MAAM,KAAA,EAAO;AACtB,IAAA,MAAA,CAAO,GAAA,CAAI,EAAA,CAAG,CAAC,CAAA,EAAA,CAAI,MAAA,CAAO,GAAA,CAAI,EAAA,CAAG,CAAC,CAAC,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,CAAI,EAAA,CAAG,CAAC,CAAA,EAAA,CAAI,MAAA,CAAO,GAAA,CAAI,EAAA,CAAG,CAAC,CAAC,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AAAA,EAChD;AACA,EAAA,MAAM,WAAA,GAAc,CAAC,GAAG,MAAM,CAAA,CAAE,MAAA,CAAO,CAAC,GAAG,CAAC,CAAA,KAAM,CAAA,KAAM,MAAM,MAAM,CAAA;AACpE,EAAA,IAAI,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AACrC,EAAA,MAAM,IAAA,GAAO,WAAA,CAAY,CAAC,CAAA,CAAE,CAAC,CAAA;AAC7B,EAAA,MAAMnB,OAAAA,GAAS,KAAA,CAAM,GAAA,CAAI,CAAC,OAAQ,EAAA,CAAG,CAAC,CAAA,KAAM,IAAA,GAAO,EAAA,CAAG,CAAC,CAAA,GAAI,EAAA,CAAG,CAAC,CAAE,CAAA;AACjE,EAAA,IAAI,IAAI,GAAA,CAAIA,OAAM,EAAE,IAAA,KAASA,OAAAA,CAAO,QAAQ,OAAO,MAAA;AACnD,EAAA,IAAIA,OAAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,MAAA;AAGlC,EAAA,MAAM,EAAA,GAAK,0BAAA,CAA2B,IAAA,CAAK,OAAO,CAAA;AAClD,EAAA,IAAI,CAAC,IAAI,OAAO,MAAA;AAChB,EAAA,MAAM,UAAU,EAAA,CAAG,CAAC,EAAE,KAAA,CAAM,YAAY,KAAK,EAAC;AAG9C,EAAA,MAAM,QAAA,GAAYA,OAAAA,CAAO,MAAA,IAAUA,OAAAA,CAAO,SAAS,CAAA,CAAA,GAAM,CAAA;AACzD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,QAAA,EAAU,OAAO,MAAA;AACxC,EAAA,IAAI,IAAI,GAAA,CAAI,OAAO,EAAE,IAAA,KAAS,OAAA,CAAQ,QAAQ,OAAO,MAAA;AAErD,EAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAAA,SAAQ,OAAA,EAAQ;AACzC;AAEO,IAAM,0BAAA,GAA2C;AAAA,EACtD,EAAA,EAAI,0BAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,WAAW,CAAA;AAAA,EACtB,MAAM,GAAA,EAAK;AACT,IAAA,IAAI,CAAC,WAAA,CAAY,IAAA,CAAK,IAAI,OAAO,CAAA,SAAU,EAAC;AAC5C,IAAA,MAAM,CAAA,GAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAC3B,IAAA,IAAI,CAAC,CAAA,EAAG,OAAO,EAAC;AAChB,IAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAAA,OAAAA,EAAQ,SAAQ,GAAI,CAAA;AAE1C,IAAA,MAAM,SAAS,CAAC,KAAA,KAAkB,CAAA,CAAA,EAAI,IAAI,GAAG,KAAK,CAAA,CAAA;AAClD,IAAA,MAAM,OAAA,GAAU,IAAI,MAAM,CAAA,CAAA;AAG1B,IAAA,MAAM,WAAoC,EAAC;AAC3C,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAIA,OAAAA,CAAO,MAAA,EAAQ,CAAA,EAAA;AACjC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAA,GAAIA,OAAAA,CAAO,MAAA,EAAQ,CAAA,EAAA,EAAK,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAElE,IAAA,MAAM,OAAA,GAAU;AAAA;AAAA,MAEd,WAAW,OAAA,EAAS,cAAA,EAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,GAAG,CAAA;AAAA;AAAA,MAEzD,QAAA,CAAS,MAAM,EAAE,IAAA,EAAM,YAAY,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,UAAA,EAAY,CAAA;AAAA,MACvE,GAAGA,OAAAA,CAAO,GAAA;AAAA,QAAI,CAAC,CAAA,EAAG,CAAA,KAChB,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,OAAA,EAAS,OAAO,YAAA,CAAa,CAAA,GAAI,YAAA,CAAa,MAAM,GAAG;AAAA,OACjG;AAAA;AAAA,MAEA,GAAGA,QAAO,GAAA,CAAI,CAAC,MAAM,OAAA,CAAQ,IAAA,EAAM,CAAA,EAAG,SAAS,CAAC,CAAA;AAAA;AAAA,MAEhD,GAAGA,OAAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,WAAW,MAAA,CAAO,CAAC,CAAA,EAAG,UAAA,EAAY,EAAE,SAAA,EAAW,CAAC,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA;AAAA;AAAA,MAEhF,GAAG,OAAA,CAAQ,GAAA;AAAA,QAAI,CAAC,CAAA,EAAG,CAAA,KACjB,QAAA,CAAS,CAAA,EAAG;AAAA,UACV,IAAA,EAAM,0BAAA;AAAA,UACN,EAAA,EAAI,OAAOA,OAAAA,CAAO,QAAA,CAAS,CAAC,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AAAA,UACjC,EAAA,EAAI,OAAOA,OAAAA,CAAO,QAAA,CAAS,CAAC,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AAAA,UACjC,OAAA,EAAS;AAAA,SACV;AAAA;AACH,KACF;AAEA,IAAA,MAAM,MAAmB,CAAC;AAAA,MACxB,MAAA,EAAQ,0BAAA;AAAA;AAAA,MAER,WAAW,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,MACtC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AClGA,IAAME,IAAAA,GAAM,+EAAA;AAGZ,IAAMkB,KAAAA,GAAO,mGAAA;AAEb,IAAM,OAAA,GAAU,kDAAA;AAEhB,IAAM,MAAA,GACJ,iJAAA;AAIF,IAAM,OAAO,IAAI,MAAA;AAAA,EACf,gKAAA,GAEE,MAAA,GACA,CAAA,OAAA,EAAU,OAAO,OAAOA,KAAI,CAAA,EAAA,CAAA;AAAA,EAC9B;AACF,CAAA;AAGA,IAAMT,YAAAA,GAAc,4BAAA;AAGpB,IAAMV,UAAAA,GAAY,oDAAA;AAGlB,SAASY,SAAAA,CAAS,KAAwB,MAAA,EAAoC;AAC5E,EAAA,MAAM,OAAO,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,MAAM,CAAA;AAC3C,EAAA,OAAO,IAAA,CAAK,WAAW,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA;AACjD;AAOO,IAAM,qBAAA,GAAsC;AAAA,EACjD,EAAA,EAAI,mBAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAACZ,UAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,IAAA,GAAOC,IAAAA,CAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AACjC,IAAA,MAAM,GAAA,GAAM,IAAA,GAAO,CAAC,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA,GAAI,IAAA;AAEjD,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,IAAA,CAAK,SAAA,GAAY,CAAA;AACjB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AACrC,QAAA,MAAM,QAAA,GAAW,CAAA,CAAE,CAAC,CAAA,KAAM,UAAA;AAC1B,QAAA,MAAM,MAAA,GAAS,EAAE,CAAC,CAAA;AAClB,QAAA,IAAI,MAAA,GAA6B,EAAE,CAAC,CAAA;AACpC,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,IAAI,CAAC,GAAA,IAAO,CAAC,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACnC,UAAA,MAAA,GAASW,SAAAA,CAAS,KAAK,MAAM,CAAA;AAAA,QAC/B;AACA,QAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,QAAA,MAAM,EAAA,GAAKF,aAAY,IAAA,CAAK,CAAA,CAAE,KAAK,KAAA,CAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,CAAA;AACpD,QAAA,IAAI,CAAC,EAAA,EAAI;AACT,QAAA,MAAM,IAAA,GAAO,GAAG,CAAC,CAAA;AACjB,QAAA,IAAI,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAG;AAC3B,QAAA,MAAM,IAAA,GAAO,WAAW,2BAAA,GAA8B,mBAAA;AACtD,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,MAAA,EAAQ,mBAAA;AAAA,UACR,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA;AAAA,UAChB,OAAA,EAAS,CAAC,QAAA,CAAS,IAAA,EAAM,EAAE,MAAM,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,CAAC;AAAA,SACzD,CAAA;AAAA,MACH;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACrEA,IAAM,GAAA,GACJ,QACA,QAAA,GACA,2GAAA;AACF,IAAM,IAAA,GAAO,oBAAA;AAGb,IAAM,SAAA,GAAY,IAAI,MAAA,CAAO,CAAA,2CAAA,EAA+B,GAAG,OAAO,IAAI,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA,EAAI,IAAI,CAAA;AAE5F,IAAM,OAAA,GAAU,IAAI,MAAA,CAAO,CAAA,EAAG,GAAG,CAAA,gBAAA,EAAc,GAAG,oCAA+B,IAAI,CAAA;AAGrF,IAAM,WAAW,IAAI,MAAA;AAAA,EACnB,CAAA,EAAG,GAAG,CAAA,IAAA,EAAO,IAAI,OAAO,GAAG,CAAA,6DAAA,CAAA;AAAA,EAC3B;AACF,CAAA;AAEA,IAAM,cAAc,IAAI,MAAA;AAAA,EACtB,CAAA,wGAAA,EAA0E,GAAG,CAAA,IAAA,EAAO,IAAI,CAAA,IAAA,EAAO,GAAG,CAAA,qBAAA,EAAmB,GAAG,CAAA,IAAA,EAAO,IAAI,CAAA,IAAA,EAAO,GAAG,CAAA,CAAA;AAAA,EAC7I;AACF,CAAA;AAGA,IAAMA,YAAAA,GAAc,4BAAA;AAGpB,IAAMV,UAAAA,GAAY,8BAAA;AAMlB,SAAS,UAAA,CAAW,IAAA,EAAc,IAAA,EAAc,IAAA,EAA8B;AAC5E,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC9B,EAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAC9B,EAAA,MAAM,IAAA,GAAO,CAAC,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AAChD,EAAA,IAAI,IAAI,GAAA,CAAI,IAAI,CAAA,CAAE,IAAA,KAAS,GAAG,OAAO,IAAA;AACrC,EAAA,IAAI,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,OAAO,QAAA,CAAS,IAAA,EAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAI,CAAC,IAAA,EAAM,IAAI,CAAA,EAAG,CAAA;AAClE;AAEO,IAAM,gBAAA,GAAiC;AAAA,EAC5C,EAAA,EAAI,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAACA,UAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,MAAA,MAAM,IAAA,GAAO,CAAC,IAAA,EAAc,IAAA,EAAc,IAAA,KAAiB;AACzD,QAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AACpB,QAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AAC1C,QAAA,IAAI,CAAC,MAAA,EAAQ;AACb,QAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AACb,QAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,cAAA,EAAgB,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,OAAA,EAAS,CAAC,MAAM,GAAG,CAAA;AAAA,MAC3E,CAAA;AAEA,MAAA,WAAA,CAAY,SAAA,GAAY,CAAA;AACxB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,WAAW,CAAA,EAAG;AAC5C,QAAA,IAAA,CAAK,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AACrB,QAAA,IAAA,CAAK,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MACvB;AAGA,MAAA,SAAA,CAAU,SAAA,GAAY,CAAA;AACtB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA,EAAG;AAC1C,QAAA,MAAM,EAAA,GAAKU,aAAY,IAAA,CAAK,CAAA,CAAE,KAAK,KAAA,CAAM,CAAA,EAAG,CAAA,CAAE,KAAK,CAAC,CAAA;AACpD,QAAA,IAAI,EAAA,EAAI,IAAA,CAAK,EAAA,CAAG,CAAC,CAAA,EAAG,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,MAChC;AAEA,MAAA,OAAA,CAAQ,SAAA,GAAY,CAAA;AACpB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG,IAAA,CAAK,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAE/D,MAAA,QAAA,CAAS,SAAA,GAAY,CAAA;AACrB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,EAAG,IAAA,CAAK,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AAAA,IAClE;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACnFA,IAAMU,aAAAA,GAAe,IAAI,MAAA,CAAO,SAAA,GAAY,0DAAuD,GAAG,CAAA;AACtG,IAAMC,aAAAA,GAAe,2BAAA;AAKrB,IAAM,SAAA,GAAY,gDAAA;AAClB,IAAM,SAAA,GAAY,sEAAA;AAGlB,IAAM,OAAA,GAAU,GAAA;AAChB,IAAM,OAAA,GAAU,GAAA;AAGhB,IAAMrB,UAAAA,GAAY,SAAA;AAGlB,SAAS,kBAAA,CAAmB,SAA4B,MAAA,EAAoC;AAC1F,EAAA,MAAM,OAAO,IAAI,MAAA,CAAO,YAAY,CAAA,QAAA,EAAW,MAAM,WAAW,GAAG,CAAA;AACnE,EAAA,KAAA,MAAW,CAAA,IAAK,SAAS,IAAI,IAAA,CAAK,KAAK,CAAA,CAAE,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,EAAA;AACzD,EAAA,OAAO,MAAA;AACT;AAKA,SAASsB,eAAc,OAAA,EAAqC;AAC1D,EAAA,MAAM,CAAA,GAAIF,aAAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACnC,EAAA,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC,CAAA;AACjB,EAAA,MAAM,CAAA,GAAIC,aAAAA,CAAa,IAAA,CAAK,OAAO,CAAA;AACnC,EAAA,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC,CAAA;AACjB,EAAA,OAAO,MAAA;AACT;AAEO,IAAM,SAAA,GAA0B;AAAA,EACrC,EAAA,EAAI,OAAA;AAAA;AAAA,EAEJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAACrB,UAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAA,GAASsB,cAAAA,CAAc,GAAA,CAAI,OAAO,CAAA;AACxC,IAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AAQrB,IAAA,MAAM,SAAkB,EAAC;AACzB,IAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAMC,QAAAA,GAAU,CAAC,EAAA,KAAe;AAC9B,QAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,EAAG;AACnC,UAAA,MAAM,CAAA,GAAI,EAAE,CAAC,CAAA;AACb,UAAA,MAAM,CAAA,GAAI,EAAE,CAAC,CAAA;AACb,UAAA,IAAI,MAAM,CAAA,EAAG;AACb,UAAA,IAAI,CAAA,KAAM,MAAA,IAAU,CAAA,KAAM,MAAA,EAAQ;AAClC,UAAA,MAAM,GAAA,GAAM,CAAC,CAAA,EAAG,CAAC,EAAE,IAAA,EAAK,CAAE,KAAK,GAAG,CAAA;AAClC,UAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,UAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,UAAA,MAAA,CAAO,KAAK,EAAE,QAAA,EAAU,EAAE,EAAA,EAAI,CAAA,EAAG,GAAG,CAAA;AAAA,QACtC;AAAA,MACF,CAAA;AACA,MAAAA,SAAQ,SAAS,CAAA;AACjB,MAAAA,SAAQ,SAAS,CAAA;AAAA,IACnB;AACA,IAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAEjC,IAAA,MAAM,MAAmB,EAAC;AAG1B,IAAA,MAAM,cAAA,GAAiB,kBAAA,CAAmB,GAAA,CAAI,OAAA,EAAS,MAAM,CAAA;AAC7D,IAAA,GAAA,CAAI,IAAA,CAAK;AAAA,MACP,MAAA,EAAQ,OAAA;AAAA,MACR,WAAW,cAAA,KAAmB,MAAA,GAAY,EAAC,GAAI,CAAC,cAAc,CAAA;AAAA,MAC9D,OAAA,EAAS,CAAC,UAAA,CAAW,MAAA,EAAQ,cAAA,EAAgB,EAAE,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,eAAA,EAAiB,CAAC;AAAA,KAC1F,CAAA;AAED,IAAA,KAAA,MAAW,MAAM,MAAA,EAAQ;AACvB,MAAA,GAAA,CAAI,IAAA,CAAK;AAAA,QACP,MAAA,EAAQ,OAAA;AAAA,QACR,SAAA,EAAW,CAAC,EAAA,CAAG,QAAQ,CAAA;AAAA,QACvB,OAAA,EAAS;AAAA,UACP,QAAA,CAAS,GAAG,CAAA,EAAG,EAAE,MAAM,UAAA,EAAY,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,UAC3D,QAAA,CAAS,GAAG,CAAA,EAAG,EAAE,MAAM,UAAA,EAAY,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,CAAA;AAAA,UAC3D,OAAA,CAAQ,EAAA,CAAG,CAAA,EAAG,EAAA,CAAG,GAAG,SAAS;AAAA;AAC/B,OACD,CAAA;AAAA,IACH;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AClHA,IAAMvB,WAAAA,GAAY,aAAA;AAElB,IAAM,kBAAA,GAAqB,kHAAA;AAE3B,IAAM,eAAA,GAAkB,2KAAA;AAExB,SAAS,SAAS,IAAA,EAAwB;AACxC,EAAA,OAAO,IAAA,CACJ,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,MAAA,CAAO,OAAO,CAAA;AACnB;AAEA,SAAS,gBAAgB,IAAA,EAAsB;AAC7C,EAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,OAAA,EAAS,GAAG,EAAE,IAAA,EAAK;AACzC;AAEA,SAAS,aAAA,CAAc,SAAiB,OAAA,EAA0E;AAChH,EAAA,OAAO,QACJ,KAAA,CAAM,QAAQ,CAAA,CACd,GAAA,CAAI,CAAC,IAAA,KAAS,eAAA,CAAgB,IAAI,CAAC,EACnC,MAAA,CAAO,OAAO,CAAA,CACd,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,IACd,IAAA;AAAA,IACA,WAAW,OAAA,CACR,MAAA,CAAO,CAAC,CAAA,KAAM,KAAK,QAAA,CAAS,eAAA,CAAgB,CAAA,CAAE,IAAI,CAAC,CAAC,CAAA,CACpD,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE;AAAA,GACpB,CAAE,CAAA;AACN;AAEA,SAAS,kBAAkB,IAAA,EAAkC;AAC3D,EAAA,MAAM,CAAA,GAAI,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA;AACtC,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,OAAO,CAAA,CAAE,CAAC,CAAA,IAAK,CAAA,CAAE,CAAC,CAAA,IAAK,GAAA;AACzB;AAEA,SAAS,eAAA,CAAgB,MAAc,MAAA,EAA2B;AAChE,EAAA,MAAM,CAAA,GAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA;AACnC,EAAA,IAAI,CAAC,CAAA,EAAG,OAAO,EAAC;AAEhB,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,CAAA,CAAE,CAAC,CAAC,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,CAAA,CAAE,CAAC,CAAC,CAAA;AAC3B,EAAA,IAAI,KAAA,CAAM,WAAW,CAAA,IAAK,KAAA,CAAM,WAAW,KAAA,CAAM,MAAA,SAAe,EAAC;AAEjE,EAAA,OAAO,MAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KACtB,SAAS,IAAA,EAAM,EAAE,IAAA,EAAM,eAAA,EAAiB,QAAQ,MAAA,EAAQ,KAAA,CAAM,CAAC,CAAA,EAAG,CACnE,CAAA;AACH;AAEO,IAAM,oBAAA,GAAqC;AAAA,EAChD,EAAA,EAAI,kBAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAACA,WAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,SAAS,aAAA,CAAc,GAAA,CAAI,OAAA,EAAS,GAAA,CAAI,OAAO,CAAA,EAAG;AAC3D,MAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,KAAA,CAAM,IAAI,CAAA;AAC3C,MAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,MAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,KAAA,CAAM,IAAA,EAAM,MAAM,CAAA;AAClD,MAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AAE1B,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,kBAAA,EAAoB,WAAW,KAAA,CAAM,SAAA,EAAW,SAAS,CAAA;AAAA,IAC9E;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AC3EA,IAAMC,IAAAA,GAAM,6DAAA;AACZ,IAAM,SAAA,GAAY,mEAAA;AAClB,IAAM,wBAAwB,IAAI,MAAA;AAAA,EAChC,YACE,MAAA,GACA,QAAA,GACA,4CAAA,GACA,SAAA,GACA,SACA,QAAA,GACA,gHAAA;AAAA,EACF;AACF,CAAA;AACA,IAAM,iBAAiB,IAAI,MAAA;AAAA,EACzB,wEAAA,GACE,SAAA,GACA,MAAA,GACA,QAAA,GACA,iFAAA;AAAA,EACF;AACF,CAAA;AACA,IAAM,SAAA,GACJ,sGAAA;AAEF,SAASW,SAAAA,CAAS,UAA6B,IAAA,EAAkC;AAC/E,EAAA,MAAM,OAAO,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,IAAI,CAAA;AAC9C,EAAA,OAAO,IAAA,CAAK,WAAW,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA;AACjD;AAEO,IAAM,2BAAA,GAA4C;AAAA,EACvD,EAAA,EAAI,2BAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAAC,IAAI,MAAA,CAAO,QAAA,GAAW,SAAA,EAAW,GAAG,CAAA,EAAG,IAAI,MAAA,CAAO,QAAA,GAAW,aAAA,EAAY,GAAG,CAAC,CAAA;AAAA,EACxF,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,GAAA,GAAMX,IAAAA,CAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAChC,IAAA,MAAM,IAAA,GAAO,SAAA,CAAU,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AACvC,IAAA,MAAM,OAAA,GAAU,qBAAA,CAAsB,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AACtD,IAAA,IAAI,CAAC,GAAA,IAAO,CAAC,QAAQ,CAAC,OAAA,SAAgB,EAAC;AAEvC,IAAA,MAAM,QAAA,GAAW,CAAC,GAAA,CAAI,CAAC,CAAA,EAAG,IAAI,CAAC,CAAA,EAAG,GAAA,CAAI,CAAC,CAAC,CAAA;AACxC,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,CAAC,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,MACjB,CAAC,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC;AAAA,KACnB;AAEA,IAAA,MAAM,kBAAkB,EAAC;AACzB,IAAA,KAAA,MAAW,CAAC,IAAA,EAAM,IAAI,CAAA,IAAK,QAAA,EAAU;AACnC,MAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,IAAK,SAAS,QAAA,CAAS,IAAI,CAAA,EAAG,OAAO,EAAC;AACjE,MAAA,MAAM,GAAA,GAAMW,SAAAA,CAAS,QAAA,EAAU,IAAI,CAAA;AACnC,MAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAClB,MAAA,eAAA,CAAgB,IAAA;AAAA,QACd,QAAA,CAAS,MAAM,EAAE,IAAA,EAAM,YAAY,IAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,CAAA;AAAA,QAC5D,OAAA,CAAQ,IAAA,EAAM,IAAA,EAAM,SAAS;AAAA,OAC/B;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,CAAC,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnC,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,CAAC,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnC,IAAA,MAAM,KAAA,GAAQ,IAAI,GAAA,CAAI,QAAA,CAAS,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,EAAE,CAAC,CAAA;AAC1D,IAAA,IAAI,CAAC,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,IAAK,CAAC,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,IAAK,IAAA,KAAS,IAAA,SAAa,EAAC;AAEnE,IAAA,MAAM,EAAA,GAAK,IAAI,IAAI,CAAA,CAAA;AACnB,IAAA,MAAM,EAAA,GAAK,IAAI,IAAI,CAAA,CAAA;AACnB,IAAA,MAAM,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnB,IAAA,MAAM,CAAA,GAAI,QAAQ,CAAC,CAAA;AACnB,IAAA,IAAI,CAAA,KAAM,CAAA,EAAG,OAAO,EAAC;AAErB,IAAA,MAAM,aAAa,CAAC,GAAG,IAAI,OAAA,CAAQ,QAAA,CAAS,cAAc,CAAC,CAAA;AAC3D,IAAA,MAAM,oBAAoB,EAAC;AAC3B,IAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,MAAA,MAAM,IAAA,GAAO,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA;AAC3B,MAAA,MAAM,GAAA,GAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA;AAC1B,MAAA,MAAM,KAAA,GAAQ,EAAE,CAAC,CAAA;AACjB,MAAA,IAAI,IAAA,KAAS,GAAA,IAAO,KAAA,KAAU,IAAA,CAAK,CAAC,CAAA,IAAK,KAAA,KAAU,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,EAAC;AACpE,MAAA,MAAM,SAAS,GAAA,KAAQ,IAAA,GAAO,EAAA,GAAK,GAAA,KAAQ,OAAO,EAAA,GAAK,MAAA;AACvD,MAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,EAAC;AACrB,MAAA,iBAAA,CAAkB,IAAA;AAAA,QAChB,QAAA,CAAS,KAAA,EAAO,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,CAAC,IAAA,EAAM,MAAM,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG;AAAA,OACzE;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,SAAA,CAAU,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA;AAC3C,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,iBAAA,CAAkB,IAAA;AAAA,QAChB,QAAA,CAAS,QAAA,CAAS,CAAC,CAAA,EAAG;AAAA,UACpB,IAAA,EAAM,cAAA;AAAA,UACN,IAAI,CAAC,CAAA,EAAG,SAAS,CAAC,CAAC,GAAG,QAAA,CAAS,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,EAAG,SAAS,CAAC,CAAC,GAAG,QAAA,CAAS,CAAC,CAAC,CAAA,CAAE;AAAA,SACpE;AAAA,OACH;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,UAAU,UAAA,EAAY,CAAC,GAAG,QAAQ,GAAG,KAAK,CAAA;AAAA,MAC1C,GAAG,eAAA;AAAA,MACH,UAAA,CAAW,EAAA,EAAI,UAAA,EAAY,EAAE,SAAA,EAAW,CAAC,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,GAAG,CAAA;AAAA,MAC5D,UAAA,CAAW,EAAA,EAAI,UAAA,EAAY,EAAE,SAAA,EAAW,CAAC,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,GAAG,CAAA;AAAA,MAC5D,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,sBAAsB,EAAA,EAAI,EAAA,EAAI,KAAA,EAAO,CAAA,EAAG,CAAA;AAAA,MAC5D,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,sBAAsB,EAAA,EAAI,EAAA,EAAI,KAAA,EAAO,CAAA,EAAG,CAAA;AAAA,MAC5D,GAAG;AAAA,KACL;AAEA,IAAA,MAAM,MAAmB,CAAC;AAAA,MACxB,MAAA,EAAQ,2BAAA;AAAA,MACR,WAAW,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,MACtC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;ACjFA,IAAM,UAAU,IAAI,MAAA;AAAA,EAClB,SAAA,GACE,SACA,QAAA,GACA,iIAAA;AAAA,EACF;AACF,CAAA;AAEA,IAAMZ,WAAAA,GAAY,IAAI,MAAA,CAAO,QAAA,GAAW,eAAY,GAAG,CAAA;AAGvD,SAAS,YAAA,CAAa,MAAc,GAAA,EAAiC;AACnE,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,CAAK,CAAC,GAAG,IAAA,CAAK,CAAC,CAAC,CAAA,CAAE,OAAO,CAAC,EAAA,KAAO,GAAA,CAAI,QAAA,CAAS,EAAE,CAAC,CAAA;AACjE,EAAA,OAAO,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAI,MAAA;AAC3C;AAEO,IAAM,2BAAA,GAA4C;AAAA;AAAA;AAAA,EAGvD,EAAA,EAAI,4BAAA;AAAA,EACJ,QAAA,EAAU,EAAA;AAAA,EACV,SAAA,EAAW,CAAC,IAAI,CAAA;AAAA,EAChB,QAAA,EAAU,CAACA,WAAS,CAAA;AAAA,EACpB,MAAM,GAAA,EAAK;AACT,IAAA,MAAM,MAAmB,EAAC;AAC1B,IAAA,KAAA,MAAW,CAAA,IAAK,IAAI,OAAA,EAAS;AAC3B,MAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA;AAC7B,MAAA,IAAI,CAAC,CAAA,EAAG;AAER,MAAA,MAAM,EAAA,GAAK,EAAE,CAAC,CAAA;AACd,MAAA,MAAM,EAAA,GAAK,EAAE,CAAC,CAAA;AACd,MAAA,MAAM,MAAM,EAAA,GAAK,EAAA;AACjB,MAAA,MAAM,QAAQ,CAAA,CAAE,CAAC,EAAE,KAAA,CAAM,uBAAuB,KAAK,EAAC;AACtD,MAAA,MAAM,SAAS,CAAA,CAAE,CAAC,EAAE,KAAA,CAAM,aAAa,KAAK,EAAC;AAG7C,MAAA,IAAI,MAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,MAAA,KAAW,OAAO,MAAA,EAAQ;AAE1D,MAAA,MAAM,MAAA,GAAS,IAAI,GAAG,CAAA,CAAA;AACtB,MAAA,MAAM,OAAA,GAAqB;AAAA,QACzB,UAAA,CAAW,QAAQ,UAAA,EAAY,EAAE,WAAW,CAAC,EAAA,EAAI,EAAE,CAAA,EAAG;AAAA,OACxD;AAEA,MAAA,IAAI,EAAA,GAAK,IAAA;AACT,MAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,QAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,QAAA,MAAM,EAAA,GAAK,OAAO,CAAC,CAAA;AACnB,QAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,IAAA,EAAM,GAAG,CAAA;AAEpC,QAAA,IAAI,CAAC,KAAA,EAAO;AAAE,UAAA,EAAA,GAAK,KAAA;AAAO,UAAA;AAAA,QAAO;AAEjC,QAAA,IAAI,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,EAAE,CAAA,IAAK,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,EAAG;AAAE,UAAA,EAAA,GAAK,KAAA;AAAO,UAAA;AAAA,QAAO;AAChF,QAAA,IAAA,CAAK,IAAI,EAAE,CAAA;AACX,QAAA,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,EAAA,EAAI,EAAE,IAAA,EAAM,sBAAsB,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,CAAC,CAAA;AAAA,MAChF;AACA,MAAA,IAAI,CAAC,EAAA,EAAI;AAET,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,4BAAA,EAA8B,SAAA,EAAW,CAAC,CAAA,CAAE,EAAE,CAAA,EAAG,OAAA,EAAS,CAAA;AAAA,IAC/E;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AACF,CAAA;;;AC1DA,IAAM,KAAA,GAAiC;AAAA,EACrC,YAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,sBAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,0BAAA;AAAA,EACA,qBAAA;AAAA,EACA,gBAAA;AAAA,EACA,SAAA;AAAA,EACA,oBAAA;AAAA,EACA,2BAAA;AAAA,EACA;AACF,CAAA;AAGO,IAAM,SAAA,GAAqC,CAAC,GAAG,KAAK,CAAA,CAAE,IAAA;AAAA,EAC3D,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA,CAAE;AAC3B,CAAA;AAEO,SAAS,SAAS,GAAA,EAA+B;AACtD,EAAA,MAAM,UAAuB,EAAC;AAC9B,EAAA,KAAA,MAAW,QAAQ,SAAA,EAAW;AAC5B,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,CAAK,GAAA,CAAI,OAAO,CAAC,CAAA,EAAG;AACrD,IAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAAA,EACjC;AACA,EAAA,OAAO,OAAA;AACT;;;ACpDA,SAAS,qBAAqB,OAAA,EAA4B;AACxD,EAAA,MAAM,OAAA,GAAU,eAAe,OAAO,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,QAAA,CAAS,EAAE,OAAA,EAAS,SAAS,CAAA;AAC7C,EAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,OAAA,EAAS,OAAO,CAAA;AAEjD,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,MAAM,OAAA,GAAU,OAAA,CACb,OAAA,CAAQ,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA,CACxB,MAAA,CAAO,CAAC,CAAA,KAAM;AACb,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAA;AAC5B,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG,OAAO,KAAA;AAC1B,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,IAAA,OAAO,IAAA;AAAA,EACT,CAAC,CAAA;AACH,EAAA,OAAO,EAAE,OAAA,EAAS,QAAA,EAAU,UAAA,EAAY,QAAQ,MAAA,EAAO;AACzD;AAEO,SAAS,wBAAwB,OAAA,EAAkC;AACxE,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAU,UAAA,EAAW,GAAI,qBAAqB,OAAO,CAAA;AAEtE,EAAA,IAAI,UAAA,KAAe,GAAG,OAAO,EAAE,IAAI,KAAA,EAAO,MAAA,EAAQ,YAAY,QAAA,EAAS;AACvE,EAAA,IAAI,CAAC,SAAS,QAAA,EAAU,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,qBAAA,EAAuB,QAAA,EAAS;AACpF,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,QAAA,EAAS;AACvC;AAsBO,SAAS,wBAAwB,OAAA,EAA6C;AACnF,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAU,UAAA,EAAW,GAAI,qBAAqB,OAAO,CAAA;AACtE,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,OAAA;AAAA,IACZ,WAAW,QAAA,CAAS,SAAA;AAAA,IACpB,QAAA;AAAA,IACA,YAAY,UAAA,GAAa,CAAA,IAAK,CAAC,QAAA,CAAS,QAAA,IAAY,QAAQ,MAAA,GAAS;AAAA,GACvE;AACF;;;AC/DA,IAAM,WAAA,GAAc,8FAAA;AAKpB,IAAM,QAAA,GAAW,4CAAA;AACjB,IAAM,aAAA,GAAgB,0EAAA;AAItB,SAAS,SAAA,CAAU,QAA4B,KAAA,EAA+C;AAC5F,EAAA,IAAI,CAAC,QAAQ,OAAO,MAAA;AACpB,EAAA,OAAO,KAAA,GAAQ,CAAA,EAAG,MAAM,CAAA,CAAA,CAAA,GAAM,MAAA;AAChC;AAIA,IAAM,SAAA,GAAY,kCAAA;AAClB,IAAM,UAAA,GAAa,oFAAA;AAOnB,SAAS,qBAAqB,OAAA,EAA8B;AAC1D,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAY;AAE9B,EAAA,MAAM,GAAA,GAAM,CAAC,EAAA,EAAY,MAAA,KAA+B;AACtD,IAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,IAAA,IAAI,CAAA;AACJ,IAAA,OAAA,CAAQ,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,OAAO,OAAO,IAAA,EAAM;AACtC,MAAA,KAAA,MAAW,CAAC,EAAA,EAAI,EAAE,CAAA,IAAK,MAAA,EAAQ;AAC7B,QAAA,MAAM,OAAO,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA,EAAG,CAAA,CAAE,EAAE,CAAC,CAAA;AACnC,QAAA,IAAI,IAAA,EAAM,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA;AAAA,MAC1B;AAAA,IACF;AAAA,EACF,CAAA;AACA,EAAA,GAAA,CAAI,aAAa,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AACzB,EAAA,GAAA,CAAI,UAAU,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AACtB,EAAA,GAAA,CAAI,aAAA,EAAe,CAAC,CAAC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAC,CAAA;AAEnC,EAAA,KAAA,MAAW,EAAA,IAAM,CAAC,SAAA,EAAW,UAAU,CAAA,EAAG;AACxC,IAAA,EAAA,CAAG,SAAA,GAAY,CAAA;AACf,IAAA,IAAI,CAAA;AACJ,IAAA,OAAA,CAAQ,CAAA,GAAI,EAAA,CAAG,IAAA,CAAK,OAAO,OAAO,IAAA,EAAM;AACtC,MAAA,KAAA,MAAW,MAAM,CAAA,CAAE,CAAC,CAAA,EAAG,KAAA,CAAM,IAAI,EAAE,CAAA;AAAA,IACrC;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,uBAAA,CAAwB,SAAiB,GAAA,EAAmC;AAC1F,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,KAAA,MAAW,KAAK,GAAA,CAAI,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,EAAE,IAAI,CAAA;AAC9C,EAAA,KAAA,MAAW,KAAK,GAAA,CAAI,MAAA,EAAQ,OAAA,CAAQ,GAAA,CAAI,EAAE,IAAI,CAAA;AAE9C,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,IAAA,IAAQ,oBAAA,CAAqB,OAAO,CAAA,EAAG;AAChD,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,OAAA,CAAQ,MAAA,KAAW,GAAG,OAAA,EAAQ;AAC7C;AAYO,SAAS,oBAAA,CAAqB,SAA6B,GAAA,EAAgC;AAChG,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA8B;AACjD,EAAA,KAAA,MAAW,KAAK,GAAA,CAAI,MAAA,SAAe,GAAA,CAAI,CAAA,CAAE,MAAM,CAAgC,CAAA;AAE/E,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAI,MAAA,CAAO,OAAO,WAAA,EAAa;AAC/B,IAAA,MAAM,IAAA,GAAQ,OAA8C,UAAA,EAAY,IAAA;AAOxE,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,KAAS,MAAA,IAAU,SAAS,kBAAA,EAAoB;AAC7D,IAAA,MAAM,OAAQ,MAAA,CAA4B,IAAA;AAC1C,IAAA,MAAM,EAAA,GAAK,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAE1B,IAAA,IAAI,CAAC,EAAA,IAAM,EAAA,CAAG,SAAS,MAAA,EAAQ,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,OAAA,CAAQ,MAAA,KAAW,GAAG,OAAA,EAAQ;AAC7C;;;AClGA,IAAM,UAAA,GAAa,4BAAA;AACnB,IAAM,cAAA,GAAiB,0CAAA;AACvB,IAAM,YAAA,GAAe,+BAAA;AAUd,SAAS,gBAAA,CACd,SACA,OAAA,EACW;AAIX,EAAA,MAAM,gBAAgB,OAAA,CAAQ,MAAA;AAAA,IAC5B,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,YAAA,IAAgB,EAAE,KAAA,KAAU;AAAA,GAC9C,CAAE,MAAA;AACF,EAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,KAAW;AAC7B,IAAA,IAAI,OAAO,EAAA,KAAO,YAAA,SAAqB,cAAA,CAAe,MAAA,EAAQ,SAAS,aAAa,CAAA;AACpF,IAAA,IAAI,MAAA,CAAO,EAAA,KAAO,WAAA,EAAa,OAAO,cAAc,MAAM,CAAA;AAC1D,IAAA,OAAO,MAAA;AAAA,EACT,CAAC,CAAA;AACH;AAWA,SAAS,cAAc,MAAA,EAA0C;AAC/D,EAAA,IAAI,OAAO,IAAA,KAAS,WAAA,IAAe,OAAO,IAAA,IAAQ,CAAC,OAAO,OAAA,EAAS;AACjE,IAAA,MAAM,EAAE,IAAA,EAAM,GAAG,IAAA,EAAK,GAAI,MAAA;AAC1B,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK;AAAA,EAClC;AACA,EAAA,IAAI,OAAO,IAAA,KAAS,gBAAA,IAAoB,OAAO,OAAA,IAAW,CAAC,OAAO,IAAA,EAAM;AACtE,IAAA,MAAM,EAAE,OAAA,EAAS,GAAG,IAAA,EAAK,GAAI,MAAA;AAC7B,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,OAAA,EAAQ;AAAA,EAClC;AACA,EAAA,IAAA,CACG,MAAA,CAAO,IAAA,KAAS,aAAA,IAAiB,MAAA,CAAO,IAAA,KAAS,sBAClD,MAAA,CAAO,IAAA,IACP,CAAC,MAAA,CAAO,OAAA,EACR;AACA,IAAA,MAAM,EAAE,IAAA,EAAM,GAAG,IAAA,EAAK,GAAI,MAAA;AAC1B,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,IAAA,EAAK;AAAA,EAClC;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,cAAA,CACP,MAAA,EACA,OAAA,EACA,aAAA,EACS;AACT,EAAA,QAAQ,OAAO,KAAA;AAAO,IACpB,KAAK,UAAA;AACH,MAAA,OAAO,iBAAA,CAAkB,MAAA,EAAQ,OAAA,EAAS,aAAa,CAAA;AAAA,IACzD,KAAK,WAAA;AACH,MAAA,OAAO,kBAAA,CAAmB,QAAQ,OAAO,CAAA;AAAA,IAC3C,KAAK,QAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,eAAA;AACH,MAAA,OAAO,cAAc,MAAM,CAAA;AAAA,IAC7B;AACE,MAAA,OAAO,MAAA;AAAA;AAEb;AAEA,SAAS,kBAAA,CACP,QACA,OAAA,EACkB;AAClB,EAAA,IAAI,OAAO,OAAA,KAAY,MAAA,IAAU,aAAa,IAAA,CAAK,OAAO,GAAG,OAAO,MAAA;AACpE,EAAA,IAAI,MAAA,CAAO,OAAA,KAAY,UAAA,EAAY,OAAO,MAAA;AAC1C,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,UAAA,EAAW;AAC1C;AAEA,SAAS,cAAc,MAAA,EAA4C;AACjE,EAAA,IAAI,MAAA,CAAO,OAAA,KAAY,UAAA,EAAY,OAAO,MAAA;AAC1C,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,UAAA,EAAW;AAC1C;AAEA,SAAS,iBAAA,CACP,MAAA,EACA,OAAA,EACA,aAAA,EACkB;AAElB,EAAA,IAAI,aAAA,KAAkB,GAAG,OAAO,MAAA;AAChC,EAAA,MAAM,IAAI,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAA,IAAK,OAAA,CAAQ,MAAM,cAAc,CAAA;AACnE,EAAA,IAAI,CAAC,GAAG,OAAO,MAAA;AACf,EAAA,MAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,CAAE,WAAA,EAAY;AAC9B,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA;AACpC,EAAA,IAAI,CAAA,GAAI,GAAG,OAAO,MAAA;AAGlB,EAAA,MAAM,YAAA,GAA4D;AAAA,IAChE,CAAA,EAAG,aAAA;AAAA,IACH,CAAA,EAAG,aAAA;AAAA,IACH,CAAA,EAAG;AAAA,GACL;AACA,EAAA,MAAM,MAAA,GAAS,aAAa,CAAC,CAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,OAAA,KAAY,QAAQ,OAAO,MAAA;AACjD,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAO;AACtC;;;AC/GO,SAAS,4BAA4B,OAAA,EAAwC;AAClF,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAY;AACpC,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,IAAI,EAAE,EAAA,KAAO,aAAA,EAAe,WAAA,CAAY,GAAA,CAAI,EAAE,IAAI,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,YAAY,IAAA,KAAS,CAAA,EAAG,OAAO,CAAC,GAAG,OAAO,CAAA;AAE9C,EAAA,MAAM,SAAA,GAAY,iBAAiB,OAAO,CAAA;AAE1C,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AACvC,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,IAAI,CAAA,CAAE,OAAO,YAAA,EAAc;AACzB,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,MAAA,EAAQ,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,IAChD,CAAA,MAAA,IAAW,CAAA,CAAE,EAAA,KAAO,WAAA,EAAa;AAC/B,MAAA,cAAA,CAAe,GAAA,CAAI,EAAE,IAAI,CAAA;AAAA,IAC3B;AAAA,EACF;AAEA,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAC9B,IAAA,IAAI,UAAU,GAAA,CAAI,IAAI,CAAA,EAAG,UAAA,CAAW,IAAI,IAAI,CAAA;AAAA,EAC9C;AACA,EAAA,IAAI,WAAW,IAAA,KAAS,CAAA,EAAG,OAAO,CAAC,GAAG,OAAO,CAAA;AAE7C,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,IAAA,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,EAAA,CAAI,CAAA;AAAA,EAC9B;AAEA,EAAA,MAAM,SAAoB,EAAC;AAC3B,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,IAAI,EAAE,EAAA,KAAO,aAAA,IAAiB,WAAW,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AACpD,MAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AAC/B,QAAA,MAAM,YAAA,GAAe,iBAAiB,CAAC,CAAA;AACvC,QAAA,IAAI,YAAA,EAAc;AAChB,UAAA,MAAA,CAAO,KAAK,YAAY,CAAA;AACxB,UAAA,cAAA,CAAe,GAAA,CAAI,EAAE,IAAI,CAAA;AAAA,QAC3B;AAAA,MACF;AACA,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,OAAO,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAI,CAAA;AAAA,IACjD,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,IAAA,CAAK,iBAAA,CAAkB,CAAA,EAAG,MAAM,CAAC,CAAA;AAAA,IAC1C;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,iBAAiB,MAAA,EAAiE;AACzF,EAAA,IAAI,MAAA,CAAO,IAAA,KAAS,UAAA,IAAc,MAAA,CAAO,MAAA,EAAQ;AAC/C,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,WAAA;AAAA,MACJ,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,YAAY,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,OAAO,MAAA;AAAO,KACxD;AAAA,EACF;AACA,EAAA,IAAI,MAAA,CAAO,IAAA,KAAS,aAAA,IAAiB,MAAA,CAAO,QAAA,EAAU;AACpD,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,WAAA;AAAA,MACJ,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,YAAY,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,OAAO,QAAA;AAAS,KACtD;AAAA,EACF;AAKA,EAAA,IAAA,CACG,MAAA,CAAO,SAAS,eAAA,IAAmB,MAAA,CAAO,SAAS,cAAA,KACpD,MAAA,CAAO,MAAA,KAAW,MAAA,CAAO,IAAA,EACzB;AACA,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,WAAA;AAAA,MACJ,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,UAAA,EAAY,EAAE,IAAA,EAAM,MAAA;AAAO,KAC7B;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,iBAAiB,OAAA,EAA0C;AAClE,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAI7B,EAAA,MAAM,UAAA,GAAa,CAAC,GAAA,KAAgB;AAClC,IAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,GAAG,CAAA,EAAG;AAC7B,MAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA;AACf,MAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IACjB;AAAA,EACF,CAAA;AACA,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,IAAI,CAAA,CAAE,OAAO,SAAA,EAAW;AACtB,MAAA,IAAA,CAAK,GAAA,CAAI,EAAE,IAAI,CAAA;AACf,MAAA,IAAA,CAAK,GAAA,CAAI,EAAE,EAAE,CAAA;AAAA,IACf,CAAA,MAAA,IAAW,CAAA,CAAE,EAAA,KAAO,WAAA,EAAa;AAC/B,MAAA,MAAM,IAAI,CAAA,CAAE,UAAA;AACZ,MAAA,IAAI,CAAA,CAAE,IAAA,KAAS,UAAA,IAAc,CAAA,CAAE,IAAA,KAAS,cAAA,IAAkB,CAAA,CAAE,IAAA,KAAS,UAAA,IAAc,CAAA,CAAE,IAAA,KAAS,aAAA,EAAe;AAC3G,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,EAAA,EAAI,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,MAClC,WAAW,CAAA,CAAE,IAAA,KAAS,UAAA,IAAc,CAAA,CAAE,SAAS,mBAAA,EAAqB;AAClE,QAAA,IAAA,CAAK,GAAA,CAAI,EAAE,IAAI,CAAA;AACf,QAAA,UAAA,CAAW,EAAE,MAAM,CAAA;AAAA,MACrB,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,cAAA,EAAgB;AACpC,QAAA,IAAA,CAAK,GAAA,CAAI,EAAE,IAAI,CAAA;AAAA,MACjB,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,oBAAA,EAAsB;AAC1C,QAAA,IAAA,CAAK,GAAA,CAAI,EAAE,KAAK,CAAA;AAChB,QAAA,UAAA,CAAW,EAAE,IAAI,CAAA;AAAA,MACnB,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,eAAA,EAAiB;AACrC,QAAA,UAAA,CAAW,EAAE,MAAM,CAAA;AAAA,MACrB,WAAW,CAAA,CAAE,IAAA,KAAS,UAAA,IAAc,CAAA,CAAE,SAAS,WAAA,EAAa;AAC1D,QAAA,UAAA,CAAW,EAAE,EAAE,CAAA;AAAA,MACjB,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,cAAA,EAAgB;AACpC,QAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,EAAA,EAAI,UAAA,CAAW,CAAC,CAAA;AAAA,MACpC;AAAA,IACF,CAAA,MAAA,IAAW,CAAA,CAAE,EAAA,KAAO,aAAA,EAAe;AACjC,MAAA,IAAI,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,GAAA,CAAI,EAAE,MAAM,CAAA;AAC/B,MAAA,IAAI,CAAA,CAAE,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,EAAE,OAAO,CAAA;AACjC,MAAA,IAAI,CAAA,CAAE,QAAQ,KAAA,MAAW,CAAA,IAAK,EAAE,MAAA,EAAQ,IAAA,CAAK,IAAI,CAAC,CAAA;AAClD,MAAA,IAAI,CAAA,CAAE,UAAU,KAAA,MAAW,CAAA,IAAK,EAAE,QAAA,EAAU,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACxD,CAAA,MAAA,IAAW,CAAA,CAAE,EAAA,KAAO,WAAA,EAAa;AAC/B,MAAA,IAAI,CAAA,CAAE,OAAA,EAAS,IAAA,CAAK,GAAA,CAAI,EAAE,OAAO,CAAA;AACjC,MAAA,IAAI,CAAA,CAAE,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,EAAE,IAAI,CAAA;AAC3B,MAAA,IAAI,CAAA,CAAE,EAAA,EAAI,UAAA,CAAW,CAAA,CAAE,EAAE,CAAA;AAAA,IAE3B,CAAA,MAAA,IAAW,CAAA,CAAE,EAAA,KAAO,YAAA,EAAc;AAChC,MAAA,KAAA,MAAW,CAAA,IAAK,CAAA,CAAE,MAAA,EAAQ,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,IACtC;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,iBAAA,CAAkB,QAAiB,MAAA,EAAsC;AAChF,EAAA,IAAI,MAAA,CAAO,OAAO,WAAA,EAAa;AAC7B,IAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,IAAA,IACE,CAAA,CAAE,IAAA,KAAS,eAAA,IACX,CAAA,CAAE,SAAS,cAAA,IACX,CAAA,CAAE,IAAA,KAAS,oBAAA,IACX,CAAA,CAAE,IAAA,KAAS,kBAAA,IACX,CAAA,CAAE,SAAS,UAAA,EACX;AACA,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA;AACrC,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,UAAA,EAAY,EAAE,GAAG,CAAA,EAAG,MAAA,EAAQ,SAAA,EAAU,EAAE;AAAA,MAC9D;AAAA,IACF,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,oBAAA,EAAsB;AAC1C,MAAA,MAAM,QAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,EAAE,KAAK,CAAA,CAAE,EAAA;AACpC,MAAA,MAAM,QAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,EAAE,KAAK,CAAA,CAAE,EAAA;AACpC,MAAA,IAAI,KAAA,KAAU,CAAA,CAAE,EAAA,IAAM,KAAA,KAAU,EAAE,EAAA,EAAI;AACpC,QAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,UAAA,EAAY,EAAE,GAAG,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,EAAA,EAAI,KAAA,EAAM,EAAE;AAAA,MACjE;AAAA,IACF;AAAA,EACF,CAAA,MAAA,IAAW,MAAA,CAAO,EAAA,KAAO,WAAA,EAAa;AACpC,IAAA,IAAI,OAAO,MAAA,IAAU,MAAA,CAAO,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,EAAG;AAC9C,MAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ,OAAO,GAAA,CAAI,MAAA,CAAO,MAAM,CAAA,EAAG;AAAA,IACzD;AACA,IAAA,IAAI,MAAA,CAAO,SAAS,aAAA,EAAe;AACjC,MAAA,MAAM,KAAK,MAAA,CAAO,OAAA,GAAU,OAAO,GAAA,CAAI,MAAA,CAAO,OAAO,CAAA,GAAI,MAAA;AACzD,MAAA,MAAM,KAAK,MAAA,CAAO,OAAA,GAAU,OAAO,GAAA,CAAI,MAAA,CAAO,OAAO,CAAA,GAAI,MAAA;AACzD,MAAA,IAAI,MAAM,EAAA,EAAI;AACZ,QAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,OAAA,EAAS,EAAA,IAAM,OAAO,OAAA,EAAS,OAAA,EAAS,EAAA,IAAM,MAAA,CAAO,OAAA,EAAQ;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;;;AClKA,SAAS,YAAA,CAAa,QAAqB,IAAA,EAAuC;AAChF,EAAA,MAAM,IAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,IAAI,CAAA;AAC5C,EAAA,IAAI,CAAC,GAAG,OAAO,IAAA;AACf,EAAA,IAAI,CAAA,CAAE,SAAS,MAAA,EAAQ,OAAO,CAAC,CAAA,CAAE,CAAA,EAAG,EAAE,CAAC,CAAA;AACvC,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AACzB,IAAA,MAAM,CAAA,GAAI,YAAA,CAAa,MAAA,EAAQ,CAAA,CAAE,EAAE,CAAA;AACnC,IAAA,MAAM,CAAA,GAAI,YAAA,CAAa,MAAA,EAAQ,CAAA,CAAE,EAAE,CAAA;AACnC,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,EAAG,OAAO,IAAA;AACrB,IAAA,OAAO,CAAA,CAAE,CAAA,CAAE,CAAC,CAAA,GAAI,EAAE,CAAC,CAAA,IAAK,CAAA,EAAA,CAAI,CAAA,CAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,KAAK,CAAC,CAAA;AAAA,EAC9C;AACA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,yBAAA,CAA0B,QAAqB,MAAA,EAA2B;AACxF,EAAA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAE1D,EAAA,KAAA,MAAW,MAAM,MAAA,EAAQ;AACvB,IAAA,IAAI,EAAA,CAAG,SAAS,oBAAA,EAAsB;AACtC,IAAA,MAAM,EAAA,GAAK,WAAA,CAAY,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA;AAChC,IAAA,MAAM,EAAA,GAAK,WAAA,CAAY,GAAA,CAAI,EAAA,CAAG,EAAE,CAAA;AAChC,IAAA,IAAI,CAAC,MAAM,CAAC,EAAA,IAAM,GAAG,IAAA,KAAS,UAAA,IAAc,EAAA,CAAG,IAAA,KAAS,UAAA,EAAY;AAEpE,IAAA,MAAM,KAAK,EAAA,CAAG,MAAA;AACd,IAAA,MAAM,KAAK,EAAA,CAAG,MAAA;AACd,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,EAAA,GAAK,EAAE,CAAA;AAC9B,IAAA,MAAM,QAAQ,EAAA,GAAK,EAAA;AAEnB,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,MAAA,EAAQ,EAAA,CAAG,MAAM,CAAA;AAC7C,IAAA,MAAM,MAAA,GAAS,YAAA,CAAa,MAAA,EAAQ,EAAA,CAAG,MAAM,CAAA;AAC7C,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,MAAA,EAAQ;AAExB,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,GAAI,MAAA,CAAO,CAAC,CAAC,CAAA;AACjE,IAAA,MAAM,OAAA,GAAU,QAAQ,IAAA,GAAO,IAAA;AAC/B,IAAA,MAAM,WAAW,KAAA,GAAQ,IAAA;AACzB,IAAA,IAAI,CAAA,GAAI,OAAA,IAAW,CAAA,GAAI,QAAA,EAAU;AAGjC,IAAA,MAAM,EAAA,GAAK,OAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,GAAG,MAAM,CAAA;AAClD,IAAA,MAAM,EAAA,GAAK,OAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,GAAG,MAAM,CAAA;AAClD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,EAAA,EAAI,SAAS,MAAA,EAAQ;AAAE,MAAA,KAAA,GAAQ,EAAA;AAAI,MAAA,MAAA,GAAS,MAAA;AAAA,IAAQ,CAAA,MAAA,IAC/C,EAAA,EAAI,IAAA,KAAS,MAAA,EAAQ;AAAE,MAAA,KAAA,GAAQ,EAAA;AAAI,MAAA,MAAA,GAAS,MAAA;AAAA,IAAQ;AAC7D,IAAA,IAAI,CAAC,KAAA,IAAS,CAAC,MAAA,EAAQ;AAEvB,IAAA,MAAM,OAAA,GAAA,CAAW,QAAQ,KAAA,IAAS,CAAA;AAClC,IAAA,IAAI,EAAA,GAAK,KAAA,CAAM,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA;AAC3B,IAAA,IAAI,EAAA,GAAK,KAAA,CAAM,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA;AAC3B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA;AAC7B,IAAA,IAAI,MAAM,IAAA,EAAM;AAAE,MAAA,EAAA,GAAK,CAAA;AAAG,MAAA,EAAA,GAAK,CAAA;AAAA,IAAG;AAClC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,EAAA,EAAI,EAAE,CAAA,IAAK,CAAA;AACnC,IAAA,KAAA,CAAM,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAK,UAAU,EAAA,GAAM,IAAA;AACvC,IAAA,KAAA,CAAM,CAAA,GAAI,MAAA,CAAO,CAAC,CAAA,GAAK,UAAU,EAAA,GAAM,IAAA;AAAA,EACzC;AACF;ACpEO,IAAM,KAAA,GAAQa,KAAA,CAClB,MAAA,EAAO,CACP,MAAM,kCAAkC,CAAA;;;AC6DpC,SAAS,aACd,CAAA,EACe;AACf,EAAA,OAAO,CAAA;AACT;;;ACpEO,IAAM,iBAAA,GAAoB;AAAA,EAC/B,OAAA,EAAS,IAAA;AAAA,EACT,MAAA,EAAQ,KAAA;AAAA,EACR,KAAA,EAAO,SAAA;AAAA,EACP,aAAA,EAAe;AACjB,CAAA;AAGO,SAAS,eAAA,CACd,EAAA,EACA,IAAA,EACA,UAAA,EACA,UAAU,IAAA,EACG;AACb,EAAA,OAAO;AAAA,IACL,EAAA;AAAA,IACA,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,IAAA;AAAA,IACP,GAAG,iBAAA;AAAA,IACH,OAAA;AAAA,IACA,KAAA,EAAO,EAAE,UAAA;AAAW,GACtB;AACF;AAGO,SAAS,uBAAA,CACd,KACA,QAAA,EAC0B;AAC1B,EAAA,OAAO,CAAC,GAAA,CAAI,SAAA,CAAU,SAAS,CAAC,CAAC,GAAG,GAAA,CAAI,SAAA,CAAU,QAAA,CAAS,CAAC,CAAC,CAAA,EAAG,GAAA,CAAI,UAAU,QAAA,CAAS,CAAC,CAAC,CAAC,CAAA;AAC5F;AAEO,IAAM,iBAAA,GAAoB;AAAA,EAC/B,OAAA,EAAS,IAAA;AAAA,EACT,MAAA,EAAQ,KAAA;AAAA,EACR,KAAA,EAAO,SAAA;AAAA,EACP,aAAA,EAAe;AACjB,CAAA;;;AChCO,IAAM,aAAa,YAAA,CAA4B;AAAA,EACpD,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,IACtB,CAAA,EAAGA,KAAAA,CAAE,MAAA,EAAO,CAAE,MAAA,EAAO;AAAA,IACrB,CAAA,EAAGA,KAAAA,CAAE,MAAA,EAAO,CAAE,MAAA;AAAO,GACtB,CAAA;AAAA,EACD,WAAA,EAAa,MAAM,EAAC;AAAA,EACpB,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,QAAQ,eAAA,CAAgB,GAAA,CAAI,UAAU,CAAA,CAAE,IAAI,GAAG,CAAA,CAAE,IAAA,EAAM,EAAE,IAAA,EAAM,QAAQ,CAAA,EAAG,CAAA,CAAE,GAAG,CAAA,EAAG,CAAA,CAAE,GAAG;AAAA,GACxF;AACH,CAAC,CAAA;AChBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI,KAAA;AAAA,IACJ,OAAA,EAASA,KAAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AAAS,GAC/B,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,EAAE,CAAA;AAAA,EAC/B,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,IAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA,EAAG,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA,EAAE;AAAA,MACrE,EAAE,OAAA,IAAW;AAAA;AACf,GACD;AACH,CAAC,CAAA;ACtBM,IAAM,kBAAkB,YAAA,CAAiC;AAAA,EAC9D,IAAA,EAAM,WAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,WAAW,CAAA;AAAA,IAC3B,SAAA,EAAW,KAAA;AAAA,IACX,CAAA,EAAGA,MAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,CAAC;AAAA,GAC3B,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,SAAS,CAAA;AAAA,EAChC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,IAAA,EAAM,WAAA,EAAa,SAAA,EAAW,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,SAAS,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA;AAAE;AACrE,GACD;AACH,CAAC,CAAA;ACpBM,IAAM,eAAe,YAAA,CAA8B;AAAA,EACxD,IAAA,EAAM,QAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,QAAQ,CAAA;AAAA,IACxB,MAAA,EAAQ,KAAA;AAAA,IACR,CAAA,EAAGA,KAAAA,CAAE,MAAA,EAAO,CAAE,MAAA;AAAO,GACtB,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,MAAM,CAAA;AAAA,EAC7B,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA,EAAG,CAAA,EAAG,CAAA,CAAE,CAAA;AAAE;AAC5D,GACD;AACH,CAAC,CAAA;ACpBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,QAAA,EAAU,KAAA;AAAA,IACV,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,MAAA;AAAO,GAC1B,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,QAAQ,CAAA;AAAA,EAC/B,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAQ,CAAA,EAAG,KAAA,EAAO,CAAA,CAAE,KAAA;AAAM;AAC1E,GACD;AACH,CAAC,CAAA;ACpBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,IAAA,EAAM,KAAA;AAAA,IACN,MAAA,EAAQ;AAAA,GACT,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,EAAE,MAAM,CAAA;AAAA,EACrC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,IAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA,EAAG,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAAE;AACnF,GACD;AACH,CAAC,CAAA;ACpBM,IAAM,qBAAqB,YAAA,CAAoC;AAAA,EACpE,IAAA,EAAM,cAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA;AAAA,IAC9B,UAAUA,KAAAA,CAAE,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC;AAAA,GACxC,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,MAAM,cAAA,EAAgB,QAAA,EAAU,wBAAwB,GAAA,EAAK,CAAA,CAAE,QAAQ,CAAA;AAAE;AAC7E,GACD;AACH,CAAC,CAAA;ACnBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,UAAUA,KAAAA,CAAE,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC;AAAA,GACxC,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,MAAM,UAAA,EAAY,QAAA,EAAU,wBAAwB,GAAA,EAAK,CAAA,CAAE,QAAQ,CAAA;AAAE;AACzE,GACD;AACH,CAAC,CAAA;ACnBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,UAAUA,KAAAA,CAAE,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC;AAAA,GACxC,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,MAAM,UAAA,EAAY,QAAA,EAAU,wBAAwB,GAAA,EAAK,CAAA,CAAE,QAAQ,CAAA;AAAE;AACzE,GACD;AACH,CAAC,CAAA;ACnBM,IAAM,oBAAoB,YAAA,CAAmC;AAAA,EAClE,IAAA,EAAM,aAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,aAAa,CAAA;AAAA,IAC7B,UAAUA,KAAAA,CAAE,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC;AAAA,GACxC,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF,EAAE,MAAM,aAAA,EAAe,QAAA,EAAU,wBAAwB,GAAA,EAAK,CAAA,CAAE,QAAQ,CAAA;AAAE;AAC5E,GACD;AACH,CAAC,CAAA;ACnBM,IAAM,qBAAqB,YAAA,CAAoC;AAAA,EACpE,IAAA,EAAM,cAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA;AAAA,IAC9B,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAM,KAAA;AAAA,IACN,MAAA,EAAQA,KAAAA,CAAE,KAAA,CAAM,CAACA,MAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAC,EAAE,QAAA;AAAS,GACxD,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,EAAE,IAAI,CAAA;AAAA,EACnC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ;AAChB,IAAA,MAAM,UAAA,GAAa,GAAA,CAAI,MAAA,CAAO,CAAA,CAAE,IAAI,CAAA,KAAM,QAAA;AAC1C,IAAA,MAAM,UAAA,GAAa,GAAA,CAAI,MAAA,CAAO,CAAA,CAAE,IAAI,CAAA,KAAM,QAAA;AAC1C,IAAA,IAAI,aAAA;AACJ,IAAA,IAAI,UAAA,IAAc,YAAY,aAAA,GAAgB,cAAA;AAAA,SAAA,IACrC,UAAA,IAAc,YAAY,aAAA,GAAgB,YAAA;AAAA,SAC9C,aAAA,GAAgB,UAAA;AAErB,IAAA,MAAM,KAAA,GAAiC;AAAA,MACrC,IAAA,EAAM,aAAA;AAAA,MACN,IAAA,EAAM,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MAC1B,IAAA,EAAM,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI;AAAA,KAC5B;AACA,IAAA,IAAI,kBAAkB,UAAA,EAAY;AAChC,MAAA,KAAA,CAAM,MAAA,GAAS,EAAE,MAAA,IAAU,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,CAAC;AAAA,MACN,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,QACxB,IAAA,EAAM,cAAA;AAAA,QACN,OAAO,CAAA,CAAE,IAAA;AAAA,QACT,GAAG,iBAAA;AAAA,QACH;AAAA;AACF,KACD,CAAA;AAAA,EACH;AACF,CAAC,CAAA;ACxCM,IAAM,gBAAgB,YAAA,CAA+B;AAAA,EAC1D,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,SAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,SAAS,CAAA;AAAA,IACzB,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACL,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,EAAE,CAAA;AAAA,EAC/B,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,SAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO,EAAE,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA,EAAG,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAE;AAC5D,GACD;AACH,CAAC,CAAA;ACtBM,IAAM,aAAa,YAAA,CAA4B;AAAA,EACpD,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAM,MAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAAA,IACtB,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACL,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,EAAE,CAAA;AAAA,EAC/B,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,MAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO,EAAE,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA,EAAG,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAE;AAC5D,GACD;AACH,CAAC,CAAA;ACtBM,IAAM,YAAY,YAAA,CAA2B;AAAA,EAClD,IAAA,EAAM,KAAA;AAAA,EACN,IAAA,EAAM,KAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,KAAK,CAAA;AAAA,IACrB,MAAA,EAAQ,KAAA;AAAA,IACR,OAAA,EAAS;AAAA,GACV,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,MAAA,EAAQ,EAAE,OAAO,CAAA;AAAA,EACxC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,KAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO,EAAE,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA,EAAG,OAAA,EAAS,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAE;AAC9E,GACD;AACH,CAAC,CAAA;ACtBM,IAAM,sBAAsB,YAAA,CAAqC;AAAA,EACtE,IAAA,EAAM,eAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,eAAe,CAAA;AAAA,IAC/B,YAAA,EAAc,KAAA;AAAA,IACd,MAAA,EAAQ;AAAA,GACT,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,YAAA,EAAc,EAAE,MAAM,CAAA;AAAA,EAC7C,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,MAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,eAAA;AAAA,UACN,YAAA,EAAc,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,YAAY,CAAA;AAAA,UAC1C,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM;AAAA;AAChC;AACF;AACF,GACD;AACH,CAAC,CAAA;AC5BM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,YAAA,EAAc,KAAA;AAAA,IACd,MAAA,EAAQ;AAAA,GACT,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,YAAA,EAAc,EAAE,MAAM,CAAA;AAAA,EAC7C,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,MAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,UAAA;AAAA,UACN,YAAA,EAAc,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,YAAY,CAAA;AAAA,UAC1C,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM;AAAA;AAChC;AACF;AACF,GACD;AACH,CAAC,CAAA;AC5BM,IAAM,qBAAqB,YAAA,CAAoC;AAAA,EACpE,IAAA,EAAM,cAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA;AAAA,IAC9B,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACL,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,EAAE,CAAA;AAAA,EAC/B,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,MAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,cAAA;AAAA,UACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,UACtB,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE;AAAA;AACxB;AACF;AACF,GACD;AACH,CAAC,CAAA;AC5BM,IAAM,sBAAsB,YAAA,CAAqC;AAAA,EACtE,IAAA,EAAM,eAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,eAAe,CAAA;AAAA,IAC/B,EAAA,EAAI,KAAA;AAAA,IACJ,MAAA,EAAQ,KAAA;AAAA,IACR,EAAA,EAAI;AAAA,GACL,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,EAAA,EAAI,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,EAAE,CAAA;AAAA,EACzC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,MAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,eAAA;AAAA,UACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,UACtB,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAAA,UAC9B,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE;AAAA;AACxB;AACF;AACF,GACD;AACH,CAAC,CAAA;ACzBM,IAAM,oBAAoB,YAAA,CAAmC;AAAA,EAClE,IAAA,EAAM,aAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,aAAa,CAAA;AAAA,IAC7B,QAAQA,KAAAA,CAAE,KAAA,CAAM,KAAK,CAAA,CAAE,IAAI,CAAC;AAAA,GAC7B,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,MAAM,CAAA;AAAA,EAChC,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,UAAU,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,EACzD,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,MAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,aAAA;AAAA,UACN,MAAA,EAAQ,EAAE,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,SAAA,CAAU,CAAC,CAAC;AAAA;AAC9C;AACF;AACF,GACD;AACH,CAAC,CAAA;AC1BM,IAAM,oBAAoB,YAAA,CAAmC;AAAA,EAClE,IAAA,EAAM,aAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,aAAa,CAAA;AAAA,IAC7B,OAAA,EAAS,KAAA;AAAA,IACT,OAAA,EAAS;AAAA,GACV,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,OAAA,EAAS,EAAE,OAAO,CAAA;AAAA,EACzC,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,QAAA,EAAS;AAAA,IACnC,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,QAAA;AAAS,GACrC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,MAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,aAAA;AAAA,UACN,OAAA,EAAS,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAA,UAChC,OAAA,EAAS,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,OAAO;AAAA;AAClC;AACF;AACF,GACD;AACH,CAAC,CAAA;ACtCM,IAAM,gBAAgB,YAAA,CAA+B;AAAA,EAC1D,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,kBAAA;AAAA,EACN,QAAA,EAAU,OAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,SAAS,CAAA;AAAA,IACzB,YAAA,EAAc,KAAA;AAAA,IACd,QAAA,EAAU,KAAA;AAAA,IACV,QAAQA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,GAAGA,KAAAA,CAAE,OAAA,CAAQ,IAAI,CAAC,CAAC,EAAE,QAAA;AAAS,GACzE,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,YAAA,EAAc,EAAE,QAAQ,CAAA;AAAA,EAC/C,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ;AAChB,IAAA,MAAM,YAAA,GAAwC;AAAA,MAC5C,IAAA,EAAM,SAAA;AAAA,MACN,YAAA,EAAc,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,YAAY,CAAA;AAAA,MAC1C,QAAA,EAAU,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAQ;AAAA,KACpC;AACA,IAAA,IAAI,CAAA,CAAE,MAAA,KAAW,MAAA,EAAW,YAAA,CAAa,SAAS,CAAA,CAAE,MAAA;AACpD,IAAA,OAAO,CAAC;AAAA,MACN,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ;AAAA,QACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,QACxB,IAAA,EAAM,MAAA;AAAA,QACN,OAAO,CAAA,CAAE,IAAA;AAAA,QACT,GAAG,iBAAA;AAAA,QACH,KAAA,EAAO,EAAE,YAAA;AAAa;AACxB,KACD,CAAA;AAAA,EACH;AACF,CAAC,CAAA;AC/BM,IAAM,gBAAgB,YAAA,CAA+B;AAAA,EAC1D,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,SAAA;AAAA,EACN,QAAA,EAAU,UAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,SAAS,CAAA;AAAA,IACzB,UAAUA,KAAAA,CAAE,KAAA,CAAM,KAAK,CAAA,CAAE,IAAI,CAAC;AAAA,GAC/B,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,SAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO,EAAE,QAAA,EAAU,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,CAAI,SAAA,CAAU,CAAC,CAAC,CAAA;AAAE;AAC7D,GACD;AACH,CAAC,CAAA;ACrBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,MAAA,EAAQ,KAAA;AAAA,IACR,YAAA,EAAc,KAAA;AAAA,IACd,OAAA,EAASA,KAAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AAAS,GAC/B,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,MAAA,EAAQ,EAAE,YAAY,CAAA;AAAA,EAC7C,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,QAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,OAAA,EAAS,EAAE,OAAA,IAAW,IAAA;AAAA,MACtB,KAAA,EAAO,EAAE,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA,EAAG,YAAA,EAAc,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,YAAY,CAAA;AAAE;AACxF,GACD;AACH,CAAC,CAAA;ACxBM,IAAM,gBAAgB,YAAA,CAA+B;AAAA,EAC1D,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,SAAS,CAAA;AAAA,IACzB,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI;AAAA,GACL,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,CAAA,CAAE,EAAE,CAAA;AAAA,EACrC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,QAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,eAAA;AAAA,UACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,UACtB,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,UACtB,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE;AAAA;AACxB;AACF;AACF,GACD;AACH,CAAC,CAAA;AC5BM,IAAM,uBAAuB,YAAA,CAAsC;AAAA,EACxE,IAAA,EAAM,gBAAA;AAAA,EACN,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,gBAAgB,CAAA;AAAA,IAChC,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI,KAAA;AAAA,IACJ,OAAA,EAASA,KAAAA,CAAE,OAAA,EAAQ,CAAE,QAAA;AAAS,GAC/B,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,EAAE,CAAA;AAAA,EAC/B,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,QAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,OAAA,EAAS,EAAE,OAAA,IAAW,IAAA;AAAA,MACtB,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,UAAA;AAAA,UACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,UACtB,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE;AAAA;AACxB;AACF;AACF,GACD;AACH,CAAC,CAAA;ACjCM,IAAM,2BAA2B,YAAA,CAA0C;AAAA,EAChF,IAAA,EAAM,oBAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,oBAAoB,CAAA;AAAA,IACpC,IAAA,EAAM,KAAA;AAAA,IACN,MAAA,EAAQ,KAAA;AAAA,IACR,KAAA,EAAO;AAAA,GACR,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,IAAA,EAAM,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,KAAK,CAAA;AAAA,EAC9C,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,WAAA,EAAY;AAAA,IACnC,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,QAAA,EAAS;AAAA,IAClC,EAAE,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,OAAA;AAAQ,GAClC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF;AAAA,QACE,IAAA,EAAM,oBAAA;AAAA,QACN,IAAA,EAAM,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,QAC1B,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAAA,QAC9B,KAAA,EAAO,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,KAAK;AAAA;AAC9B;AACF,GACD;AACH,CAAC,CAAA;AC9BM,IAAM,2BAA2B,YAAA,CAA0C;AAAA,EAChF,IAAA,EAAM,oBAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,oBAAoB,CAAA;AAAA,IACpC,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI,KAAA;AAAA,IACJ,KAAA,EAAOA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAC;AAAA,GAC5C,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,EAAE,CAAA;AAAA,EAC/B,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,QAAA,EAAS;AAAA,IAC9B,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,QAAA;AAAS,GAChC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF;AAAA,QACE,IAAA,EAAM,oBAAA;AAAA,QACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,QACtB,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,QACtB,OAAO,CAAA,CAAE;AAAA;AACX;AACF,GACD;AACH,CAAC,CAAA;AC5BM,IAAM,iCAAiC,YAAA,CAAgD;AAAA,EAC5F,IAAA,EAAM,0BAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,0BAA0B,CAAA;AAAA,IAC1C,EAAA,EAAI,KAAA;AAAA,IACJ,EAAA,EAAI,KAAA;AAAA,IACJ,OAAA,EAAS;AAAA,GACV,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,CAAA,CAAE,OAAO,CAAA;AAAA,EAC1C,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,QAAA,EAAS;AAAA,IAC9B,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,QAAA,EAAS;AAAA,IAC9B,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,OAAA;AAAQ,GACpC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF;AAAA,QACE,IAAA,EAAM,0BAAA;AAAA,QACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,QACtB,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,QACtB,OAAA,EAAS,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,OAAO;AAAA;AAClC;AACF,GACD;AACH,CAAC,CAAA;AClCM,IAAM,sBAAsB,YAAA,CAAqC;AAAA,EACtE,IAAA,EAAM,eAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,eAAe,CAAA;AAAA,IAC/B,MAAA,EAAQ,KAAA;AAAA,IACR,MAAA,EAAQ;AAAA,GACT,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,MAAA,EAAQ,EAAE,MAAM,CAAA;AAAA,EACvC,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,QAAA,EAAS;AAAA,IAClC,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,WAAA;AAAY,GACvC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF;AAAA,QACE,IAAA,EAAM,eAAA;AAAA,QACN,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAAA,QAC9B,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM;AAAA;AAChC;AACF,GACD;AACH,CAAC,CAAA;AC5BM,IAAM,wBAAwB,YAAA,CAAuC;AAAA,EAC1E,IAAA,EAAM,iBAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,iBAAiB,CAAA;AAAA,IACjC,IAAA,EAAM,KAAA;AAAA,IACN,MAAA,EAAQ,KAAA;AAAA,IACR,KAAA,EAAOA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAC;AAAA,GAC5C,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,EAAE,MAAM,CAAA;AAAA,EACrC,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAQ;AAAA,IAC/B,EAAE,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,QAAA;AAAS,GACpC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,eAAA;AAAA,MACN,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACpB,CAAA,CAAE,IAAA;AAAA,MACF;AAAA,QACE,IAAA,EAAM,iBAAA;AAAA,QACN,IAAA,EAAM,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,QAC1B,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAAA,QAC9B,OAAO,CAAA,CAAE;AAAA;AACX;AACF,GACD;AACH,CAAC,CAAA;AC9BM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,MAAA,EAAQ,KAAA;AAAA,IACR,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAAS,GAC7B,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,EAAE,MAAM,CAAA;AAAA,EAC7B,UAAU,CAAC,EAAE,OAAO,QAAA,EAAU,IAAA,EAAM,SAAS,CAAA;AAAA,EAC7C,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,QAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO,EAAE,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,EAAE,MAAM,CAAA,EAAG,MAAA,EAAQ,CAAA,CAAE,MAAA;AAAO;AAC7D,GACD;AACH,CAAC,CAAA;ACvBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,UAAUA,KAAAA,CAAE,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC;AAAA,GACxC,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,QAAA,EAAU,CAAC,EAAE,KAAA,EAAO,YAAY,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,EAC3D,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,QAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,UAAA;AAAA,QACN,QAAA,EAAU;AAAA,UACR,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,UAC3B,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,UAC3B,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC;AAAA;AAC7B;AACF;AACF,GACD;AACH,CAAC,CAAA;AC7BM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,SAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,UAAUA,KAAAA,CAAE,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC,CAAA;AAAA,IACvC,QAAA,EAAU;AAAA,GACX,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,EAAM,OAAA,EAAS,MAAM,IAAA,EAAK;AAAA,IAC/C,EAAE,KAAA,EAAO,UAAA,EAAY,IAAA,EAAM,OAAA;AAAQ,GACrC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,MACxB,IAAA,EAAM,QAAA;AAAA,MACN,OAAO,CAAA,CAAE,IAAA;AAAA,MACT,GAAG,iBAAA;AAAA,MACH,KAAA,EAAO;AAAA,QACL,YAAA,EAAc;AAAA,UACZ,IAAA,EAAM,UAAA;AAAA,UACN,IAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,UAC/B,IAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,UAC/B,IAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA;AAAA,UAC/B,QAAA,EAAU,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAQ;AAAA;AACpC;AACF;AACF,GACD;AACH,CAAC,CAAA;ACjCM,IAAM,oBAAoB,YAAA,CAAmC;AAAA,EAClE,IAAA,EAAM,aAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,aAAa,CAAA;AAAA,IAC7B,MAAA,EAAQ,KAAA;AAAA,IACR,CAAA,EAAG,KAAA;AAAA,IACH,CAAA,EAAG,KAAA;AAAA,IACH,aAAA,EAAe;AAAA,GAChB,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,aAAa,CAAA;AAAA,EACxD,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,gBAAgB,GAAA,CAAI,SAAA,CAAU,EAAE,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM;AAAA,MACrD,IAAA,EAAM,aAAA;AAAA,MACN,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAAA,MAC9B,CAAA,EAAG,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA;AAAA,MACpB,CAAA,EAAG,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,CAAC,CAAA;AAAA,MACpB,aAAA,EAAe,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,aAAa;AAAA,KAC7C;AAAA,GACF;AACH,CAAC,CAAA;ACxBM,IAAM,iBAAiB,YAAA,CAAgC;AAAA,EAC5D,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA;AAAA,IAC1B,UAAUA,KAAAA,CAAE,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,CAAC,CAAA;AAAA,IACvC,QAAA,EAAU;AAAA,GACX,CAAA;AAAA,EACD,aAAa,CAAC,CAAA,KAAM,CAAC,GAAG,EAAE,QAAQ,CAAA;AAAA,EAClC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,gBAAgB,GAAA,CAAI,SAAA,CAAU,EAAE,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM;AAAA,MACrD,IAAA,EAAM,UAAA;AAAA,MACN,QAAA,EAAU,uBAAA,CAAwB,GAAA,EAAK,CAAA,CAAE,QAAQ,CAAA;AAAA,MACjD,QAAA,EAAU,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,QAAQ;AAAA,KACnC;AAAA,GACF;AACH,CAAC,CAAA;ACpBM,IAAM,qBAAqB,YAAA,CAAoC;AAAA,EACpE,IAAA,EAAM,cAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,KAAAA,CAAE,MAAA,CAAO,EAAE,MAAM,KAAA,EAAO,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,OAAO,CAAA;AAAA,EAC5F,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,OAAO,CAAA;AAAA,EACpC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,gBAAgB,GAAA,CAAI,SAAA,CAAU,EAAE,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM;AAAA,MACrD,IAAA,EAAM,aAAA;AAAA,MACN,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,MAC1B,SAAA,EAAW,EAAE,IAAA,EAAM,cAAA,EAAgB,QAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAE,KACrE;AAAA,GACF;AACH,CAAC,CAAA;ACfM,IAAM,oBAAoB,YAAA,CAAmC;AAAA,EAClE,IAAA,EAAM,aAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,KAAAA,CAAE,MAAA,CAAO,EAAE,MAAM,KAAA,EAAO,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,aAAa,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,OAAO,CAAA;AAAA,EAC3F,aAAa,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,EAAA,EAAI,EAAE,OAAO,CAAA;AAAA,EACpC,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ,CAAC;AAAA,IACjB,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,gBAAgB,GAAA,CAAI,SAAA,CAAU,EAAE,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM;AAAA,MACrD,IAAA,EAAM,aAAA;AAAA,MACN,MAAA,EAAQ,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAAA,MAC1B,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,MAAM,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAE,KAClE;AAAA,GACF;AACH,CAAC,CAAA;ACbD,IAAM,YAAA,GAAe;AAAA,EACnB,OAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,QAAA,EAAS;AAAA,EACtC,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACrB,CAAA;AACA,IAAM,SAAA,GAAYA,KAAAA,CAAE,kBAAA,CAAmB,MAAA,EAAQ;AAAA,EAC7CA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA,EAAG,MAAA,EAAQ,KAAA,EAAO,GAAG,YAAA,EAAc,CAAA;AAAA,EAC5EA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,eAAe,CAAA,EAAG,EAAA,EAAI,KAAA,EAAO,EAAA,EAAI,KAAA,EAAO,GAAG,cAAc,CAAA;AAAA,EACpFA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,SAAS,CAAA,EAAG,KAAA,EAAOA,KAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,EAAG,GAAG,cAAc;AACxF,CAAC,CAAA;AAGD,SAAS,eAAA,CAAkC,MAAS,CAAA,EAA2C;AAC7F,EAAA,MAAM,GAAA,GAAM,EAAE,GAAG,IAAA,EAAK;AACtB,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,MAAA,EAAW,GAAA,CAAI,QAAQ,CAAA,CAAE,KAAA;AACzC,EAAA,IAAI,CAAA,CAAE,MAAA,KAAW,MAAA,EAAW,GAAA,CAAI,SAAS,CAAA,CAAE,MAAA;AAC3C,EAAA,OAAO,GAAA;AACT;AAEO,IAAM,wBAAwB,YAAA,CAAuC;AAAA,EAC1E,IAAA,EAAM,iBAAA;AAAA,EACN,IAAA,EAAM,OAAA;AAAA,EACN,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQA,MAAE,MAAA,CAAO;AAAA,IACf,IAAA,EAAM,KAAA;AAAA,IACN,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,iBAAiB,CAAA;AAAA,IACjC,IAAA,EAAM,KAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA,IACT,QAAA,EAAU;AAAA,GACX,CAAA;AAAA,EACD,WAAA,EAAa,CAAC,CAAA,KAAM;AAClB,IAAA,MAAM,IAAI,CAAA,CAAE,QAAA;AACZ,IAAA,MAAM,QAAQ,CAAA,CAAE,IAAA,KAAS,cAAA,GAAiB,CAAC,EAAE,MAAM,CAAA,GAC/C,CAAA,CAAE,IAAA,KAAS,kBAAkB,CAAC,CAAA,CAAE,IAAI,CAAA,CAAE,EAAE,IAAI,EAAC;AACjD,IAAA,OAAO,CAAC,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,OAAA,EAAS,GAAG,KAAK,CAAA;AAAA,EACrC,CAAA;AAAA;AAAA;AAAA,EAGA,QAAA,EAAU;AAAA,IACR,EAAE,KAAA,EAAO,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAQ;AAAA,IAC/B,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAM,OAAA;AAAQ,GACpC;AAAA,EACA,IAAA,EAAM,CAAC,CAAA,EAAG,GAAA,KAAQ;AAChB,IAAA,MAAM,IAAI,CAAA,CAAE,QAAA;AACZ,IAAA,MAAM,QAAA,GAAW,EAAE,IAAA,KAAS,cAAA,GACxB,gBAAgB,EAAE,IAAA,EAAM,gBAAgB,MAAA,EAAQ,GAAA,CAAI,UAAU,CAAA,CAAE,MAAM,GAAE,EAAG,CAAC,IAC5E,CAAA,CAAE,IAAA,KAAS,eAAA,GACT,eAAA,CAAgB,EAAE,IAAA,EAAM,iBAAiB,EAAA,EAAI,GAAA,CAAI,UAAU,CAAA,CAAE,EAAE,GAAG,EAAA,EAAI,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA,IAAK,CAAC,CAAA,GAC9F,gBAAgB,EAAE,IAAA,EAAM,WAAW,KAAA,EAAO,CAAA,CAAE,KAAA,EAAM,EAAG,CAAC,CAAA;AAC5D,IAAA,OAAO,CAAC;AAAA,MACN,IAAA,EAAM,SAAA;AAAA,MACN,MAAA,EAAQ,gBAAgB,GAAA,CAAI,SAAA,CAAU,EAAE,IAAI,CAAA,EAAG,EAAE,IAAA,EAAM;AAAA,QACrD,IAAA,EAAM,iBAAA;AAAA,QACN,IAAA,EAAM,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,IAAI,CAAA;AAAA,QAC1B,OAAA,EAAS,GAAA,CAAI,SAAA,CAAU,CAAA,CAAE,OAAO,CAAA;AAAA,QAChC;AAAA,OACD;AAAA,KACF,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;AC5BD,IAAM,WAAA,GAA4C;AAAA,EAChD,UAAA;AAAA,EAAY,cAAA;AAAA,EAAgB,eAAA;AAAA,EAAiB,YAAA;AAAA,EAAc,cAAA;AAAA,EAC3D,cAAA;AAAA,EAAgB,kBAAA;AAAA,EAAoB,cAAA;AAAA,EAAgB,cAAA;AAAA,EACpD,iBAAA;AAAA,EAAmB,kBAAA;AAAA;AAAA,EAEnB,wBAAA;AAAA,EAA0B,wBAAA;AAAA,EAA0B,8BAAA;AAAA,EACpD,mBAAA;AAAA,EAAqB,qBAAA;AAAA,EACrB,aAAA;AAAA,EAAe,UAAA;AAAA,EAAY,SAAA;AAAA,EAC3B,mBAAA;AAAA,EAAqB,cAAA;AAAA,EAAgB,kBAAA;AAAA,EACrC,mBAAA;AAAA,EAAqB,iBAAA;AAAA,EAAmB,iBAAA;AAAA,EAAmB,aAAA;AAAA,EAC3D,aAAA;AAAA,EACA,cAAA;AAAA,EAAgB,aAAA;AAAA,EAAe,oBAAA;AAAA;AAAA,EAE/B,cAAA;AAAA,EAAgB,cAAA;AAAA,EAAgB,cAAA;AAAA;AAAA,EAEhC,iBAAA;AAAA,EAAmB,cAAA;AAAA,EAAgB,kBAAA;AAAA,EAAoB,iBAAA;AAAA;AAAA,EAEvD;AACF,CAAA;AAEO,IAAM,aAAA,GACX,IAAI,GAAA,CAAI,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAEtC,IAAM,cAAmC,IAAI,GAAA;AAAA,EAClD,WAAA,CAAY,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,OAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI;AACjE,CAAA;AAEO,IAAM,wBAA6C,IAAI,GAAA;AAAA,EAC5D,WAAA,CAAY,MAAA;AAAA,IACV,CAAC,CAAA,KACC,CAAA,CAAE,IAAA,KAAS,SAAA,IACX,CAAA,CAAE,IAAA,KAAS,MAAA,IACX,CAAA,CAAE,IAAA,KAAS,KAAA,IACX,CAAA,CAAE,IAAA,KAAS;AAAA,GACf,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI;AACrB,CAAA;AAEO,IAAM,eAAoC,IAAI,GAAA;AAAA,EACnD,WAAA,CAAY,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI;AAClE,CAAA;AAG+BA,KAAAA,CAAE,kBAAA;AAAA,EAC/B,MAAA;AAAA,EACA,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,MAAM;AACjC;;;AClEO,SAAS,OAAA,CACd,IAAA,EACA,OAAA,EACA,IAAA,EACgB;AAChB,EAAA,OAAO,EAAE,MAAM,OAAA,EAAS,IAAA,EAAM,MAAM,IAAA,EAAM,IAAA,EAAM,MAAM,IAAA,EAAK;AAC7D;;;ACpBA,SAAS,YAAY,GAAA,EAAkC;AACrD,EAAA,OAAO,CAAC,CAAC,GAAA,IAAO,GAAA,CAAI,IAAA,KAAS,OAAA;AAC/B;AAEA,SAAS,WAAW,GAAA,EAAkC;AACpD,EAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,IAAA,KAAS,SAAS,OAAO,KAAA;AACzC,EAAA,OAAO,qBAAA,CAAsB,GAAA,CAAK,GAAA,CAAI,MAAA,CAAqB,IAAI,CAAA;AACjE;AAEA,SAAS,aAAa,GAAA,EAAkC;AACtD,EAAA,IAAI,CAAC,GAAA,IAAO,GAAA,CAAI,IAAA,KAAS,SAAS,OAAO,KAAA;AACzC,EAAA,OAAO,YAAA,CAAa,GAAA,CAAK,GAAA,CAAI,MAAA,CAAqB,IAAI,CAAA;AACxD;AAEA,SAAS,eAAe,GAAA,EAAkC;AACxD,EAAA,OAAO,CAAC,CAAC,GAAA,IAAO,GAAA,CAAI,SAAS,OAAA,IAAY,GAAA,CAAI,OAAqB,IAAA,KAAS,SAAA;AAC7E;AAEA,IAAM,cAAA,GAAsE;AAAA,EAC1E,KAAA,EAAO,WAAA;AAAA,EACP,WAAA,EAAa,UAAA;AAAA,EACb,MAAA,EAAQ,YAAA;AAAA,EACR,OAAA,EAAS,cAAA;AAAA,EACT,OAAO,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA,IAAK,EAAE,IAAA,KAAS,OAAA;AAAA,EAChC,cAAA,EAAgB,CAAC,CAAA,KAAM,CAAC,CAAC;AAC3B,CAAA;AACA,IAAM,aAAA,GAAyC;AAAA,EAC7C,KAAA,EAAO,OAAA;AAAA,EACP,WAAA,EAAa,WAAA;AAAA,EACb,MAAA,EAAQ,QAAA;AAAA,EACR,OAAA,EAAS,SAAA;AAAA,EACT,KAAA,EAAO,OAAA;AAAA,EACP,cAAA,EAAgB;AAClB,CAAA;AAMO,SAAS,YAAA,CAAa,KAAgB,OAAA,EAA0C;AACrF,EAAA,MAAM,SAA2B,EAAC;AAElC,EAAA,MAAM,QAAQ,CACZ,KAAA,EACA,KAAA,EACA,OAAA,EACA,WACA,QAAA,KACG;AACH,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA;AAC/B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAA,CAAO,IAAA,CAAK,OAAA;AAAA,QAAQ,aAAA;AAAA,QAClB,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,KAAK,qBAAgB,OAAO,CAAA,4BAAA,CAAA;AAAA,QACxC,EAAE,IAAA,EAAM,CAAC,KAAA,EAAO,KAAK,CAAA;AAAE,OAAE,CAAA;AAC3B,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,SAAA,CAAU,GAAG,CAAA,EAAG;AACnB,MAAA,MAAA,CAAO,IAAA,CAAK,OAAA;AAAA,QAAQ,eAAA;AAAA,QAClB,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,KAAK,KAAK,OAAO,CAAA,0BAAA,EAAmB,QAAQ,CAAA,WAAA,EAAS,IAAI,IAAA,KAAS,OAAA,GAAU,OAAA,GAAW,GAAA,CAAI,OAAqB,IAAI,CAAA,CAAA,CAAA;AAAA,QAChI,EAAE,IAAA,EAAM,CAAC,KAAA,EAAO,KAAK,CAAA;AAAE,OAAE,CAAA;AAAA,IAC7B;AAAA,EACF,CAAA;AAGA,EAAA,MAAM,iBAAA,uBAAwB,GAAA,EAAY;AAC1C,EAAA,MAAM,QAAA,GAAW,CAAC,KAAA,EAAe,MAAA,KAA2C;AAC1E,IAAA,MAAM,GAAA,GAAM,aAAA,CAAc,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA;AACzC,IAAA,MAAM,MAAM,GAAA,EAAK,QAAA;AACjB,IAAA,IAAI,CAAC,KAAK,OAAO,KAAA;AACjB,IAAA,MAAM,QACJ,OAAO,GAAA,KAAQ,UAAA,GAAa,GAAA,CAAI,MAAe,CAAA,GAAI,GAAA;AACrD,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,MAAA,MAAM,GAAA,GAAO,MAAA,CAAmC,IAAA,CAAK,KAAK,CAAA;AAC1D,MAAA,MAAM,KAAA,GAAkB,IAAA,CAAK,IAAA,GACvB,GAAA,IAAoB,EAAC,GACvB,GAAA,IAAO,IAAA,GACL,EAAC,GACD,CAAC,GAAa,CAAA;AACpB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,OAAA,EAAS,CAAA,KAAM;AAC5B,QAAA,MAAM,KAAA,GAAQ,KAAK,IAAA,GAAO,CAAA,EAAG,KAAK,KAAK,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAA,GAAM,IAAA,CAAK,KAAA;AACvD,QAAA,KAAA,CAAM,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,cAAA,CAAe,IAAA,CAAK,IAAI,CAAA,EAAG,aAAA,CAAc,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,MAClF,CAAC,CAAA;AAAA,IACH;AACA,IAAA,iBAAA,CAAkB,IAAI,KAAK,CAAA;AAC3B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACA,EAAA,KAAA,MAAW,KAAK,GAAA,CAAI,MAAA,EAAQ,QAAA,CAAS,CAAA,CAAE,MAAM,CAAC,CAAA;AAC9C,EAAA,KAAA,MAAW,KAAK,GAAA,CAAI,MAAA,EAAQ,QAAA,CAAS,CAAA,CAAE,MAAM,CAAC,CAAA;AAE9C,EAAA,KAAA,MAAW,CAAA,IAAK,IAAI,MAAA,EAAQ;AAC1B,IAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AACnC,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,MAAA;AAAQ,QAAA;AAAA,MACb,KAAK,UAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA;AAAA,MACF,KAAK,WAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA,CAAE,SAAA,EAAW,gBAAgB,SAAS,CAAA;AACjE,QAAA;AAAA,MACF,KAAK,QAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,YAAY,WAAW,CAAA;AACzD,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,UAAA,EAAY,CAAA,CAAE,QAAA,EAAU,cAAc,QAAQ,CAAA;AAC5D,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA,CAAE,IAAA,EAAM,aAAa,OAAO,CAAA;AAClD,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,YAAY,WAAW,CAAA;AACzD,QAAA;AAAA,MACF,KAAK,cAAA;AAAA,MACL,KAAK,UAAA;AAAA,MACL,KAAK,UAAA;AAAA,MACL,KAAK,aAAA;AACH,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,UAAA,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,CAAA,SAAA,EAAY,CAAC,CAAA,CAAA,CAAA,EAAK,EAAE,QAAA,CAAS,CAAC,CAAA,EAAG,WAAA,EAAa,OAAO,CAAA;AAAA,QACrE;AACA,QAAA;AAAA,MACF,KAAK,cAAA,EAAgB;AACnB,QAAA,MAAM,eAAe,CAAC,CAAA,KAA0B,WAAW,CAAC,CAAA,IAAK,aAAa,CAAC,CAAA;AAC/E,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA,CAAE,IAAA,EAAM,cAAc,4BAAuB,CAAA;AACnE,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA,CAAE,IAAA,EAAM,cAAc,4BAAuB,CAAA;AACnE,QAAA;AAAA,MACF;AAAA,MACA,KAAK,aAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,cAAc,QAAQ,CAAA;AACxD,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,GAAA,EAAK,CAAA,CAAE,CAAA,EAAG,aAAa,OAAO,CAAA;AAC5C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,GAAA,EAAK,CAAA,CAAE,CAAA,EAAG,aAAa,OAAO,CAAA;AAC5C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,eAAA,EAAiB,CAAA,CAAE,aAAA,EAAe,aAAa,OAAO,CAAA;AACpE,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,UAAA,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,CAAA,SAAA,EAAY,CAAC,CAAA,CAAA,CAAA,EAAK,EAAE,QAAA,CAAS,CAAC,CAAA,EAAG,WAAA,EAAa,OAAO,CAAA;AAAA,QACrE;AACA,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,UAAA,EAAY,CAAA,CAAE,QAAA,EAAU,aAAa,OAAO,CAAA;AAC1D,QAAA;AAAA,MACF,KAAK,cAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,aAAa,OAAO,CAAA;AACxD,QAAA;AAAA,MACF,KAAK,aAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,YAAY,WAAW,CAAA;AAC3D,QAAA;AAAA;AACJ,EACF;AAEA,EAAA,KAAA,MAAW,CAAA,IAAK,IAAI,MAAA,EAAQ;AAC1B,IAAA,IAAI,iBAAA,CAAkB,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AACnC,IAAA,QAAQ,EAAE,IAAA;AAAM,MACd,KAAK,SAAA;AAAA,MACL,KAAK,MAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA;AAAA,MACF,KAAK,KAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,aAAa,OAAO,CAAA;AACtD,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,SAAA,EAAW,CAAA,CAAE,OAAA,EAAS,aAAa,OAAO,CAAA;AACxD,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,CAAA,CAAE,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA,EAAG,MACrB,KAAA,CAAM,CAAA,CAAE,IAAA,EAAM,CAAA,SAAA,EAAY,CAAC,CAAA,CAAA,CAAA,EAAK,CAAA,EAAG,WAAA,EAAa,OAAO,CAAC,CAAA;AAC1D,QAAA;AAAA,MACF,KAAK,eAAA;AAAA,MACL,KAAK,UAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA,CAAE,YAAA,EAAc,aAAa,OAAO,CAAA;AAClE,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,YAAY,WAAW,CAAA;AACzD,QAAA;AAAA,MACF,KAAK,cAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA;AAAA,MACF,KAAK,eAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,aAAa,OAAO,CAAA;AACtD,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA,CAAE,YAAA,EAAc,aAAa,OAAO,CAAA;AAClE,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,UAAA,EAAY,CAAA,CAAE,QAAA,EAAU,cAAc,QAAQ,CAAA;AAC5D,QAAA;AAAA,MACF,KAAK,UAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA,CAAE,MAAA,EAAQ,aAAa,OAAO,CAAA;AACtD,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,cAAA,EAAgB,CAAA,CAAE,YAAA,EAAc,aAAa,OAAO,CAAA;AAClE,QAAA;AAAA,MACF,KAAK,SAAA;AACH,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA,KAAA,CAAM,EAAE,IAAA,EAAM,IAAA,EAAM,CAAA,CAAE,EAAA,EAAI,aAAa,OAAO,CAAA;AAC9C,QAAA;AAAA;AACJ,EACF;AAEA,EAAA,OAAO,EAAE,MAAA,EAAO;AAClB;AAGO,SAAS,YAAY,MAAA,EAAyC;AACnE,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA;AACzC,EAAA,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,CAAA,yCAAA,EAA4C,MAAA,CAAO,IAAI,CAAA,CAAA,CAAG,CAAA;AACpF,EAAA,OAAO,GAAA,CAAI,YAAY,MAAe,CAAA;AACxC;;;ACnMA,IAAM,GAAA,GAAM,CAAA;AAKL,SAAS,wBAAA,CAAyB,QAAqB,MAAA,EAA2B;AAEvF,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAsB;AAClC,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA;AACtB,IAAA,IAAI,MAAM,MAAA,EAAW;AAAE,MAAA,MAAA,CAAO,GAAA,CAAI,GAAG,CAAC,CAAA;AAAG,MAAA,OAAO,CAAA;AAAA,IAAG;AACnD,IAAA,IAAI,CAAA,KAAM,GAAG,OAAO,CAAA;AACpB,IAAA,MAAM,IAAA,GAAO,KAAK,CAAC,CAAA;AACnB,IAAA,MAAA,CAAO,GAAA,CAAI,GAAG,IAAI,CAAA;AAClB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACA,EAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,EAAW,CAAA,KAAc;AACtC,IAAA,MAAM,KAAK,IAAA,CAAK,CAAC,CAAA,EAAG,EAAA,GAAK,KAAK,CAAC,CAAA;AAC/B,IAAA,IAAI,EAAA,KAAO,EAAA,EAAI,MAAA,CAAO,GAAA,CAAI,IAAI,EAAE,CAAA;AAAA,EAClC,CAAA;AAEA,EAAA,MAAM,QAAA,GAAsC,CAAC,GAAG,MAAA,EAAQ,GAAG,MAAM,CAAA;AACjE,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,IAAA,CAAK,EAAE,IAAI,CAAA;AACX,IAAA,KAAA,MAAW,OAAO,WAAA,CAAY,CAAC,GAAG,KAAA,CAAM,CAAA,CAAE,MAAM,GAAG,CAAA;AAAA,EACrD;AAGA,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAA6C;AACpE,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,EAAG,CAAA,KAAM;AACvB,IAAA,IAAI,CAAA,CAAE,IAAA,KAAS,MAAA,EAAQ,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,IAAA,EAAM,EAAE,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,CAAA;AAAA,EAC/D,CAAC,CAAA;AACD,EAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AAG3B,EAAA,MAAM,QAAA,uBAAe,GAAA,EAA+C;AACpE,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAoB;AAC7C,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,UAAA,EAAY;AACpC,IAAA,MAAM,IAAA,GAAO,KAAK,IAAI,CAAA;AACtB,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,EAAG;AAAE,MAAA,QAAA,CAAS,GAAA,CAAI,IAAA,EAAM,EAAE,CAAA;AAAG,MAAA,YAAA,CAAa,GAAA,CAAI,IAAA,EAAM,GAAA,CAAI,KAAK,CAAA;AAAA,IAAG;AACtF,IAAA,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,CAAG,IAAA,CAAK,GAAG,CAAA;AAC5B,IAAA,YAAA,CAAa,GAAA,CAAI,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,YAAA,CAAa,IAAI,IAAI,CAAA,EAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,EACrE;AAGA,EAAA,IAAI,QAAA,CAAS,QAAQ,CAAA,EAAG;AAGxB,EAAA,MAAM,QAAQ,CAAC,GAAG,QAAA,CAAS,IAAA,EAAM,CAAA,CAAE,IAAA;AAAA,IACjC,CAAC,GAAG,CAAA,KAAM,YAAA,CAAa,IAAI,CAAC,CAAA,GAAK,YAAA,CAAa,GAAA,CAAI,CAAC;AAAA,GACrD;AAGA,EAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAuB;AACrC,IAAA,IAAI,OAAO,QAAA,EAAU,IAAA,GAAO,CAAA,QAAA,EAAW,IAAA,GAAO,UAAU,IAAA,GAAO,CAAA,QAAA;AAC/D,IAAA,MAAM,GAAA,GAAM,CAAC,CAAA,EAAW,CAAA,KAAc;AACpC,MAAA,IAAI,CAAA,GAAI,MAAM,IAAA,GAAO,CAAA;AACrB,MAAA,IAAI,CAAA,GAAI,MAAM,IAAA,GAAO,CAAA;AACrB,MAAA,IAAI,CAAA,GAAI,MAAM,IAAA,GAAO,CAAA;AACrB,MAAA,IAAI,CAAA,GAAI,MAAM,IAAA,GAAO,CAAA;AAAA,IACvB,CAAA;AACA,IAAA,KAAA,MAAW,EAAE,CAAA,EAAE,IAAK,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,EAAI,GAAA,CAAI,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA;AACrD,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAI,IAAA,CAAK,CAAA,CAAE,IAAI,CAAA,KAAM,IAAA,EAAM;AAC3B,MAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AACzB,QAAA,MAAM,CAAA,GAAI,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA;AACjC,QAAA,IAAI,CAAA,EAAG;AAAE,UAAA,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,CAAE,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,MAAM,CAAA;AAAG,UAAA,GAAA,CAAI,CAAA,CAAE,EAAE,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,CAAE,CAAA,CAAE,CAAA,GAAI,CAAA,CAAE,MAAM,CAAA;AAAA,QAAG;AAAA,MAC7F,CAAA,MAAA,IAAW,CAAA,CAAE,IAAA,KAAS,UAAA,EAAY;AAChC,QAAA,MAAM,CAAA,GAAI,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA;AACjC,QAAA,MAAM,EAAA,GAAK,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,YAAY,CAAA;AACxC,QAAA,IAAI,KAAK,EAAA,EAAI;AACX,UAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,EAAE,CAAA,GAAI,EAAA,CAAG,CAAA,CAAE,CAAA,EAAG,CAAA,CAAE,CAAA,CAAE,CAAA,GAAI,EAAA,CAAG,EAAE,CAAC,CAAA;AACnD,UAAA,GAAA,CAAI,EAAE,CAAA,CAAE,CAAA,GAAI,GAAG,CAAA,CAAE,CAAA,CAAE,IAAI,CAAC,CAAA;AAAG,UAAA,GAAA,CAAI,EAAE,CAAA,CAAE,CAAA,GAAI,GAAG,CAAA,CAAE,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,QACrD;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAM,IAAA,EAAK;AAAA,EAClC,CAAA;AAGA,EAAA,IAAI,UAAU,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,EAAE,IAAA,GAAO,GAAA;AACtC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,IAAA,GAAO,MAAM,CAAC,CAAA;AACpB,IAAA,MAAM,EAAA,GAAK,OAAO,IAAI,CAAA;AACtB,IAAA,MAAM,EAAA,GAAK,UAAU,EAAA,CAAG,IAAA;AACxB,IAAA,KAAA,MAAW,EAAE,GAAE,IAAK,QAAA,CAAS,IAAI,IAAI,CAAA,IAAM,CAAA,IAAK,EAAA;AAChD,IAAA,OAAA,GAAU,EAAA,CAAG,OAAO,EAAA,GAAK,GAAA;AAAA,EAC3B;AACF;;;AClFO,SAAS,QAAA,GAAuB;AACrC,EAAA,OAAO;AAAA,IACL,QAAQ,EAAC;AAAA,IACT,QAAQ,EAAC;AAAA,IACT,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,UAAA,sBAAgB,GAAA,EAAI;AAAA,IACpB,aAAA,sBAAmB,GAAA;AAAI,GACzB;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,KAAA,CAAM;AAAA,EAC5C,WAAA,CACE,OAAA,EACgB,MAAA,EACA,KAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAHG,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AACA,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AAAA,EACd;AACF;;;ACxBO,IAAM,KAAA,GAAQ,kBAAA;AAEd,SAAS,kBAAkB,OAAA,EAAwC;AACxE,EAAA,QAAQ,OAAA;AAAS,IACf,KAAK,aAAA;AACH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA,GAAI,KAAK,CAAC,CAAA;AAAA,IACxC,KAAK,aAAA;AAEH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAChC,KAAK,aAAA;AAEH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,EAAA,EAAI,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IACjC,KAAK,aAAA;AAEH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAChC,KAAK,YAAA;AACH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAChC,KAAK,YAAA;AACH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAChC,KAAK,YAAA;AAOH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAChC,KAAK,KAAA;AAAA,IACL;AAEE,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA;AAEpC;AAEO,SAAS,eAAA,GAA6C;AAE3D,EAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AACxC;AAEO,SAAS,mBAAmB,OAAA,EAA4C;AAC7E,EAAA,IAAI,YAAY,MAAA,EAAQ,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA,EAAG,CAAC,GAAA,EAAK,CAAC,GAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAElE,EAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,GAAG,GAAG,CAAA,EAAG,CAAC,CAAA,EAAG,GAAG,CAAC,CAAA;AAC5C;AAEO,SAAS,gBAAA,GAA8C;AAE5D,EAAA,OAAO,CAAC,CAAC,EAAA,EAAI,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,IAAI,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,GAAG,CAAC,CAAA;AAC9C;AAEO,SAAS,mBAAmB,OAAA,EAA4C;AAC7E,EAAA,QAAQ,OAAA;AAAS,IACf,KAAK,OAAA;AAEH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IACxC,KAAK,UAAA;AAEH,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IACxC,KAAK,SAAA;AAAA,IACL;AACE,MAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA;AAE9C;AAEO,SAAS,sBAAA,GAAoD;AAClE,EAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA;AACxC;AAEO,SAAS,sBAAA,GAAoD;AAClE,EAAA,OAAO,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,KAAK,GAAG,CAAA,EAAG,CAAC,GAAA,EAAK,CAAC,CAAC,CAAA;AAC9C;AAMO,SAASW,SAAAA,CAAS,GAAe,CAAA,EAAc;AACpD,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AAC9B,EAAA,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA;AACf,EAAA,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA;AACzB;AAMO,IAAM,mBAAA,GAAmD;AAAA,EAC9D,CAAC,GAAG,CAAC,CAAA;AAAA,EACL,CAAC,IAAI,CAAC,CAAA;AAAA,EACN,CAAC,GAAG,EAAE,CAAA;AAAA,EACN,CAAC,IAAI,EAAE,CAAA;AAAA,EACP,CAAC,GAAG,CAAC,CAAA;AAAA,EACL,CAAC,IAAI,CAAC,CAAA;AAAA,EACN,CAAC,GAAG,CAAC,CAAA;AAAA,EACL,CAAC,GAAG,EAAE;AACR,CAAA;AAEO,SAAS,iBAAiB,CAAA,EAAiC;AAGhE,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,KAAK,CAAA,CAAE,MAAA,EAAQ,IAAI,CAAA,CAAE,SAAS,MAAA,EAAQ,KAAA,EAAA;AACjD,EAAA,OAAO,CAAC,GAAG,mBAAA,CAAoB,KAAA,GAAQ,mBAAA,CAAoB,MAAM,CAAC,CAAA;AACpE;AAEO,SAAS,QAAA,CAAS,GAAe,EAAA,EAAe;AACrD,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA,EAAG;AAC/B,EAAA,CAAA,CAAE,MAAA,CAAO,KAAK,EAAE,CAAA;AAChB,EAAA,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,EAAA,CAAG,IAAI,CAAA;AAC1B;AAEO,SAAS,eAAA,CAAgB,GAAe,IAAA,EAAsB;AACnE,EAAA,IAAI,CAAC,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,IAAI,GAAG,OAAO,IAAA;AACpC,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,CAAA,CAAE,WAAW,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,EAAG,CAAC,EAAE,CAAA,EAAG,CAAA,EAAA;AACxC,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,CAAC,CAAA,CAAA;AACpB;AAEO,SAAS,eAAA,CAAgB,GAAe,IAAA,EAAsB;AACnE,EAAA,IAAI,CAAC,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,IAAI,GAAG,OAAO,IAAA;AACpC,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OAAO,CAAA,CAAE,WAAW,GAAA,CAAI,CAAA,EAAG,IAAI,CAAA,EAAG,CAAC,EAAE,CAAA,EAAG,CAAA,EAAA;AACxC,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,CAAC,CAAA,CAAA;AACpB;AAEO,SAAS,aAAA,CAAc,CAAA,EAAe,CAAA,EAAW,CAAA,EAAmB;AACzE,EAAA,MAAM,EAAA,GAAK,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AACpB,EAAA,MAAM,EAAA,GAAK,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AACpB,EAAA,MAAM,QAAA,GAAW,EAAE,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA,IAAK,CAAA,CAAE,aAAA,CAAc,GAAA,CAAI,EAAE,CAAA;AAClE,EAAA,IAAI,UAAU,OAAO,QAAA;AACrB,EAAA,MAAM,OAAO,eAAA,CAAgB,CAAA,EAAG,GAAG,CAAC,CAAA,EAAG,CAAC,CAAA,CAAE,CAAA;AAC1C,EAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,WAAW,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,CAAA;AACnD,EAAA,CAAA,CAAE,aAAA,CAAc,GAAA,CAAI,EAAA,EAAI,IAAI,CAAA;AAC5B,EAAA,OAAO,IAAA;AACT;AAMO,SAAS,0BAAA,CAA2B,CAAA,EAAe,GAAA,EAAa,MAAA,EAAwB;AAG7F,EAAA,IACE,aAAa,IAAA,CAAK,GAAG,KAAK,YAAA,CAAa,IAAA,CAAK,MAAM,CAAA,IAAK,GAAA,KAAQ,UAC/D,CAAA,CAAE,UAAA,CAAW,IAAI,GAAG,CAAA,IAAK,EAAE,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA,EAChD;AACA,IAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA,GAAM,MAAA,GAAS,CAAC,GAAA,EAAK,MAAM,CAAA,GAAI,CAAC,MAAA,EAAQ,GAAG,CAAA;AAC1D,IAAA,OAAO,aAAA,CAAc,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,EAC9B;AAEA,EAAA,OAAO,iBAAA,CAAkB,GAAG,GAAG,CAAA;AACjC;AAEO,SAAS,iBAAA,CAAkB,GAAe,GAAA,EAAqB;AAGpE,EAAA,IAAI,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,GAAG,GAAG,OAAO,GAAA;AAElC,EAAA,IAAI,IAAI,MAAA,KAAW,CAAA,IAAK,CAAA,CAAE,UAAA,CAAW,IAAI,GAAA,CAAI,CAAC,CAAC,CAAA,IAAK,EAAE,UAAA,CAAW,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG;AAC5E,IAAA,OAAO,cAAc,CAAA,EAAG,GAAA,CAAI,CAAC,CAAA,EAAG,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,EACxC;AAEA,EAAA,MAAM,SAAA,GAAY,GAAA,CAAI,KAAA,CAAM,yDAAyD,CAAA;AACrF,EAAA,IAAI,SAAA,IAAa,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,UAAU,CAAC,CAAC,CAAA,IAAK,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,SAAA,CAAU,CAAC,CAAC,CAAA,EAAG;AACjF,IAAA,OAAO,cAAc,CAAA,EAAG,SAAA,CAAU,CAAC,CAAA,EAAG,SAAA,CAAU,CAAC,CAAC,CAAA;AAAA,EACpD;AAEA,EAAA,OAAO,GAAA;AACT;AAEO,SAAS,UAAU,GAAA,EAAsC;AAC9D,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,CAAA,EAAG,OAAO,CAAC,IAAI,CAAC,CAAA,EAAG,GAAA,CAAI,CAAC,CAAC,CAAA;AAC5C,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,KAAA,CAAM,yDAAyD,CAAA;AAC7E,EAAA,IAAI,CAAA,SAAU,CAAC,CAAA,CAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAC,CAAA;AACzB,EAAA,OAAO,IAAA;AACT;AAOO,IAAM,cAAA,GAAoD;AAAA,EAC/D,QAAA,EAAU,CAAC,KAAA,EAAO,aAAA,EAAe,eAAe,aAAA,EAAe,aAAA,EAAe,YAAA,EAAc,YAAA,EAAc,YAAY,CAAA;AAAA,EACtH,MAAA,EAAQ,CAAC,UAAU,CAAA;AAAA,EACnB,SAAA,EAAW,CAAC,UAAA,EAAY,MAAA,EAAQ,MAAM,CAAA;AAAA,EACtC,OAAA,EAAS,CAAC,UAAU,CAAA;AAAA,EACpB,SAAA,EAAW,CAAC,OAAA,EAAS,UAAA,EAAY,SAAS,CAAA;AAAA,EAC1C,aAAA,EAAe,CAAC,UAAU,CAAA;AAAA,EAC1B,aAAA,EAAe,CAAC,KAAK;AACvB,CAAA;;;AC/LO,IAAM,cAAA,GAAkD,CAAC,CAAA,EAAG,MAAA,KAAW;AAC5E,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,cAAA,IAAkB,EAAC;AAG3C,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,MAAA,CAAO,KAAK,CAAA;AAC3C,EAAA,IAAI,CAAC,OAAA,IAAW,CAAC,QAAQ,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA,EAAG;AAEjD,IAAA,MAAA,GAAS,EAAE,GAAG,MAAA,EAAQ,SAAU,OAAA,GAAU,CAAC,KAAK,KAAA,EAAgC;AAAA,EAClF;AAEA,EAAA,IAAI,MAAA;AACJ,EAAA,QAAQ,OAAO,KAAA;AAAO,IACpB,KAAK,UAAA;AAAY,MAAA,MAAA,GAAS,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAAG,MAAA;AAAA,IAC7D,KAAK,QAAA;AAAU,MAAA,MAAA,GAAS,eAAA,EAAgB;AAAG,MAAA;AAAA,IAC3C,KAAK,WAAA;AAAa,MAAA,MAAA,GAAS,kBAAA,CAAmB,OAAO,OAAO,CAAA;AAAG,MAAA;AAAA,IAC/D,KAAK,SAAA;AAAW,MAAA,MAAA,GAAS,gBAAA,EAAiB;AAAG,MAAA;AAAA,IAC7C,KAAK,WAAA;AAAa,MAAA,MAAA,GAAS,kBAAA,CAAmB,OAAO,OAAO,CAAA;AAAG,MAAA;AAAA,IAC/D,KAAK,eAAA;AAAiB,MAAA,MAAA,GAAS,sBAAA,EAAuB;AAAG,MAAA;AAAA,IACzD,KAAK,eAAA;AAAiB,MAAA,MAAA,GAAS,sBAAA,EAAuB;AAAG,MAAA;AAAA,IACzD;AACE,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,iCAAA,EAAuB,MAAA,CAAO,KAAK,IAAI,MAAM,CAAA;AAAA;AAG9E,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,MAAA,CAAO,MAAA,EAAQ;AACnC,IAAA,MAAM,IAAI,kBAAA;AAAA,MACR,CAAA,MAAA,EAAS,OAAO,KAAK,CAAA,UAAA,EAAQ,OAAO,MAAM,CAAA,mBAAA,EAAiB,OAAO,MAAM,CAAA,CAAA;AAAA,MACxE;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAA,CAAO,OAAA,CAAQ,CAAC,KAAA,EAAO,CAAA,KAAM;AAC3B,IAAA,MAAM,EAAA,GAAK,SAAS,KAAK,CAAA;AACzB,IAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,EAAA,IAAM,OAAO,CAAC,CAAA;AAC7B,IAAAA,SAAAA,CAAS,GAAG,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,EACjD,CAAC,CAAA;AAED,EAAA,MAAM,WAAW,eAAA,CAAgB,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,EAAE,CAAC,CAAA;AACnD,EAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,CAAC,GAAG,MAAM,CAAA,EAAG,CAAA;AACxE,CAAA;;;AC5CO,IAAM,aAAA,GAAgB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7E,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AAC3B,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,CAAA,CAAE,EAAE,CAAA;AAC3B,EAAA,IAAI,CAAC,MAAM,MAAM,IAAI,mBAAmB,CAAA,gDAAA,EAAiC,CAAA,CAAE,EAAE,CAAA,CAAA,EAAI,MAAM,CAAA;AAEvF,EAAA,aAAA,CAAc,GAAG,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AACjC,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAM,UAAA,EAAY,EAAA,EAAI,IAAA,CAAK,CAAC,CAAA,EAAG,EAAA,EAAI,IAAA,CAAK,CAAC,GAAG,CAAA;AAClE,CAAA;;;ACVO,IAAM,aAAA,GAAgB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7E,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AAC3B,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA;AAC9C,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,MAAA,EAAQ,QAAA,EAAU,CAAA;AACxE,CAAA;;;ACLO,IAAM,aAAA,GAAgB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7E,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AAC3B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,CAAA,CAAE,EAAA,EAAI,CAAA;AACrE,CAAA;AAEO,IAAM,iBAAA,GAAoB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACjF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,cAAA,EAAgB;AAC/B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,cAAA,EAAgB,QAAA,EAAU,CAAA,CAAE,EAAA,EAAI,CAAA;AACzE,CAAA;AAEO,IAAM,aAAA,GAAgB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7E,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AAC3B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,CAAA,CAAE,EAAA,EAAI,CAAA;AACrE,CAAA;AAEO,IAAM,gBAAA,GAAmB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAChF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,aAAA,EAAe;AAC9B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,aAAA,EAAe,QAAA,EAAU,CAAA,CAAE,EAAA,EAAI,CAAA;AACxE,CAAA;AAEO,IAAM,aAAA,GAAgB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7E,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AAC3B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,CAAA,CAAE,EAAA,EAAI,QAAA,EAAU,CAAA,CAAE,UAAU,CAAA;AAC3F,CAAA;;;AC5BO,IAAM,iBAAA,GAAoB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACjF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,cAAA,EAAgB;AAC/B,EAAA,MAAM,KAAK,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,EAAA,CAAG,CAAC,CAAC,CAAA;AACvC,EAAA,MAAM,KAAK,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,EAAA,CAAG,CAAC,CAAC,CAAA;AACvC,EAAAA,UAAS,CAAA,EAAG;AAAA,IACV,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,IAAA,EAAM,cAAA;AAAA,IACN,IAAA,EAAM,EAAA;AAAA,IACN,IAAA,EAAM,EAAA;AAAA,IACN,GAAI,EAAE,MAAA,KAAW,MAAA,GAAY,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAO,GAAI;AAAC,GACtD,CAAA;AACH,CAAA;AAEO,IAAM,uBAAA,GAA0B,CAAC,CAAA,EAAe,MAAA,KAAkC;AACvF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,oBAAA,EAAsB;AACrC,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA;AAC3C,EAAAA,UAAS,CAAA,EAAG;AAAA,IACV,MAAM,MAAA,CAAO,IAAA;AAAA,IAAM,IAAA,EAAM,oBAAA;AAAA,IACzB,IAAA,EAAM,OAAA;AAAA,IAAS,QAAQ,CAAA,CAAE,MAAA;AAAA,IAAQ,OAAO,CAAA,CAAE;AAAA,GAC3C,CAAA;AACH,CAAA;AAEO,IAAM,uBAAA,GAA0B,CAAC,CAAA,EAAe,MAAA,KAAkC;AACvF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,oBAAA,EAAsB;AACrC,EAAAA,UAAS,CAAA,EAAG;AAAA,IACV,MAAM,MAAA,CAAO,IAAA;AAAA,IAAM,IAAA,EAAM,oBAAA;AAAA,IACzB,IAAI,CAAA,CAAE,EAAA;AAAA,IAAI,IAAI,CAAA,CAAE,EAAA;AAAA,IAAI,OAAO,CAAA,CAAE;AAAA,GAC9B,CAAA;AACH,CAAA;AAEO,IAAM,6BAAA,GAAgC,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7F,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,0BAAA,EAA4B;AAC3C,EAAAA,UAAS,CAAA,EAAG;AAAA,IACV,MAAM,MAAA,CAAO,IAAA;AAAA,IAAM,IAAA,EAAM,0BAAA;AAAA,IACzB,IAAI,CAAA,CAAE,EAAA;AAAA,IAAI,IAAI,CAAA,CAAE,EAAA;AAAA,IAAI,SAAS,CAAA,CAAE;AAAA,GAChC,CAAA;AACH,CAAA;;;ACzCO,IAAM,kBAAA,GAAqB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAClF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,eAAA,EAAiB;AAChC,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA;AAC7C,EAAAA,UAAS,CAAA,EAAG;AAAA,IACV,MAAM,MAAA,CAAO,IAAA;AAAA,IAAM,IAAA,EAAM,eAAA;AAAA,IACzB,QAAQ,CAAA,CAAE,MAAA;AAAA,IAAQ,MAAA,EAAQ;AAAA,GAC3B,CAAA;AACH,CAAA;AAEO,IAAM,iBAAA,GAAoB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACjF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,cAAA,EAAgB;AAC/B,EAAAA,UAAS,CAAA,EAAG;AAAA,IACV,MAAM,MAAA,CAAO,IAAA;AAAA,IAAM,IAAA,EAAM,iBAAA;AAAA,IACzB,MAAM,CAAA,CAAE,IAAA;AAAA,IAAM,QAAQ,CAAA,CAAE,MAAA;AAAA,IAAQ,OAAO,CAAA,CAAE;AAAA,GAC1C,CAAA;AACH,CAAA;;;ACjBO,IAAM,cAAA,GAAiB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC9E,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,WAAA,EAAa;AAC5B,EAAA,MAAM,GAAA,GAAM,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,EAAE,CAAA;AACrC,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,IAAA,EAAM,WAAA,EAAa,SAAA,EAAW,GAAA,EAAK,CAAA,EAAG,CAAA,CAAE,CAAA,IAAK,KAAK,CAAA;AACrF,CAAA;AAEO,IAAM,SAAA,GAAY,CAAC,CAAA,EAAe,MAAA,KAAkC;AACzE,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,MAAA,EAAQ;AACvB,EAAA,MAAM,CAAC,CAAA,EAAG,CAAC,IAAI,CAAA,CAAE,EAAA,IAAM,iBAAiB,CAAC,CAAA;AACzC,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,MAAM,IAAA,EAAM,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG,CAAA;AACvD,CAAA;;;ACVO,IAAM,sBAAA,GAAyB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACtF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,mBAAA,EAAqB;AACpC,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAC/B,EAAA,IAAI,CAAC,MAAM,MAAM,IAAI,mBAAmB,CAAA,yCAAA,EAAyC,CAAA,CAAE,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA;AACnG,EAAA,MAAM,OAAA,GAAU,gBAAgB,CAAA,EAAG,CAAA,GAAA,EAAM,EAAE,IAAI,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA,CAAE,CAAA;AAC5D,EAAA,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,iBAAiB,EAAA,EAAI,IAAA,CAAK,CAAC,CAAA,EAAG,QAAQ,CAAA,CAAE,IAAA,EAAM,IAAI,IAAA,CAAK,CAAC,GAAG,CAAA;AAC9F,EAAA,aAAA,CAAc,GAAG,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AACjC,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAM,cAAA,EAAgB,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,MAAM,GAAG,CAAA;AACjG,CAAA;;;ACLO,IAAM,8BAAA,GAAiC,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC9F,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,2BAAA,EAA6B;AAC5C,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AACpB,EAAA,MAAM,IAAA,GAAO,SAAA,CAAU,CAAA,CAAE,MAAM,CAAA;AAC/B,EAAA,IAAI,CAAC,MAAM,MAAM,IAAI,mBAAmB,CAAA,iDAAA,EAAiD,CAAA,CAAE,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA;AAE3G,EAAA,MAAM,OAAA,GAAU,gBAAgB,CAAA,EAAG,CAAA,GAAA,EAAM,EAAE,IAAI,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA,CAAE,CAAA;AAC5D,EAAA,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,iBAAiB,EAAA,EAAI,IAAA,CAAK,CAAC,CAAA,EAAG,QAAQ,CAAA,CAAE,IAAA,EAAM,IAAI,IAAA,CAAK,CAAC,GAAG,CAAA;AAE9F,EAAA,MAAM,OAAA,GAAU,gBAAgB,CAAA,EAAG,CAAA,IAAA,EAAO,EAAE,IAAI,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA,CAAE,CAAA;AAC7D,EAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,eAAA,EAAiB,YAAA,EAAc,CAAA,CAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,CAAA;AAC3F,EAAA,aAAA,CAAc,GAAG,IAAA,CAAK,CAAC,CAAA,EAAG,IAAA,CAAK,CAAC,CAAC,CAAA;AACjC,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAM,cAAA,EAAgB,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,MAAM,GAAG,CAAA;AACjG,CAAA;;;ACpBO,IAAM,sBAAA,GAAyB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACtF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,mBAAA,EAAqB;AACpC,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAGpB,EAAA,MAAM,OAAA,GAAU,gBAAgB,CAAA,EAAG,CAAA,IAAA,EAAO,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,CAAE,CAAA;AACrD,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,SAAS,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,CAAA,CAAE,GAAG,EAAA,EAAI,CAAA,CAAE,CAAA,EAAG,OAAA,EAAS,OAAO,CAAA;AACjF,EAAA,MAAM,QAAA,GAAW,gBAAgB,CAAA,EAAG,CAAA,IAAA,EAAO,EAAE,CAAC,CAAA,EAAG,CAAA,CAAE,CAAC,CAAA,CAAE,CAAA;AACtD,EAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,OAAA,EAAS,YAAA,EAAc,CAAA,CAAE,CAAA,EAAG,OAAA,EAAS,OAAO,CAAA;AACpG,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,MAAM,CAAA;AAC7C,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAM,cAAA,EAAgB,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,CAAA,CAAE,KAAA,IAAS,GAAG,CAAA;AACjG,CAAA;;;ACbO,IAAM,gBAAA,GAAmB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAChF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,aAAA,EAAe;AAC9B,EAAAA,SAAAA,CAAS,GAAG,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,IAAA,EAAM,eAAe,MAAA,EAAQ,CAAA,CAAE,QAAQ,CAAA,EAAG,CAAA,CAAE,GAAG,CAAA,EAAG,CAAA,CAAE,GAAG,aAAA,EAAe,CAAA,CAAE,eAAe,CAAA;AAC1H,CAAA;;;ACJO,IAAM,iBAAA,GAAoB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACjF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,cAAA,EAAgB;AAC/B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,OAAA,EAAS,CAAA,CAAE,SAAS,CAAA;AACvF,CAAA;AAEO,IAAM,gBAAA,GAAmB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAChF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,aAAA,EAAe;AAC9B,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,CAAA,EAAG,CAAA,CAAE,OAAO,CAAA;AAC9C,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,CAAA,CAAE,EAAA,EAAI,OAAA,EAAS,SAAS,CAAA;AACpF,CAAA;;;ACVO,IAAM,oBAAA,GAAuB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACpF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,iBAAA,EAAmB;AAClC,EAAA,aAAA,CAAc,CAAA,EAAG,CAAA,CAAE,IAAA,EAAM,CAAA,CAAE,OAAO,CAAA;AAClC,EAAAA,UAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,MAAM,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,CAAA,CAAE,MAAM,OAAA,EAAS,CAAA,CAAE,SAAS,QAAA,EAAU,CAAA,CAAE,UAAU,CAAA;AACpH,CAAA;;;ACKO,IAAM,qBAAA,GAAwB,CAAC,CAAA,EAAe,MAAA,KAAkC;AACrF,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,kBAAA,EAAoB;AACnC,EAAA,MAAM,MAAA,GAAS,EAAE,MAAA,CAAO,IAAA,CAAK,CAAC,EAAA,KAAO,EAAA,CAAG,IAAA,KAAS,CAAA,CAAE,MAAM,CAAA;AACzD,EAAA,IAAI,CAAC,MAAA,EAAQ;AAEb,EAAA,IAAI,EAAA;AACJ,EAAA,IAAI,EAAA;AACJ,EAAA,IAAI,CAAA;AAEJ,EAAA,IAAI,MAAA,CAAO,SAAS,UAAA,EAAY;AAC9B,IAAA,MAAM,MAAA,GAAS,EAAE,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,MAAA,CAAO,MAAM,CAAA;AAC5D,IAAA,IAAI,MAAA,IAAU,MAAA,CAAO,IAAA,KAAS,MAAA,EAAQ;AACpC,MAAA,EAAA,GAAK,MAAA,CAAO,CAAA;AACZ,MAAA,EAAA,GAAK,MAAA,CAAO,CAAA;AACZ,MAAA,CAAA,GAAI,MAAA,CAAO,MAAA;AAAA,IACb;AAAA,EACF,CAAA,MAAA,IAAW,MAAA,CAAO,IAAA,KAAS,UAAA,EAAY;AACrC,IAAA,MAAM,MAAA,GAAS,EAAE,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,MAAA,CAAO,MAAM,CAAA;AAC5D,IAAA,MAAM,IAAA,GAAO,EAAE,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,MAAA,CAAO,YAAY,CAAA;AAChE,IAAA,IAAI,UAAU,MAAA,CAAO,IAAA,KAAS,UAAU,IAAA,IAAQ,IAAA,CAAK,SAAS,MAAA,EAAQ;AACpE,MAAA,EAAA,GAAK,MAAA,CAAO,CAAA;AACZ,MAAA,EAAA,GAAK,MAAA,CAAO,CAAA;AACZ,MAAA,CAAA,GAAI,KAAK,KAAA,CAAM,IAAA,CAAK,IAAI,EAAA,EAAI,IAAA,CAAK,IAAI,EAAE,CAAA;AAAA,IACzC;AAAA,EACF;AAEA,EAAA,IAAI,EAAA,KAAO,UAAa,EAAA,KAAO,MAAA,IAAa,MAAM,MAAA,IAAa,EAAE,IAAI,CAAA,CAAA,EAAI;AACzE,EAAA,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,CAAA,EAAG,IAAI,CAAC,CAAA;AAC/B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,MAAA,EAAQ,CAAA,EAAG,EAAA,GAAK,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA;AACnE,CAAA;;;ACvCO,IAAM,aAAA,GAAgB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7E,EAAA,MAAM,IAAI,MAAA,CAAO,UAAA;AACjB,EAAA,IAAI,CAAA,CAAE,SAAS,UAAA,EAAY;AAC3B,EAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,OAAO,IAAA,EAAM,IAAA,EAAM,UAAA,EAAY,QAAA,EAAU,EAAE,MAAA,EAAQ,KAAA,EAAO,CAAA,CAAE,KAAA,IAAS,GAAG,CAAA;AAC9F,CAAA;;;ACQO,IAAM,kBAAA,GAAuF;AAAA,EAClG,QAAA,EAAU,aAAA;AAAA,EAAe,QAAA,EAAU,aAAA;AAAA,EACnC,QAAA,EAAU,aAAA;AAAA,EAAe,YAAA,EAAc,iBAAA;AAAA,EAAmB,QAAA,EAAU,aAAA;AAAA,EACpE,WAAA,EAAa,gBAAA;AAAA,EAAkB,QAAA,EAAU,aAAA;AAAA,EACzC,YAAA,EAAc,iBAAA;AAAA,EAAmB,kBAAA,EAAoB,uBAAA;AAAA,EAAyB,kBAAA,EAAoB,uBAAA;AAAA,EAClG,wBAAA,EAA0B,6BAAA;AAAA,EAC1B,aAAA,EAAe,kBAAA;AAAA,EAAoB,YAAA,EAAc,iBAAA;AAAA,EACjD,SAAA,EAAW,cAAA;AAAA,EAAgB,IAAA,EAAM,SAAA;AAAA,EACjC,iBAAA,EAAmB,sBAAA;AAAA,EAAwB,yBAAA,EAA2B,8BAAA;AAAA,EACtE,iBAAA,EAAmB,sBAAA;AAAA,EACnB,WAAA,EAAa,gBAAA;AAAA,EAAkB,YAAA,EAAc,iBAAA;AAAA,EAAmB,WAAA,EAAa,gBAAA;AAAA,EAC7E,eAAA,EAAiB,oBAAA;AAAA,EACjB,gBAAA,EAAkB,qBAAA;AAAA,EAClB,QAAA,EAAU;AACZ,CAAA;AAEO,IAAM,aAAA,GAAgB,CAAC,CAAA,EAAe,MAAA,KAAkC;AAC7E,EAAA,MAAM,EAAA,GAAK,kBAAA,CAAmB,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AACpD,EAAA,IAAI,EAAA,EAAI,EAAA,CAAG,CAAA,EAAG,MAAM,CAAA;AACtB,CAAA;;;AChCO,IAAM,YAAA,GAA8C,CAAC,CAAA,EAAG,MAAA,KAAW;AACxE,EAAA,MAAM,EAAE,IAAA,EAAM,EAAA,EAAI,KAAA,EAAM,GAAI,MAAA;AAC5B,EAAA,QAAQ,KAAA;AAAO,IACb,KAAK,SAAA;AACH,MAAA,aAAA,CAAc,CAAA,EAAG,MAAM,EAAE,CAAA;AACzB,MAAA;AAAA,IACF,KAAK,MAAA;AACH,MAAA,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,eAAA,CAAgB,CAAA,EAAG,KAAK,IAAI,CAAA,EAAG,EAAE,CAAA,CAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,IAAI,IAAA,EAAM,EAAA,EAAI,IAAI,CAAA;AAC1F,MAAA;AAAA,IACF,KAAK,KAAA;AACH,MAAA,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,eAAA,CAAgB,CAAA,EAAG,KAAK,IAAI,CAAA,EAAG,EAAE,CAAA,CAAE,GAAG,IAAA,EAAM,KAAA,EAAO,QAAQ,IAAA,EAAM,OAAA,EAAS,IAAI,CAAA;AAClG,MAAA;AAAA,IACF,KAAK,cAAA;AACH,MAAA,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,eAAA,CAAgB,CAAA,EAAG,MAAM,IAAI,CAAA,EAAG,EAAE,CAAA,CAAE,GAAG,IAAA,EAAM,cAAA,EAAgB,IAAI,IAAA,EAAM,EAAA,EAAI,IAAI,CAAA;AACnG,MAAA;AAAA,IACF,KAAK,eAAA;AAGH,MAAA,MAAM,IAAI,kBAAA;AAAA,QACR,wFAAA;AAAA,QACA;AAAA,OACF;AAAA;AAEN,CAAA;;;ACvBO,IAAM,eAAA,GAAoD,CAAC,CAAA,EAAG,MAAA,KAAW;AAC9E,EAAA,IAAI,MAAA,CAAO,SAAS,eAAA,EAAiB;AACnC,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,IAAU,CAAC,OAAO,OAAA,EAAS;AACrC,MAAA,MAAM,IAAI,kBAAA,CAAmB,yCAAA,EAAsC,MAAM,CAAA;AAAA,IAC3E;AACA,IAAA,QAAA,CAAS,CAAA,EAAG;AAAA,MACV,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,IAAA,EAAM,UAAA;AAAA,MACN,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,cAAc,MAAA,CAAO;AAAA,KACtB,CAAA;AAAA,EACH,CAAA,MAAA,IAAW,MAAA,CAAO,IAAA,KAAS,UAAA,EAAY;AACrC,IAAA,IAAI,CAAC,OAAO,MAAA,EAAQ;AAClB,MAAA,MAAM,IAAI,kBAAA,CAAmB,0BAAA,EAAuB,MAAM,CAAA;AAAA,IAC5D;AACA,IAAA,QAAA,CAAS,CAAA,EAAG;AAAA,MACV,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,IAAA,EAAM,SAAA;AAAA,MACN,EAAA,EAAI,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA;AAAA,MACnB,EAAA,EAAI,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA;AAAA,MACnB,EAAA,EAAI,MAAA,CAAO,MAAA,CAAO,CAAC;AAAA,KACpB,CAAA;AAAA,EACH,CAAA,MAAA,IAAW,MAAA,CAAO,IAAA,KAAS,cAAA,EAAgB;AACzC,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,WAAW,MAAA,EAAW;AACjD,MAAA,MAAM,IAAI,kBAAA,CAAmB,uCAAA,EAAoC,MAAM,CAAA;AAAA,IACzE;AACA,IAAA,IAAI,CAAC,CAAA,CAAE,MAAA,CAAO,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,MAAA,CAAO,MAAM,CAAA,EAAG;AACnD,MAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,iBAAiB,CAAC,CAAA;AACjC,MAAAA,SAAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,QAAS,IAAA,EAAM,MAAA,EAAQ,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA,IAC1D;AACA,IAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,MAAA,EAAQ,MAAA,CAAO,QAAQ,CAAA;AAAA,EACnG,CAAA,MAAA,IAAW,MAAA,CAAO,IAAA,KAAS,UAAA,EAAY;AACrC,IAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,MAAA,MAAM,IAAI,kBAAA,CAAmB,6BAAA,EAA0B,MAAM,CAAA;AAAA,IAC/D;AACA,IAAA,QAAA,CAAS,CAAA,EAAG;AAAA,MACV,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,IAAA,EAAM,gBAAA;AAAA,MACN,EAAA,EAAI,MAAA,CAAO,SAAA,CAAU,CAAC,CAAA;AAAA,MACtB,EAAA,EAAI,MAAA,CAAO,SAAA,CAAU,CAAC;AAAA,KACvB,CAAA;AAAA,EACH,CAAA,MAAA,IAAW,MAAA,CAAO,IAAA,KAAS,aAAA,EAAe;AACxC,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,QAAgB,IAAI,kBAAA,CAAmB,iCAA4B,MAAM,CAAA;AACrF,IAAA,KAAA,MAAW,CAAA,IAAK,OAAO,QAAA,EAAU;AAC/B,MAAA,IAAI,CAAC,EAAE,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,CAAC,CAAA,EAAG;AACvC,QAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,oBAAA,EAAuB,CAAC,wCAAoB,MAAM,CAAA;AAAA,MACjF;AAAA,IACF;AACA,IAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,MAAM,UAAA,EAAY,QAAA,EAAU,MAAA,CAAO,QAAA,EAAU,CAAA;AAAA,EAChF;AACF,CAAA;;;AClDO,IAAM,aAAA,GAAgD,CAAC,CAAA,EAAG,MAAA,KAAW;AAC1E,EAAA,QAAQ,OAAO,IAAA;AAAM,IACnB,KAAK,aAAA,EAAe;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,CAAC,MAAA,CAAO,IAAI,MAAM,IAAI,kBAAA,CAAmB,mCAAA,EAAgC,MAAM,CAAA;AACtG,MAAA,MAAM,SAAS,0BAAA,CAA2B,CAAA,EAAG,MAAA,CAAO,EAAA,EAAI,OAAO,OAAO,CAAA;AACtE,MAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,eAAA,EAAiB,YAAA,EAAc,MAAA,CAAO,OAAA,EAAS,MAAA,EAAQ,CAAA;AAC9F,MAAA;AAAA,IACF;AAAA,IACA,KAAK,iBAAA,EAAmB;AACtB,MAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,CAAC,MAAA,CAAO,IAAI,MAAM,IAAI,kBAAA,CAAmB,uCAAA,EAAoC,MAAM,CAAA;AAC1G,MAAA,MAAM,SAAS,0BAAA,CAA2B,CAAA,EAAG,MAAA,CAAO,EAAA,EAAI,OAAO,OAAO,CAAA;AACtE,MAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,UAAA,EAAY,YAAA,EAAc,MAAA,CAAO,OAAA,EAAS,MAAA,EAAQ,CAAA;AACzF,MAAA;AAAA,IACF;AAAA,IACA,KAAK,WAAA,EAAa;AAChB,MAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,CAAC,MAAA,CAAO,QAAQ,MAAM,IAAI,kBAAA,CAAmB,qCAAA,EAAkC,MAAM,CAAA;AAC5G,MAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,MAAM,IAAA,EAAM,SAAA,EAAW,YAAA,EAAc,MAAA,CAAO,SAAS,QAAA,EAAU,MAAA,CAAO,MAAA,EAAQ,MAAA,EAAQ,MAAM,CAAA;AACvH,MAAA;AAAA,IACF;AAAA,IACA,KAAK,gBAAA,EAAkB;AACrB,MAAA,IAAI,CAAC,MAAA,CAAO,IAAA,IAAQ,CAAC,MAAA,CAAO,QAAQ,MAAM,IAAI,kBAAA,CAAmB,uCAAA,EAAoC,MAAM,CAAA;AAC3G,MAAA,IAAI,MAAA,CAAO,UAAU,MAAA,EAAQ;AAC3B,QAAA,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,EAAA,CAAA,EAAM,IAAA,EAAM,SAAA,EAAW,YAAA,EAAc,OAAO,IAAA,EAAM,QAAA,EAAU,OAAO,MAAA,EAAQ,MAAA,EAAQ,GAAG,CAAA;AACxH,QAAA,QAAA,CAAS,GAAG,EAAE,IAAA,EAAM,CAAA,EAAG,MAAA,CAAO,IAAI,CAAA,EAAA,CAAA,EAAM,IAAA,EAAM,SAAA,EAAW,YAAA,EAAc,OAAO,IAAA,EAAM,QAAA,EAAU,OAAO,MAAA,EAAQ,MAAA,EAAQ,GAAG,CAAA;AAAA,MAC1H,CAAA,MAAO;AACL,QAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,KAAU,QAAA,GAAW,CAAA,GAAI,CAAA;AAC/C,QAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,MAAM,IAAA,EAAM,SAAA,EAAW,YAAA,EAAc,MAAA,CAAO,IAAA,EAAM,QAAA,EAAU,MAAA,CAAO,MAAA,EAAQ,QAAQ,CAAA;AAAA,MAChH;AACA,MAAA;AAAA,IACF;AAAA,IACA,KAAK,eAAA,EAAiB;AAGpB,MAAA,IAAI,CAAC,OAAO,EAAA,IAAM,CAAC,OAAO,MAAA,IAAU,CAAC,OAAO,EAAA,EAAI;AAC9C,QAAA,MAAM,IAAI,kBAAA,CAAmB,yCAAA,EAAsC,MAAM,CAAA;AAAA,MAC3E;AACA,MAAA,QAAA,CAAS,CAAA,EAAG;AAAA,QACV,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,IAAA,EAAM,eAAA;AAAA,QACN,IAAI,MAAA,CAAO,EAAA;AAAA,QACX,QAAQ,MAAA,CAAO,MAAA;AAAA,QACf,IAAI,MAAA,CAAO;AAAA,OACZ,CAAA;AACD,MAAA;AAAA,IACF;AAAA,IACA,KAAK,aAAA,EAAe;AAElB,MAAA,IAAI,CAAC,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,MAAA,CAAO,SAAS,CAAA,EAAG;AAC9C,QAAA,MAAM,IAAI,kBAAA,CAAmB,6CAAA,EAA2B,MAAM,CAAA;AAAA,MAChE;AACA,MAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,MAAM,aAAA,EAAe,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,CAAA;AAC7E,MAAA;AAAA,IACF;AAAA,IACA,KAAK,aAAA,EAAe;AAElB,MAAA,IAAI,CAAC,MAAA,CAAO,OAAA,IAAW,CAAC,OAAO,OAAA,EAAS;AACtC,QAAA,MAAM,IAAI,kBAAA,CAAmB,wCAAA,EAAqC,MAAM,CAAA;AAAA,MAC1E;AACA,MAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,aAAA,EAAe,OAAA,EAAS,MAAA,CAAO,OAAA,EAAS,OAAA,EAAS,MAAA,CAAO,SAAS,CAAA;AACxG,MAAA;AAAA,IACF;AAAA;AAEJ,CAAA;;;AC9DO,IAAM,cAAA,GAAkD,CAAC,CAAA,EAAG,MAAA,KAAW;AAC5E,EAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,IAAA,IAAI,CAAC,EAAE,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,KAAK,CAAA,EAAG;AAC3C,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,kBAAA,EAAqB,KAAK,wCAAoB,MAAM,CAAA;AAAA,IACnF;AAAA,EACF;AACA,EAAA,MAAM,WAAW,eAAA,CAAgB,CAAA,EAAG,OAAO,MAAA,CAAO,IAAA,CAAK,EAAE,CAAC,CAAA;AAC1D,EAAA,QAAA,CAAS,CAAA,EAAG,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,CAAC,GAAG,MAAA,CAAO,MAAM,CAAA,EAAG,CAAA;AAC/E,CAAA;;;ACHO,IAAM,WAAA,GAA2E;AAAA,EACtF,YAAA,EAAc,cAAA;AAAA,EACd,WAAA,EAAa,aAAA;AAAA,EACb,SAAA,EAAW,YAAA;AAAA,EACX,aAAA,EAAe,eAAA;AAAA,EACf,WAAA,EAAa,aAAA;AAAA,EACb,YAAA,EAAc;AAChB,CAAA;;;ACAO,SAAS,aAAa,OAAA,EAAwC;AACnE,EAAA,MAAM,IAAI,QAAA,EAAS;AACnB,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,MAAA,CAAO,EAAE,CAAA;AACnC,IAAA,IAAI,KAAA,EAAO,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA;AAAA,EAC5B;AAGA,EAAA,yBAAA,CAA0B,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,MAAM,CAAA;AAE5C,EAAA,wBAAA,CAAyB,CAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,MAAM,CAAA;AAC3C,EAAA,OAAO,EAAE,SAAS,CAAA,EAAG,MAAA,EAAQ,EAAE,MAAA,EAAQ,MAAA,EAAQ,EAAE,MAAA,EAAO;AAC1D;ACzBA,SAAS,QAAQ,GAAA,EAAsF;AACrG,EAAA,IAAI,IAAI,MAAA,GAAS,CAAA,EAAG,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAC7F,EAAA,OAAO,GAAA;AACT;AAEA,IAAM,YAAA,GAAe,MAAM,IAAA,CAAK,aAAA,CAAc,QAAQ,CAAA,CACnD,OAAO,CAAC,CAAA,KAAM,YAAY,GAAA,CAAI,CAAA,CAAE,IAAI,CAAC,CAAA,CACrC,IAAI,CAAC,CAAA,KAAM,EAAE,MAAM,CAAA;AAEtB,IAAM,YAAA,GAAe,MAAM,IAAA,CAAK,aAAA,CAAc,QAAQ,CAAA,CACnD,OAAO,CAAC,CAAA,KAAM,CAAC,WAAA,CAAY,GAAA,CAAI,EAAE,IAAI,CAAC,EACtC,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAA;AAGf,IAAM,WAAWX,KAAAA,CAAE,kBAAA,CAAmB,MAAA,EAAQ,OAAA,CAAQ,YAAY,CAAC,CAAA;AACnE,IAAM,WAAWA,KAAAA,CAAE,kBAAA,CAAmB,MAAA,EAAQ,OAAA,CAAQ,YAAY,CAAC,CAAA;AAEnE,IAAM,QAAA,GAAWA,MAAE,MAAA,CAAO;AAAA,EAC/B,OAAA,EAASA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;AAAA,EACpB,MAAA,EAAQA,KAAAA,CAAE,KAAA,CAAM,QAAQ,CAAA;AAAA,EACxB,QAAQA,KAAAA,CAAE,KAAA,CAAM,QAAQ,CAAA,CAAE,OAAA,CAAQ,EAAE;AACtC,CAAC,CAAA;;;ACiEM,IAAM,eAAA,GAA0B;AAAA,EACrC,IAAA,EAAM,CAAC,GAAA,EAAK,EAAA,EAAI,IAAI,GAAG,CAAA;AAAA,EACvB,QAAA,EAAU,KAAA;AAAA,EACV,QAAA,EAAU;AACZ,CAAA;AAEO,IAAM,eAAA,GAA0B;AAAA,EACrC,QAAQ,CAAC,EAAA,EAAI,GAAG,EAAA,EAAI,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,EAC5B,OAAA,EAAS,EAAA;AAAA,EACT,SAAA,EAAW;AACb,CAAA;AAEO,IAAM,oBAAA,GAAoC;AAAA,EAC/C,IAAA,EAAM,GAAA;AAAA,EAAK,IAAA,EAAM,EAAA;AAAA,EAAI,IAAA,EAAM,GAAA;AAAA,EAAK,IAAA,EAAM,EAAA;AAAA,EACtC,QAAA,EAAU,IAAA;AAAA,EAAM,QAAA,EAAU;AAC5B,CAAA;AAWO,SAAS,iBAAiB,MAAA,EAAuB;AACtD,EAAA,MAAM,IAAA,GAAO,EAAE,OAAA,EAAS,IAAI,KAAA,EAAO,EAAC,EAAG,OAAA,EAAS,CAAA,EAAE;AAClD,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,IAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,EAAE,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,CAAA,EAAG,IAAA,EAAM,eAAA,EAAgB,EAAE;AAAA,IAC9E,KAAK,IAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,EAAE,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,CAAA,EAAG,IAAA,EAAM,eAAA,EAAgB,EAAE;AAAA,IAC9E,KAAK,SAAA;AACH,MAAA,OAAO,EAAE,GAAG,IAAA,EAAM,IAAA,EAAM,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAA,EAAS,CAAA,EAAG,IAAA,EAAM,oBAAA,EAAqB,EAAE;AAAA;AAE5F;;;AChHO,SAAS,aAAa,GAAA,EAA8B;AACzD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAoB;AACxC,EAAA,MAAM,SAA2B,EAAC;AAClC,EAAA,IAAI,OAAA,GAAU,CAAA;AAEd,EAAA,KAAA,MAAW,CAAA,IAAK,IAAI,MAAA,EAAQ;AAC1B,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AACvB,MAAA,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB,CAAA,kBAAA,EAAe,EAAE,IAAI,CAAA,CAAA,CAAA,EAAK,EAAE,IAAA,EAAM,CAAC,CAAA,CAAE,IAAI,CAAA,EAAG,CAAC,CAAA;AACnF,MAAA;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,WAAW,CAAA;AAAA,EAClF;AAEA,EAAA,KAAA,MAAW,CAAA,IAAK,IAAI,MAAA,EAAQ;AAC1B,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA,EAAG;AACvB,MAAA,MAAA,CAAO,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB,CAAA,kBAAA,EAAe,EAAE,IAAI,CAAA,CAAA,CAAA,EAAK,EAAE,IAAA,EAAM,CAAC,CAAA,CAAE,IAAI,CAAA,EAAG,CAAC,CAAA;AACnF,MAAA;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,IAAA,EAAM,EAAE,IAAA,EAAM,CAAA,CAAE,IAAA,EAAM,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,WAAW,CAAA;AAAA,EAClF;AAEA,EAAA,OAAO,EAAE,SAAS,MAAA,EAAO;AAC3B;;;AC7BO,SAAS,aAAa,OAAA,EAA4C;AACvE,EAAA,MAAM,KAAA,uBAAY,GAAA,EAAmB;AACrC,EAAA,MAAM,MAAA,uBAAa,GAAA,EAA2B;AAC9C,EAAA,MAAM,SAA2B,EAAC;AAClC,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AAEvC,EAAA,KAAA,MAAW,QAAQ,OAAA,CAAQ,IAAA,IAAQ,KAAA,CAAM,GAAA,CAAI,MAAM,OAAO,CAAA;AAE1D,EAAA,SAAS,WAAA,CAAY,OAAe,GAAA,EAAa;AAE/C,IAAA,MAAM,KAAA,GAAkB,CAAC,KAAK,CAAA;AAC9B,IAAA,IAAI,GAAA,GAAiC,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AACrD,IAAA,OAAO,OAAO,GAAA,KAAQ,GAAA,IAAO,MAAM,MAAA,GAAS,OAAA,CAAQ,OAAO,CAAA,EAAG;AAC5D,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AACd,MAAA,GAAA,GAAM,MAAA,CAAO,IAAI,GAAG,CAAA;AAAA,IACtB;AACA,IAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AAEd,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,KAAO,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAE,CAAC,CAAA;AACpE,IAAA,MAAM,OAAA,GAAU,CAAC,GAAG,KAAA,CAAM,KAAA,CAAM,MAAM,CAAA,EAAG,GAAG,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAC,CAAA;AAClE,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,QAAG,CAAA;AAC5B,IAAA,IAAI,cAAA,CAAe,GAAA,CAAI,GAAG,CAAA,EAAG;AAC7B,IAAA,cAAA,CAAe,IAAI,GAAG,CAAA;AACtB,IAAA,MAAA,CAAO,IAAA,CAAK,OAAA;AAAA,MAAQ,OAAA;AAAA,MAClB,gCAAmB,KAAA,CAAM,OAAA,EAAQ,CAAE,IAAA,CAAK,UAAK,CAAC,CAAA,CAAA;AAAA,MAC9C,EAAE,IAAA,EAAM,CAAC,GAAG,KAAK,CAAA,EAAG,MAAM,qEAAA;AAAuD,KAAE,CAAA;AAAA,EACvF;AAEA,EAAA,SAAS,IAAI,IAAA,EAAc;AACzB,IAAA,KAAA,CAAM,GAAA,CAAI,MAAM,MAAM,CAAA;AACtB,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAC5B,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,KAAA,MAAW,GAAA,IAAO,WAAA,CAAY,GAAA,CAAI,MAAM,CAAA,EAAG;AACzC,QAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA,EAAG;AACvB,QAAA,MAAM,CAAA,GAAI,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA;AACvB,QAAA,IAAI,MAAM,MAAA,EAAQ;AAChB,UAAA,WAAA,CAAY,MAAM,GAAG,CAAA;AACrB,UAAA;AAAA,QACF;AACA,QAAA,IAAI,MAAM,OAAA,EAAS;AACjB,UAAA,MAAA,CAAO,GAAA,CAAI,KAAK,IAAI,CAAA;AACpB,UAAA,GAAA,CAAI,GAAG,CAAA;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,IAAA,KAAA,CAAM,GAAA,CAAI,MAAM,OAAO,CAAA;AAAA,EACzB;AAEA,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,IAAA,EAAK,EAAG;AACjC,IAAA,IAAI,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,KAAM,OAAA,EAAS;AAC/B,MAAA,MAAA,CAAO,GAAA,CAAI,MAAM,IAAI,CAAA;AACrB,MAAA,GAAA,CAAI,IAAI,CAAA;AAAA,IACV;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,MAAA,EAAO;AAClB;;;AC7CO,SAAS,SAAS,OAAA,EAAwC;AAC/D,EAAA,MAAM,GAAA,GAAM,CAAC,GAAG,OAAA,CAAQ,MAAM,CAAA;AAC9B,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,MAAM,QAAkB,EAAC;AAGzB,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAsB;AACzC,EAAA,KAAA,MAAW,QAAQ,GAAA,EAAK;AACtB,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAC5B,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,EAAE,CAAA;AACnB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,WAAA,CAAY,GAAA,CAAI,MAAM,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,CAAA;AACjE,IAAA,MAAA,CAAO,GAAA,CAAI,MAAM,IAAI,CAAA;AAAA,EACvB;AAIA,EAAA,IAAI,UAAA,GAAa,IAAA;AACjB,EAAA,OAAO,UAAA,EAAY;AACjB,IAAA,UAAA,GAAa,KAAA;AACb,IAAA,KAAA,MAAW,QAAQ,GAAA,EAAK;AACtB,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG;AACvB,MAAA,MAAM,IAAA,GAAO,MAAA,CAAO,GAAA,CAAI,IAAI,CAAA;AAC5B,MAAA,IAAI,IAAA,CAAK,MAAM,CAAC,CAAA,KAAM,QAAQ,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG;AACrC,QAAA,OAAA,CAAQ,IAAI,IAAI,CAAA;AAChB,QAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AACf,QAAA,UAAA,GAAa,IAAA;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,QAAQ,GAAA,EAAK;AACtB,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACzC;AAEA,EAAA,OAAO,KAAA;AACT;;;ACzDO,SAAS,UAAU,OAAA,EAAmD;AAC3E,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAoB;AACzC,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAoB;AACpC,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,OAAA,CAAQ,SAAQ,EAAG;AAC3C,IAAA,MAAM,GAAA,GAAM,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,OAAO,IAAI,CAAA;AAC7C,IAAA,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,CAAA,uCAAA,EAA0C,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,CAAA,CAAG,CAAA;AACtF,IAAA,MAAM,SAAS,GAAA,CAAI,MAAA;AACnB,IAAA,QAAA,CAAS,IAAI,MAAA,EAAA,CAAS,QAAA,CAAS,IAAI,MAAM,CAAA,IAAK,KAAK,CAAC,CAAA;AACpD,IAAA,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA,EAAG,MAAM,GAAG,QAAA,CAAS,GAAA,CAAI,MAAM,CAAC,CAAA,CAAE,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,GAAA;AACT;;;ACAA,SAAS,OAAO,MAAA,EAA+C;AAC7D,EAAA,MAAM,GAAA,GAAM,aAAA,CAAc,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA;AACzC,EAAA,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,CAAA,oCAAA,EAAuC,MAAA,CAAO,IAAI,CAAA,CAAA,CAAG,CAAA;AAE/E,EAAA,OAAO,GAAA,CAAI,IAAA,KAAS,SAAA,GAAY,OAAA,GAAW,GAAA,CAAI,IAAA;AACjD;AAEA,SAAS,gBAAA,CACP,KACA,SAAA,EACa;AACb,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAoB;AAC5C,EAAA,OAAO;AAAA,IACL,UAAU,IAAA,EAAM;AACd,MAAA,MAAM,EAAA,GAAK,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA;AACvB,MAAA,IAAI,CAAC,EAAA,EAAI,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,IAAI,CAAA,CAAA,CAAG,CAAA;AAC9D,MAAA,OAAO,EAAA;AAAA,IACT,CAAA;AAAA,IACA,OAAO,IAAA,EAAM;AACX,MAAA,MAAM,IAAA,GAAO,SAAA,CAAU,GAAA,CAAI,IAAI,CAAA;AAC/B,MAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,KAAA,CAAM,CAAA,6BAAA,EAAgC,IAAI,CAAA,CAAA,CAAG,CAAA;AAElE,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IACA,SAAA,CAAU,YAAY,MAAA,EAAQ;AAC5B,MAAA,MAAM,GAAA,GAAM,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AACnC,MAAA,WAAA,CAAY,IAAI,GAAA,EAAA,CAAM,WAAA,CAAY,IAAI,GAAG,CAAA,IAAK,KAAK,CAAC,CAAA;AACpD,MAAA,MAAM,GAAA,GAAM,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA;AAC/B,MAAA,OAAO,CAAA,IAAA,EAAO,UAAU,CAAA,CAAA,EAAI,MAAM,GAAG,GAAG,CAAA,CAAA;AAAA,IAC1C;AAAA,GACF;AACF;AAEO,SAAS,UAAU,MAAA,EAAkC;AAE1D,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,SAAA,CAAU,MAAM,CAAA;AACxC,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,MAAM,MAAA,GAA2B,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA;AAAA,MAAI,CAAC,GAAA,KACxD,OAAA,CAAQ,QAAA,EAAU,GAAA,CAAI,OAAA,EAAS,EAAE,IAAA,EAAM,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,MAAM,GAAG;AAAA,KAC/D;AACA,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAO;AAAA,EAC7B;AAIA,EAAA,MAAM,MAAM,MAAA,CAAO,IAAA;AAGnB,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,SAAA,EAAU,GAAI,aAAa,GAAG,CAAA;AACvD,EAAA,MAAM,EAAE,MAAA,EAAQ,SAAA,EAAU,GAAI,YAAA,CAAa,KAAK,OAAO,CAAA;AACvD,EAAA,MAAM,EAAE,MAAA,EAAQ,WAAA,EAAY,GAAI,aAAa,OAAO,CAAA;AAEpD,EAAA,MAAM,YAAY,CAAC,GAAG,WAAW,GAAG,SAAA,EAAW,GAAG,WAAW,CAAA;AAC7D,EAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,QAAQ,SAAA,EAAU;AAGhE,EAAA,MAAM,GAAA,GAAM,UAAU,OAAO,CAAA;AAG7B,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAA4B;AAClD,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,CAAA,IAAK,OAAA,CAAQ,SAAQ,EAAG;AAC3C,IAAA,SAAA,CAAU,GAAA,CAAI,IAAA,EAAM,MAAA,CAAO,GAAA,CAAI,MAAM,CAAC,CAAA;AAAA,EACxC;AAGA,EAAA,MAAM,UAAuC,EAAC;AAC9C,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,GAAA,GAAM,gBAAA,CAAiB,GAAA,EAAK,SAAS,CAAA;AAE3C,EAAA,MAAM,UAAA,GAAa,CAAC,MAAA,KAAkC;AACpD,IAAA,MAAM,GAAA,GAAM,aAAA,CAAc,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA;AACzC,IAAA,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,CAAA,kCAAA,EAAqC,MAAA,CAAO,IAAI,CAAA,CAAA,CAAG,CAAA;AAC7E,IAAA,MAAM,OAAA,GAA2B,GAAA,CAAI,IAAA,CAAK,MAAA,EAAiB,GAAG,CAAA;AAC9D,IAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,MAAA,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA,GAAI,GAAA,CAAI,MAAA;AAC7B,MAAA,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,EAAE,CAAA;AAAA,IAC1B;AAAA,EACF,CAAA;AAIA,EAAA,MAAM,WAAA,GAAc,SAAS,OAAO,CAAA;AACpC,EAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAC9B,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA;AAC5B,IAAA,IAAI,GAAA,EAAK,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAAA,EAChC;AAEA,EAAA,MAAM,KAAA,GAAQ,iBAAiB,IAAI,CAAA;AACnC,EAAA,MAAM,KAAA,GAAe;AAAA,IACnB,OAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAS,KAAA,CAAM,MAAA;AAAA,IACf,MAAM,KAAA,CAAM;AAAA,GACd;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,KAAA,EAAM;AAC3B;;;AC/EO,SAAS,cAAA,CACd,UACA,MAAA,EACc;AACd,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,GAAA,CAAI,SAAS,CAAA;AAC1C,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,GAAA,CAAI,SAAS,CAAA;AAEtC,EAAA,MAAM,UAAyB,EAAC;AAChC,EAAA,MAAM,QAAuB,EAAC;AAC9B,EAAA,MAAM,QAAuB,EAAC;AAG9B,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAY;AACtC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,CAAY,QAAQ,CAAA,EAAA,EAAK;AAC3C,IAAA,MAAM,EAAA,GAAK,YAAY,CAAC,CAAA;AAExB,IAAA,MAAM,QAAA,GAAW,SAAA,CAAU,SAAA,CAAU,CAAC,EAAA,EAAI,GAAA,KAAQ,CAAC,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA,IAAK,EAAA,KAAO,EAAE,CAAA;AACtF,IAAA,IAAI,YAAY,CAAA,EAAG;AACjB,MAAA,aAAA,CAAc,IAAI,QAAQ,CAAA;AAC1B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,aAAa,SAAA,CAAU,SAAA;AAAA,MAAU,CAAC,EAAA,EAAI,GAAA,KAC1C,CAAC,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA,IAAK,UAAA,CAAW,EAAA,EAAI,EAAA,EAAI,CAAC;AAAA,KACjD;AACA,IAAA,IAAI,cAAc,CAAA,EAAG;AACnB,MAAA,aAAA,CAAc,IAAI,UAAU,CAAA;AAC5B,MAAA,KAAA,CAAM,IAAA,CAAK;AAAA,QACT,IAAA,EAAM,OAAA;AAAA,QACN,QAAQ,CAAA,SAAA,EAAY,EAAE,CAAA,MAAA,EAAS,SAAA,CAAU,UAAU,CAAC,CAAA;AAAA,OACrD,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,IAAI,CAAA;AAAA,EAC9C;AAEA,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,IAAI,CAAC,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,EAAG;AACzB,MAAA,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,QAAQ,SAAA,CAAU,CAAC,GAAG,CAAA;AAAA,IACpD;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,QAAQ,MAAA,KAAW,CAAA,IAAK,MAAM,MAAA,KAAW,CAAA,IAAK,MAAM,MAAA,KAAW,CAAA;AAAA,IACnE,OAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;AAGA,SAAS,UAAU,MAAA,EAAyB;AAC1C,EAAA,QAAQ,OAAO,EAAA;AAAI,IACjB,KAAK,YAAA;AACH,MAAA,OAAO;AAAA,QACL,YAAA;AAAA,QACA,MAAA,CAAO,KAAA;AAAA,QACN,MAAA,CAA4B,OAAA;AAAA,QAC7B,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,GAAG;AAAA,OACxB,CAAE,KAAK,GAAG,CAAA;AAAA,IACZ,KAAK,WAAA;AACH,MAAA,OAAO,CAAC,WAAA,EAAa,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,UAAA,CAAW,IAAA,EAAM,aAAA,CAAc,MAAA,CAAO,UAAU,CAAC,CAAA,CAAE,KAAK,GAAG,CAAA;AAAA,IACtG,KAAK,SAAA;AACH,MAAA,OAAO,CAAC,SAAA,EAAW,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,MAAM,MAAA,CAAO,EAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,IACnE,KAAK,aAAA,EAAe;AAClB,MAAA,IAAI,MAAA,CAAO,IAAA,KAAS,eAAA,EAAiB,OAAO,CAAA,YAAA,EAAe,MAAA,CAAO,IAAI,CAAA,eAAA,EAAkB,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,MAAA,CAAO,OAAO,CAAA,CAAA;AACvH,MAAA,IAAI,MAAA,CAAO,IAAA,KAAS,UAAA,EAAiB,OAAO,CAAA,YAAA,EAAe,MAAA,CAAO,IAAI,CAAA,UAAA,EAAa,MAAA,CAAO,MAAA,EAAQ,IAAA,CAAK,GAAG,KAAK,EAAE,CAAA,CAAA;AACjH,MAAA,IAAI,MAAA,CAAO,IAAA,KAAS,cAAA,EAAiB,OAAO,CAAA,YAAA,EAAe,MAAA,CAAO,IAAI,CAAA,cAAA,EAAiB,MAAA,CAAO,MAAM,CAAA,CAAA,EAAI,MAAA,CAAO,MAAM,CAAA,CAAA;AACrH,MAAA,IAAI,MAAA,CAAO,IAAA,KAAS,aAAA,EAAiB,OAAO,CAAA,YAAA,EAAe,MAAA,CAAO,IAAI,CAAA,aAAA,EAAgB,MAAA,CAAO,QAAA,EAAU,IAAA,CAAK,GAAG,KAAK,EAAE,CAAA,CAAA;AACtH,MAAA,OAAO,CAAA,YAAA,EAAe,MAAA,CAAO,IAAI,CAAA,CAAA,EAAK,OAAe,IAAI,CAAA,CAAA;AAAA,IAC3D;AAAA,IACA,KAAK,WAAA,EAAa;AAChB,MAAA,MAAM,IAAA,GAAO;AAAA,QACX,WAAA;AAAA,QAAa,MAAA,CAAO,IAAA;AAAA,QAAM,MAAA,CAAO,IAAA;AAAA,QACjC,OAAO,OAAA,IAAW,EAAA;AAAA,QAAI,OAAO,EAAA,IAAM,EAAA;AAAA,QAAI,OAAO,IAAA,IAAQ,EAAA;AAAA,QAAI,OAAO,MAAA,IAAU,EAAA;AAAA,QAAI,OAAO,KAAA,IAAS;AAAA,OACjG,CAAE,KAAK,GAAG,CAAA;AACV,MAAA,IAAI,MAAA,CAAO,IAAA,KAAS,aAAA,EAAe,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAA,CAAK,MAAA,CAAO,MAAA,IAAU,EAAC,EAAG,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AACpF,MAAA,IAAI,MAAA,CAAO,IAAA,KAAS,aAAA,EAAe,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,OAAA,IAAW,EAAE,CAAA,CAAA,EAAI,MAAA,CAAO,WAAW,EAAE,CAAA,CAAA;AACjG,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,IACA,KAAK,YAAA;AACH,MAAA,OAAO,CAAC,YAAA,EAAc,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA;AAE3E;AAEA,SAAS,cAAc,CAAA,EAA0C;AAC/D,EAAA,QAAQ,EAAE,IAAA;AAAM,IACd,KAAK,UAAA;AAAY,MAAA,OAAO,CAAA,CAAE,EAAA;AAAA,IAC1B,KAAK,UAAA;AAAY,MAAA,OAAO,CAAA,EAAG,CAAA,CAAE,IAAI,CAAA,EAAA,EAAK,EAAE,MAAM,CAAA,CAAA;AAAA,IAC9C,KAAK,UAAA;AAAA,IACL,KAAK,cAAA;AAAA,IACL,KAAK,UAAA;AAAA,IACL,KAAK,aAAA;AACH,MAAA,OAAO,CAAA,CAAE,EAAA,CAAG,IAAA,CAAK,GAAG,CAAA;AAAA,IACtB,KAAK,cAAA;AAAgB,MAAA,OAAO,CAAA,CAAE,EAAA,CAAG,IAAA,CAAK,MAAG,CAAA;AAAA,IACzC,KAAK,WAAA;AAAa,MAAA,OAAO,GAAG,CAAA,CAAE,EAAE,CAAA,CAAA,EAAI,CAAA,CAAE,KAAK,KAAK,CAAA,CAAA;AAAA,IAChD,KAAK,MAAA;AAAQ,MAAA,OAAO,EAAE,EAAA,GAAK,CAAA,CAAE,EAAA,CAAG,IAAA,CAAK,GAAG,CAAA,GAAI,GAAA;AAAA,IAC5C,KAAK,oBAAA;AAAuB,MAAA,OAAO,CAAA,mBAAA,EAAsB,EAAE,IAAI,CAAA,CAAA,EAAI,EAAE,MAAM,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,CAAA;AAAA,IACtF,KAAK,oBAAA;AAAuB,MAAA,OAAO,CAAA,mBAAA,EAAsB,EAAE,EAAE,CAAA,CAAA,EAAI,EAAE,EAAE,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,CAAA;AAAA,IAChF,KAAK,0BAAA;AAA4B,MAAA,OAAO,CAAA,yBAAA,EAA4B,EAAE,EAAE,CAAA,CAAA,EAAI,EAAE,EAAE,CAAA,CAAA,EAAI,EAAE,OAAO,CAAA,CAAA;AAAA,IAC7F,KAAK,eAAA;AAAuB,MAAA,OAAO,CAAA,cAAA,EAAiB,CAAA,CAAE,MAAM,CAAA,CAAA,EAAI,EAAE,MAAM,CAAA,CAAA;AAAA,IACxE,KAAK,cAAA;AAAuB,MAAA,OAAO,CAAA,aAAA,EAAgB,EAAE,IAAI,CAAA,CAAA,EAAI,EAAE,MAAM,CAAA,CAAA,EAAI,EAAE,KAAK,CAAA,CAAA;AAAA,IAChF,KAAK,mBAAA;AAAuB,MAAA,OAAO,CAAA,kBAAA,EAAqB,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,EAAE,MAAM,CAAA,CAAA;AAAA,IAC1E,KAAK,2BAAA;AAA6B,MAAA,OAAO,CAAA,0BAAA,EAA6B,CAAA,CAAE,IAAI,CAAA,CAAA,EAAI,EAAE,MAAM,CAAA,CAAA;AAAA,IACxF,KAAK,aAAA;AAAuB,MAAA,OAAO,CAAA,YAAA,EAAe,CAAA,CAAE,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,aAAa,CAAA,CAAA;AAAA,IAC3F,KAAK,cAAA;AAAuB,MAAA,OAAO,CAAA,aAAA,EAAgB,CAAA,CAAE,EAAE,CAAA,CAAA,EAAI,EAAE,OAAO,CAAA,CAAA;AAAA,IACpE,KAAK,aAAA;AAAuB,MAAA,OAAO,CAAA,YAAA,EAAe,CAAA,CAAE,EAAE,CAAA,CAAA,EAAI,EAAE,OAAO,CAAA,CAAA;AAAA,IACnE,KAAK,UAAA;AAAuB,MAAA,OAAO,CAAA,SAAA,EAAY,EAAE,EAAA,CAAG,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,EAAI,EAAE,QAAQ,CAAA,CAAA;AAAA,IAC3E,KAAK,mBAAA;AAAuB,MAAA,OAAO,CAAA,kBAAA,EAAqB,CAAA,CAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,KAAA,IAAS,CAAC,CAAA,CAAA;AAAA,IAC9F,KAAK,iBAAA,EAAmB;AACtB,MAAA,MAAM,IAAI,CAAA,CAAE,QAAA;AACZ,MAAA,MAAM,IAAA,GAAO,EAAE,IAAA,KAAS,cAAA,GAAiB,KAAK,CAAA,CAAE,MAAM,KAClD,CAAA,CAAE,IAAA,KAAS,kBAAkB,CAAA,IAAA,EAAO,CAAA,CAAE,EAAE,CAAA,CAAA,EAAI,CAAA,CAAE,EAAE,CAAA,CAAA,GAChD,CAAA,IAAA,EAAO,EAAE,KAAK,CAAA,CAAA;AAClB,MAAA,OAAO,mBAAmB,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,OAAO,IAAI,IAAI,CAAA,CAAA;AAAA,IACvD;AAAA,IACA,KAAK,kBAAA;AAAoB,MAAA,OAAO,CAAA,iBAAA,EAAoB,EAAE,MAAM,CAAA,CAAA;AAAA,IAC5D,KAAK,UAAA;AAAY,MAAA,OAAO,YAAY,CAAA,CAAE,MAAM,CAAA,CAAA,EAAI,CAAA,CAAE,SAAS,EAAE,CAAA,CAAA;AAAA;AAEjE;AAEA,SAAS,UAAA,CAAW,CAAA,EAAW,CAAA,EAAW,KAAA,EAAwB;AAChE,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG,KAAK,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAChD,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG,KAAK,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAChD,EAAA,OAAO,EAAA,KAAO,EAAA;AAChB;AA8FO,SAAS,cAAA,CAAe,SAA6B,GAAA,EAA8B;AACxF,EAAA,MAAM,SAAwB,EAAC;AAG/B,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAI,MAAA,CAAO,EAAA,KAAO,YAAA,IAAgB,MAAA,CAAO,UAAU,UAAA,EAAY;AAC/D,IAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AACvB,IAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,WAAW,CAAA,EAAG;AACtC,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,WAAA,CAAY,MAAM,CAAA;AAC7C,IAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,IAAI,MAAA,CAAO,MAAA;AACzB,IAAA,MAAM,WAAW,IAAI,GAAA;AAAA,MACnB,GAAA,CAAI,OAAO,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,EAAE,IAAA,EAAM,CAAC,EAAE,CAAA,EAAG,CAAA,CAAE,CAAC,CAAqB,CAAC;AAAA,KACjG;AACA,IAAA,MAAM,EAAA,GAAK,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA;AACzB,IAAA,MAAM,EAAA,GAAK,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA;AACzB,IAAA,MAAM,EAAA,GAAK,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA;AACzB,IAAA,IAAI,CAAC,EAAA,IAAM,CAAC,EAAA,IAAM,CAAC,EAAA,EAAI;AACvB,IAAA,MAAM,QAAQ,IAAA,KAAS,GAAA,GAAM,EAAA,GAAK,IAAA,KAAS,MAAM,EAAA,GAAK,EAAA;AACtD,IAAA,MAAM,SAAS,IAAA,KAAS,GAAA,GAAM,EAAA,GAAK,IAAA,KAAS,MAAM,EAAA,GAAK,EAAA;AACvD,IAAA,MAAM,SAAS,IAAA,KAAS,GAAA,GAAM,EAAA,GAAK,IAAA,KAAS,MAAM,EAAA,GAAK,EAAA;AACvD,IAAA,MAAM,EAAA,GAAK,CAAC,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AACtD,IAAA,MAAM,EAAA,GAAK,CAAC,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAA,GAAI,KAAA,CAAM,CAAC,CAAC,CAAA;AACtD,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,CAAC,CAAA,GAAI,EAAA,CAAG,CAAC,CAAA,GAAI,EAAA,CAAG,CAAC,CAAA,GAAI,EAAA,CAAG,CAAC,CAAA;AACxC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,GAAI,IAAA,EAAM;AACxB,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,OAAA;AAAA,QACN,MAAA,EAAQ,CAAA,SAAA,EAAY,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAC,CAAA,kBAAA,EAAqB,IAAI,CAAA,wBAAA,EAAqB,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA;AAAA,OAC1F,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,OAAO,MAAA,KAAW,CAAA;AAAA,IACtB,SAAS,EAAC;AAAA,IACV,KAAA,EAAO,MAAA;AAAA,IACP,OAAO;AAAC,GACV;AACF;;;ACtPO,SAAS,uBAAuB,OAAA,EAAyC;AAC9E,EAAA,MAAM,GAAA,GAAM,wBAAwB,OAAO,CAAA;AAC3C,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,GAAA,CAAI,MAAA,EAAQ,QAAA,EAAU,GAAA,CAAI,QAAA,EAAS;AAG5E,EAAA,MAAM,UAAU,2BAAA,CAA4B,gBAAA,CAAiB,GAAA,CAAI,OAAA,EAAS,OAAO,CAAC,CAAA;AAElF,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,aAAa,OAAO,CAAA;AAAA,EAC5B,SAAS,CAAA,EAAG;AACV,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,aAAA,EAAe,MAAA,EAAQ,MAAA,CAAO,CAAC,CAAA,EAAG,QAAA,EAAU,GAAA,CAAI,QAAA,EAAS;AAAA,EACvF;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI;AACF,IAAA,OAAA,GAAU,UAAU,GAAG,CAAA;AAAA,EACzB,SAAS,CAAA,EAAG;AACV,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,iBAAA,EAAmB,MAAA,EAAQ,MAAA,CAAO,CAAC,CAAA,EAAG,QAAA,EAAU,GAAA,CAAI,QAAA,EAAS;AAAA,EAC3F;AACA,EAAA,IAAI,CAAC,QAAQ,EAAA,EAAI;AACf,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,KAAA;AAAA,MACJ,MAAA,EAAQ,gBAAA;AAAA,MACR,MAAA,EAAQ,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,MACrE,UAAU,GAAA,CAAI;AAAA,KAChB;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,OAAA,EAAS,GAAG,CAAA;AAC3C,EAAA,IAAI,CAAC,QAAQ,EAAA,EAAI;AACf,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,QAAQ,aAAA,EAAe,QAAA,EAAU,IAAI,QAAA,EAAS;AAAA,EACpE;AAGA,EAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,OAAA,EAAS,GAAG,CAAA;AAClD,EAAA,IAAI,CAAC,MAAM,EAAA,EAAI;AACb,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,eAAA,EAAiB,MAAA,EAAQ,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,EAAG,QAAA,EAAU,IAAI,QAAA,EAAS;AAAA,EACvG;AAIA,EAAA,MAAM,QAAA,GAAW,oBAAA,CAAqB,OAAA,EAAS,GAAG,CAAA;AAClD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,gBAAA,EAAkB,MAAA,EAAQ,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,EAAG,QAAA,EAAU,IAAI,QAAA,EAAS;AAAA,EAC3G;AAEA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA;AAAA,IACJ,MAAA,EAAQ,EAAE,OAAA,EAAS,GAAA,EAAK,SAAA,EAAW,SAAS,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,GAAA,CAAI,QAAA;AAAS,GACtF;AACF;AAEA,SAAS,OAAO,CAAA,EAAoB;AAClC,EAAA,OAAO,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AAClD;;;AC5EA,SAAS,aAAa,MAAA,EAAyB;AAC7C,EAAA,MAAM,CAAA,GAAI,QAAQ,IAAA,EAAK;AACvB,EAAA,OAAO,CAAA,GAAI,CAAA,EAAA,EAAK,CAAC,CAAA,CAAA,GAAK,EAAA;AACxB;AAGA,SAAS,YAAY,MAAA,EAAyB;AAC5C,EAAA,MAAM,KAAA,GAAA,CAAS,MAAA,IAAU,EAAA,EACtB,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA,CACnB,OAAO,OAAO,CAAA;AACjB,EAAA,OAAO,MAAM,MAAA,GAAS,CAAA,GAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GAAI,gDAAA;AAC/C;AAEO,SAAS,0BAA0B,IAAA,EAAiC;AACzE,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,QAAA,EAAS,GAAI,IAAA;AACrC,EAAA,QAAQ,MAAA;AAAQ;AAAA,IAEd,KAAK,UAAA;AACH,MAAA,OAAO,iJAAA;AAAA,IACT,KAAK,qBAAA,EAAuB;AAC1B,MAAA,MAAM,KAAA,GAAA,CAAS,QAAA,EAAU,SAAA,IAAa,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,IAAA,EAAI,CAAA,CAAE,IAAI,CAAA,IAAA,CAAG,CAAA;AAClE,MAAA,IAAI,KAAA,CAAM,WAAW,CAAA,EAAG;AACtB,QAAA,OAAO,6IAAA;AAAA,MACT;AACA,MAAA,OAAO,CAAA,0HAAA,EAAuD,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,8BAAA,CAAA;AAAA,IAChF;AAAA,IACA,KAAK,eAAA;AACH,MAAA,OAAO,CAAA,gCAAA,EAAe,WAAA,CAAY,MAAM,CAAC,CAAA,2FAAA,CAAA;AAAA;AAAA,IAG3C,KAAK,aAAA;AACH,MAAA,OAAO,CAAA,6GAAA,EAA0D,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,IACvF,KAAK,iBAAA;AAAA,IACL,KAAK,gBAAA;AACH,MAAA,OAAO,CAAA,2GAAA,EAA0D,YAAA,CAAa,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,IACvF,KAAK,aAAA;AACH,MAAA,OAAO,+HAAA;AAAA,IACT,KAAK,gBAAA;AACH,MAAA,OAAO,CAAA,wFAAA,EAAgD,WAAA,CAAY,MAAM,CAAC,CAAA,sCAAA,CAAA;AAAA,IAE5E,SAAS;AAEP,MAAA,MAAM,MAAA,GAAgB,MAAA;AACtB,MAAA,OAAO,CAAA,mDAAA,EAA6B,MAAA,CAAO,MAAM,CAAC,CAAA,EAAA,CAAA;AAAA,IACpD;AAAA;AAEJ;;;AClDA,IAAM,UAAA,GAA+B;AAAA,EACnC,WAAA,EAAa,CAAA;AAAA,EACb,YAAA,EAAc,CAAA;AAAA,EACd,eAAA,EAAiB,CAAA;AAAA,EACjB,mBAAA,EAAqB;AACvB,CAAA;AAuCA,eAAsB,oBAAA,CACpB,OAAA,EACA,KAAA,GAA+B,EAAC,EACD;AAI/B,EAAA,MAAM,GAAA,GAAM,uBAAuB,OAAO,CAAA;AAC1C,EAAA,IAAI,IAAI,EAAA,EAAI;AACV,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,IAAA;AAAA,MACJ,OAAA,EAAS,IAAI,MAAA,CAAO,OAAA;AAAA,MACpB,GAAA,EAAK,IAAI,MAAA,CAAO,GAAA;AAAA,MAChB,SAAA,EAAW,IAAI,MAAA,CAAO,SAAA;AAAA,MACtB,MAAA,EAAQ,IAAI,MAAA,CAAO,MAAA;AAAA,MACnB,KAAA,EAAO,UAAA;AAAA,MACP,QAAA,EAAU;AAAA,KACZ;AAAA,EACF;AAIA,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,KAAA;AAAA,IACJ,MAAA,EAAQ,oBAAA;AAAA,IACR,OAAA,EAAS,0BAA0B,GAAG,CAAA;AAAA,IACtC,KAAA,EAAO,UAAA;AAAA,IACP,QAAA,EAAU;AAAA,GACZ;AACF;;;ACnDA,IAAM,oBAAA,GAAuB,CAAA;AAe7B,eAAsB,oBAAA,CACpB,KAAA,EACA,IAAA,GAAoC,EAAC,EACV;AAC3B,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAK,EAAG;AACzB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,+BAAA,EAAc;AAAA,EAC7C;AAEA,EAAA,MAAM,EAAE,QAAA,EAAU,WAAA,EAAa,MAAA,EAAQ,GAAG,SAAQ,GAAI,IAAA;AACtD,EAAA,MAAM,WAAA,GAAc,aAAA,CAAc,MAAA,IAAU,oBAAoB,CAAA;AAEhE,EAAA,IAAI,IAAA,GAAoC,IAAA;AACxC,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,WAAA,EAAa,OAAA,EAAA,EAAW;AACvD,IAAA,MAAM,CAAA,GAAI,MAAM,oBAAA,CAAqB,KAAA,CAAM,SAAS,OAAO,CAAA;AAC3D,IAAA,IAAA,GAAO,CAAA;AACP,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,IAAI;AAAE,QAAA,QAAA,CAAS,GAAG,OAAO,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAA,MAAiC;AAAA,IACvE;AACA,IAAA,IAAI,CAAA,CAAE,IAAI,OAAO,EAAE,IAAI,IAAA,EAAM,KAAA,EAAO,CAAA,CAAE,SAAA,CAAU,KAAA,EAAM;AACtD,IAAA,IAAA,CAAK,EAAE,MAAA,KAAW,iBAAA,IAAqB,EAAE,MAAA,KAAW,eAAA,KAAoB,UAAU,WAAA,EAAa;AAC7F,MAAA;AAAA,IACF;AACA,IAAA;AAAA,EACF;AACA,EAAA,OAAO,aAAa,IAAK,CAAA;AAC3B;AAEA,SAAS,cAAc,CAAA,EAAmB;AACxC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,GAAG,OAAO,oBAAA;AAChC,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAC,CAAA;AAC/C;AAEA,SAAS,aAAa,MAAA,EAAgD;AACpE,EAAA,IAAI,MAAA,CAAO,IAAI,OAAO,EAAE,IAAI,IAAA,EAAM,KAAA,EAAO,MAAA,CAAO,SAAA,CAAU,KAAA,EAAM;AAEhE,EAAA,QAAQ,OAAO,MAAA;AAAQ,IACrB,KAAK,eAAA;AAAA,IACL,KAAK,iBAAA;AAAA,IACL,KAAK,cAAA;AACH,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,OAAA,EACE;AAAA,OACJ;AAAA,IACF,KAAK,oBAAA;AAAA,IACL;AAIE,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,OAAO,OAAA,EAAQ;AAAA;AAElD;AC7FO,IAAM,eAAA,GAAkBA,MAC5B,MAAA,CAAO;AAAA,EACN,UAAUA,KAAAA,CAAE,IAAA,CAAK,CAAC,OAAA,EAAS,QAAQ,CAAC,CAAA;AAAA;AAAA,EAEpC,MAAA,EAAQ,SAAS,QAAA,EAAS;AAAA;AAAA,EAE1B,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACrB,CAAC,CAAA,CACA,MAAA;AAAA,EACC,CAAC,CAAA,KAAO,CAAA,CAAE,QAAA,KAAa,OAAA,GAAU,CAAA,CAAE,MAAA,IAAU,IAAA,GAAO,CAAA,CAAE,MAAA,IAAU,IAAA,IAAQ,CAAA,CAAE,OAAO,MAAA,GAAS,CAAA;AAAA,EAC1F;AAAA,IACE,OAAA,EACE;AAAA;AAEN;AAOK,SAAS,kBAAA,GAA8C;AAC5D,EAAA,OAAOY,gCAAgB,eAAA,EAAiB;AAAA,IACtC,MAAA,EAAQ,aAAA;AAAA,IACR,YAAA,EAAc;AAAA,GACf,CAAA;AACH;AAGO,SAAS,iBAAiB,GAAA,EAAiC;AAChE,EAAA,IAAI,GAAA,CAAI,QAAA,KAAa,OAAA,IAAW,GAAA,CAAI,UAAU,IAAA,EAAM;AAClD,IAAA,MAAM,IAAI,MAAM,0FAAwE,CAAA;AAAA,EAC1F;AAIA,EAAA,OAAO,GAAA,CAAI,MAAA;AACb;AClCO,IAAM,MAAA,GAASZ,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,KAAA,CAAM,0BAA0B,CAAA;AAO/CA,MAAE,IAAA,CAAK;AAAA,EACrC,KAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,YAAA;AAAA;AAAA,EACA,YAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAC;AAE2BA,MAAE,IAAA,CAAK;AAAA,EACjC;AAAA;AACF,CAAC;AAE6BA,MAAE,IAAA,CAAK;AAAA,EACnC;AAAA;AACF,CAAC;AAEgCA,MAAE,IAAA,CAAK;AAAA,EACtC,MAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAC;AAE8BA,MAAE,IAAA,CAAK;AAAA,EACpC;AAAA;AACF,CAAC;AAEgCA,MAAE,IAAA,CAAK;AAAA,EACtC,OAAA;AAAA;AAAA,EACA,UAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAC;AAEoCA,MAAE,IAAA,CAAK;AAAA,EAC1C;AAAA;AACF,CAAC;AAYD,IAAM,UAAA,GAAaA,MAAE,IAAA,CAAK;AAAA,EACxB,UAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGD,IAAM,aAAA,GAAgBA,MAAE,IAAA,CAAK;AAAA;AAAA,EAE3B,KAAA;AAAA,EAAO,aAAA;AAAA,EACP,aAAA;AAAA,EAAe,aAAA;AAAA,EAAe,aAAA;AAAA,EAC9B,YAAA;AAAA,EAAc,YAAA;AAAA,EAAc,YAAA;AAAA;AAAA,EAE5B,UAAA;AAAA;AAAA,EAEA,MAAA;AAAA,EAAQ,MAAA;AAAA;AAAA,EAER,OAAA;AAAA,EAAS,UAAA;AAAA,EAAY;AACvB,CAAC,CAAA;AAGM,IAAM,gBAAA,GAAmBA,MAAE,MAAA,CAAO;AAAA,EACvC,EAAA,EAAIA,KAAAA,CAAE,OAAA,CAAQ,YAAY,CAAA;AAAA,EAC1B,KAAA,EAAO,UAAA;AAAA,EACP,MAAA,EAAQA,MAAE,KAAA,CAAM,MAAM,EAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA;AAAA,EACpC,OAAA,EAAS,aAAA,CAAc,OAAA,CAAQ,KAAK,CAAA;AAAA,EACpC,gBAAgBA,KAAAA,CAAE,MAAA,CAAO,MAAA,EAAQA,KAAAA,CAAE,MAAM,CAACA,KAAAA,CAAE,MAAA,EAAO,EAAGA,MAAE,MAAA,EAAQ,CAAC,CAAC,EAAE,QAAA;AACtE,CAAC,CAAA;AAGM,IAAM,eAAA,GAAkBA,MAAE,MAAA,CAAO;AAAA,EACtC,EAAA,EAAIA,KAAAA,CAAE,OAAA,CAAQ,WAAW,CAAA;AAAA,EACzB,IAAA,EAAM,MAAA;AAAA,EACN,UAAA,EAAYA,KAAAA,CAAE,kBAAA,CAAmB,MAAA,EAAQ;AAAA,IACvCA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA,EAAG,EAAA,EAAIA,KAAAA,CAAE,MAAA,EAAO,EAAG,CAAA;AAAA,IACxDA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,UAAU,CAAA,EAAG,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQA,KAAAA,CAAE,MAAA,IAAU,CAAA;AAAA,IAC1EA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,UAAU,CAAA,EAAG,EAAA,EAAIA,KAAAA,CAAE,MAAM,CAAC,MAAA,EAAQ,QAAQ,MAAM,CAAC,GAAG,CAAA;AAAA,IAC/EA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,cAAc,CAAA,EAAG,EAAA,EAAIA,KAAAA,CAAE,MAAM,CAAC,MAAA,EAAQ,QAAQ,MAAM,CAAC,GAAG,CAAA;AAAA,IACnFA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,UAAU,CAAA,EAAG,EAAA,EAAIA,KAAAA,CAAE,MAAM,CAAC,MAAA,EAAQ,QAAQ,MAAM,CAAC,GAAG,CAAA;AAAA,IAC/EA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,aAAa,CAAA,EAAG,EAAA,EAAIA,KAAAA,CAAE,MAAM,CAAC,MAAA,EAAQ,QAAQ,MAAM,CAAC,GAAG,CAAA;AAAA,IAClFA,MAAE,MAAA,CAAO;AAAA,MACP,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA;AAAA,MAC9B,EAAA,EAAIA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,QAAO,EAAGA,KAAAA,CAAE,MAAA,EAAQ,CAAC,CAAA;AAAA,MACpC,MAAA,EAAQA,KAAAA,CAAE,KAAA,CAAM,CAACA,MAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAC,EAAE,QAAA;AAAS,KACxD,CAAA;AAAA,IACDA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,WAAW,CAAA,EAAG,EAAA,EAAIA,KAAAA,CAAE,MAAA,EAAO,EAAG,GAAGA,KAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,IAAI,CAAC,CAAA,CAAE,QAAA,EAAS,EAAG,CAAA;AAAA,IACjGA,KAAAA,CAAE,OAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,MAAM,CAAA,EAAG,EAAA,EAAIA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,MAAA,IAAUA,KAAAA,CAAE,MAAA,EAAQ,CAAC,CAAA,CAAE,QAAA,EAAS,EAAG,CAAA;AAAA;AAAA;AAAA;AAAA,IAItFA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,kBAAkB,CAAA,EAAG,MAAA,EAAQ,MAAA,EAAQ,CAAA;AAAA;AAAA;AAAA,IAGhEA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,UAAU,CAAA,EAAG,MAAA,EAAQ,MAAA,EAAQ,OAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,IAAY,CAAA;AAAA;AAAA,IAEtFA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,oBAAoB,CAAA,EAAG,IAAA,EAAMA,KAAAA,CAAE,QAAO,EAAG,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,QAAQ,CAAA;AAAA,IACnGA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,oBAAoB,CAAA,EAAG,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,MAAA,EAAQ,KAAA,EAAOA,MAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,EAAG,CAAA;AAAA;AAAA;AAAA,IAGxHA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,0BAA0B,CAAA,EAAG,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,MAAA,EAAQ,OAAA,EAAS,QAAQ,CAAA;AAAA,IACjGA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,eAAe,CAAA,EAAG,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQA,KAAAA,CAAE,MAAA,IAAU,CAAA;AAAA,IACjFA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA,EAAG,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAOA,MAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,EAAG,CAAA;AAAA,IACxHA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,mBAAmB,CAAA,EAAG,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQA,KAAAA,CAAE,MAAA,IAAU,CAAA;AAAA;AAAA;AAAA,IAGnFA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,2BAA2B,CAAA,EAAG,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQA,KAAAA,CAAE,MAAA,IAAU,CAAA;AAAA;AAAA,IAE3FA,MAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,aAAa,CAAA,EAAG,MAAA,EAAQ,MAAA,EAAQ,GAAG,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,aAAA,EAAe,QAAQ,CAAA;AAAA,IACxGA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,cAAc,CAAA,EAAG,EAAA,EAAI,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAQ,CAAA;AAAA,IACzEA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,aAAa,CAAA,EAAG,EAAA,EAAI,MAAA,EAAQ,OAAA,EAASA,KAAAA,CAAE,MAAA,IAAU,CAAA;AAAA,IAC5EA,MAAE,MAAA,CAAO,EAAE,MAAMA,KAAAA,CAAE,OAAA,CAAQ,UAAU,CAAA,EAAG,EAAA,EAAIA,MAAE,KAAA,CAAM,CAAC,QAAQ,MAAA,EAAQ,MAAM,CAAC,CAAA,EAAG,QAAA,EAAU,QAAQ,CAAA;AAAA;AAAA,IAEjGA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,MAAE,OAAA,CAAQ,mBAAmB,CAAA,EAAG,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,MAAA,EAAQA,MAAE,MAAA,EAAO,EAAG,KAAA,EAAOA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAGA,KAAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAC,CAAA,CAAE,QAAA,IAAY,CAAA;AAAA,IACpJA,MAAE,MAAA,CAAO;AAAA,MACP,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,iBAAiB,CAAA;AAAA,MACjC,IAAA,EAAM,MAAA;AAAA,MACN,OAAA,EAAS,MAAA;AAAA;AAAA;AAAA,MAGT,QAAA,EAAUA,KAAAA,CAAE,kBAAA,CAAmB,MAAA,EAAQ;AAAA,QACrCA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,QAAQ,cAAc,CAAA,EAAG,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAOA,KAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,QAAA,EAAS,EAAG,MAAA,EAAQA,MAAE,MAAA,EAAO,CAAE,QAAA,EAAS,EAAG,CAAA;AAAA,QACpIA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,eAAe,CAAA,EAAG,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,MAAA,EAAQ,KAAA,EAAOA,MAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAA,EAAS,EAAG,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,EAAG,CAAA;AAAA,QAC7IA,KAAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,KAAAA,CAAE,OAAA,CAAQ,SAAS,CAAA,EAAG,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,EAAG,KAAA,EAAOA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAA,EAAS,EAAG,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,EAAG;AAAA,OAC9I;AAAA,KACF;AAAA,GACF;AACH,CAAC,CAAA;AAGM,IAAM,cAAA,GAAiBA,MAAE,MAAA,CAAO;AAAA,EACrC,EAAA,EAAIA,KAAAA,CAAE,OAAA,CAAQ,SAAS,CAAA;AAAA,EACvB,IAAA,EAAM,MAAA;AAAA,EACN,EAAA,EAAI,MAAA;AAAA,EACJ,KAAA,EAAOA,MAAE,IAAA,CAAK;AAAA,IACZ,SAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACD,CAAA,CAAE,OAAA,CAAQ,SAAS;AACtB,CAAC,CAAA;AAGM,IAAM,iBAAA,GAAoBA,MAAE,MAAA,CAAO;AAAA,EACxC,EAAA,EAAIA,KAAAA,CAAE,OAAA,CAAQ,aAAa,CAAA;AAAA,EAC3B,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAMA,MAAE,IAAA,CAAK,CAAC,iBAAiB,UAAA,EAAY,cAAA,EAAgB,aAAA,EAAe,UAAU,CAAC,CAAA;AAAA,EACrF,MAAA,EAAQ,OAAO,QAAA,EAAS;AAAA,EACxB,OAAA,EAAS,OAAO,QAAA,EAAS;AAAA,EACzB,MAAA,EAAQA,MAAE,KAAA,CAAM,CAAC,QAAQ,MAAA,EAAQ,MAAM,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA;AAAA,EAEnD,QAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,QAAA,EAAS;AAAA,EACvC,QAAA,EAAUA,MAAE,KAAA,CAAM,CAAC,QAAQ,MAAA,EAAQ,MAAM,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA;AAAA,EAErD,SAAA,EAAWA,MAAE,KAAA,CAAM,CAAC,QAAQ,MAAM,CAAC,EAAE,QAAA;AACvC,CAAC,CAAA;AAGM,IAAM,eAAA,GAAkBA,MAAE,MAAA,CAAO;AAAA,EACtC,EAAA,EAAIA,KAAAA,CAAE,OAAA,CAAQ,WAAW,CAAA;AAAA,EACzB,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAMA,KAAAA,CAAE,IAAA,CAAK,CAAC,aAAA,EAAe,iBAAA,EAAmB,WAAA,EAAa,gBAAA,EAAkB,eAAA,EAAiB,aAAA,EAAe,aAAa,CAAC,CAAA;AAAA,EAC7H,OAAA,EAAS,OAAO,QAAA,EAAS;AAAA,EACzB,EAAA,EAAI,OAAO,QAAA,EAAS;AAAA,EACpB,IAAA,EAAM,OAAO,QAAA,EAAS;AAAA,EACtB,MAAA,EAAQ,OAAO,QAAA,EAAS;AAAA,EACxB,KAAA,EAAOA,MAAE,IAAA,CAAK,CAAC,SAAS,QAAA,EAAU,MAAM,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA;AAAA,EAEpD,MAAA,EAAQA,KAAAA,CAAE,KAAA,CAAM,MAAM,EAAE,QAAA,EAAS;AAAA;AAAA,EAEjC,OAAA,EAAS,OAAO,QAAA,EAAS;AAAA,EACzB,OAAA,EAAS,OAAO,QAAA,EAAS;AAAA;AAAA;AAAA,EAGzB,EAAA,EAAI,OAAO,QAAA,EAAS;AAAA,EACpB,MAAA,EAAQ,OAAO,QAAA,EAAS;AAAA,EACxB,EAAA,EAAI,OAAO,QAAA;AACb,CAAC,CAAA;AAGM,IAAM,gBAAA,GAAmBA,MAAE,MAAA,CAAO;AAAA,EACvC,EAAA,EAAIA,KAAAA,CAAE,OAAA,CAAQ,YAAY,CAAA;AAAA,EAC1B,OAAOA,KAAAA,CAAE,IAAA,CAAK,CAAC,UAAA,EAAY,eAAe,CAAC,CAAA;AAAA,EAC3C,MAAA,EAAQA,MAAE,KAAA,CAAM,MAAM,EAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC;AACtC,CAAC,CAAA;AAGM,IAAM,OAAA,GAAUA,KAAAA,CAAE,kBAAA,CAAmB,IAAA,EAAM;AAAA,EAChD,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,cAAA;AAAA,EACA,iBAAA;AAAA,EACA,eAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAC;AAyBM,IAAM,eAAA,GAAkBA,MAC5B,MAAA,CAAO;AAAA,EACN,UAAUA,KAAAA,CAAE,IAAA,CAAK,CAAC,OAAA,EAAS,QAAQ,CAAC,CAAA;AAAA,EACpC,OAAA,EAASA,KAAAA,CAAE,KAAA,CAAM,OAAO,EAAE,QAAA,EAAS;AAAA,EACnC,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACrB,CAAC,CAAA,CACA,MAAA;AAAA,EACC,CAAC,CAAA,KACC,CAAA,CAAE,aAAa,OAAA,GACX,KAAA,CAAM,QAAQ,CAAA,CAAE,OAAO,KAAK,CAAA,CAAE,OAAA,CAAQ,SAAS,CAAA,GAC/C,CAAA,CAAE,UAAU,IAAA,IAAQ,CAAA,CAAE,OAAO,MAAA,GAAS,CAAA;AAAA,EAC5C;AAAA,IACE,OAAA,EACE;AAAA;AAEN;ACpQK,SAAS,wBAAA,GAAoD;AAClE,EAAA,OAAOY,gCAAgB,eAAA,EAAiB;AAAA,IACtC,MAAA,EAAQ,aAAA;AAAA,IACR,YAAA,EAAc;AAAA,GACf,CAAA;AACH;AAEO,SAAS,mBAAmB,GAAA,EAA0C;AAC3E,EAAA,IAAI,GAAA,CAAI,QAAA,KAAa,OAAA,IAAW,GAAA,CAAI,WAAW,IAAA,EAAM;AACnD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,GAAA,CAAI,OAAA;AACb;;;ACFA,IAAM,QAAA,GAA4B;AAAA,EAChC;AAAA,IACE,OAAA,EAAS,kBAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA;AAAM;AACjF,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,4CAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,aAAA;AAAc;AACzF,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,sCAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,YAAA;AAAa;AACxF,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,wBAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,QAAA,EAAU,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,SAAS,UAAA;AAAW;AACzF,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,kCAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,WAAA,EAAa,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,SAAS,UAAA;AAAW;AAC5F,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,oCAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,aAAA;AAAc;AACzF,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,oCAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,aAAA;AAAc;AACzF,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,oBAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,SAAS,UAAA;AAAW;AAC1F,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,+BAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,eAAA,EAAiB,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,SAAS,UAAA;AAAW;AAChG,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,2DAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,WAAA,EAAa,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,SAAS,UAAA;AAAW;AAC5F,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,8EAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,IAAA,EAAK,EAAE;AAAA,MACzE,EAAE,IAAI,SAAA,EAAW,IAAA,EAAM,KAAK,EAAA,EAAI,GAAA,EAAK,OAAO,SAAA;AAAU;AACxD,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,oFAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,GAAA,EAAK,MAAA,EAAQ,MAAK,EAAE;AAAA,MACxF,EAAE,IAAI,SAAA,EAAW,IAAA,EAAM,KAAK,EAAA,EAAI,GAAA,EAAK,OAAO,SAAA;AAAU;AACxD,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,yCAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,IAAA,EAAK;AAAE;AAC3E,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,kCAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAK,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,IAAI,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,GAAE;AAAE;AACtF,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,oEAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,aAAA,EAAe,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAAE;AAC5E,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,oEAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,aAAA,EAAe,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAAE;AAC5E,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,sGAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,eAAA,EAAiB,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,SAAS,UAAA,EAAW;AAAA,MAC9F,EAAE,IAAI,SAAA,EAAW,IAAA,EAAM,KAAK,EAAA,EAAI,GAAA,EAAK,OAAO,SAAA,EAAU;AAAA,MACtD,EAAE,IAAI,SAAA,EAAW,IAAA,EAAM,KAAK,EAAA,EAAI,GAAA,EAAK,OAAO,SAAA,EAAU;AAAA,MACtD,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAK,UAAA,EAAY,EAAE,IAAA,EAAM,cAAA,EAAgB,EAAA,EAAI,CAAC,IAAA,EAAM,IAAI,GAAE;AAAE;AACvF,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,8FAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,YAAA;AAAa;AACxF,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,mGAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,eAAA,EAAiB,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,SAAS,KAAA,EAAM;AAAA,MACzF,EAAE,EAAA,EAAI,aAAA,EAAe,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAE;AAAA,MAC1E,EAAE,IAAI,SAAA,EAAW,IAAA,EAAM,KAAK,EAAA,EAAI,GAAA,EAAK,OAAO,SAAA,EAAU;AAAA,MACtD,EAAE,IAAI,SAAA,EAAW,IAAA,EAAM,KAAK,EAAA,EAAI,GAAA,EAAK,OAAO,SAAA;AAAU;AACxD,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,oGAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,MAAM,aAAA,EAAe,OAAA,EAAS,GAAA,EAAK,EAAA,EAAI,IAAA;AAAK;AAC5E,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,4HAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,aAAA,EAAe,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAE;AAAA,MAC1E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,IAAA,EAAM,MAAM,WAAA,EAAa,OAAA,EAAS,GAAA,EAAK,MAAA,EAAQ,GAAA;AAAI;AAC9E,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,qLAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,aAAA,EAAe,IAAA,EAAM,GAAA,EAAK,MAAM,cAAA,EAAgB,MAAA,EAAQ,GAAA,EAAK,MAAA,EAAQ,CAAA,EAAE;AAAA,MAC7E,EAAE,IAAI,WAAA,EAAa,IAAA,EAAM,KAAK,UAAA,EAAY,EAAE,IAAA,EAAM,MAAA,EAAO,EAAE;AAAA,MAC3D,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,KAAA,EAAO,OAAA,EAAQ;AAAA,MAC/F,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAA,EAAO,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAK,KAAA,EAAO,QAAA;AAAS;AAClG,GACF;AAAA;AAAA,EAEA;AAAA,IACE,OAAA,EAAS,oCAAA;AAAA,IACT,SAAS;AAAC,GACZ;AAAA,EACA;AAAA,IACE,OAAA,EAAS,qBAAA;AAAA,IACT,SAAS;AAAC,GACZ;AAAA,EACA;AAAA,IACE,OAAA,EAAS,yDAAA;AAAA,IACT,SAAS;AAAC,GACZ;AAAA,EACA;AAAA,IACE,OAAA,EAAS,oGAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,aAAA,EAAe,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAE;AAAA,MAC1E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,YAAY,EAAE,IAAA,EAAM,aAAA,EAAe,MAAA,EAAQ,KAAK,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAK,aAAA,EAAe,KAAI;AAAE;AACrH,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,uGAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAK,UAAA,EAAY,EAAE,IAAA,EAAM,aAAA,EAAe,IAAI,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,GAAE,EAAE;AAAA,MACvF,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,UAAA,EAAY,EAAE,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,GAAA,EAAK,OAAA,EAAS,MAAK;AAAE;AAC5F,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,6DAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,YAAY,EAAE,IAAA,EAAM,UAAA,EAAY,EAAA,EAAI,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,QAAA,EAAU,KAAI;AAAE;AACrG,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,wKAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,GAAA,EAAK,UAAA,EAAY,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,GAAA,EAAK,MAAA,EAAQ,MAAK,EAAE;AAAA,MACxF,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAK,UAAA,EAAY,EAAE,IAAA,EAAM,aAAA,EAAe,IAAI,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,GAAE,EAAE;AAAA,MACvF,EAAE,IAAI,SAAA,EAAW,IAAA,EAAM,KAAK,EAAA,EAAI,GAAA,EAAK,OAAO,SAAA,EAAU;AAAA,MACtD,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAK,UAAA,EAAY,EAAE,IAAA,EAAM,mBAAA,EAAqB,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,MAAA,EAAQ,MAAK;AAAE;AACxG,GACF;AAAA,EACA;AAAA,IACE,OAAA,EAAS,wHAAA;AAAA,IACT,OAAA,EAAS;AAAA,MACP,EAAE,EAAA,EAAI,YAAA,EAAc,KAAA,EAAO,UAAA,EAAY,MAAA,EAAQ,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA,EAAG,OAAA,EAAS,KAAA,EAAM;AAAA,MAC/E,EAAE,EAAA,EAAI,WAAA,EAAa,IAAA,EAAM,KAAK,UAAA,EAAY,EAAE,IAAA,EAAM,mBAAA,EAAqB,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,MAAA,EAAQ,KAAI;AAAE;AACvG;AAEJ,CAAA;AAEO,SAAS,uBAAA,GAAkC;AAChD,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM;AACtC,IAAA,MAAM,WACJ,CAAA,CAAE,OAAA,CAAQ,MAAA,GAAS,CAAA,GACf,EAAE,QAAA,EAAU,OAAA,EAAS,OAAA,EAAS,CAAA,CAAE,SAAQ,GACxC,EAAE,QAAA,EAAU,QAAA,EAAU,QAAQ,uGAAA,EAA+C;AACnF,IAAA,OAAO,CAAA,kBAAA,EAAa,IAAI,CAAC;AAAA,kBAAA,EACnB,EAAE,OAAO;AAAA;AAAA,EAEjB,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAC,CAAA,CAAA;AAAA,EACjC,CAAC,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA;AAEd,EAAA,OAAO,CAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA,EAAA,EAsHL,SAAS,MAAM,CAAA;;AAAA,EAEjB,QAAQ;AAAA,CAAA;AAEV;;;AClVA,eAAsB,0BAAA,CACpB,OAAA,EACA,IAAA,GAA0C,EAAC,EACV;AACjC,EAAA,IAAI;AACF,IAAA,MAAM,CAAA,GAAI,MAAM,oBAAA,CAAqB,OAAA,EAAS,IAAI,CAAA;AAClD,IAAA,IAAI,EAAE,EAAA,EAAI;AACR,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,SAAA;AAAA,QACN,KAAK,CAAA,CAAE,GAAA;AAAA,QACP,SAAS,CAAA,CAAE,OAAA;AAAA,QACX,KAAA,EAAO;AAAA,UACL,WAAA,EAAa,EAAE,KAAA,CAAM,WAAA;AAAA,UACrB,YAAA,EAAc,EAAE,KAAA,CAAM;AAAA;AACxB,OACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,MAAM,OAAA,EAAS,IAAA,EAAM,EAAE,MAAA,EAAQ,OAAA,EAAS,EAAE,OAAA,EAAQ;AAAA,EAC7D,SAAS,CAAA,EAAG;AACV,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,OAAA;AAAA,MACN,IAAA,EAAM,YAAA;AAAA,MACN,SAAS,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC;AAAA,KACpD;AAAA,EACF;AACF;;;AC7CA,SAAS,iBAAiB,MAAA,EAA2B;AACnD,EAAA,MAAM,CAAA,GAAI,MAAA;AACV,EAAA,IAAI,CAAA,CAAE,OAAO,YAAA,EAAc;AACzB,IAAA,OAAO,MAAM,OAAA,CAAQ,CAAA,CAAE,MAAM,CAAA,GAAK,CAAA,CAAE,SAAsB,EAAC;AAAA,EAC7D;AAEA,EAAA,IAAI,OAAO,CAAA,CAAE,IAAA,KAAS,UAAU,OAAO,CAAC,EAAE,IAAI,CAAA;AAC9C,EAAA,OAAO,EAAC;AACV;AAOO,SAAS,YAAA,CAAa,KAAyB,GAAA,EAAoC;AACxF,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAY;AACjC,EAAA,KAAA,MAAW,CAAA,IAAK,KAAK,KAAA,MAAW,CAAA,IAAK,iBAAiB,CAAC,CAAA,EAAG,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA;AAExE,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAY,GAAA,CAAI,GAAA,CAAI,CAAC,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAC,CAAA;AAC9D,EAAA,MAAM,GAAA,GAAiB,CAAC,GAAG,GAAG,CAAA;AAE9B,EAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACnB,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAA;AAC5B,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,IAAA,MAAM,KAAA,GAAQ,iBAAiB,CAAC,CAAA;AAChC,IAAA,IAAI,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,SAAS,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG;AACxC,IAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AACZ,IAAA,GAAA,CAAI,KAAK,CAAC,CAAA;AAAA,EACZ;AACA,EAAA,OAAO,GAAA;AACT","file":"ai.js","sourcesContent":["// src/stamps/geometry-2d/ai/deterministic/vocabulary.ts\n//\n// Tập từ khóa \"geometry-relevant\" để confidence.ts đo coverage.\n// Format: lowercase, có dấu. countGeometryKeywords lowercase input rồi match.\n\nexport const GEOMETRY_KEYWORDS: readonly string[] = [\n // Base shapes\n 'tam giác', 'đường tròn', 'đương tròn', 'hình chữ nhật', 'hình vuông',\n 'hình bình hành', 'hình thoi', 'hình thang', 'tứ giác',\n // Triangle variants\n 'vuông tại', 'cân tại', 'đều',\n // Circle parts\n 'bán kính', 'tâm', 'đường kính', 'đương kính',\n // Segments / on-segment\n 'đoạn',\n // Derived points\n 'trung điểm', 'chân đường cao', 'chân đương cao', 'hình chiếu',\n 'trọng tâm', 'trực tâm', 'tâm nội tiếp', 'tâm ngoại tiếp',\n // Cevian names\n 'đường cao', 'đương cao', 'trung tuyến', 'phân giác', 'trung trực',\n // Special lines/circles\n 'tiếp tuyến', 'tiếp điểm', 'tiếp xúc',\n 'nội tiếp', 'ngoại tiếp',\n // Euler line (issue #47). Đánh dấu mọi clause \"Euler\" là geo-clause để\n // mention Euler chưa được claim (suy biến tam giác đều, hoặc đường tròn Euler\n // 9 điểm defer) → escalate fail-safe thay vì silent render-nothing.\n 'euler',\n // Trục đẳng phương (issue #47, construct 2). \"đẳng phương\" (≥10 ký tự, phân\n // biệt) đánh dấu clause là geo-clause: nếu radicalAxis rule miss (đồng tâm /\n // ≠2 đường tròn) → clause không phủ → escalate fail-safe (KHÔNG silent\n // render-nothing). Lowercase vì countGeometryKeywords lowercase input.\n 'đẳng phương',\n // Đường thẳng Simson (issue #47, construct 3). \"simson\" (danh từ riêng phân\n // biệt) đánh dấu clause là geo-clause: nếu simson rule miss (thiếu đường tròn\n // ngoại tiếp / >1 tam giác / P trùng đỉnh) → clause không phủ → escalate\n // fail-safe (KHÔNG silent render-nothing). Lowercase vì countGeometryKeywords\n // lowercase input.\n 'simson',\n // Đường tròn chín điểm / đường tròn Euler (issue #47, construct 4). \"chín điểm\"\n // đánh dấu clause là geo-clause: \"đường tròn Euler\" đã geo qua \"đường tròn\"/\n // \"euler\" sẵn, nhưng \"chín điểm\" (≥8 ký tự, phân biệt) phủ thêm cách diễn đạt\n // trần \"đường tròn chín điểm\" + làm fail-safe tường minh (nếu ninePoint rule\n // miss vì >1 tam giác → clause không phủ → escalate, KHÔNG silent render-nothing).\n // Lowercase vì countGeometryKeywords lowercase input.\n 'chín điểm',\n // Relations\n 'song song', 'vuông góc', 'giao điểm', 'cắt', 'đường thẳng', 'đương thẳng',\n // Ký hiệu (symbol-only phrasing tương đương từ chữ): \"⊥\" ≡ \"vuông góc\".\n // perpFoot rule đã nhận \"⊥\" ở tầng construct (PERP_DRAW), nhưng gate\n // hasGeometry trước đây CHỈ nhận chữ \"vuông góc\" → clause mà \"⊥\" là tín hiệu\n // hình học DUY NHẤT bị coi là văn xuôi (hasGeometry=false). Thêm \"⊥\" để 2\n // phrasing hành xử như nhau ở gate coverage (issue #46 nhóm A).\n '⊥',\n\n // === EN keywords (issue #46 group B) =======================================\n // Bộ từ khoá tiếng Anh để 1 clause TOÀN tiếng Anh được tính là geo-clause\n // (countGeometryKeywords > 0) → coverage gate không escalate sai dù rule EN đã\n // match. countGeometryKeywords lowercase input nên lưu lowercase ở đây.\n //\n // CHỈ thêm danh từ construct ĐA-KÝ-TỰ phân biệt, KHÔNG va chạm có hại như\n // substring của text tiếng Việt hay của nhau. KHÔNG thêm từ ngắn mơ hồ (\"on\",\n // \"at\", \"line\", \"point\", \"right\") vì dễ false-positive (\"point\" ⊂ \"appoint\",\n // \"at\" ⊂ \"tại\"…). Một danh từ construct / clause là đủ để đánh dấu geo.\n //\n // GOTCHA substring: \"centre\" ⊃ \"center\" KHÔNG xảy ra (khác chính tả); \"circle\"\n // KHÔNG ⊂ từ VN. \"radius\"/\"diameter\"/\"center\" là danh từ riêng cho circle.\n 'triangle',\n 'circle',\n 'square',\n 'rectangle',\n 'parallelogram',\n 'rhombus',\n 'trapezoid',\n 'trapezium',\n 'quadrilateral',\n 'midpoint',\n 'radius',\n 'diameter',\n 'center',\n 'centre',\n 'equilateral',\n 'isosceles',\n // Triangle centers (issue #46 group B). \"orthocenter\"/\"circumcenter\"/\n // \"incenter\" already contain \"center\" (already a keyword) — but list all four\n // explicitly for clarity + robustness. British -centre spellings included.\n 'centroid',\n 'orthocenter',\n 'orthocentre',\n 'circumcenter',\n 'circumcentre',\n 'incenter',\n 'incentre',\n // perpBisector + reflection EN (issue #46 group B). Hai danh từ này biến clause\n // \"perpendicular bisector …\" / \"reflection …\" tiếng Anh thành geo-clause để\n // coverage gate hoạt động: nếu rule EN match đủ thì clause được phủ; nếu clause\n // malformed (thiếu cặp đỉnh / thiếu trục) thì geo-clause không được phủ →\n // escalate (fail-safe), KHÔNG silent-incomplete. Đều ≥8 ký tự, phân biệt, không\n // substring của từ VN/EN nào hiện có (không va chạm).\n 'bisector',\n 'reflection',\n // tangentFromExt EN (issue #46 group B). Clause \"Draw the tangents from A to\n // (O)\" dùng ký hiệu \"(O)\" — KHÔNG có text keyword nào khác → coverage gate = 0\n // → escalate dù rule match. \"tangent\" (≥7 ký tự, phân biệt, KHÔNG substring của\n // từ VN/EN nào hiện có) đánh dấu clause là geo-clause. indexOf nên \"tangent\" tự\n // khớp trong \"tangents\"/\"tangent lines\" — KHÔNG cần thêm \"tangents\" riêng.\n 'tangent',\n // perpFoot EN (issue #46 group B). Clause \"Let H be the projection of A onto\n // BC\" / \"foot of the perpendicular from A to BC\" / \"Draw AH perpendicular to\n // BC\" → đánh dấu geo-clause để coverage gate fail-safe: nếu rule EN miss thì\n // geo-clause không phủ → escalate, KHÔNG silent-incomplete (triangle-only bỏ\n // điểm H). Cả hai ≥10 ký tự, phân biệt, không substring của từ VN/EN nào hiện\n // có. \"perpendicular bisector of BC\" đã có 'bisector' → 'perpendicular' chỉ\n // tăng count, không đổi hành vi.\n 'perpendicular',\n 'projection',\n // pointAtDistance EN (issue #46 group B). Clause \"On ray BA extended beyond A,\n // take D such that AD = AB\" / \"Extend AB beyond B to D ...\" / \"On the opposite\n // ray of ray BA, take D ...\" → mark geo-clause. \"extend\" (indexOf also matches\n // \"extended\"/\"extending\") + the phrase \"opposite ray\" (geometry-specific). If\n // the rule misses a malformed clause → geo-clause unclaimed → escalate\n // (fail-safe), NOT silent-drop of point D. No harmful substring collision with\n // any existing VN/EN keyword.\n 'extend',\n 'opposite ray',\n // cevian EN (issue #46 group B). Clause \"Draw the median AM\" / \"Draw the\n // altitude AH\" → mark geo-clause. Nếu rule không parse được clause median/\n // altitude bị lỗi → geo-clause không phủ → escalate (fail-safe), KHÔNG\n // silent-incomplete (triangle-only bỏ điểm chân). ('bisector' đã có ở trên.)\n // Cả hai đều là danh từ hình học riêng, không substring va chạm có hại.\n 'median',\n 'altitude',\n // connect EN (issue #46 nhóm B). VN \"đoạn\" LÀ keyword → \"segment\" parity để\n // \"Draw segment XY\" standalone là geo-clause: rule connect EN claim → render;\n // clause malformed (\"segment\" không cặp HOA) → geo unclaimed → escalate\n // (fail-safe). ≥7 ký tự, phân biệt, không substring va chạm. \"line\"/\"ray\"/\"draw\"/\n // \"join\"/\"connect\" CỐ Ý KHÔNG thêm (đối VN \"đường thẳng\"/\"tia\"/… cũng không phải\n // keyword → parity: render in-context, escalate standalone).\n 'segment',\n];\n\nexport function countGeometryKeywords(text: string): number {\n const lower = text.toLowerCase();\n let count = 0;\n for (const kw of GEOMETRY_KEYWORDS) {\n let from = 0;\n while (true) {\n const i = lower.indexOf(kw, from);\n if (i < 0) break;\n count++;\n from = i + kw.length;\n }\n }\n return count;\n}\n","// src/stamps/geometry-2d/ai/deterministic/coverage.ts\n//\n// Clause segmentation + coverage cho deterministic-first gate.\n// Track A chỉ \"tự tin\" dùng kết quả khi MỌI clause mang nội dung hình học\n// đều được ít nhất 1 rule match claim. Còn sót → escalate AI.\nimport { countGeometryKeywords } from './vocabulary';\n\nexport interface Clause {\n id: number;\n text: string;\n /** clause chứa ≥1 từ khoá hình học → tính vào mẫu số coverage. */\n hasGeometry: boolean;\n}\n\nexport interface CoverageReport {\n complete: boolean;\n coveredClauseIds: number[];\n uncovered: Clause[];\n ratio: number;\n}\n\ninterface MatchLike {\n clauseIds: number[];\n}\n\n/**\n * Tách đề thành clause theo dấu câu (. ; xuống dòng) và dấu phẩy đứng trước\n * từ dẫn (\"Gọi\", \"Vẽ\", \"Kẻ\"…). Clause thuần văn xuôi (không từ khoá hình học)\n * vẫn được giữ nhưng `hasGeometry=false` để không ép escalate.\n */\nexport function segmentClauses(problem: string): Clause[] {\n // Comma-split lookahead: tách clause ở dấu phẩy đứng TRƯỚC từ dẫn. VN dùng\n // (Gọi|Vẽ|Kẻ|Cho|Lấy|Dựng|trên|với). EN ADDITIVE (issue #46 group B): các từ\n // dẫn sub-clause viết HOA đầu câu (Let|Draw|Mark|Take|Construct|Join) — \"Triangle\n // ABC, let M be the midpoint of BC\" tách thành 2 clause. Thuần additive: không\n // đổi segmentation VN (alternation rời nhau, không trùng từ).\n return problem\n .split(\n /[.;\\n]+|,\\s*(?=(?:Gọi|Vẽ|Kẻ|Cho|Lấy|Dựng|trên|với|Let|Draw|Mark|Take|Construct|Join)\\b)/u,\n )\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .map((text, id) => ({ id, text, hasGeometry: countGeometryKeywords(text) > 0 }));\n}\n\nexport function computeCoverage(\n clauses: readonly Clause[],\n matches: readonly MatchLike[],\n): CoverageReport {\n const claimed = new Set<number>();\n for (const m of matches) for (const id of m.clauseIds) claimed.add(id);\n\n const geoClauses = clauses.filter((c) => c.hasGeometry);\n const uncovered = geoClauses.filter((c) => !claimed.has(c.id));\n const coveredClauseIds = geoClauses\n .filter((c) => claimed.has(c.id))\n .map((c) => c.id);\n\n return {\n complete: uncovered.length === 0 && geoClauses.length > 0,\n coveredClauseIds,\n uncovered,\n ratio: geoClauses.length === 0 ? 0 : coveredClauseIds.length / geoClauses.length,\n };\n}\n","// src/stamps/geometry-2d/ai/rules/_shared.ts\n//\n// Helper dùng chung cho rule module: intent factory (cast IntentT tập trung 1 chỗ)\n// + trích tên điểm từ lời dẫn tiếng Việt. Rule module KHÔNG tự cast `as any`.\nimport type { IntentT } from '../intent';\n\n// --- Intent factories (cast tập trung) ---------------------------------------\n// variant/shape/kind là string runtime; zod validate lại ở builder/transpile,\n// nên cast qua unknown an toàn trong phạm vi NLU.\n\nexport function drawShape(\n shape: string,\n labels: string[],\n variant = 'any',\n explicitCoords?: Record<string, readonly [number, number]>,\n): IntentT {\n return {\n op: 'draw-shape',\n shape,\n labels,\n variant,\n ...(explicitCoords ? { explicitCoords } : {}),\n } as unknown as IntentT;\n}\n\nexport function addPoint(name: string, constraint: Record<string, unknown>): IntentT {\n return { op: 'add-point', name, constraint } as unknown as IntentT;\n}\n\nexport function connect(from: string, to: string, style = 'segment'): IntentT {\n return { op: 'connect', from, to, style } as unknown as IntentT;\n}\n\nexport function drawCircle(\n name: string,\n spec: string,\n extra: Record<string, unknown> = {},\n): IntentT {\n return { op: 'draw-circle', name, spec, ...extra } as unknown as IntentT;\n}\n\nexport function drawLine(\n name: string,\n kind: string,\n extra: Record<string, unknown> = {},\n): IntentT {\n return { op: 'draw-line', name, kind, ...extra } as unknown as IntentT;\n}\n\n/** Đa giác con (triangle|quadrilateral) nối các ĐIỂM ĐÃ CÓ — không tạo coord mới. */\nexport function markShape(shape: string, labels: string[]): IntentT {\n return { op: 'mark-shape', shape, labels } as unknown as IntentT;\n}\n\n// --- Point-name extraction ----------------------------------------------------\n\nconst INTRO_NAME =\n /(?:Gọi|Lấy|Dựng|Vẽ|Kẻ|Đặt|Xác định)\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)\\b/u;\nconst NAME_LA = /\\b([A-Z])(?:['′]?)\\s+là\\b/u;\n\n/**\n * Trích tên điểm được giới thiệu trong clause:\n * \"Gọi M là trung điểm BC\" → \"M\"\n * \"Lấy điểm D trên cạnh AB\" → \"D\"\n * \"H là trực tâm\" → \"H\"\n * Trả undefined nếu không tìm thấy (caller tự quyết fallback / bỏ qua).\n */\nexport function extractPointName(clauseText: string): string | undefined {\n const intro = INTRO_NAME.exec(clauseText);\n if (intro) return intro[1];\n const la = NAME_LA.exec(clauseText);\n if (la) return la[1];\n return undefined;\n}\n\n/** Tách \"BC\" → [\"B\",\"C\"]; \"AB\" → [\"A\",\"B\"]. Trả [] nếu không phải cặp đỉnh. */\nexport function pairFromToken(token: string): string[] {\n const m = /^([A-Z])([A-Z])$/u.exec(token.trim());\n return m ? [m[1], m[2]] : [];\n}\n\n// --- Side / segment prefix ----------------------------------------------------\n// Tiền tố \"cạnh\"/\"đoạn\" tuỳ chọn TRƯỚC cặp đỉnh, cho phép bổ ngữ \"huyền\"/\"thẳng\"\n// chen giữa: \"cạnh BC\", \"cạnh huyền BC\", \"đoạn AC\", \"đoạn thẳng AC\". Fail-safe:\n// \"cạnh thẳng\"/\"đoạn huyền\" (sai cặp) KHÔNG khớp vì bổ ngữ bị buộc đúng loại.\n// Là FRAGMENT regex (string, không cờ) để nhúng vào pattern lớn hơn — bổ ngữ là\n// optional nên prefix vẫn khớp dạng trần \"cạnh BC\".\nexport const SIDE_PREFIX = '(?:cạnh(?:\\\\s+huyền)?\\\\s+|đoạn(?:\\\\s+thẳng)?\\\\s+)?';\n\n/** \"đường\" và typo \"đương\" (thiếu dấu huyền). */\nexport const DUONG_KW = '[Đđ]ư[ờơ]ng';\n\n/** \"đường tròn\" và typo \"đương tròn\". */\nexport const CIRCLE_KW = DUONG_KW + '\\\\s*tròn';\n\n/**\n * Kiểm tra tên có phải là nhãn điểm (tâm) hay không.\n * Thỏa mãn: 1 chữ HOA + tuỳ chọn dấu phẩy/số (vd: O, O', O1).\n */\nexport function isCenterName(name: string): boolean {\n return /^[A-Z]['′]?\\d*$/u.test(name);\n}\n","// src/stamps/geometry-2d/ai/rules/triangle.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { drawShape, addPoint, drawCircle, markShape } from './_shared';\n\n// MULTI-MATCH: 1 clause có thể chứa NHIỀU tam giác (\"tam giác ABC và tam giác\n// ABD vuông tại A\", \"tam giác đều DEF nội tiếp tam giác ABC\"). Bắt MỌI tam giác\n// (cờ 'g'), variant bind từ TEXT WINDOW giữa tam giác này và tam giác KẾ — KHÔNG\n// vơ chữ \"đều\"/\"vuông tại X\" của tam giác khác.\n//\n// leadMod = từ bổ nghĩa ĐỨNG TRƯỚC bộ 3 đỉnh (\"tam giác đều DEF\", \"tam giác\n// vuông ABC\", \"tam giác cân ABC\"). leadMod \"đều\" → equilateral ngay; \"vuông\"/\n// \"cân\" leadMod (không có \"tại X\") không đủ thông tin chọn đỉnh → để window xử lý.\nconst TRI_G = /tam giác\\s+(?:(đều|vuông|cân)\\s+)?([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\nconst RIGHT_AT = /vuông\\s+tại\\s+([A-Z])(?![A-Za-z])/u;\nconst ISO_AT = /cân\\s+tại\\s+([A-Z])(?![A-Za-z])/u;\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Dùng lookaround \\p{L} để chặn match giữa từ dài hơn.\nconst EQUILATERAL = /(?<!\\p{L})đều(?!\\p{L})/u;\n\n// === EN patterns (issue #46 group B) ========================================\n// MULTI-MATCH như VN: cờ 'g'. leadMod ĐỨNG TRƯỚC \"triangle\" (mirror \"tam giác đều\n// DEF\"): \"equilateral triangle ABC\", \"right triangle ABC\", \"isosceles triangle\n// ABC\". First-letter case flexibility ([Tt], [Ee]…) — KHÔNG cờ 'i' (sẽ phá [A-Z]\n// nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]).\nconst TRI_EN_G =\n /(?:([Ee]quilateral|[Rr]ight-angled|[Rr]ight|[Ii]sosceles)\\s+)?[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n// Window modifiers (đứng SAU nhãn): \"right angle at A\" / \"right-angled at A\".\nconst RIGHT_AT_EN = /[Rr]ight(?:\\s+angle|-angled)\\s+at\\s+([A-Z])(?![A-Za-z])/u;\n// \"with apex A\" / \"apex at A\" / \"apex A\". CHỈ nhận khi ngữ cảnh cân (isosceles).\nconst APEX_AT_EN = /apex\\s+(?:at\\s+)?([A-Z])(?![A-Za-z])/u;\n// \"... is equilateral\" / \"equilateral triangle …\" trong window riêng tam giác này.\nconst EQUILATERAL_EN = /(?<![A-Za-z])[Ee]quilateral(?![A-Za-z])/u;\nconst ISOSCELES_EN = /(?<![A-Za-z])[Ii]sosceles(?![A-Za-z])/u;\n\n/** Chuẩn hoá leadMod EN về token canonical: 'equilateral'|'right'|'isosceles'. */\nfunction normLeadEn(lead: string | undefined): string | undefined {\n if (!lead) return undefined;\n const l = lead.toLowerCase();\n if (l === 'equilateral') return 'equilateral';\n if (l === 'right' || l === 'right-angled') return 'right';\n if (l === 'isosceles') return 'isosceles';\n return undefined;\n}\n\ninterface TriHit {\n labels: string[];\n /** leadMod đứng ngay trước bộ 3 đỉnh, hoặc undefined. */\n lead?: string;\n /** ngôn ngữ của hit — quyết định dùng window VN hay EN khi suy variant. */\n lang: 'vi' | 'en';\n /** offset bắt đầu match (để sắp xếp + tính window theo thứ tự text). */\n start: number;\n /** vị trí ngay sau match (đầu window). */\n end: number;\n}\n\n/**\n * Suy variant cho 1 tam giác từ: leadMod (\"tam giác đều DEF\") + WINDOW text\n * (đoạn từ ngay sau bộ 3 đỉnh tới đầu tam giác kế / hết clause). \"vuông tại X\" /\n * \"cân tại X\" CHỈ áp nếu X ∈ labels của tam giác NÀY (tránh bind nhầm sang tam\n * giác khác cùng clause). Quy ước enum (xem TriangleVariantZ): cân tại A ⇒\n * isoceles-BC (đáy CYCLIC: apex A→BC, B→CA, C→AB); vuông tại A ⇒ right-at-A.\n */\n// Variant enum là POSITIONAL theo INDEX đỉnh đặc biệt trong labels (builder\n// triangleCanonical: isoceles-BC ⇒ apex = vertex[0], right-at-A ⇒ vertex[0]\n// vuông). KHÔNG dùng chữ-cái-nhãn: tam giác [A,C,D] \"cân tại A\" (apex idx 0) →\n// isoceles-BC (positional), KHÔNG phải \"isoceles-CD\". Với nhãn ABC chuẩn,\n// positional trùng label nên tương thích ngược.\nconst RIGHT_BY_IDX = ['right-at-A', 'right-at-B', 'right-at-C'];\nconst ISO_BY_IDX = ['isoceles-BC', 'isoceles-CA', 'isoceles-AB'];\n\n// === Thales: tam giác VUÔNG nội tiếp đường tròn → đường kính + glider ===========\n// Vuông tại A nội tiếp (O) ⟺ BC là ĐƯỜNG KÍNH (góc nội tiếp chắn nửa đường tròn).\n// Dựng RÀNG BUỘC (kéo vẫn vuông): 2 đầu mút đường kính free + tâm O = trung điểm +\n// đường tròn centerThrough (bán kính theo đầu mút) + apex là glider onCircle.\n// → góc vuông tại apex luôn đúng; AB<AC chọn bằng vị trí đầu mút cạnh ngắn (bên trái).\n//\n// CHỈ kích hoạt khi tam giác VUÔNG + có ngữ cảnh \"nội tiếp đường tròn/(O)\" SAU nhãn\n// (window). \"đường tròn nội tiếp tam giác\" (incircle) đứng TRƯỚC nhãn → KHÔNG ở\n// trong window → không kích hoạt (đúng: incircle không liên quan góc vuông).\nconst THALES_R = 4;\nconst THALES_THETA = 2.3; // ~131° (góc phần tư II) → apex gần đầu mút TRÁI = cạnh ngắn\n\n// \"nội tiếp (trong)? (đường tròn (O)/tâm O)? | (O)\" — circumcircle tam giác inscribed.\nconst TRI_INSCRIBED =\n /nội\\s*tiếp\\s+(?:trong\\s+)?(?:đường\\s*tròn\\s*(?:\\(\\s*([A-Z])\\s*\\)|tâm\\s+([A-Z]))?|\\(\\s*([A-Z])\\s*\\))/u;\n// Bất đẳng thức cạnh \"AB < AC\" / \"AC > AB\" (2 cạnh chia sẻ đỉnh vuông).\nconst INEQ = /([A-Z])([A-Z])\\s*([<>])\\s*([A-Z])([A-Z])/u;\n\n/** Tên đường tròn ngoại tiếp từ window; undefined nếu không có \"nội tiếp …\". */\nfunction inscribedCircleName(window: string): string | undefined {\n const m = TRI_INSCRIBED.exec(window);\n if (!m) return undefined;\n return m[1] ?? m[2] ?? m[3] ?? ''; // '' → caller default 'O'\n}\n\n/** Đầu mút (≠ apex) của cạnh NGẮN hơn theo \"AB < AC\"; default others[0]. */\nfunction shorterLegEnd(window: string, apex: string, others: string[]): string {\n const m = INEQ.exec(window);\n if (m) {\n const op = m[3];\n const o1 = m[1] === apex ? m[2] : m[2] === apex ? m[1] : undefined; // cạnh 1 (≠apex)\n const o2 = m[4] === apex ? m[5] : m[5] === apex ? m[4] : undefined; // cạnh 2 (≠apex)\n if (o1 && o2 && others.includes(o1) && others.includes(o2)) {\n return op === '<' ? o1 : o2; // '<' → cạnh 1 ngắn; '>' → cạnh 2 ngắn\n }\n }\n return others[0];\n}\n\n/**\n * Dựng Thales cho tam giác vuông (apex tại index `apexIdx`) nội tiếp đường tròn\n * `circleNameRaw`. Trả null nếu tên tâm đụng nhãn đỉnh (fail-safe → drawShape).\n */\nfunction thalesIntents(\n labels: string[],\n apexIdx: number,\n circleNameRaw: string,\n window: string,\n): IntentT[] | null {\n const apex = labels[apexIdx];\n const others = labels.filter((_, i) => i !== apexIdx); // 2 đầu mút đường kính\n const cn = circleNameRaw || 'O';\n if (labels.includes(cn)) return null; // tên tâm trùng đỉnh → bỏ Thales (an toàn)\n const shortEnd = shorterLegEnd(window, apex, others);\n const longEnd = others[0] === shortEnd ? others[1] : others[0];\n return [\n addPoint(shortEnd, { kind: 'free', at: [-THALES_R, 0] }), // cạnh ngắn: đầu mút TRÁI\n addPoint(longEnd, { kind: 'free', at: [THALES_R, 0] }),\n addPoint(cn, { kind: 'midpoint', of: shortEnd + longEnd }), // tâm O = trung điểm đường kính\n drawCircle(cn, 'centerThrough', { center: cn, through: shortEnd }),\n addPoint(apex, { kind: 'onCircle', circle: cn, theta: THALES_THETA }), // apex glider (gần TRÁI)\n markShape('triangle', labels),\n ];\n}\n\nfunction variantFor(hit: TriHit, window: string): string {\n return hit.lang === 'en' ? variantForEn(hit, window) : variantForVi(hit, window);\n}\n\nfunction variantForVi(hit: TriHit, window: string): string {\n const { labels, lead } = hit;\n // \"tam giác đều DEF\" hoặc chữ \"đều\" trong window riêng của tam giác này.\n if (lead === 'đều' || EQUILATERAL.test(window)) return 'equilateral';\n\n const ra = RIGHT_AT.exec(window);\n if (ra) {\n const i = labels.indexOf(ra[1]);\n if (i >= 0) return RIGHT_BY_IDX[i];\n }\n\n const iso = ISO_AT.exec(window);\n if (iso) {\n const i = labels.indexOf(iso[1]);\n if (i >= 0) return ISO_BY_IDX[i];\n }\n\n return 'any';\n}\n\n/**\n * EN variant — mirror VN POSITIONAL semantics. leadMod canonical ('equilateral'/\n * 'right'/'isosceles') + WINDOW riêng tam giác này. \"right triangle ABC\" KHÔNG có\n * \"right angle at X\" → 'any' (đủ thông tin loại nhưng không biết đỉnh, fail-safe\n * như VN \"tam giác vuông ABC\"). \"isosceles\" không \"apex X\" → 'any'. apex/right-at\n * CHỈ áp nếu đỉnh ∈ labels (tránh bind nhầm / đỉnh ngoài tam giác).\n */\nfunction variantForEn(hit: TriHit, window: string): string {\n const { labels, lead } = hit;\n if (lead === 'equilateral' || EQUILATERAL_EN.test(window)) return 'equilateral';\n\n // \"right angle at A\" / \"right-angled at A\" → positional. CHỈ trong window\n // (không vơ modifier của tam giác kế).\n const ra = RIGHT_AT_EN.exec(window);\n if (ra) {\n const i = labels.indexOf(ra[1]);\n if (i >= 0) return RIGHT_BY_IDX[i];\n }\n\n // Apex CHỈ có nghĩa trong ngữ cảnh cân: leadMod 'isosceles' HOẶC từ \"isosceles\"\n // trong window. \"with apex A\" → isoceles theo INDEX của A trong labels.\n const isoCtx = lead === 'isosceles' || ISOSCELES_EN.test(window);\n if (isoCtx) {\n const ap = APEX_AT_EN.exec(window);\n if (ap) {\n const i = labels.indexOf(ap[1]);\n if (i >= 0) return ISO_BY_IDX[i];\n }\n }\n\n return 'any';\n}\n\n/**\n * \"tam giác ABC\" / \"triangle ABC\" → draw-shape triangle. NHIỀU tam giác / clause\n * → emit-all (mỗi tam giác 1 intent), variant bind theo cú pháp gần (leadMod +\n * window) để KHÔNG mis-render (vd không gán \"đều\"/\"equilateral\" của DEF cho ABC).\n *\n * EN ADDITIVE (issue #46 group B): quét THÊM TRI_EN_G. Hit VN+EN gom chung, sắp\n * theo vị trí TEXT; window mỗi hit = từ sau nhãn tới START của hit KẾ (modifier\n * tiền-vị của tam giác kế KHÔNG lọt vào window hit hiện tại). VN behavior giữ\n * nguyên: với chỉ-VN, start hit kế = vị trí \"tam giác\" kế ≡ logic indexOf cũ.\n */\nexport const triangleRule: LanguageRule = {\n id: 'triangle',\n priority: 100,\n languages: ['vi', 'en'],\n patterns: [TRI_G, TRI_EN_G],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const hits: TriHit[] = [];\n\n TRI_G.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(c.text)) !== null) {\n hits.push({\n lead: m[1],\n lang: 'vi',\n labels: [m[2], m[3], m[4]],\n start: m.index,\n end: m.index + m[0].length,\n });\n }\n\n TRI_EN_G.lastIndex = 0;\n while ((m = TRI_EN_G.exec(c.text)) !== null) {\n hits.push({\n lead: normLeadEn(m[1]),\n lang: 'en',\n labels: [m[2], m[3], m[4]],\n start: m.index,\n end: m.index + m[0].length,\n });\n }\n\n if (hits.length === 0) continue;\n\n // Sắp theo vị trí TEXT để window mỗi hit kết thúc ở START hit kế (gồm cả\n // modifier tiền-vị của hit kế) → không leak modifier giữa các tam giác.\n hits.sort((a, b) => a.start - b.start);\n\n const intents = hits.flatMap((hit, idx) => {\n const next = hits[idx + 1];\n const windowEnd = next ? next.start : c.text.length;\n const window = c.text.slice(hit.end, windowEnd);\n const variant = variantFor(hit, window);\n // Thales: tam giác VUÔNG + nội tiếp đường tròn (window) → dựng ràng buộc\n // (đường kính + apex glider) thay draw-shape free (free chỉ \"may mắn\" vuông,\n // kéo là vỡ + không thoả AB<AC). circle3 của circleTriangle bị idempotent\n // loại (cùng tên → centerThrough của triangle prio 100 thắng).\n const rightIdx = RIGHT_BY_IDX.indexOf(variant);\n if (rightIdx >= 0) {\n const circleName = inscribedCircleName(window);\n if (circleName !== undefined) {\n const thales = thalesIntents(hit.labels, rightIdx, circleName, window);\n if (thales) return thales;\n }\n }\n return [drawShape('triangle', hit.labels, variant)];\n });\n\n out.push({ ruleId: 'triangle', clauseIds: [c.id], intents });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/quad.ts\n//\n// Tứ giác / đa giác 4 đỉnh: hình vuông, chữ nhật, bình hành, thoi, thang\n// (cân/vuông/thường), tứ giác chung. Mỗi loại trích 4 ký tự HOA liền sau tên\n// hình → draw-shape với shape + variant tương ứng.\nimport type { LanguageRule, RuleContext, RuleMatch } from './_types';\nimport { drawShape, drawCircle, addPoint, markShape } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Dùng lookaround \\p{L} (cờ 'u') ở prefilter để chặn biên từ.\n// 4 đỉnh = ĐÚNG 4 ký tự HOA liền nhau (vd \"ABCD\") neo ngay sau tên hình; neo\n// biên cuối (?![A-Z]) để 5+ đỉnh (\"ABCDE\") KHÔNG match → escalate qua guard.\nconst QUAD = '([A-Z])([A-Z])([A-Z])([A-Z])(?![A-Z])';\n\n// Mỗi entry: regex tên hình (đã neo trước 4 đỉnh) → shape + variant.\n// CỜ 'g' để matchAll quét MỌI khai báo hình trong cùng một clause (vd \"hình\n// bình hành ABCD và hình chữ nhật EFGH\" → 2 shape, theo thứ tự TEXT).\n// Thứ tự QUAN TRỌNG: loại cụ thể (hình thang cân/vuông) phải đứng TRƯỚC loại\n// chung (hình thang), và mọi \"hình ...\" phải đứng trước \"tứ giác\" chung — vì\n// engine consume vùng text đã match nên loại cụ thể giành quyền trước.\ninterface QuadKind {\n name: RegExp;\n shape: string;\n variant: string;\n}\n\nconst KINDS: QuadKind[] = [\n // hình thang cân / vuông (modifier TRƯỚC đỉnh) — phải match trước thang chung\n {\n name: new RegExp('hình\\\\s+thang\\\\s+cân\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'isoceles',\n },\n {\n name: new RegExp('hình\\\\s+thang\\\\s+vuông\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'right',\n },\n // hình thang chung — sau đó dò modifier 'vuông'/'cân' đứng SAU đỉnh\n // (\"hình thang ABCD vuông tại A\" → right; \"...cân\" → isoceles).\n {\n name: new RegExp('hình\\\\s+thang\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'general',\n },\n {\n name: new RegExp('hình\\\\s+vuông\\\\s+' + QUAD, 'gu'),\n shape: 'square',\n variant: 'standard',\n },\n {\n name: new RegExp('hình\\\\s+chữ\\\\s+nhật\\\\s+' + QUAD, 'gu'),\n shape: 'rectangle',\n variant: 'wide',\n },\n {\n name: new RegExp('hình\\\\s+bình\\\\s+hành\\\\s+' + QUAD, 'gu'),\n shape: 'parallelogram',\n variant: 'standard',\n },\n {\n name: new RegExp('hình\\\\s+thoi\\\\s+' + QUAD, 'gu'),\n shape: 'rhombus',\n variant: 'standard',\n },\n {\n name: new RegExp('tứ\\\\s+giác(?:\\\\s+lồi)?\\\\s+' + QUAD, 'gu'),\n shape: 'quadrilateral',\n variant: 'any',\n },\n\n // === EN names (issue #46 group B) — same shape/variant mapping as VN ========\n // First-letter case flex ([Ss]quare…) — KHÔNG cờ 'i' (sẽ phá [A-Z] nhãn QUAD).\n // Modifier EN đứng TRƯỚC tên (\"isosceles trapezoid ABCD\") → entry riêng cho\n // isosceles/right trapezoid, đặt TRƯỚC trapezoid chung để giành quyền (overlaps).\n // KHÔNG có post-positional modifier EN trong slice này (chỉ pre-positional).\n {\n name: new RegExp('[Ii]sosceles\\\\s+(?:[Tt]rapezoid|[Tt]rapezium)\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'isoceles',\n },\n {\n name: new RegExp('[Rr]ight\\\\s+(?:[Tt]rapezoid|[Tt]rapezium)\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'right',\n },\n {\n name: new RegExp('(?:[Tt]rapezoid|[Tt]rapezium)\\\\s+' + QUAD, 'gu'),\n shape: 'trapezoid',\n variant: 'general',\n },\n {\n name: new RegExp('[Ss]quare\\\\s+' + QUAD, 'gu'),\n shape: 'square',\n variant: 'standard',\n },\n {\n name: new RegExp('[Rr]ectangle\\\\s+' + QUAD, 'gu'),\n shape: 'rectangle',\n variant: 'wide',\n },\n {\n name: new RegExp('[Pp]arallelogram\\\\s+' + QUAD, 'gu'),\n shape: 'parallelogram',\n variant: 'standard',\n },\n {\n name: new RegExp('[Rr]hombus\\\\s+' + QUAD, 'gu'),\n shape: 'rhombus',\n variant: 'standard',\n },\n {\n name: new RegExp('[Qq]uadrilateral\\\\s+' + QUAD, 'gu'),\n shape: 'quadrilateral',\n variant: 'any',\n },\n];\n\n// Prefilter toàn đề: bất kỳ tên hình 4 đỉnh nào (VN + EN).\nconst PREFILTER =\n /hình\\s+(?:vuông|chữ\\s+nhật|bình\\s+hành|thoi|thang)|tứ\\s+giác|[Ss]quare|[Rr]ectangle|[Pp]arallelogram|[Rr]hombus|[Tt]rapezoid|[Tt]rapezium|[Qq]uadrilateral/u;\n\n// \"hình thang ABCD vuông tại A\" / \"...cân ...\" — modifier đứng SAU đỉnh, ngay\n// sau cụm 4 đỉnh (cho phép xen khoảng trắng). Cờ 'u' bắt buộc cho ký tự Việt.\nconst RIGHT_AFTER = /vuông(?!\\p{L})/u;\nconst ISO_AFTER = /(?<!\\p{L})cân(?!\\p{L})/u;\n// Biên cắt tail: KHÔNG cho modifier \"vuông\"/\"cân\" của hình SAU (\"…và hình vuông\n// EFGH\") bị gán nhầm cho hình thang đứng trước → dừng tail ở khai báo hình kế.\nconst NEXT_SHAPE = /hình\\s|tứ\\s+giác/u;\n\ninterface Hit {\n index: number;\n shape: string;\n variant: string;\n labels: string[];\n /** offset ngay sau cụm 4 đỉnh, để dò modifier hậu vị cho hình thang chung. */\n afterEnd: number;\n}\n\n/**\n * Quét MỌI khai báo hình trong một clause. Mỗi vị trí ký tự chỉ thuộc một kind\n * (kind cụ thể giành trước nhờ thứ tự KINDS). Trả về danh sách hit đã sắp theo\n * vị trí TEXT để emit đúng thứ tự xuất hiện trong đề.\n */\nfunction scanClause(text: string): Hit[] {\n const claimed: Hit[] = [];\n const taken: Array<[number, number]> = []; // vùng [start,end) đã thuộc kind trước\n\n const overlaps = (start: number, end: number) =>\n taken.some(([s, e]) => start < e && end > s);\n\n for (const k of KINDS) {\n k.name.lastIndex = 0;\n for (const m of text.matchAll(k.name)) {\n const start = m.index ?? 0;\n const end = start + m[0].length;\n if (overlaps(start, end)) continue; // đã bị kind cụ thể hơn chiếm\n taken.push([start, end]);\n\n let variant = k.variant;\n // Hình thang chung: dò modifier hậu vị ngay sau 4 đỉnh (\"ABCD vuông tại A\").\n // Cắt tail tại khai báo hình kế tiếp để không nuốt modifier của hình sau.\n if (k.shape === 'trapezoid' && k.variant === 'general') {\n let tail = text.slice(end, end + 24);\n const next = NEXT_SHAPE.exec(tail);\n if (next) tail = tail.slice(0, next.index);\n if (RIGHT_AFTER.test(tail)) variant = 'right';\n else if (ISO_AFTER.test(tail)) variant = 'isoceles';\n }\n claimed.push({\n index: start,\n shape: k.shape,\n variant,\n labels: [m[1], m[2], m[3], m[4]],\n afterEnd: end,\n });\n }\n }\n\n claimed.sort((a, b) => a.index - b.index);\n return claimed;\n}\n\n// --- Tứ giác nội tiếp đường tròn (cyclic quadrilateral) — issue #46 nhóm C/B --\n//\n// \"Cho tứ giác ABCD nội tiếp đường tròn (O)\" hiện chỉ vẽ tứ giác, BỎ đường tròn\n// (render coverage-complete nhưng thiếu hình). Bổ sung đường tròn ngoại tiếp đi\n// qua đúng 4 đỉnh — đặt 4 đỉnh ĐỒNG VIÊN để circle3 thực sự đi qua cả 4.\n//\n// EN (nhóm B Tier 2, fix silent-incomplete): detectCyclic nay nhận thêm các dạng\n// tiếng Anh — Pattern A \"(is/are) inscribed in (a/the) circle (O)\", Pattern B\n// \"circle (O) circumscribes/(is) circumscribed (about/around) ...\". Trước đây đề\n// EN render quad-ONLY (rớt circle âm thầm); nay parity VN (quad concyclic +\n// through3). TRIANGLE_DECL cũng nhận \"Triangle ABC\" để fail-safe ownedByOthers\n// chặn silent-wrong khi tứ giác EN chia đỉnh với tam giác EN.\n//\n// KIẾN TRÚC single-emitter: quadRule LÀ emitter DUY NHẤT của hình tứ giác. Khi\n// phát hiện ngữ cảnh nội tiếp, CHÍNH rule này emit (circle + 4 glider + polygon)\n// — KHÔNG dùng draw-shape (vốn tạo đỉnh FREE) cho nhánh nội tiếp.\n//\n// FIX 2026-06-09 (bug \"đỉnh D không trên đường tròn, kéo đường tròn D không theo\"):\n// trước đây nhánh nội tiếp emit draw-shape (4 đỉnh FREE ở toạ độ đồng viên TĨNH) +\n// circle3 qua 3 đỉnh → đỉnh thứ 4 chỉ TÌNH CỜ nằm trên circle, KHÔNG ràng buộc →\n// kéo 1 trong 3 đỉnh kia (định nghĩa lại circle3) thì đỉnh 4 ở lại, rời đường tròn.\n// NAY: đường tròn centerRadius (tâm O hiện) + 4 đỉnh là glider `onCircle` (theta cố\n// định) → TẤT CẢ ràng buộc trên đường tròn; kéo tâm O cả 4 di chuyển theo, luôn\n// đồng viên. polygon nối 4 đỉnh qua mark-shape (không tạo coord mới).\n//\n// 4 đỉnh trên đường tròn bán kính 5 (đồng viên), góc theta cố định cho layout lồi\n// A→B→C→D (chiều kim đồng hồ), bảo toàn bố cục cũ.\nconst CYCLIC_QUAD_COORDS: readonly [number, number][] = [\n [-3, 4],\n [4, 3],\n [3, -4],\n [-4, -3],\n];\n// Bán kính + góc theta dẫn xuất TỪ toạ độ trên (đồng bộ layout): glider đặt tại\n// (cos θ, sin θ)·r quanh tâm → giữ đúng vị trí lồi như bản free cũ.\nconst CYCLIC_RADIUS = Math.hypot(CYCLIC_QUAD_COORDS[0][0], CYCLIC_QUAD_COORDS[0][1]);\nconst CYCLIC_QUAD_THETAS: readonly number[] = CYCLIC_QUAD_COORDS.map(([x, y]) =>\n Math.atan2(y, x),\n);\n\n// Tên tâm tuỳ chọn: \"(O)\" hoặc \"tâm O\" (mượn idiom của circleTriangle).\nconst CENTER = '(?:\\\\(\\\\s*([A-Z])\\\\s*\\\\)|tâm\\\\s+([A-Z]))?';\n\n// Pattern A — tứ giác nội tiếp đường tròn: \"ABCD nội tiếp (trong) đường tròn\n// (O)/tâm O\". Neo ^ vào phần text NGAY SAU 4 đỉnh (hit.afterEnd). Center group 1|2.\nconst QUAD_INSCRIBED_IN_CIRCLE = new RegExp(\n '^[\\\\s,]*(?:nội\\\\s*tiếp\\\\s+(?:trong\\\\s+)?(?:một\\\\s+)?đường\\\\s*tròn|(?:is\\\\s+|are\\\\s+)?inscribed\\\\s+in\\\\s+(?:a\\\\s+|the\\\\s+)?circle)\\\\s*' +\n CENTER,\n 'iu',\n);\n\n// Pattern B — đường tròn ngoại tiếp tứ giác: \"đường tròn (O)/tâm O ngoại tiếp\"\n// đứng NGAY TRƯỚC \"tứ giác ABCD\". Neo $ vào phần text TRƯỚC hit.index. Center 1|2.\nconst CIRCLE_CIRCUMSCRIBES_QUAD = new RegExp(\n '(?:đường\\\\s*tròn|circle)\\\\s*' +\n CENTER +\n '\\\\s*(?:ngoại\\\\s*tiếp|(?:is\\\\s+|are\\\\s+)?circumscrib(?:es|ed)(?:\\\\s+(?:about|around))?)\\\\s+$',\n 'iu',\n);\n\n// Khai báo tam giác bất kỳ trong đề — 3 đỉnh HOA của nó \"thuộc\" tam giác (không\n// được dời sang toạ độ đồng viên của tứ giác). Cờ 'g' để quét mọi khai báo.\nconst TRIANGLE_DECL = /(?:tam\\s*giác|[Tt]riangle)\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n\n/**\n * Tập ký tự đỉnh \"thuộc về hình khác\" trong TOÀN đề: mọi đỉnh tam giác + đỉnh\n * của mọi tứ giác hit KHÁC (chuỗi nhãn khác hit hiện tại). Nếu 4 đỉnh của tứ\n * giác này giao tập đó → KHÔNG áp dụng đồng viên (đặt chúng theo CYCLIC_QUAD\n * sẽ phá toạ độ đã có của hình kia → silent-wrong).\n */\nfunction ownedByOthers(ctx: RuleContext, selfLabels: string[]): Set<string> {\n const owned = new Set<string>();\n TRIANGLE_DECL.lastIndex = 0;\n for (const m of ctx.problem.matchAll(TRIANGLE_DECL)) {\n owned.add(m[1]);\n owned.add(m[2]);\n owned.add(m[3]);\n }\n const selfKey = selfLabels.join('');\n for (const c of ctx.clauses) {\n for (const h of scanClause(c.text)) {\n if (h.labels.join('') === selfKey) continue; // chính tứ giác này\n for (const lbl of h.labels) owned.add(lbl);\n }\n }\n return owned;\n}\n\n/**\n * Phát hiện ngữ cảnh nội tiếp cho 1 hit tứ giác chung trong clause `text`.\n * Trả tên tâm (hoặc '') nếu khớp Pattern A/B; undefined nếu không nội tiếp.\n */\nfunction detectCyclic(text: string, hit: Hit): string | undefined {\n // Pattern A: phần text NGAY SAU 4 đỉnh.\n const a = QUAD_INSCRIBED_IN_CIRCLE.exec(text.slice(hit.afterEnd));\n if (a) return a[1] ?? a[2] ?? '';\n // Pattern B: phần text TRƯỚC \"tứ giác\" (hit.index = đầu \"tứ giác\").\n const b = CIRCLE_CIRCUMSCRIBES_QUAD.exec(text.slice(0, hit.index));\n if (b) return b[1] ?? b[2] ?? '';\n return undefined;\n}\n\n/**\n * Tứ giác / đa giác 4 đỉnh → draw-shape. Duyệt từng clause, quét EMIT-ALL mọi\n * khai báo hình (theo thứ tự text). KHÔNG trích được ĐÚNG 4 đỉnh HOA liền (vd\n * \"ABCDE\" 5 đỉnh) → bỏ qua khai báo đó (escalate AI qua guard).\n *\n * Tứ giác CHUNG (shape 'quadrilateral') có ngữ cảnh nội tiếp đường tròn → emit\n * THÊM draw-circle (through3) + đặt 4 đỉnh đồng viên qua explicitCoords. Hình\n * có tên (vuông/chữ nhật/...) NGOÀI phạm vi increment này (giữ hành vi cũ).\n *\n * GIỚI HẠN ĐÃ BIẾT (defer, không sửa): nếu CÙNG nhãn tứ giác được khai báo ở\n * HAI clause (vd \"Cho tứ giác ABCD. Đường tròn ngoại tiếp tứ giác ABCD\") — một\n * plain + một cyclic — cả hai draw-shape sống sót qua JSON dedup (explicitCoords\n * khác nhau) → polygon trùng \"ABCD2\" chồng lên nhau. Hiếm gặp + lành tính\n * (polygon trùng khít, không sai hình học). Test/probe để 1-clause để né.\n */\nexport const quadRule: LanguageRule = {\n id: 'quad',\n priority: 100,\n languages: ['vi', 'en'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n for (const hit of scanClause(c.text)) {\n let intents = [drawShape(hit.shape, hit.labels, hit.variant)];\n // Chỉ tứ giác CHUNG: thử phát hiện đường tròn ngoại tiếp.\n if (hit.shape === 'quadrilateral') {\n const center = detectCyclic(c.text, hit);\n if (center !== undefined) {\n // Fail-safe: đỉnh dùng chung với hình khác → giữ quad-only.\n const owned = ownedByOthers(ctx, hit.labels);\n const shared = hit.labels.some((lbl) => owned.has(lbl));\n if (!shared) {\n const centerName = center || 'O';\n // Đường tròn centerRadius (tâm `centerName`) — resolveCircleNames sẽ\n // inject point tâm + rename circle khi name trùng center (\"(O)\"=tâm O).\n // 4 đỉnh = glider onCircle (theta cố định, layout lồi) → CONSTRAINED.\n // polygon nối 4 đỉnh qua mark-shape (đỉnh đã có, không tạo coord mới).\n // Thứ tự: circle TRƯỚC (glider ref nó), rồi 4 glider, rồi polygon.\n intents = [\n drawCircle(centerName, 'centerRadius', {\n center: centerName,\n radius: CYCLIC_RADIUS,\n }),\n ...hit.labels.map((lbl, i) =>\n addPoint(lbl, { kind: 'onCircle', circle: centerName, theta: CYCLIC_QUAD_THETAS[i] }),\n ),\n markShape(hit.shape, hit.labels),\n ];\n }\n }\n }\n out.push({\n ruleId: 'quad',\n clauseIds: [c.id],\n intents,\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/connect.ts\n//\n// Construct 'connect': vẽ đoạn / đường thẳng / tia giữa 2 đỉnh có tên.\n// BẢO THỦ (priority thấp 40): chỉ claim clause khi có TỪ KHOÁ vẽ rõ ràng\n// (đoạn | cạnh | nối | kẻ | đường thẳng | tia) đi kèm cặp 2 ký tự HOA.\n// KHÔNG khớp \"tam giác ABC\" (3 ký tự liền) hay tên đường 1 ký tự (\"đường d\").\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { connect } from './_shared';\nimport type { IntentT } from '../intent';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Dùng lookaround \\p{L}; cờ 'u' bắt buộc cho mọi regex Việt.\n// Cặp đỉnh = 2 ký tự HOA liền; (?![A-Z]) chặn \"ABC\" (tam giác) khỏi bị bắt.\n\n// LƯU Ý case: KHÔNG dùng cờ 'i' (nó khiến [A-Z] khớp chữ thường → \"đoạn THẳng\"\n// bắt \"th\" làm cặp T,H rác, vỡ pipeline). Nhưng vẫn cần khớp keyword HOA đầu câu\n// (\"Kẻ\", \"Nối\", \"Đoạn\") → case-insensitive CHỈ ở ký tự đầu keyword bằng [Xx].\n// Vertices LUÔN strict [A-Z].\n// \"đường thẳng AB\" → line. \"đường thẳng\" phải đứng trước cặp.\nconst LINE_KW = /[Đđ]ường\\s*thẳng\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"tia AB\" → ray. Không bắt \"tia phân giác\", \"tia đối\" (theo sau là chữ thường).\nconst RAY_KW = /(?<!\\p{L})[Tt]ia\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"tia đối của tia XY\": cụm tia ĐỐI — match \"tia XY\" bên trong KHÔNG được emit ray\n// naive X→Y vì điểm mới nằm trên tia NGƯỢC hướng (gốc X, đi xa Y). Vẽ ray X→Y\n// sẽ minh hoạ SAI hướng (tia gốc thay vì tia đối). pointAtDistance đã dựng điểm\n// mới đúng trên tia đối; connect suppress để tránh ray double/sai hướng.\n// Kiểm tra text NGAY TRƯỚC vị trí match \"tia\": kết thúc bằng \"đối của \" (≥0 space).\nconst TIA_DOI_BEFORE = /tia\\s*đối\\s+của\\s+$/u;\n// \"nối A với/và B\" → segment. Tên 1 ký tự, không phải cặp.\nconst NOI_KW = /(?<!\\p{L})[Nn]ối\\s+([A-Z])\\s+(?:với|và)\\s+([A-Z])(?![A-Za-z])/gu;\n// \"đoạn (thẳng) AB\" | \"cạnh AB\" | \"kẻ AB\" → segment.\nconst SEG_KW =\n /(?<!\\p{L})(?:[Đđ]oạn(?:\\s*thẳng)?|[Cc]ạnh|[Kk]ẻ)\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n\n// ============ EN connect forms (issue #46 nhóm B) ============================\n// connect.ts vốn VN-only. Mirror các form VN sang EN, GIỮ NGUYÊN parity ở gate\n// vocab: VN \"đoạn\" LÀ keyword → EN \"segment\" cũng vào vocab (standalone render).\n// VN \"đường thẳng\"/\"tia\"/\"nối\"/\"kẻ\" KHÔNG phải keyword → EN \"line\"/\"ray\"/\"connect\"/\n// \"join\"/\"draw\" cũng KHÔNG vào vocab → chỉ render IN-CONTEXT (vd có tam giác), đề\n// standalone → escalate (geoClauses=0). Đối xứng VN/EN tuyệt đối + tôn trọng\n// do-not-add list (\"line\" đã bị cấm trong vocabulary.ts).\n//\n// runDeterministicIntents dedup intent theo JSON.stringify CROSS-RULE → \"Draw AH\n// perpendicular to BC\" khớp CẢ perpFoot (emit connect(A,H,'segment')) lẫn DRAW_PAIR_EN\n// (cũng connect(A,H,'segment')) → IDENTICAL → deduped, vô hại.\n\n// \"segment XY\" → segment (đối VN \"đoạn\"). Group 1,2 = cặp HOA.\nconst SEG_NOUN_EN = /(?<![A-Za-z])[Ss]egment\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"line XY\" → line (đối VN \"đường thẳng\").\nconst LINE_NOUN_EN = /(?<![A-Za-z])[Ll]ine\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// Guard cho segment/line noun: BỎ match nếu cặp thuộc clause của rule prio cao\n// hơn đã SỞ HỮU cặp: perpBisector (\"(perpendicular) bisector (segment|line) PAIR\")\n// / perpFoot (\"perpendicular to (line|segment) PAIR\") / pointAtDistance (\"Extend(ed)\n// segment|line XY beyond …\"). 3 rule đó emit cặp đúng style HOẶC dựng điểm phái sinh;\n// connect KHÔNG được double-emit segment/line trần — đặc biệt với pointAtDistance:\n// clause malformed (thiếu distance / sai hướng) → pointAtDistance KHÔNG emit → clause\n// cần ESCALATE; connect claim sẽ MASK escalate đó (silent-incomplete, bỏ điểm mới).\n// Case flex [Bb]/[Pp]/[Ee] (BẮT BUỘC: HOA đầu clause không được slip — bài học batch16).\nconst NOUN_OWNED_BEFORE_EN = /(?:[Bb]isector|[Pp]erpendicular\\s+to|[Ee]xtend(?:ed)?)\\s+$/u;\n// \"ray XY\" → ray (đối VN \"tia\"). 2 guard:\n// (a) preceding \"opposite ray of ray XY\" (OPPOSITE_RAY_BEFORE_EN): điểm mới nằm trên\n// tia ĐỐI → vẽ ray X→Y SAI hướng (EN mirror VN TIA_DOI_BEFORE, batch9 8ee33af).\n// (b) trailing \"(?!\\s*,?\\s*extended)\": \"ray XY extended beyond Z\" là construct CỦA\n// pointAtDistance (RAY_EXTENDED_EN). connect KHÔNG claim — nếu malformed (thiếu\n// distance / Z≠Y sai hướng) pointAtDistance escalate fail-safe; connect claim sẽ\n// MASK (silent-incomplete bỏ điểm D). Well-formed thì pointAtDistance đã lo điểm\n// D — connect đứng ngoài để giữ EN-cũ (batch15) byte-identical.\n// \"Draw ray AB\" trần (không \"extended\"/không \"opposite ray of\") → vẫn vẽ ray A→B.\nconst RAY_NOUN_EN = /(?<![A-Za-z])[Rr]ay\\s+([A-Z])([A-Z])(?![A-Za-z])(?!\\s*,?\\s*extended)/gu;\nconst OPPOSITE_RAY_BEFORE_EN = /opposite\\s+ray\\s+of\\s+$/u;\n// \"Connect/Join XY\" → segment (đối VN \"nối\", form cặp HOA).\nconst JOIN_PAIR_EN = /(?<![A-Za-z])(?:[Cc]onnect|[Jj]oin)\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n// \"Connect/Join X and/to/with Y\" → segment (tên 1 ký tự, mirror VN NOI_KW).\nconst JOIN_AND_EN =\n /(?<![A-Za-z])(?:[Cc]onnect|[Jj]oin)\\s+([A-Z])\\s+(?:and|to|with)\\s+([A-Z])(?![A-Za-z])/gu;\n// \"Draw XY\" trần → segment (đối VN \"kẻ\"). perpFoot draw-form \"Draw AH perpendicular\n// to BC\" cũng khớp nhưng emit connect(A,H,'segment') IDENTICAL → deduped.\n// perpBisector/cevian/tangent draw-form có \"the\"/\"two\"/chữ thường sau \"Draw\" →\n// KHÔNG cặp HOA → KHÔNG match ở đây.\nconst DRAW_PAIR_EN = /(?<![A-Za-z])[Dd]raw\\s+([A-Z])([A-Z])(?![A-Za-z])/gu;\n\nfunction collect(\n re: RegExp,\n text: string,\n style: string,\n used: Set<string>,\n out: IntentT[],\n // Guard tuỳ chọn: bỏ qua match nếu text NGAY TRƯỚC vị trí match khớp regex này\n // (vd \"tia đối của \" trước \"tia XY\" → không emit ray naive sai hướng).\n skipIfPrecededBy?: RegExp,\n): void {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n if (skipIfPrecededBy && skipIfPrecededBy.test(text.slice(0, m.index))) {\n continue;\n }\n const a = m[1].toUpperCase();\n const b = m[2].toUpperCase();\n // Dedup theo cặp đỉnh trong cùng clause: vẽ trùng AB nhiều lần vô nghĩa,\n // và tránh 2 từ khoá khác nhau cùng claim 1 cặp (vd \"đoạn AB\" + \"kẻ AB\").\n const key = `${a}${b}`;\n if (used.has(key)) continue;\n used.add(key);\n out.push(connect(a, b, style));\n }\n}\n\n/**\n * Mỗi clause khớp ≥1 từ khoá vẽ → push 1 RuleMatch (gom mọi cặp tìm được).\n * Nhiều cặp trong cùng clause ⇒ nhiều intent, cùng clauseId.\n * Priority 40: thấp để rule chuyên biệt (trung trực, phân giác…) claim trước.\n */\nexport const connectRule: LanguageRule = {\n id: 'connect',\n priority: 40,\n languages: ['vi', 'en'],\n patterns: [\n LINE_KW, RAY_KW, NOI_KW, SEG_KW,\n SEG_NOUN_EN, LINE_NOUN_EN, RAY_NOUN_EN, JOIN_PAIR_EN, JOIN_AND_EN, DRAW_PAIR_EN,\n ],\n match(ctx) {\n const result: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const intents: IntentT[] = [];\n // Dùng span-key để 1 vị trí không bị 2 từ khoá double-count, nhưng cho\n // phép nhiều cặp khác vị trí trong cùng clause.\n const used = new Set<string>();\n // Thứ tự quan trọng: \"đường thẳng AB\" phải claim trước SEG (chứa \"thẳng\"\n // KHÔNG match SEG vì SEG yêu cầu \"đoạn thẳng\"/\"cạnh\"/\"kẻ\", không \"đường\").\n collect(LINE_KW, c.text, 'line', used, intents);\n // RAY: suppress ray naive khi nằm trong cụm \"tia đối của tia XY\" (hướng tia\n // gốc X→Y sai so với điểm mới trên tia đối). pointAtDistance lo điểm mới.\n collect(RAY_KW, c.text, 'ray', used, intents, TIA_DOI_BEFORE);\n collect(NOI_KW, c.text, 'segment', used, intents);\n collect(SEG_KW, c.text, 'segment', used, intents);\n // EN forms (issue #46 nhóm B). `used` dedup cặp đã claim bởi form VN trong\n // cùng clause (clause trộn ngôn ngữ hiếm, nhưng an toàn). Thứ tự: noun trước,\n // verb sau; DRAW cuối (trần nhất).\n collect(SEG_NOUN_EN, c.text, 'segment', used, intents, NOUN_OWNED_BEFORE_EN);\n collect(LINE_NOUN_EN, c.text, 'line', used, intents, NOUN_OWNED_BEFORE_EN);\n collect(RAY_NOUN_EN, c.text, 'ray', used, intents, OPPOSITE_RAY_BEFORE_EN);\n collect(JOIN_PAIR_EN, c.text, 'segment', used, intents);\n collect(JOIN_AND_EN, c.text, 'segment', used, intents);\n collect(DRAW_PAIR_EN, c.text, 'segment', used, intents);\n if (intents.length > 0) {\n result.push({ ruleId: 'connect', clauseIds: [c.id], intents });\n }\n }\n return result;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/midpoint.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, pairFromToken, SIDE_PREFIX } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\n\n// Prefilter toàn đề. \"trung điểm\" KHÔNG khớp \"trung trực\" (an toàn, rule khác lo).\nconst MIDPOINT = /trung\\s*điểm/u;\n\n// Dạng A (GLOBAL): tên điểm ĐỨNG TRƯỚC \"(là) trung điểm (của (cạnh|đoạn)) <PAIR>\".\n// \"Gọi M là trung điểm BC\" | \"M là trung điểm của BC\" | \"M trung điểm cạnh BC\"\n// | \"M là trung điểm cạnh huyền BC\" | \"trung điểm đoạn thẳng AC\"\n// Tên = ký tự HOA NGAY TRƯỚC cụm trung điểm (cục bộ quanh match, KHÔNG quét intro).\nconst NAME_BEFORE_G = new RegExp(\n `([A-Z])(?:['′]?)\\\\s+(?:là\\\\s+|=\\\\s+)?trung\\\\s*điểm\\\\s+(?:của\\\\s+)?${SIDE_PREFIX}([A-Z])([A-Z])(?!\\\\p{L})`,\n 'gu',\n);\n\n// Dạng B (GLOBAL): tên điểm ĐỨNG SAU \"trung điểm <NAME> của (cạnh|đoạn) <PAIR>\".\n// \"trung điểm I của (cạnh huyền) AB\" | \"trung điểm I của đoạn thẳng BC\"\nconst NAME_AFTER_G = new RegExp(\n `trung\\\\s*điểm\\\\s+([A-Z])(?:['′]?)\\\\s+của\\\\s+${SIDE_PREFIX}([A-Z])([A-Z])(?!\\\\p{L})`,\n 'gu',\n);\n\n// Distributive \"lần lượt\": \"M, N (, P) lần lượt là trung điểm AB, AC (, BC)\" →\n// zip 1-1: M=mid(AB), N=mid(AC), P=mid(BC). group1 = blob tên (≥2, phẩy),\n// group2 = blob cặp đỉnh (≥2, phẩy). Số tên PHẢI bằng số cặp (else bỏ qua,\n// escalate — không đoán lệch). SIDE_PREFIX cho \"(các) cạnh/đoạn\" trước blob cặp.\nconst DISTRIB = new RegExp(\n `((?:[A-Z](?:['′]?)\\\\s*,\\\\s*)+[A-Z](?:['′]?))\\\\s+lần\\\\s*lượt\\\\s+(?:là\\\\s+)?(?:điểm\\\\s+)?trung\\\\s*điểm\\\\s+(?:của\\\\s+)?(?:các\\\\s+)?${SIDE_PREFIX}((?:[A-Z][A-Z]\\\\s*,\\\\s*)*(?:[A-Z][A-Z]\\\\s*,\\\\s*)?[A-Z][A-Z](?:\\\\s*và\\\\s*[A-Z][A-Z])?)`,\n 'u',\n);\n\n// Tách 1 token tên trong blob distributive → \"M\" / \"M'\" (prime normalize ′→').\nfunction nameToken(raw: string): string | undefined {\n const m = /^([A-Z])(['′]?)/u.exec(raw.trim());\n if (!m) return undefined;\n return m[2] ? `${m[1]}'` : m[1];\n}\n\n// === EN patterns (issue #46 group B) ========================================\n// Prefilter EN: \"midpoint\" (first-letter case flex [Mm], KHÔNG cờ 'i' — phá [A-Z]).\nconst MIDPOINT_EN = /[Mm]idpoint/u;\n// EN side/segment prefix tuỳ chọn TRƯỚC cặp đỉnh: \"segment BC\", \"side BC\".\nconst SIDE_PREFIX_EN = '(?:segment\\\\s+|side\\\\s+)?';\n\n// EN dạng A (GLOBAL): tên ĐỨNG TRƯỚC. \"M is the midpoint of BC\" | \"let M be the\n// midpoint of segment BC\". Tên = HOA NGAY TRƯỚC \"is/be the midpoint\" (cục bộ).\n// (?![A-Za-z]) neo cuối cặp đỉnh (chặn \"BCD\" 3 chữ → escalate-safe).\nconst NAME_BEFORE_EN_G = new RegExp(\n `([A-Z])(?:['′]?)\\\\s+(?:is|be)\\\\s+the\\\\s+midpoint\\\\s+of\\\\s+${SIDE_PREFIX_EN}([A-Z])([A-Z])(?![A-Za-z])`,\n 'gu',\n);\n\n// EN dạng B (GLOBAL): tên ĐỨNG SAU. \"midpoint M of BC\" | \"midpoint I of segment AB\".\nconst NAME_AFTER_EN_G = new RegExp(\n `[Mm]idpoint\\\\s+([A-Z])(?:['′]?)\\\\s+of\\\\s+${SIDE_PREFIX_EN}([A-Z])([A-Z])(?![A-Za-z])`,\n 'gu',\n);\n\n/**\n * \"Gọi M là trung điểm BC\" → add-point M {kind:'midpoint', of:'BC'}.\n *\n * GLOBAL: emit MỌI cụm \"trung điểm <PAIR>\" trong clause (vd \"M là trung điểm BC\n * và N là trung điểm AC\" → 2 add-point). Tên điểm bind THEO TỪNG MATCH cục bộ:\n * - dạng A: ký tự HOA NGAY TRƯỚC \"(là) trung điểm\" — KHÔNG quét lời dẫn\n * toàn clause (tránh \"Lấy điểm D, gọi M là trung điểm BC\" gán nhầm 'D').\n * - dạng B: ký tự HOA NGAY SAU \"trung điểm\" (\"trung điểm I của AB\").\n * Match nào không có tên cục bộ HOẶC cặp đỉnh không hợp lệ → BỎ QUA match đó\n * (escalate AI), không bịa tên.\n */\nexport const midpointRule: LanguageRule = {\n id: 'midpoint',\n priority: 50,\n languages: ['vi', 'en'],\n patterns: [MIDPOINT, MIDPOINT_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const hasVi = MIDPOINT.test(c.text);\n const hasEn = MIDPOINT_EN.test(c.text);\n if (!hasVi && !hasEn) continue;\n\n const emit = (name: string, pairToken: string, clauseId: number) => {\n const pair = pairFromToken(pairToken);\n if (!name || pair.length !== 2) return;\n out.push({\n ruleId: 'midpoint',\n clauseIds: [clauseId],\n intents: [addPoint(name, { kind: 'midpoint', of: pair.join('') })],\n });\n };\n\n if (hasVi) {\n // Distributive \"lần lượt\" ưu tiên: \"M, N lần lượt là trung điểm AB, AC\"\n // → M=mid(AB), N=mid(AC). Số tên = số cặp mới emit (else bỏ qua → escalate).\n const dm = DISTRIB.exec(c.text);\n if (dm) {\n const names = dm[1]\n .split(',')\n .map((s) => nameToken(s))\n .filter((x): x is string => !!x);\n const pairs = dm[2]\n .split(/\\s*,\\s*|\\s+và\\s+/u)\n .map((s) => s.trim())\n .filter(Boolean);\n if (names.length >= 2 && names.length === pairs.length) {\n for (let i = 0; i < names.length; i++) emit(names[i], pairs[i], c.id);\n continue; // clause đã xử lý bằng distributive — skip dạng A/B + EN\n }\n }\n\n // Theo dõi vị trí cụm \"trung điểm\" đã được dạng A claim, để dạng B không\n // nhân đôi cùng một occurrence.\n const consumed = new Set<number>();\n\n // Dạng A — tên đứng trước. Vị trí cụm \"trung điểm\" = chỉ số bắt đầu match\n // (gần đúng: match bắt đầu ở ký tự tên, \"trung điểm\" theo ngay sau).\n NAME_BEFORE_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_BEFORE_G)) {\n const tdIdx = c.text.indexOf('trung', m.index ?? 0);\n if (tdIdx >= 0) consumed.add(tdIdx);\n emit(m[1], m[2] + m[3], c.id);\n }\n\n // Dạng B — tên đứng sau \"trung điểm\". Bỏ qua occurrence đã được dạng A claim.\n NAME_AFTER_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_AFTER_G)) {\n const tdIdx = m.index ?? 0;\n if (consumed.has(tdIdx)) continue;\n emit(m[1], m[2] + m[3], c.id);\n }\n }\n\n // --- EN (issue #46 group B) — dạng A (name before) + B (name after) -----\n // EN dạng A khớp \"X is/be the midpoint of …\"; dạng B khớp \"midpoint X of …\".\n // 2 dạng không chồng (A cần \"is/be the\", B cần HOA ngay sau \"midpoint\") nên\n // KHÔNG cần consumed-set như VN.\n if (hasEn) {\n NAME_BEFORE_EN_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_BEFORE_EN_G)) {\n emit(m[1], m[2] + m[3], c.id);\n }\n NAME_AFTER_EN_G.lastIndex = 0;\n for (const m of c.text.matchAll(NAME_AFTER_EN_G)) {\n emit(m[1], m[2] + m[3], c.id);\n }\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/perpBisector.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, pairFromToken } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Dùng lookaround \\p{L} (cờ 'u') thay cho \\b.\n//\n// \"(đường) trung trực (của) (đoạn|đoạn thẳng|cạnh) <PAIR>\"\n// \"đường trung trực của BC\" → connect('B','C','perpBisector')\n// \"trung trực AB\" → connect('A','B','perpBisector')\n// \"d là đường trung trực BC\" → connect('B','C','perpBisector') (tên 'd' bỏ qua;\n// connect không nhận name)\n//\n// Cụm nối giữa \"trung trực\" và cặp đỉnh: optional \"của\", \"đoạn\", \"đoạn thẳng\",\n// \"cạnh\" (lặp tự do). Cặp đỉnh = 2 ký tự HOA liền.\n// Cờ 'g' để bắt MỌI cụm \"trung trực <PAIR>\" trong 1 clause (vd \"trung trực BC\n// và trung trực CA\" → emit cả 2). Reset lastIndex trước mỗi clause.\nconst PERP_BISECTOR =\n /(?<!\\p{L})trung\\s*trực\\s+(?:(?:của|đoạn|đoạn\\s+thẳng|cạnh)\\s+)*([A-Z][A-Z])(?!\\p{L})/gu;\n\n// \"(đường) trung trực (của) PAIR1 cắt [đường thẳng|đoạn|cạnh|tia]? PAIR2 tại D\":\n// đường trung trực CỦA PAIR1 (line dựng) ∩ đường PAIR2 = điểm D.\n// \"Đường trung trực của BC cắt AB tại D\" → perpBisector(B,C) + D=giao(pb_BC, AB)\n// group1 = PAIR1 (đoạn lấy trung trực); group2 = PAIR2 (đường bị cắt); group3 = D.\n//\n// perpBisector là LINE dựng (không phải đoạn) nên KHÔNG dùng intersection rule\n// generic (vốn chỉ nhận cặp đỉnh): rule này tự đặt perpBisector + intersection ref\n// TÊN shape mà connect builder sinh ('pb_<PAIR1>', deterministic + dedup JSON nên\n// duy nhất). PAIR1/PAIR2 chia sẻ đỉnh là BÌNH THƯỜNG (pb là đường khác đoạn PAIR2).\nconst PERP_BIS_CUT =\n /(?<!\\p{L})[Tt]rung\\s*trực\\s+(?:(?:của|đoạn|đoạn\\s+thẳng|cạnh)\\s+)*([A-Z][A-Z])(?!\\p{L})\\s+cắt\\s+(?:đường\\s*thẳng\\s+|đoạn(?:\\s+thẳng)?\\s+|cạnh\\s+|tia\\s+)?([A-Z][A-Z])(?!\\p{L})\\s+tại\\s+([A-Z])(?!\\p{L})/gu;\n\n/** prefilter nhanh trên toàn đề. */\nconst PREFILTER = /trung\\s*trực/u;\n\n// === EN (issue #46 group B) ===\n// \"(the)? perpendicular bisector (of|the|segment|line|side)* PAIR\" → connect(P1,P2,'perpBisector').\n// First-letter flex [Pp] (KHÔNG cờ 'i'). Global để bắt nhiều cụm/clause như VN.\nconst PERP_BISECTOR_EN =\n /[Pp]erpendicular\\s+bisector\\s+(?:(?:of|the|segment|line|side)\\s+)*([A-Z][A-Z])(?!\\p{L})/gu;\nconst PERP_BISECTOR_EN_PRE = /[Pp]erpendicular\\s+bisector/u;\n\n/**\n * \"(đường) trung trực của <PAIR>\" → connect(P1, P2, 'perpBisector').\n *\n * GLOBAL: 1 clause có thể chứa nhiều cụm trung trực (\"trung trực BC và trung\n * trực CA\") → emit connect cho MỖI cặp. Lấy cặp đỉnh ngay sau mỗi \"trung trực\"\n * (bỏ qua \"của/đoạn/cạnh\" xen giữa). Cụm không trích được cặp đỉnh hợp lệ →\n * bỏ qua cụm đó (escalate AI, an toàn hơn đoán sai). Tên đường (vd \"d là …\")\n * không cần — connect không nhận name.\n */\nexport const perpBisectorRule: LanguageRule = {\n id: 'perpBisector',\n priority: 70,\n languages: ['vi', 'en'],\n patterns: [PREFILTER, PERP_BISECTOR_EN_PRE],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n PERP_BISECTOR.lastIndex = 0; // regex 'g' có state — reset mỗi clause\n for (const m of c.text.matchAll(PERP_BISECTOR)) {\n const pair = pairFromToken(m[1]);\n if (pair.length !== 2) continue; // không trích được cặp đỉnh → bỏ cụm\n out.push({\n ruleId: 'perpBisector',\n clauseIds: [c.id],\n intents: [connect(pair[0], pair[1], 'perpBisector')],\n });\n }\n\n // \"trung trực PAIR1 cắt PAIR2 tại D\" → perpBisector(PAIR1) + giao điểm D.\n // Emit connect(perpBisector) NGAY TRƯỚC intersection (cùng match) để shape\n // 'pb_<PAIR1>' tồn tại khi transpile resolve ref của intersection (connect\n // trùng với loop plain ở trên sẽ bị dedup JSON → an toàn).\n PERP_BIS_CUT.lastIndex = 0;\n for (const m of c.text.matchAll(PERP_BIS_CUT)) {\n const pb = pairFromToken(m[1]);\n const line = pairFromToken(m[2]);\n const d = m[3];\n if (pb.length !== 2 || line.length !== 2) continue;\n // Giao điểm phải là điểm MỚI: D không trùng đỉnh nào của 2 cặp.\n if (new Set([pb[0], pb[1], line[0], line[1]]).has(d)) continue;\n const pbName = `pb_${pb[0]}${pb[1]}`; // khớp connect builder uniqueShapeName('pb_BC')\n out.push({\n ruleId: 'perpBisector',\n clauseIds: [c.id],\n intents: [\n connect(pb[0], pb[1], 'perpBisector'),\n addPoint(d, { kind: 'intersection', of: [pbName, m[2]] }),\n ],\n });\n }\n\n // --- EN (issue #46 group B) — mirror VN: global, emit-all, escalate-safe ---\n PERP_BISECTOR_EN.lastIndex = 0;\n for (const m of c.text.matchAll(PERP_BISECTOR_EN)) {\n const pair = pairFromToken(m[1]);\n if (pair.length !== 2) continue;\n out.push({\n ruleId: 'perpBisector',\n clauseIds: [c.id],\n intents: [connect(pair[0], pair[1], 'perpBisector')],\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/cevian.ts\n//\n// Cevian (đường đồng quy từ đỉnh): đường cao / trung tuyến / phân giác.\n// Phrasing thực tế: tên cevian dạng VF = đỉnh + chân (vd \"đường cao AH\",\n// \"AM là trung tuyến\", \"vẽ phân giác AD\"). Cần triangle context (ctx.problem)\n// để suy ra cạnh đối diện đỉnh = 2 đỉnh còn lại.\n//\n// Mỗi cevian khớp → RuleMatch với 2 intent cùng clauseId:\n// - add-point (chân: perpFoot / midpoint / angleBisectorFoot)\n// - connect (đoạn cevian visible VF, style segment)\n//\n// Nguyên tắc fail-safe:\n// - 1 clause có thể chứa NHIỀU cevian (cùng/khác loại): dùng matchAll (cờ /g)\n// để emit ĐỦ, không chỉ match đầu tiên.\n// - foot trùng đỉnh tam giác (\"đường cao AB\" → foot=B) → SKIP (đừng tạo\n// add-point sẽ bị builder hạ về 'free' → fidelity guard escalate).\n// - 2 cevian KHÁC nhau cùng đặt 1 tên chân (vd \"đường cao AH\" + \"trung tuyến\n// BH\" — cùng tên H nhưng ràng buộc mâu thuẫn) → SKIP tất cả cevian mang tên\n// chân đó (không claim → coverage escalate). Thà escalate còn hơn dựng SAI.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect } from './_shared';\n\n// Tam giác từ toàn đề (cần để suy cạnh đối diện). LƯU Ý: \\b không khớp quanh\n// ký tự Việt → dùng class trực tiếp, có cờ 'u'.\nconst TRI = /tam\\s*giác(?:\\s+(?:vuông|cân|đều|nhọn|tù))?\\s+([A-Z])([A-Z])([A-Z])/u;\n\n// === EN (issue #46 group B) =================================================\n// Tam giác tiếng Anh: \"triangle ABC\" (first-letter case flex [Tt], KHÔNG cờ 'i'\n// — sẽ phá [A-Z] nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]). Adjective\n// \"right/isosceles/…\" chỉ đứng TRƯỚC \"triangle\" nên vẫn khớp (vd \"right triangle\n// ABC\"). Đề VN không chứa \"triangle\" và đề EN không chứa \"tam giác\" → VN\n// byte-identical.\nconst TRI_EN = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\n\n// Cevian type → patterns. Mỗi pattern capture đỉnh (g1) + chân (g2): 2 ký tự\n// HOA liền (vd \"AH\"). (?![A-Z]) chặn match nhầm vào cụm 3 ký tự (vd \"ABC\").\n// TẤT CẢ pattern dùng cờ /g để matchAll bắt MỌI cevian trong 1 clause.\ntype CevianType = 'altitude' | 'median' | 'bisector' | 'externalBisector';\n\n// LƯU Ý case: KHÔNG dùng cờ 'i' (làm [A-Z] khớp chữ thường → bắt rác). Nhưng\n// keyword có thể HOA ở đầu câu (\"Đường cao AH\", \"Trung tuyến AM\", \"Phân giác AD\")\n// → ký tự đầu keyword + verb dùng [Xx]; vertices LUÔN strict [A-Z].\nconst CEVIAN_PATTERNS: ReadonlyArray<{ type: CevianType; patterns: readonly RegExp[] }> = [\n {\n type: 'altitude',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Hh]ạ|[Dd]ựng)\\s+[Đđ]ường\\s*cao\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /[Đđ]ường\\s*cao\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?đường\\s*cao/gu,\n // EN (issue #46 group B). g1=apex g2=foot, nhãn strict [A-Z], NO cờ 'i'.\n // First-letter flex [Aa] (HOA đầu câu \"Altitude AH\"); KHÔNG cờ 'i' (phá nhãn).\n // forward \"altitude AH\" (lời dẫn \"Draw the \" phía trước bỏ qua). \"foot of\n // the altitude from A to BC\" KHÔNG khớp: sau \"altitude\" là \"from\" (chữ\n // thường), không cặp HOA → perpFoot.ts sở hữu.\n /[Aa]ltitude\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n // reverse \"AH is/be the altitude\". (?![A-Za-z]) chặn \"altitudes\"/nối chữ.\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:is|be)\\s+(?:the\\s+)?altitude(?![A-Za-z])/gu,\n ],\n },\n {\n type: 'median',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\s+[Tt]rung\\s*tuyến\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /[Tt]rung\\s*tuyến\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?trung\\s*tuyến/gu,\n // EN (issue #46 group B). g1=apex g2=foot. First-letter flex [Mm].\n /[Mm]edian\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:is|be)\\s+(?:the\\s+)?median(?![A-Za-z])/gu,\n ],\n },\n {\n // \"phân giác (trong) AD\": từ \"trong\" (phân giác TRONG = internal bisector,\n // loại thường) tuỳ chọn chen giữa \"phân giác\" và cặp đỉnh. \"phân giác NGOÀI\"\n // (external bisector) CHƯA hỗ trợ: forward tự reject (sau \"phân giác\" là chữ\n // thường \"ngoài\", không HOA pair); suffix cần (?!\\s+ngoài) để KHÔNG nhận nhầm\n // \"AD là phân giác ngoài\" thành internal → escalate (fail-safe).\n type: 'bisector',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\s+(?:[Đđ]ường\\s*|[Tt]ia\\s+)?phân\\s*giác(?:\\s+trong)?\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?:[Đđ]ường\\s*phân\\s*giác|[Tt]ia\\s+phân\\s*giác|[Pp]hân\\s*giác)(?:\\s+trong)?\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?(?:đường\\s*|tia\\s+)?phân\\s*giác(?:\\s+trong)?(?!\\s+ngoài)/gu,\n // EN (issue #46 group B) — internal bisector ONLY. g1=apex g2=foot.\n // forward \"(angle)? bisector AD\". 3 negative lookbehind:\n // (?<![Pp]erpendicular\\s) — \"perpendicular bisector AD\" thuộc perpBisector.ts\n // (EN regex của nó CŨNG khớp cặp HOA) → tránh double-emit.\n // (?<![Ee]xternal\\s)/(?<![Ee]xterior\\s) — external bisector EN DEFER → KHÔNG\n // nhận nhầm thành internal (silent-wrong).\n // Dạng \"of angle\"/\"angle bisector of\" (angleBisectorAngle.ts) tự loại: cần\n // cặp HOA NGAY sau \"bisector\", \"of\" chen vào sẽ phá khớp. First-letter flex\n // [Bb] (HOA đầu câu) — lookbehind PHẢI first-letter flex [Pp]/[Ee] để chặn cả\n // \"Perpendicular\"/\"External\" HOA đầu clause (else double-emit silent-wrong).\n /(?<![Pp]erpendicular\\s)(?<![Ee]xternal\\s)(?<![Ee]xterior\\s)(?:[Aa]ngle\\s+)?[Bb]isector\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n // reverse \"AD is/be the (angle)? bisector\". (?!\\s+of) chặn \"is the bisector\n // of …\" (thuộc angleBisectorAngle). \"the perpendicular/external bisector\"\n // tự loại: từ chen giữa \"the\" và \"bisector\" phá (?:angle\\s+)?bisector.\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:is|be)\\s+(?:the\\s+)?(?:angle\\s+)?bisector(?!\\s+of)(?![A-Za-z])/gu,\n ],\n },\n {\n // \"phân giác NGOÀI AD\" (external bisector, Issue #46 nhóm A). Nhánh RIÊNG,\n // BẮT BUỘC có từ \"ngoài\" sau \"phân giác\" (forward) hoặc trước/sau cặp đỉnh\n // (suffix). Phân giác ngoài ⊥ phân giác trong tại đỉnh → builder dựng qua\n // angleBisector(trong) + perpendicular. KHÔNG đụng pattern 'bisector' nội bộ\n // (vốn đã reject \"ngoài\" qua chữ thường forward + (?!\\s+ngoài) suffix).\n type: 'externalBisector',\n patterns: [\n /(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\s+(?:[Đđ]ường\\s*|[Tt]ia\\s+)?phân\\s*giác\\s+ngoài\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?:[Đđ]ường\\s*phân\\s*giác|[Tt]ia\\s+phân\\s*giác|[Pp]hân\\s*giác)\\s+ngoài\\s+([A-Z])([A-Z])(?![A-Z])/gu,\n /(?<![A-Z])([A-Z])([A-Z])\\s+(?:là\\s+|=\\s+)?(?:đường\\s*|tia\\s+)?phân\\s*giác\\s+ngoài/gu,\n ],\n },\n];\n\n// Prefilter: bất kỳ từ khoá cevian nào trên toàn đề (hoa đầu câu → [Đđ]/[Tt]/[Pp]).\n// EN (issue #46 group B): runRules prefilter theo `patterns` (BỎ QUA field\n// `languages`) → đề EN thuần cần EN prefilter thì match() mới chạy. Đây là cờ\n// boolean .test() thuần (KHÔNG capture nhãn) nên cờ 'i' AN TOÀN.\nconst PREFILTER = [\n /[Đđ]ường\\s*cao/u,\n /[Tt]rung\\s*tuyến/u,\n /[Pp]hân\\s*giác/u,\n /median/i,\n /altitude/i,\n /bisector/i,\n];\n\n/** Cạnh đối diện đỉnh V trong tam giác = 2 đỉnh còn lại, join token (vd \"BC\"). */\nfunction opposite(tri: readonly string[], vertex: string): string | undefined {\n const rest = tri.filter((v) => v !== vertex);\n return rest.length === 2 ? rest[0] + rest[1] : undefined;\n}\n\ninterface Cevian {\n clauseId: number;\n type: CevianType;\n apex: string;\n foot: string;\n opp: string;\n}\n\n/**\n * \"đường cao AH\" / \"trung tuyến AM\" / \"phân giác AD\" → add-point(chân) +\n * connect(VF). apex PHẢI là đỉnh tam giác (else bỏ qua: tránh match nhầm\n * cặp như \"BD cắt\"). Không có tam giác hoặc apex ngoài tam giác → escalate.\n */\nexport const cevianRule: LanguageRule = {\n id: 'cevian',\n priority: 60,\n languages: ['vi', 'en'],\n patterns: PREFILTER,\n match(ctx) {\n // Tam giác gate: VN trước, EN fallback (mirror angleBisectorAngle). Đề VN\n // không chứa \"triangle\", đề EN không chứa \"tam giác\" → VN byte-identical.\n const triMatch = TRI.exec(ctx.problem);\n const triMatchEN = TRI_EN.exec(ctx.problem);\n const tri = triMatch\n ? [triMatch[1], triMatch[2], triMatch[3]]\n : triMatchEN\n ? [triMatchEN[1], triMatchEN[2], triMatchEN[3]]\n : null;\n if (!tri) return []; // không có tam giác → escalate\n\n // ── Pass 1: gom MỌI cevian hợp lệ (apex là đỉnh, foot không trùng đỉnh) ──\n // Dedup theo (apex,foot,type) — KHÔNG dedup chỉ theo tên chân: 2 cevian\n // khác nhau cùng tên chân là XUNG ĐỘT (xử ở pass 2), không phải trùng lặp.\n const candidates: Cevian[] = [];\n const seen = new Set<string>(); // \"apex|foot|type\"\n\n for (const c of ctx.clauses) {\n for (const cp of CEVIAN_PATTERNS) {\n for (const re of cp.patterns) {\n re.lastIndex = 0;\n for (const m of c.text.matchAll(re)) {\n const apex = m[1];\n const foot = m[2];\n // apex phải là đỉnh tam giác; else có thể là cặp cạnh ngẫu nhiên.\n if (!tri.includes(apex)) continue;\n // foot trùng đỉnh tam giác (\"đường cao AB\" → foot=B) → SKIP sớm:\n // builder sẽ hạ điểm về 'free' → fidelity guard escalate; bỏ ở đây\n // cho sạch (không claim → coverage escalate trực tiếp).\n if (tri.includes(foot)) continue;\n const opp = opposite(tri, apex);\n if (!opp) continue; // apex không suy ra được cạnh đối diện → bỏ qua\n\n const key = `${apex}|${foot}|${cp.type}`;\n if (seen.has(key)) continue;\n seen.add(key);\n candidates.push({ clauseId: c.id, type: cp.type, apex, foot, opp });\n }\n }\n }\n }\n\n // ── Pass 2: phát hiện XUNG ĐỘT tên chân ──\n // Nếu 1 tên chân được ≥2 cevian khác nhau đặt (vd \"đường cao AH\" +\n // \"trung tuyến BH\" cùng tên H, ràng buộc mâu thuẫn) → bỏ TẤT cevian mang\n // tên đó. Không claim → escalate (thà escalate còn hơn dựng SAI ngữ nghĩa).\n const footCount = new Map<string, number>();\n for (const cv of candidates) footCount.set(cv.foot, (footCount.get(cv.foot) ?? 0) + 1);\n\n const out: RuleMatch[] = [];\n for (const cv of candidates) {\n if ((footCount.get(cv.foot) ?? 0) > 1) continue; // tên chân xung đột → skip\n\n let pointIntent;\n if (cv.type === 'altitude') {\n pointIntent = addPoint(cv.foot, { kind: 'perpFoot', from: cv.apex, onLine: cv.opp });\n } else if (cv.type === 'median') {\n pointIntent = addPoint(cv.foot, { kind: 'midpoint', of: cv.opp });\n } else if (cv.type === 'externalBisector') {\n pointIntent = addPoint(cv.foot, {\n kind: 'externalAngleBisectorFoot',\n from: cv.apex,\n onLine: cv.opp,\n });\n } else {\n pointIntent = addPoint(cv.foot, {\n kind: 'angleBisectorFoot',\n from: cv.apex,\n onLine: cv.opp,\n });\n }\n\n out.push({\n ruleId: 'cevian',\n clauseIds: [cv.clauseId],\n intents: [pointIntent, connect(cv.apex, cv.foot, 'segment')],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/angleBisectorAngle.ts\n//\n// Phân giác theo GÓC (3-point angle, KHÔNG đặt tên chân) — Issue #46 nhóm A.\n//\n// Phrasing đề thi RẤT phổ biến: \"Vẽ tia phân giác của góc BAC\", \"phân giác góc\n// BAC\", \"đường phân giác của góc A\"… → vẽ phân giác TRONG của góc, VISIBLE,\n// KHÔNG có tên chân (khác hẳn cevian \"phân giác AD\" foot-named).\n//\n// Emit 1 intent draw-line/angleBisector (VISIBLE), KHÔNG add-point foot, KHÔNG\n// connect. vertex = đỉnh góc:\n// - \"góc XYZ\" (3 ký tự HOA): vertex = chữ GIỮA (Y), p1=X, p2=Z.\n// - \"góc A\" (1 ký tự, trong tam giác): vertex=A, p1/p2 = 2 đỉnh còn lại\n// (suy như cevian opposite). Không có tam giác để suy 2 tia → escalate.\n//\n// Discriminator: PHẢI có \"góc\" + (cụm 3 HOA HOẶC 1 HOA là đỉnh tam giác). KHÔNG\n// đụng cevian \"phân giác AD\"/\"phân giác ngoài AD\" (2 ký tự foot-named): cevian\n// pattern yêu cầu cặp HOA NGAY sau \"phân giác\", nhưng ở đây sau \"phân giác\" là\n// \"góc\" (chữ thường) → cevian không khớp → KHÔNG double-emit.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { drawLine } from './_shared';\n\n// Tam giác từ toàn đề (cần để suy 2 cạnh cho \"góc A\"). \\b không khớp quanh ký\n// tự Việt → dùng class trực tiếp, cờ 'u'.\nconst TRI = /tam\\s*giác(?:\\s+(?:vuông|cân|đều|nhọn|tù))?\\s+([A-Z])([A-Z])([A-Z])/u;\n\n// === EN (issue #46 group B) =================================================\n// Tam giác tiếng Anh: \"triangle ABC\" (first-letter case flex [Tt], KHÔNG cờ 'i'\n// — sẽ phá [A-Z] nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]). Không cần\n// 'g' (chỉ cần tam giác đầu tiên để fallback suy 2 cạnh, như TRI VN).\nconst TRI_EN = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\n\n// Prefilter: VN cần \"phân giác\" + \"góc\"; EN cần \"angle bisector\" (Form B) hoặc\n// \"bisector of (the)? angle/∠\" (Form A). `.some` → ANY khớp là trigger match().\n// \"languages\" là metadata thuần (runRules prefilter theo `patterns`, BỎ QUA nó).\nconst PREFILTER = [\n /[Pp]hân\\s*giác/u,\n /góc/u,\n /[Aa]ngle\\s+bisector/u, // Form B EN\n /[Bb]isector\\s+of\\s+(?:the\\s+)?(?:[Aa]ngle|∠)/u, // Form A EN\n];\n\n// \"phân giác … góc XYZ\" (3 ký tự HOA liền). (?![A-Z]) chặn cụm 4+ ký tự.\n// Cho phép cụm dẫn \"(đường|tia) phân giác (của)? góc\" — bổ ngữ optional.\nconst ANGLE3 =\n /phân\\s*giác\\s+(?:(?:của|cho)\\s+)?góc\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/giu;\n// \"phân giác … góc A\" (1 ký tự HOA, không theo sau bởi HOA khác → không phải 3-point).\nconst ANGLE1 =\n /phân\\s*giác\\s+(?:(?:của|cho)\\s+)?góc\\s+([A-Z])(?![A-Z])/giu;\n\n// \"chân (của)? (đường|tia)? \" NGAY TRƯỚC \"phân giác\" → cụm \"CHÂN phân giác\" là\n// FOOT (điểm), thuộc angleBisectorFoot.ts. angleBisectorAngle né để KHÔNG vẽ tia\n// phân giác trùng (foot builder đã tự dựng tia bên trong) → tránh double-emit.\nconst CHAN_BEFORE = /chân\\s+(?:của\\s+)?(?:đường\\s*|tia\\s+)?$/u;\n\n// === EN regex (issue #46 group B) ===========================================\n// First-letter flex [Bb]/[Aa] (KHÔNG cờ 'i' — sẽ phá [A-Z] nhãn). Nhãn HOA\n// strict, neo (?![A-Z]). Cờ 'g' để emit-all + matchAll. Yêu cầu chữ\n// \"angle\"/∠ → KHÔNG khớp \"perpendicular bisector of BC\" (không có \"angle\").\n//\n// Form A: \"(the)? bisector of (the)? (angle|∠) XYZ\" — bổ ngữ \"the\" optional.\n// \"Draw the bisector of angle BAC.\" → {p1:B, vertex:A, p2:C}\n// Form B: \"(the)? angle bisector of XYZ\" — \"of\" sau \"bisector\", KHÔNG \"angle/∠\".\n// \"The angle bisector of MNP.\" → {M,N,P}\nconst ANGLE3_EN_A =\n /[Bb]isector\\s+of\\s+(?:the\\s+)?(?:[Aa]ngle|∠)\\s*([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\nconst ANGLE3_EN_B =\n /[Aa]ngle\\s+bisector\\s+of\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n// 1-letter \"angle A\" (Form A only — Form B \"angle bisector of A\" hiếm/mơ hồ,\n// defer). Cần tam giác EN để suy 2 cạnh.\nconst ANGLE1_EN_A =\n /[Bb]isector\\s+of\\s+(?:the\\s+)?(?:[Aa]ngle|∠)\\s*([A-Z])(?![A-Z])/gu;\n\n/** 2 đỉnh còn lại của tam giác (≠ vertex), giữ thứ tự xuất hiện trong tri. */\nfunction others(tri: readonly string[], vertex: string): string[] {\n return tri.filter((v) => v !== vertex);\n}\n\ninterface Hit {\n clauseId: number;\n p1: string;\n vertex: string;\n p2: string;\n}\n\n/**\n * \"phân giác (của) góc XYZ/A\" → draw-line/angleBisector VISIBLE (1 intent,\n * không foot, không connect). vertex = chữ giữa (3-point) hoặc đỉnh tam giác\n * (1-letter, suy 2 cạnh từ tam giác). Mơ hồ / không suy được 2 tia → escalate.\n */\nexport const angleBisectorAngleRule: LanguageRule = {\n id: 'angleBisectorAngle',\n // Cao hơn cevian (60) — chạy trước; tuy nhiên 2 rule không tranh chấp vì\n // discriminator \"góc\" loại cevian khỏi cụm này.\n priority: 62,\n languages: ['vi', 'en'],\n patterns: PREFILTER,\n match(ctx) {\n // Tam giác fallback (suy 2 cạnh cho \"góc A\"/\"angle A\"): VN trước, EN sau.\n // Đề VN không chứa \"triangle\" và đề EN không chứa \"tam giác\" → KHÔNG đụng\n // nhau (VN byte-identical).\n const triMatch = TRI.exec(ctx.problem);\n const triMatchEN = TRI_EN.exec(ctx.problem);\n const tri = triMatch\n ? [triMatch[1], triMatch[2], triMatch[3]]\n : triMatchEN\n ? [triMatchEN[1], triMatchEN[2], triMatchEN[3]]\n : null;\n\n const hits: Hit[] = [];\n const seen = new Set<string>(); // \"p1|vertex|p2\" dedup\n\n for (const c of ctx.clauses) {\n // ── 3-point \"góc XYZ\": vertex = chữ giữa, không cần tam giác ──\n ANGLE3.lastIndex = 0;\n for (const m of c.text.matchAll(ANGLE3)) {\n if (CHAN_BEFORE.test(c.text.slice(0, m.index))) continue; // \"chân … phân giác\" = foot\n const [p1, vertex, p2] = [m[1], m[2], m[3]];\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n\n // ── 1-letter \"góc A\": cần tam giác để suy 2 cạnh ──\n // Dùng pattern ANGLE1 nhưng BỎ QUA những match đã bị ANGLE3 nuốt (cùng vị\n // trí bắt đầu): so vị trí của vertex 1-letter với các 3-point đã thấy.\n ANGLE1.lastIndex = 0;\n for (const m of c.text.matchAll(ANGLE1)) {\n if (CHAN_BEFORE.test(c.text.slice(0, m.index))) continue; // \"chân … phân giác\" = foot\n const vertex = m[1];\n if (!tri) continue; // không tam giác → escalate\n if (!tri.includes(vertex)) continue; // đỉnh ngoài tam giác → bỏ qua\n const rest = others(tri, vertex);\n if (rest.length !== 2) continue; // không suy được 2 tia → bỏ qua\n const [p1, p2] = rest;\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n\n // ── EN 3-point: Form A \"(bisector of) angle XYZ\" + Form B \"angle bisector\n // of XYZ\". vertex = chữ giữa, không cần tam giác. seen dedup chung VN.\n for (const re of [ANGLE3_EN_A, ANGLE3_EN_B]) {\n re.lastIndex = 0;\n for (const m of c.text.matchAll(re)) {\n const [p1, vertex, p2] = [m[1], m[2], m[3]];\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n }\n\n // ── EN 1-letter \"angle A\" (Form A): cần tam giác EN/VN để suy 2 cạnh.\n ANGLE1_EN_A.lastIndex = 0;\n for (const m of c.text.matchAll(ANGLE1_EN_A)) {\n const vertex = m[1];\n if (!tri) continue; // không tam giác → escalate\n if (!tri.includes(vertex)) continue; // đỉnh ngoài tam giác → bỏ qua\n const rest = others(tri, vertex);\n if (rest.length !== 2) continue; // không suy được 2 tia → bỏ qua\n const [p1, p2] = rest;\n const key = `${p1}|${vertex}|${p2}`;\n if (seen.has(key)) continue;\n seen.add(key);\n hits.push({ clauseId: c.id, p1, vertex, p2 });\n }\n }\n\n return hits.map<RuleMatch>((h) => ({\n ruleId: 'angleBisectorAngle',\n clauseIds: [h.clauseId],\n intents: [\n drawLine(`bis${h.p1}${h.vertex}${h.p2}`, 'angleBisector', {\n p1: h.p1,\n vertex: h.vertex,\n p2: h.p2,\n }) as IntentT,\n ],\n }));\n },\n};\n","// src/stamps/geometry-2d/ai/rules/centers.ts\n//\n// Tâm tam giác: trọng tâm (centroid), trực tâm (orthocenter), tâm đường tròn\n// ngoại tiếp (circumcenter), tâm đường tròn nội tiếp (incenter).\n//\n// Mọi kind này cần bộ 3 đỉnh of=[A,B,C]. Bind theo tam giác NÊU TRONG CÙNG\n// CLAUSE với cụm từ khoá (vd \"trọng tâm tam giác DEF\" → of=[D,E,F]) — KHÔNG lấy\n// tam giác đầu đề. Chỉ fallback tam giác toàn đề khi clause không nêu tam giác\n// nào VÀ đề có ĐÚNG 1 tam giác. Nhập nhằng (clause không nêu, đề >1 tam giác)\n// → bỏ qua (escalate). Không có tam giác nào → bỏ qua (escalate).\n// Tên điểm phải trích được (HOA ngay sau cụm từ khoá, hoặc \"X là <từ khoá>\");\n// nếu không → bỏ qua, KHÔNG bịa tên.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// Tam giác (global): quét mọi tam giác nêu trong một đoạn text.\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// === EN (issue #46 group B) =================================================\n// Tam giác tiếng Anh: \"triangle ABC\" (first-letter case flex [Tt], KHÔNG cờ 'i'\n// — sẽ phá [A-Z] nhãn). Nhãn = ĐÚNG 3 ký tự HOA liền, neo (?![A-Z]). ADDITIVE:\n// quét THÊM cùng TRI_G; merge theo vị trí TEXT để VN behavior giữ nguyên.\nconst TRI_EN_G = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/gu;\n\n// Từ khoá tâm. \\b không khớp quanh ký tự Việt nên dùng lookaround \\p{L}.\n// \"trọng tâm\" — chặn nhầm với \"trung tâm\" bằng cách yêu cầu đúng \"trọng\".\nconst CENTROID_KW = /(?<!\\p{L})trọng\\s*tâm(?!\\p{L})/u;\n// \"trực tâm\" — chặn nhầm với \"trung trực\" (kết thúc bằng \"trực\", không phải \"trực tâm\").\nconst ORTHO_KW = /(?<!\\p{L})trực\\s*tâm(?!\\p{L})/u;\n// \"ngoại tiếp\" → circumcenter.\nconst CIRCUM_KW = /(?<!\\p{L})ngoại\\s*tiếp(?!\\p{L})/u;\n// \"nội tiếp\" → incenter (chỉ khi nói về TÂM, không phải \"tam giác nội tiếp đường tròn\").\nconst INSCRIBE_KW = /(?<!\\p{L})nội\\s*tiếp(?!\\p{L})/u;\n// Tên tâm đứng trước \"tâm\" qua \"là\": \"O là tâm\", \"Gọi O là tâm (đường tròn)…\".\nconst NAME_BEFORE_TAM = /(?<!\\p{L})([A-Z])\\s+là\\s+tâm(?!\\p{L})/u;\n\n// === EN keyword (issue #46 group B) =========================================\n// Từ khoá tâm tiếng Anh. First-letter case flex ([Cc], [Oo]…) — KHÔNG cờ 'i'\n// (sẽ phá [A-Z] nhãn). British spelling -centre cũng nhận. Neo (?![A-Za-z]) để\n// không khớp giữa từ dài hơn. centroid → centroid; orthocenter/-centre →\n// orthocenter; circumcenter/-centre → circumcenter; incenter/-centre → incenter.\nconst CENTROID_KW_EN = /(?<![A-Za-z])[Cc]entroid(?![A-Za-z])/u;\nconst ORTHO_KW_EN = /(?<![A-Za-z])[Oo]rthocent(?:er|re)(?![A-Za-z])/u;\nconst CIRCUM_KW_EN = /(?<![A-Za-z])[Cc]ircumcent(?:er|re)(?![A-Za-z])/u;\nconst INCENTER_KW_EN = /(?<![A-Za-z])[Ii]ncent(?:er|re)(?![A-Za-z])/u;\n\n// Tên điểm đứng NGAY SAU cụm từ khoá: \"trọng tâm G\", \"tâm (đường tròn) ngoại tiếp O\".\nfunction nameAfter(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const rest = text.slice(m.index + m[0].length);\n // bỏ qua các từ chêm phổ biến (\"của\", \"là\", \"tam giác\", \"đường tròn\", dấu câu)\n const after = /^[\\s,:của là]*?(?:tam\\s*giác\\s+)?([A-Z])(?!\\p{L})/u.exec(rest);\n return after ? after[1] : undefined;\n}\n\n// Tên điểm đứng TRƯỚC cụm từ khoá: \"G là trọng tâm\", \"H là trực tâm\".\nfunction nameBefore(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const before = text.slice(0, m.index);\n // \"...<HOA> (là)? \" ngay trước từ khoá\n const mm = /(?<!\\p{L})([A-Z])\\s+(?:là\\s+)?$/u.exec(before);\n return mm ? mm[1] : undefined;\n}\n\nfunction resolveName(text: string, kw: RegExp): string | undefined {\n return nameBefore(text, kw) ?? nameAfter(text, kw);\n}\n\n// Tâm đường tròn ngoại/nội tiếp: tên đứng trước \"tâm\" (qua \"là\") — vd \"Gọi O là\n// tâm đường tròn ngoại tiếp\" — hoặc sau cụm từ khoá — vd \"ngoại tiếp O\".\nfunction resolveCenterName(text: string, kw: RegExp): string | undefined {\n const before = NAME_BEFORE_TAM.exec(text);\n if (before) return before[1];\n return nameAfter(text, kw);\n}\n\n// --- EN name resolution (issue #46 group B) ---------------------------------\n// Tên điểm đứng TRƯỚC cụm từ khoá EN qua \"is/be the\": \"G is the centroid\",\n// \"Let H be the orthocenter\". Tên = ký tự HOA NGAY TRƯỚC \"is/be the <kw>\"\n// (cục bộ, KHÔNG quét lời dẫn toàn clause). KHÔNG cờ 'i' (giữ [A-Z]).\nfunction nameBeforeEn(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const before = text.slice(0, m.index);\n // \"...<HOA> (is|be) the \" ngay trước từ khoá.\n const mm = /(?<![A-Za-z])([A-Z])\\s+(?:is|be)\\s+the\\s+$/u.exec(before);\n return mm ? mm[1] : undefined;\n}\n\n// Tên điểm đứng NGAY SAU cụm từ khoá EN: \"centroid G\", \"orthocenter H\".\n// Bỏ qua từ chêm \"of\"/\"the\" KHÔNG được phép ở đây — nếu sau từ khoá là \"of …\"\n// (vd \"centroid of triangle ABC\") thì KHÔNG có tên điểm → undefined (fail-safe,\n// KHÔNG bịa tên).\nfunction nameAfterEn(text: string, kw: RegExp): string | undefined {\n const m = kw.exec(text);\n if (!m) return undefined;\n const rest = text.slice(m.index + m[0].length);\n const after = /^\\s+([A-Z])(?![A-Za-z])/u.exec(rest);\n return after ? after[1] : undefined;\n}\n\nfunction resolveNameEn(text: string, kw: RegExp): string | undefined {\n return nameBeforeEn(text, kw) ?? nameAfterEn(text, kw);\n}\n\n/** Một tam giác phát hiện trong text: bộ 3 đỉnh + offset bắt đầu match. */\ninterface TriHit {\n tri: string[];\n index: number;\n}\n\n/**\n * Tập tam giác (bộ 3 đỉnh + vị trí) nêu trong một đoạn text, gồm CẢ VN\n * (\"tam giác ABC\") VÀ EN (\"triangle ABC\"), sắp theo vị trí TEXT. ADDITIVE:\n * với đề thuần VN, chỉ TRI_G khớp ⇒ kết quả identical với hành vi cũ.\n */\nfunction triangleHits(text: string): TriHit[] {\n const hits: TriHit[] = [];\n TRI_G.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(text)) !== null) {\n hits.push({ tri: [m[1], m[2], m[3]], index: m.index });\n }\n TRI_EN_G.lastIndex = 0;\n while ((m = TRI_EN_G.exec(text)) !== null) {\n hits.push({ tri: [m[1], m[2], m[3]], index: m.index });\n }\n hits.sort((a, b) => a.index - b.index);\n return hits;\n}\n\n/**\n * Tập tam giác (mỗi tam giác = bộ 3 đỉnh) nêu trong một đoạn text. Trùng (cùng\n * 3 chữ liền) được giữ theo lượt xuất hiện; caller dedup nếu cần.\n */\nfunction trianglesIn(text: string): string[][] {\n return triangleHits(text).map((h) => h.tri);\n}\n\n/**\n * Tam giác để bind 'of' cho 1 clause:\n * 1. Ưu tiên tam giác nêu NGAY TRONG clause (gần cụm từ khoá nhất theo index).\n * 2. Nếu clause không nêu tam giác nào → fallback tam giác toàn đề CHỈ KHI đề\n * có duy nhất 1 tam giác (theo bộ đỉnh, dedup). Nhiều tam giác → undefined\n * (nhập nhằng, escalate). Không có tam giác → undefined.\n */\nfunction resolveTriangle(\n clauseText: string,\n kwIndex: number,\n uniqueProblemTri: string[] | undefined,\n): string[] | undefined {\n const inClause = triangleHits(clauseText);\n if (inClause.length > 0) {\n // chọn tam giác gần cụm từ khoá nhất (ưu tiên đứng SAU; nếu không có thì lấy\n // tam giác gần nhất bất kể phía). Gồm cả tam giác VN lẫn EN trong clause.\n let best: { tri: string[]; dist: number } | undefined;\n for (const h of inClause) {\n const idx = h.index;\n // khoảng cách: ưu tiên tam giác đứng sau từ khoá (idx >= kwIndex).\n const after = idx >= kwIndex;\n const dist = Math.abs(idx - kwIndex) + (after ? 0 : 1_000);\n if (!best || dist < best.dist) best = { tri: h.tri, dist };\n }\n return best?.tri;\n }\n return uniqueProblemTri;\n}\n\n/**\n * Tâm tam giác → add-point với of=[A,B,C]. Một clause có thể nêu nhiều tâm\n * (vd \"trọng tâm G và trực tâm H\"); emit từng intent, cùng claim clause.\n */\nexport const centersRule: LanguageRule = {\n id: 'centers',\n priority: 70,\n languages: ['vi', 'en'],\n patterns: [\n CENTROID_KW,\n ORTHO_KW,\n CIRCUM_KW,\n INSCRIBE_KW,\n CENTROID_KW_EN,\n ORTHO_KW_EN,\n CIRCUM_KW_EN,\n INCENTER_KW_EN,\n ],\n match(ctx) {\n // Tam giác duy nhất toàn đề (dedup theo bộ đỉnh) — dùng làm fallback khi\n // clause KHÔNG tự nêu tam giác. Nhiều tam giác khác nhau → undefined (nhập\n // nhằng → escalate). Không có → undefined (không dựng được → escalate).\n const allTri = trianglesIn(ctx.problem);\n const distinct = new Set(allTri.map((t) => t.join('')));\n const uniqueProblemTri = distinct.size === 1 ? allTri[0] : undefined;\n\n // helper: bind 'of' cho 1 cụm từ khoá tại vị trí kwIndex trong clause.\n const ofFor = (text: string, kw: RegExp): string[] | undefined => {\n const m = kw.exec(text);\n const kwIndex = m ? m.index : 0;\n return resolveTriangle(text, kwIndex, uniqueProblemTri);\n };\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const intents = [];\n\n if (CENTROID_KW.test(c.text)) {\n const name = resolveName(c.text, CENTROID_KW);\n const of = ofFor(c.text, CENTROID_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'centroid', of }));\n }\n if (ORTHO_KW.test(c.text)) {\n const name = resolveName(c.text, ORTHO_KW);\n const of = ofFor(c.text, ORTHO_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'orthocenter', of }));\n }\n // circumcenter: \"ngoại tiếp\". incenter: \"nội tiếp\" nhưng KHÔNG khi clause\n // cũng có \"ngoại tiếp\" (cùng cụm gây nhập nhằng) — ưu tiên ngoại tiếp.\n if (CIRCUM_KW.test(c.text)) {\n const name = resolveCenterName(c.text, CIRCUM_KW);\n const of = ofFor(c.text, CIRCUM_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'circumcenter', of }));\n } else if (INSCRIBE_KW.test(c.text)) {\n const name = resolveCenterName(c.text, INSCRIBE_KW);\n const of = ofFor(c.text, INSCRIBE_KW);\n if (name && of) intents.push(addPoint(name, { kind: 'incenter', of }));\n }\n\n // --- EN (issue #46 group B) — mirror VN semantics, mỗi từ khoá độc lập --\n // Các danh từ tâm EN là chính tả riêng biệt (centroid/orthocenter/\n // circumcenter/incenter) nên KHÔNG nhập nhằng lẫn nhau như \"ngoại/nội\n // tiếp\" VN — xử lý từng cái độc lập. Tên + of giải qua helper EN; thiếu\n // tên HOẶC of không bind được → bỏ qua (escalate, KHÔNG bịa).\n if (CENTROID_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, CENTROID_KW_EN);\n const of = ofFor(c.text, CENTROID_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'centroid', of }));\n }\n if (ORTHO_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, ORTHO_KW_EN);\n const of = ofFor(c.text, ORTHO_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'orthocenter', of }));\n }\n if (CIRCUM_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, CIRCUM_KW_EN);\n const of = ofFor(c.text, CIRCUM_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'circumcenter', of }));\n }\n if (INCENTER_KW_EN.test(c.text)) {\n const name = resolveNameEn(c.text, INCENTER_KW_EN);\n const of = ofFor(c.text, INCENTER_KW_EN);\n if (name && of) intents.push(addPoint(name, { kind: 'incenter', of }));\n }\n\n if (intents.length > 0) {\n out.push({ ruleId: 'centers', clauseIds: [c.id], intents });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/perpFoot.ts\n//\n// Hình chiếu vuông góc / chân đường vuông góc (đường cao):\n// \"Gọi H là hình chiếu (vuông góc) của A trên/lên/xuống (đường thẳng|cạnh)? BC\"\n// \"Gọi H là chân đường vuông góc (hạ|kẻ) từ A (đến|xuống) BC\"\n// \"H, K lần lượt là hình chiếu của B trên AC và của C trên AB\" → 2 foot\n// → addPoint('H', { kind:'perpFoot', from:'A', onLine:'BC' })\n//\n// onLine giữ nguyên token sau giới từ (pair 'BC' hoặc tên đường 1 ký tự 'd').\n//\n// Tên foot bind CỤC BỘ (ký tự HOA + \"là\" NGAY TRƯỚC cụm \"hình chiếu\"/\"chân đường\"),\n// KHÔNG lấy lời dẫn đầu clause — tránh gán nhầm cho \"Gọi N là điểm bất kỳ, H là …\".\n// Match GLOBAL để dựng đủ nhiều foot trong cùng clause.\n//\n// SKIP (để pipeline escalate AI thay vì đoán sai):\n// - không trích được tên foot cục bộ;\n// - modifier \"trung điểm (của)? hình chiếu …\" — đổi nghĩa, foot không còn là điểm cần dựng.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, DUONG_KW } from './_shared';\n\n// LƯU Ý: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt. Mọi\n// regex chứa ký tự Việt dùng cờ 'u' + tránh \\b.\n\n// Prefilter toàn đề: \"hình chiếu\" / \"chân đường (cao|vuông góc)\" / ký hiệu ⊥ /\n// \"vuông góc\" (cho dạng \"Kẻ AH ⊥ BC tại H\"). \"vuông góc\" rộng nhưng match() chỉ\n// emit khi pattern khớp thật → an toàn.\nconst PREFILTER = new RegExp(\n 'hình\\\\s*chiếu|chân\\\\s+(?:của\\\\s+)?' +\n DUONG_KW +\n '\\\\s+(?:cao|vuông\\\\s*góc)|⊥|vuông\\\\s*góc',\n 'u',\n);\n// EN prefilter (issue #46 group B). runRules prefilter theo `patterns` (BỎ QUA\n// field `languages`) → BẮT BUỘC có 1 EN regex thì match() mới chạy cho đề EN\n// thuần. Rộng nhưng match() chỉ emit khi core khớp thật → an toàn.\nconst PREFILTER_EN = /projection|perpendicular|foot\\s+of/i;\n\n// onLine token: tên đường 1 ký tự HOA HOẶC cặp đỉnh 2 ký tự HOA (vd 'BC'). Chấp\n// nhận tiền tố \"đường thẳng\" / \"cạnh\" / \"đoạn\" trước token.\nconst LINE = '(?:' + DUONG_KW + '\\\\s*thẳng\\\\s+|cạnh\\\\s+|đoạn\\\\s+)?([A-Z]{1,2})(?![A-Z])';\nconst PREP = '(?:trên|lên|xuống|đến|tới)';\n\n// \"hình chiếu (vuông góc)? (của)? X PREP [cạnh|đường thẳng] LINE\"\nconst PROJ_CORE = `hình\\\\s*chiếu\\\\s+(?:vuông\\\\s*góc\\\\s+)?(?:của\\\\s+)?([A-Z])\\\\s+${PREP}\\\\s+${LINE}`;\n// \"chân đường (vuông góc|cao) (hạ|kẻ|vẽ|dựng)? (từ)? X PREP LINE\"\nconst FOOT_CORE = `chân\\\\s+(?:của\\\\s+)?${DUONG_KW}\\\\s+(?:vuông\\\\s*góc|cao)\\\\s*(?:hạ\\\\s+|kẻ\\\\s+|vẽ\\\\s+|dựng\\\\s+)?(?:từ\\\\s+)?([A-Z])\\\\s+${PREP}\\\\s+${LINE}`;\n\n// Phân phối \"X, Y lần lượt là <core của FROM1 ... LINE1> và (của|từ)? FROM2 PREP LINE2\".\n// groups: 1=name1 2=name2 | PROJ: 3=from1 4=line1 | FOOT: 5=from1 6=line1 | tail: 7=from2 8=line2\nconst LANLUOT = new RegExp(\n `([A-Z])(?:[′'])?\\\\s*,\\\\s*([A-Z])(?:[′'])?\\\\s+lần\\\\s+lượt\\\\s+là\\\\s+(?:${PROJ_CORE}|${FOOT_CORE})\\\\s+và\\\\s+(?:của\\\\s+|từ\\\\s+)?([A-Z])\\\\s+${PREP}\\\\s+${LINE}`,\n 'gu',\n);\n\n// Một foot đơn (projection hoặc chân đường).\n// groups: PROJ 1=from 2=line | FOOT 3=from 4=line\nconst SINGLE = new RegExp(`(?:${PROJ_CORE})|(?:${FOOT_CORE})`, 'gu');\n\n// Distributive SHARED-FROM: \"X, Y, Z lần lượt là hình chiếu (vuông góc)? của D\n// trên BC, CA, AB\" → zip tên↔cạnh, MỘT `from` (D) chung. KHÁC LANLUOT (2 chân,\n// mỗi chân from riêng, nối \"và\"): ở đây 1 from + DANH SÁCH cạnh ngăn phẩy (≥2).\n// Số tên PHẢI bằng số cạnh (else bỏ → escalate, không đoán lệch).\n// groups: 1=names blob (≥2, phẩy) | 2=from | 3=lines blob (≥2, phẩy)\nconst NAMES_BLOB = \"((?:[A-Z](?:['′]?)\\\\s*,\\\\s*)+[A-Z](?:['′]?))\";\nconst LINES_BLOB = '((?:[A-Z]{1,2}\\\\s*,\\\\s*)+[A-Z]{1,2})(?!\\\\p{L})';\nconst DISTRIB_PROJ = new RegExp(\n NAMES_BLOB +\n '\\\\s+lần\\\\s*lượt\\\\s+(?:là\\\\s+)?hình\\\\s*chiếu\\\\s+(?:vuông\\\\s*góc\\\\s+)?(?:của\\\\s+)?([A-Z])(?!\\\\p{L})' +\n '\\\\s+(?:trên|lên|xuống|đến)\\\\s+(?:các\\\\s+)?' +\n LINES_BLOB,\n 'gu',\n);\nconst DISTRIB_FOOT = new RegExp(\n NAMES_BLOB +\n '\\\\s+lần\\\\s*lượt\\\\s+(?:là\\\\s+)?chân\\\\s+(?:của\\\\s+)?đường\\\\s+(?:vuông\\\\s*góc|cao)\\\\s*(?:hạ\\\\s+|kẻ\\\\s+|vẽ\\\\s+|dựng\\\\s+)?(?:từ\\\\s+)?([A-Z])(?!\\\\p{L})' +\n '\\\\s+(?:đến|xuống|trên|tới)\\\\s+(?:các\\\\s+)?' +\n LINES_BLOB,\n 'gu',\n);\n\n/** Tách blob tên distributive \"X, Y, Z\" → ['X','Y','Z'] (chuẩn hoá prime ′→'). */\nfunction splitNames(blob: string): string[] {\n return blob\n .split(',')\n .map((s) => {\n const mm = /^([A-Z])(['′]?)/u.exec(s.trim());\n return mm ? (mm[2] ? `${mm[1]}'` : mm[1]) : '';\n })\n .filter(Boolean);\n}\n\n// \"Kẻ/Vẽ/Dựng XY (⊥|vuông góc với?) [cạnh|đường thẳng]? LINE (tại Z)?\"\n// \"Kẻ AH ⊥ BC tại H\" | \"Vẽ AH vuông góc với BC\" | \"Dựng AH vuông góc cạnh BC\"\n// Tên foot = chữ thứ 2 của cặp XY (g2); from = g1; onLine = g3. \"tại Z\" (g4) nếu\n// có PHẢI trùng foot (else xung đột → skip). connect.ts (SEG_KW \"Kẻ AH\") đã lo\n// đoạn AH → rule này CHỈ emit add-point, KHÔNG connect (tránh double).\n// groups: 1=from 2=foot 3=onLine 4=tại-point(optional)\nconst PERP_DRAW = new RegExp(\n `(?:[Kk]ẻ|[Vv]ẽ|[Dd]ựng)\\\\s+([A-Z])([A-Z])(?![A-Z])\\\\s+(?:⊥|vuông\\\\s*góc(?:\\\\s+với)?)\\\\s+(?:với\\\\s+)?(?:đường\\\\s*thẳng\\\\s+|cạnh\\\\s+|đoạn\\\\s+)?([A-Z]{1,2})(?![A-Z])(?:\\\\s+tại\\\\s+([A-Z]))?`,\n 'gu',\n);\n\n// modifier \"trung điểm (của)?\" NGAY TRƯỚC cụm → đổi nghĩa, không dựng foot.\nconst MID_BEFORE = /trung\\s+điểm(?:\\s+của)?\\s*$/u;\n// Tên foot cục bộ: ký tự HOA + \"là\" NGAY TRƯỚC cụm (vd \"Gọi H là \", \"… , H là \").\nconst NAME_BEFORE = /([A-Z])(?:[′'])?\\s+là\\s+$/u;\n\n// === EN (issue #46 group B) ==================================================\n// Additive — KHÔNG đụng building block VN ở trên. Nhãn STRICT [A-Z] (KHÔNG cờ\n// 'i' — sẽ nuốt chữ thường); first-letter flex của verb bằng [Dd]/[Cc].\n//\n// onLine token EN: tiền tố \"line \"/\"side \"/\"segment \" optional + 1-2 ký tự HOA,\n// neo (?![A-Z]) để chặn cụm 3+ ký tự.\nconst LINE_EN = '(?:line\\\\s+|side\\\\s+|segment\\\\s+)?([A-Z]{1,2})(?![A-Z])';\n\n// Form A — \"(orthogonal)? projection of X (onto|on|to) LINE\"\n// groups: 1=from 2=line\nconst PROJ_CORE_EN = `(?:orthogonal\\\\s+)?projection\\\\s+of\\\\s+([A-Z])\\\\s+(?:onto|on|to)\\\\s+${LINE_EN}`;\n// Form B — \"foot of (the)? (perpendicular|altitude) from X (to|onto|on) LINE\"\n// groups: 1=from 2=line\nconst FOOT_CORE_EN = `foot\\\\s+of\\\\s+(?:the\\\\s+)?(?:perpendicular|altitude)\\\\s+from\\\\s+([A-Z])\\\\s+(?:to|onto|on)\\\\s+${LINE_EN}`;\n\n// Single EN core (projection HOẶC foot-of). Ghép 2 group block → group dịch:\n// PROJ: 1=from 2=line | FOOT: 3=from 4=line → đọc bằng m[1]??m[3], m[2]??m[4].\nconst SINGLE_EN = new RegExp(`(?:${PROJ_CORE_EN})|(?:${FOOT_CORE_EN})`, 'gu');\n\n// Form C draw — \"Draw|Construct|Drop XY perpendicular to (line|side|segment)? LINE (at Z)?\"\n// \"Draw AH perpendicular to BC at H\" | \"Construct AH perpendicular to BC\"\n// foot = chữ thứ 2 cặp XY (g2); from = g1; onLine = g3; at = g4 (optional).\n// \"Draw the perpendicular bisector …\" KHÔNG khớp: sau \"Draw\" là \"the\" (chữ\n// thường) chứ không phải cặp HOA → perpBisector territory, không double-emit.\n// groups: 1=from 2=foot 3=onLine 4=at(optional)\nconst PERP_DRAW_EN = new RegExp(\n `(?:[Dd]raw|[Cc]onstruct|[Dd]rop)\\\\s+([A-Z])([A-Z])(?![A-Z])\\\\s+perpendicular\\\\s+to\\\\s+(?:line\\\\s+|side\\\\s+|segment\\\\s+)?([A-Z]{1,2})(?![A-Z])(?:\\\\s+at\\\\s+([A-Z]))?`,\n 'gu',\n);\n\n// Tên foot ĐỨNG TRƯỚC core qua \"Let X be the …\" / \"X is the …\".\n// \"Let H be the projection …\" | \"K is the orthogonal projection …\"\nconst NAME_BEFORE_EN = /([A-Z])(?:[′'])?\\s+(?:be|is)\\s+(?:the\\s+)?$/u;\n\ninterface Foot {\n name: string;\n from: string;\n onLine: string;\n /** Emit thêm connect(from, foot) — đoạn vuông góc từ điểm tới chân. Dùng cho:\n * Form C (EN draw \"Draw AH ⊥ BC\") + distributive VN \"X,Y,Z hình chiếu của D…\"\n * (thể hiện hình chiếu DX/DY/DZ). Foot đơn VN KHÔNG set → byte-identical. */\n withSegment?: boolean;\n}\n\n/** Parse mọi foot trong 1 clause. Trả [] nếu không bind được tên / bị skip. */\nfunction parseFeet(text: string): Foot[] {\n const out: Foot[] = [];\n const consumed: Array<[number, number]> = [];\n\n // 0) Distributive SHARED-FROM: \"X, Y, Z lần lượt là hình chiếu/chân vuông góc\n // của D trên BC, CA, AB\" → zip tên↔cạnh (from D chung). Span đã khớp →\n // consumed để SINGLE không xử lại. Zip lệch (số tên ≠ số cạnh) → bỏ.\n for (const re of [DISTRIB_PROJ, DISTRIB_FOOT]) {\n re.lastIndex = 0;\n for (const dm of text.matchAll(re)) {\n const names = splitNames(dm[1]);\n const from = dm[2];\n const lines = dm[3].split(',').map((s) => s.trim()).filter(Boolean);\n if (names.length < 2 || names.length !== lines.length) continue; // zip lệch → escalate\n // withSegment: vẽ kèm đoạn vuông góc from→foot (DX/DY/DZ) để THỂ HIỆN hình\n // chiếu (render perpFoot chỉ tạo điểm chân, không tự vẽ đường rớt vuông góc).\n names.forEach((name, i) => out.push({ name, from, onLine: lines[i], withSegment: true }));\n consumed.push([dm.index ?? 0, (dm.index ?? 0) + dm[0].length]);\n }\n }\n\n // 1) \"X, Y lần lượt là … và …\" → 2 foot (name bind sẵn trong cú pháp).\n LANLUOT.lastIndex = 0;\n let lm: RegExpExecArray | null;\n while ((lm = LANLUOT.exec(text)) !== null) {\n if (MID_BEFORE.test(text.slice(0, lm.index))) continue; // \"trung điểm của …\" → skip\n const from1 = lm[3] ?? lm[5];\n const line1 = lm[4] ?? lm[6];\n out.push({ name: lm[1], from: from1, onLine: line1 });\n out.push({ name: lm[2], from: lm[7], onLine: lm[8] });\n consumed.push([lm.index, lm.index + lm[0].length]);\n }\n\n // 2) foot đơn — bind tên CỤC BỘ. Bỏ qua nếu nằm trong span \"lần lượt\" đã xử lý.\n SINGLE.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = SINGLE.exec(text)) !== null) {\n const start = m.index;\n if (consumed.some(([a, b]) => start >= a && start < b)) continue;\n const before = text.slice(0, start);\n if (MID_BEFORE.test(before)) continue; // \"trung điểm của hình chiếu …\" → đổi nghĩa\n const nm = NAME_BEFORE.exec(before);\n if (!nm) continue; // không có tên cục bộ → escalate AI\n out.push({ name: nm[1], from: m[1] ?? m[3], onLine: m[2] ?? m[4] });\n }\n\n // 3) \"Kẻ XY ⊥ LINE (tại Z)\" — tên foot lấy từ cặp XY (không cần \"X là\").\n PERP_DRAW.lastIndex = 0;\n let pm: RegExpExecArray | null;\n while ((pm = PERP_DRAW.exec(text)) !== null) {\n const from = pm[1];\n const foot = pm[2];\n const onLine = pm[3];\n const at = pm[4]; // \"tại Z\" (optional)\n if (at && at !== foot) continue; // \"tại K\" ≠ chân H → xung đột → escalate\n if (onLine.includes(foot)) continue; // chân trùng đỉnh của đường → degenerate\n out.push({ name: foot, from, onLine });\n }\n\n // 4) EN projection / foot-of — tên bind ĐỨNG TRƯỚC qua \"Let X be the …\"/\"X is\n // the …\". Không có tên-trước → escalate (fail-safe). \"trung điểm\" KHÔNG\n // áp dụng EN; MID_BEFORE giữ nguyên VN, ở đây không cần.\n SINGLE_EN.lastIndex = 0;\n let em: RegExpExecArray | null;\n while ((em = SINGLE_EN.exec(text)) !== null) {\n const before = text.slice(0, em.index);\n const nm = NAME_BEFORE_EN.exec(before);\n if (!nm) continue; // không có \"X be/is the\" → escalate AI\n const from = em[1] ?? em[3];\n const onLine = em[2] ?? em[4];\n out.push({ name: nm[1], from, onLine });\n }\n\n // 5) EN draw form \"Draw XY perpendicular to LINE (at Z)\" — foot = chữ 2 cặp XY.\n // connect.ts VN-only → tự emit connect(from, foot) để vẽ đoạn (parity VN).\n PERP_DRAW_EN.lastIndex = 0;\n let dm: RegExpExecArray | null;\n while ((dm = PERP_DRAW_EN.exec(text)) !== null) {\n const from = dm[1];\n const foot = dm[2];\n const onLine = dm[3];\n const at = dm[4]; // \"at Z\" (optional)\n if (at && at !== foot) continue; // \"at K\" ≠ chân H → xung đột → escalate\n if (onLine.includes(foot)) continue; // chân trùng đỉnh đường → degenerate\n out.push({ name: foot, from, onLine, withSegment: true });\n }\n return out;\n}\n\n/**\n * Mỗi clause → 0..n add-point perpFoot. Tên foot bind cục bộ theo cú pháp gần,\n * match global để dựng đủ (vd \"H, K lần lượt …\" = 2 foot).\n */\nexport const perpFootRule: LanguageRule = {\n id: 'perpFoot',\n priority: 65,\n languages: ['vi', 'en'],\n patterns: [PREFILTER, PREFILTER_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const feet = parseFeet(c.text);\n if (feet.length === 0) continue;\n // Foot add-point TRƯỚC; với EN draw form (withSegment) push THÊM connect\n // NGAY SAU add-point của foot đó (H phải tồn tại trước khi connect tham\n // chiếu). VN feet không set withSegment → byte-identical.\n const intents = feet.flatMap((f) => {\n const add = addPoint(f.name, { kind: 'perpFoot', from: f.from, onLine: f.onLine });\n return f.withSegment ? [add, connect(f.from, f.name, 'segment')] : [add];\n });\n out.push({ ruleId: 'perpFoot', clauseIds: [c.id], intents });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/circleRadius.ts\n//\n// Đường tròn theo TÂM: bán kính số / bán kính ký hiệu CHỮ / \"đi qua <điểm>\".\n// - \"đường tròn (tâm) O bán kính 3\" → centerRadius {center:'O', radius:3}\n// - \"(O; 3)\" / \"(O, 3)\" → centerRadius {center:'O', radius:3}\n// - \"(O; R)\" / \"(I; r)\" / \"bán kính R\" → centerRadius bán kính CANONICAL\n// (issue #46 nhóm A — xem dưới)\n// - \"đường tròn tâm O đi qua A\" → centerThrough {center:'O', through:'A'}\n//\n// CHỈ emit khi có bán kính SỐ, bán kính ký hiệu CHỮ (R/r), hoặc \"đi qua <điểm>\".\n// \"(O)\" trơ (không số/chữ/\"đi qua\") → bỏ qua (chỉ tham chiếu; rule khác/AI xử lý).\n//\n// BÁN KÍNH KÝ HIỆU CHỮ (issue #46): \"Cho đường tròn (O; R)\" cực phổ biến ở đề thi.\n// R là KÝ HIỆU (giá trị thực không cho) → vẽ với bán kính CANONICAL dương để minh\n// hoạ (fail-safe: không sai ngữ nghĩa — đường tròn tâm O bán kính tuỳ ý). CHỈ nhận\n// đúng [Rr] đứng riêng: hệ số \"2R\" (defer Cụm C) và chữ khác \"(A; B)\" → bỏ qua.\n//\n// GOTCHA segmentation: segmentClauses() tách trên '.' ';' ',' nên ký hiệu gọn\n// \"(O; 3)\" / \"(O, 2.5)\" BỊ cắt ngang clause (\"(O\" và \"3)\" thành 2 clause). Vì\n// vậy nhánh PAREN quét trên TOÀN đề (ctx.problem) rồi gán match cho clause chứa\n// fragment \"(<tâm>\". Nhánh WORDS / THROUGH segment nguyên vẹn → quét per-clause.\n//\n// GOTCHA \\b: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { Clause } from '../deterministic/coverage';\nimport { drawCircle, CIRCLE_KW } from './_shared';\n\n// \"đường tròn tâm O bán kính 3\" / \"(O) bán kính 3\" / \"O bán kính 3\".\n// Tâm 1 ký tự HOA; \"tâm\" optional; có thể bọc trong ngoặc \"(O)\".\n// Hỗ trợ PAREN tên chữ (alpha, omega...).\n//\n// GLOBAL (/gu) vì 1 clause có thể nêu NHIỀU đường tròn (\"tâm I bán kính 2 và\n// tâm O bán kính 5\" không có dấu câu tách → cùng clause). matchAll quét hết.\n//\n// Gap tâm→\"bán kính\" dùng tempered quantifier `(?:(?!đường|và\\s)[^A-Z])*?` để\n// KHÔNG nhảy qua một \"đường tròn\" khác hay liên từ \"và \" (ranh giới giữa 2 hình).\n// Nếu nhảy qua được, \"tâm O và … tâm I bán kính 5\" sẽ bind nhầm 5 vào O. Chặn ở\n// đây ⇒ match bắt đầu từ O thất bại, regex tự dời tới \"tâm I bán kính 5\" (đúng),\n// còn \"tâm O\" trơ (không số) không bị nuốt → không claim → escalate phần đó.\nconst CENTER_RADIUS_WORDS_G = new RegExp(\n CIRCLE_KW +\n '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?:\\\\s*\\\\))?(?:(?!đường|và\\\\s)[^A-Z])*?bán\\\\s*kính\\\\s+(\\\\d+(?:[.,]\\\\d+)?)',\n 'gu',\n);\n\n// \"đường tròn tâm O đi qua A\" / \"(O) đi qua A\" / \"O đi qua A\".\n// GLOBAL: nhiều \"đường tròn … đi qua …\" trong 1 clause.\nconst CENTER_THROUGH_G = new RegExp(\n CIRCLE_KW + '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?:\\\\s*\\\\))?\\\\s+đi\\\\s+qua\\\\s+([A-Z])',\n 'gu',\n);\n\n// Phần \"đi qua B và C\" (≥2 điểm surface): chưa hỗ trợ (DSL centerThrough 1 điểm).\n// Phát hiện để SKIP match đó → điểm thứ 2 (C) thiếu trong DSL → named-entity\n// guard escalate AI (an toàn) thay vì render thiếu C.\nconst THROUGH_MULTI = /đi\\s+qua\\s+[A-Z]\\s*(?:và|,)\\s*[A-Z]/u;\n\n// Ký hiệu gọn \"(O; 3)\" / \"(O, 3)\" — quét toàn đề (global) vì có thể nhiều.\nconst CENTER_RADIUS_PAREN_G = /\\(\\s*([A-Z])\\s*[;,]\\s*(\\d+(?:[.,]\\d+)?)\\s*\\)/gu;\n\n/**\n * Bán kính CANONICAL (board units) khi đề cho bán kính KÝ HIỆU CHỮ (\"(O; R)\",\n * \"bán kính R\"). Giá trị thực là ký hiệu → vẽ minh hoạ; khớp scale với bán kính\n * số mặc định nhỏ (vd \"(O; 3)\"). circleCR yêu cầu radius > 0.\n */\nexport const SYMBOLIC_RADIUS = 3;\n\n// Ký hiệu gọn bán kính CHỮ \"(O; R)\" / \"(I; r)\" — quét toàn đề. Bán kính CHỈ [Rr]\n// đứng RIÊNG (theo sau là ')'): \"2R\" (hệ số, defer) và chữ khác \"(A; B)\" KHÔNG\n// khớp → escalate (fail-safe). Center 1 ký tự HOA như nhánh số.\nconst CENTER_RADIUS_LETTER_PAREN_G = /\\(\\s*([A-Z])\\s*[;,]\\s*[Rr]\\s*\\)/gu;\n\n// \"đường tròn tâm O bán kính R\" — words, bán kính CHỮ. Mirror tempered của\n// CENTER_RADIUS_WORDS_G; (?![A-Za-z]) chặn \"Ra\"/\"Rồi\"… và phần số (\"2R\") để\n// nhánh số lo. GLOBAL: nhiều đường tròn / clause.\n// \"đường tròn tâm O bán kính R\" — words, bán kính CHỮ. Mirror tempered của\n// CENTER_RADIUS_WORDS_G; (?![A-Za-z]) chặn \"Ra\"/hệ số \"2R\" (nhánh số lo phần \"2\", nhưng \"radius 2R\"\n// hiếm; vẫn fail-safe vì \\d không có sau \"radius\" khi viết \"radius R\").\nconst CENTER_RADIUS_LETTER_WORDS_G = new RegExp(\n CIRCLE_KW +\n '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?:\\\\s*\\\\))?(?:(?!đường|và\\\\s)[^A-Z])*?bán\\\\s*kính\\\\s+[Rr](?![A-Za-z])',\n 'gu',\n);\n\n// === EN words patterns (issue #46 group B) ==================================\n// Tiền tố tâm EN dùng chung cho cả 3 dạng (radius số / radius CHỮ / passing\n// through). Chấp nhận: \"circle with center O\", \"circle centered at O\", \"circle\n// of center O\" + chính tả Anh-Anh \"centre\". cent(?:er|re) + (?:ed)? + (?:at|of)?\n// First-letter case flex [Cc] — KHÔNG cờ 'i' (sẽ phá [A-Z] tâm/điểm).\n//\n// Gap tâm→keyword: tempered `(?:(?![Cc]ircle)[^A-Z])*?` — KHÔNG nhảy qua \"circle\"\n// khác (ranh giới giữa 2 đường tròn) và KHÔNG nuốt chữ HOA (tâm/điểm kế). Lazy →\n// dừng ở \"radius\"/\"passing\" gần nhất. GLOBAL: nhiều đường tròn / clause.\nconst CIRCLE_CENTER_EN =\n '[Cc]ircle\\\\s+(?:with\\\\s+|of\\\\s+)?cent(?:er|re)(?:ed)?\\\\s+(?:at\\\\s+|of\\\\s+)?([A-Z])(?![A-Za-z])';\nconst EN_GAP = '(?:(?![Cc]ircle)[^A-Z])*?';\n\n// \"circle with center O and radius 3\" / \"circle centered at O with radius 3\" /\n// \"circle of center O radius 3\" → centerRadius số.\nconst CIRCLE_CR_EN_G = new RegExp(\n CIRCLE_CENTER_EN + EN_GAP + 'radius\\\\s+(\\\\d+(?:[.,]\\\\d+)?)',\n 'gu',\n);\n\n// \"circle with center O and radius R\" (bán kính CHỮ ký hiệu) → canonical.\n// (?![A-Za-z]) chặn \"Ra\"/hệ số \"2R\" (nhánh số lo phần \"2\", nhưng \"radius 2R\"\n// hiếm; vẫn fail-safe vì \\d không có sau \"radius\" khi viết \"radius R\").\nconst CIRCLE_CR_LETTER_EN_G = new RegExp(\n CIRCLE_CENTER_EN + EN_GAP + 'radius\\\\s+[Rr](?![A-Za-z])',\n 'gu',\n);\n\n// \"circle with center O passing through A\" / \"circle centered at O passing\n// through A\" → centerThrough. Điểm = 1 ký tự HOA neo (?![A-Za-z]).\nconst CIRCLE_THROUGH_EN_G = new RegExp(\n CIRCLE_CENTER_EN + EN_GAP + 'passing\\\\s+through\\\\s+([A-Z])(?![A-Za-z])',\n 'gu',\n);\n\n// Prefilter EN (NON-global để không vướng lastIndex ở .some(test)).\nconst EN_PREFILTER = new RegExp(CIRCLE_CENTER_EN, 'u');\n\n/** \"3\" / \"3.5\" / \"3,5\" → number. NaN nếu không parse được. */\nfunction parseNum(raw: string): number {\n return Number(raw.replace(',', '.'));\n}\n\n/**\n * Circle này là đường tròn NGOẠI/NỘI TIẾP tam giác? (\"tam giác ABC nội tiếp\n * đường tròn (O; 3)\") → circleTriangle sở hữu (through3/inscribedIn theo 3 đỉnh);\n * circleRadius KHÔNG emit thêm 1 đường tròn rời (sẽ chồng + không nhất quán).\n * Bán kính chỉ là chú thích — circumcircle xác định bởi 3 đỉnh, bỏ radius là OK.\n */\nfunction isInscribedCircumscribed(problem: string, center: string): boolean {\n // Quan hệ \"nội/ngoại tiếp\" (VN) + \"inscribed/circumscribes/circumscribed\" (EN,\n // issue #46 group B). EN mirror chống silent-WRONG: \"Triangle ABC inscribed in\n // circle (O; 3)\" — circleTriangle EN sở hữu through3 (qua 3 đỉnh) → circleRadius\n // KHÔNG emit centerRadius rời quanh O.\n const REL = '(?:(?:nội|ngoại)\\\\s*tiếp|[Ii]nscribed|[Cc]ircumscrib(?:es|ed))';\n // Chiều 1 — quan hệ ĐỨNG TRƯỚC circle: \"(tam giác) nội/ngoại tiếp … (O\".\n // Gap [^.]{0,30}? đủ nuốt \"in circle \" trước \"(O\" (EN).\n const after = new RegExp(\n `${REL}[^.]{0,30}?(?:đường\\\\s*tròn\\\\s*|[Cc]ircle\\\\s*)?\\\\(?\\\\s*${center}(?![A-Z])`,\n 'u',\n );\n // Chiều 2 — circle ĐỨNG TRƯỚC quan hệ: ký hiệu \"(O; R) … ngoại/nội tiếp\".\n // circleTriangle sở hữu circumcircle/incircle (qua 3 đỉnh) → circleRadius bỏ\n // để tránh DOUBLE-circle quanh O. [^()]* không vượt ngoặc khác; [^.]{0,30}?\n // không nhảy câu (giữ proximity, tránh false-positive với circle rời khác).\n const before = new RegExp(\n `\\\\(\\\\s*${center}\\\\s*[;,][^()]*\\\\)[^.]{0,30}?${REL}`,\n 'u',\n );\n return after.test(problem) || before.test(problem);\n}\n\n/** Clause chứa fragment \"(<center>\" (ký hiệu gọn bị segmentation cắt vào đây). */\nfunction findParenClauseId(\n clauses: readonly Clause[],\n center: string,\n): number | undefined {\n const frag = new RegExp(`\\\\(\\\\s*${center}(?![A-Z])`, 'u');\n for (const c of clauses) if (frag.test(c.text)) return c.id;\n return undefined;\n}\n\nexport const circleRadiusRule: LanguageRule = {\n id: 'circleRadius',\n priority: 75,\n languages: ['vi', 'en'],\n patterns: [\n CENTER_RADIUS_WORDS_G,\n CENTER_THROUGH_G,\n /\\(\\s*[A-Z]\\s*[;,]\\s*\\d/u,\n /\\(\\s*[A-Z]\\s*[;,]\\s*[Rr]\\s*\\)/u, // ký hiệu bán kính CHỮ \"(O; R)\"\n /bán\\s*kính\\s+[Rr](?![A-Za-z])/u, // words bán kính CHỮ \"bán kính R\"\n EN_PREFILTER, // EN \"circle with center O …\" (issue #46 group B)\n ],\n match(ctx) {\n const out: RuleMatch[] = [];\n\n // --- Per-clause: dạng \"bán kính <số>\" + \"đi qua <điểm>\" (segment nguyên) ---\n for (const c of ctx.clauses) {\n // 1) \"đi qua <điểm>\" (centerThrough). GLOBAL: nhiều đường tròn / clause.\n // \"đi qua B và C\" (≥2 điểm) → SKIP toàn bộ centerThrough clause này:\n // chưa hỗ trợ multi-surface-point, để guard escalate (không render thiếu).\n const throughMulti = THROUGH_MULTI.test(c.text);\n if (!throughMulti) {\n CENTER_THROUGH_G.lastIndex = 0;\n let ct: RegExpExecArray | null;\n while ((ct = CENTER_THROUGH_G.exec(c.text)) !== null) {\n const center = ct[1];\n const through = ct[2];\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerThrough', { center, through })],\n });\n }\n }\n\n // 2) \"bán kính <số>\". GLOBAL: \"tâm I bán kính 2 và tâm O bán kính 5\" emit\n // 2 intent. Gap tempered (xem CENTER_RADIUS_WORDS_G) ⇒ không bind nhầm.\n // radius CHỮ (\"R\") → \\d không match → bỏ qua → escalate.\n CENTER_RADIUS_WORDS_G.lastIndex = 0;\n let crw: RegExpExecArray | null;\n while ((crw = CENTER_RADIUS_WORDS_G.exec(c.text)) !== null) {\n const center = crw[1];\n const radius = parseNum(crw[2]);\n if (!Number.isFinite(radius) || radius <= 0) continue;\n if (isInscribedCircumscribed(ctx.problem, center)) continue; // circleTriangle sở hữu\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius })],\n });\n }\n\n // 3) \"bán kính R/r\" (bán kính CHỮ ký hiệu) → centerRadius bán kính canonical.\n // Clause có \"nội/ngoại tiếp\" → mơ hồ (circleTriangle/escalate sở hữu) → bỏ\n // (clause-local, không ảnh hưởng nhánh số ở clause khác).\n if (!/(?:nội|ngoại)\\s*tiếp/u.test(c.text)) {\n CENTER_RADIUS_LETTER_WORDS_G.lastIndex = 0;\n let clw: RegExpExecArray | null;\n while ((clw = CENTER_RADIUS_LETTER_WORDS_G.exec(c.text)) !== null) {\n const center = clw[1];\n if (isInscribedCircumscribed(ctx.problem, center)) continue;\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius: SYMBOLIC_RADIUS })],\n });\n }\n }\n\n // --- EN words (issue #46 group B) ---------------------------------------\n // Fail-safe: clause có \"inscribed\"/\"circumscribed\" → circle phụ thuộc\n // tam giác/hình (circleTriangle EN OUT OF SCOPE) → KHÔNG emit lone circle.\n if (!/[Ii]nscribed|[Cc]ircumscribed/u.test(c.text)) {\n // 1) passing through → centerThrough.\n CIRCLE_THROUGH_EN_G.lastIndex = 0;\n let ent: RegExpExecArray | null;\n while ((ent = CIRCLE_THROUGH_EN_G.exec(c.text)) !== null) {\n const center = ent[1];\n const through = ent[2];\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerThrough', { center, through })],\n });\n }\n\n // 2) radius <số> → centerRadius.\n CIRCLE_CR_EN_G.lastIndex = 0;\n let ecr: RegExpExecArray | null;\n while ((ecr = CIRCLE_CR_EN_G.exec(c.text)) !== null) {\n const center = ecr[1];\n const radius = parseNum(ecr[2]);\n if (!Number.isFinite(radius) || radius <= 0) continue;\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius })],\n });\n }\n\n // 3) radius R/r (ký hiệu CHỮ) → centerRadius canonical.\n CIRCLE_CR_LETTER_EN_G.lastIndex = 0;\n let ecl: RegExpExecArray | null;\n while ((ecl = CIRCLE_CR_LETTER_EN_G.exec(c.text)) !== null) {\n const center = ecl[1];\n out.push({\n ruleId: 'circleRadius',\n clauseIds: [c.id],\n intents: [drawCircle(center, 'centerRadius', { center, radius: SYMBOLIC_RADIUS })],\n });\n }\n }\n }\n\n // --- Toàn đề: ký hiệu gọn \"(O; 3)\" / \"(O, 3)\" (bị segmentation cắt) -------\n CENTER_RADIUS_PAREN_G.lastIndex = 0;\n let pm: RegExpExecArray | null;\n while ((pm = CENTER_RADIUS_PAREN_G.exec(ctx.problem)) !== null) {\n const center = pm[1];\n const radius = parseNum(pm[2]);\n if (!Number.isFinite(radius) || radius <= 0) continue;\n if (isInscribedCircumscribed(ctx.problem, center)) continue; // circleTriangle sở hữu\n const clauseId = findParenClauseId(ctx.clauses, center);\n out.push({\n ruleId: 'circleRadius',\n clauseIds: clauseId === undefined ? [] : [clauseId],\n intents: [drawCircle(center, 'centerRadius', { center, radius })],\n });\n }\n\n // --- Toàn đề: ký hiệu bán kính CHỮ \"(O; R)\" / \"(I; r)\" (segmenter cắt ';') ---\n // Bán kính ký hiệu → bán kính canonical. Guard 2 chiều bỏ qua khi đường tròn\n // nội/ngoại tiếp tam giác (circleTriangle sở hữu).\n CENTER_RADIUS_LETTER_PAREN_G.lastIndex = 0;\n let lpm: RegExpExecArray | null;\n while ((lpm = CENTER_RADIUS_LETTER_PAREN_G.exec(ctx.problem)) !== null) {\n const center = lpm[1];\n if (isInscribedCircumscribed(ctx.problem, center)) continue; // circleTriangle sở hữu\n const clauseId = findParenClauseId(ctx.clauses, center);\n out.push({\n ruleId: 'circleRadius',\n clauseIds: clauseId === undefined ? [] : [clauseId],\n intents: [drawCircle(center, 'centerRadius', { center, radius: SYMBOLIC_RADIUS })],\n });\n }\n\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/circleTriangle.ts\n//\n// Đường tròn nội/ngoại tiếp tam giác:\n// \"đường tròn ngoại tiếp tam giác ABC\" → circumcircle → drawCircle through3\n// \"đường tròn nội tiếp tam giác ABC\" → incircle → drawCircle inscribedIn\n//\n// LƯU Ý disambiguate \"nội tiếp\" có 2 nghĩa ngược nhau tuỳ ngữ cảnh:\n// - \"ĐƯỜNG TRÒN nội tiếp tam giác\" → incircle (inscribedIn)\n// - \"TAM GIÁC nội tiếp đường tròn\" → circumcircle (through3) — tam giác nội\n// tiếp tức đường tròn NGOẠI tiếp tam giác.\n// \"ngoại tiếp\" (đường tròn ngoại tiếp tam giác) luôn là circumcircle.\n//\n// QUAN TRỌNG (chống mis-render):\n// - \"đường tròn ngoại/nội tiếp\" PHẢI theo sau bởi \"tam giác <XYZ>\" (token \"tam\n// giác\" bắt buộc). Nếu theo sau là \"tứ giác\"/\"hình ...\" (vd \"đường tròn\n// ngoại tiếp tứ giác BCEF\") → CHƯA hỗ trợ → KHÔNG claim để escalate AI, KHÔNG\n// được vơ tam giác đầu đề (mis-render circle qua 3 đỉnh khác).\n// - Bind tam giác từ cụm ngay SAU từ khoá trong clause (không phải tam giác\n// đầu tiên trong đề). Nhiều cấu trúc / clause → emit-all (matchAll cờ 'g').\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawCircle, CIRCLE_KW } from './_shared';\n\n// \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Dùng lookaround \\p{L} + cờ 'u'.\nconst HAS_INSCRIBE = /(?<!\\p{L})(?:nội|ngoại)\\s*tiếp(?!\\p{L})/iu;\n\n// Tên tâm tuỳ chọn xen giữa \"đường tròn\" và \"ngoại/nội tiếp\": \"(O)\" hoặc \"tâm O\".\n// (?:...)? để có thể vắng. Cờ 'i' an toàn ở cụm từ khoá; ([A-Z]) vẫn HOA-only.\n// PAREN hỗ trợ cả tên chữ (alpha, omega, (O)...).\nconst CENTER = '(?:\\\\(\\\\s*([^\\\\s;,).:]+)\\\\s*\\\\)|tâm\\\\s+([A-Z]))?';\n\n// \"đường tròn [ (O)/tâm O ] ngoại tiếp tam giác XYZ\" → circumcircle (through3).\n// Token \"tam giác\" + 3 đỉnh HOA BẮT BUỘC ngay sau \"ngoại tiếp\". Cờ 'g' để bắt\n// MỌI cấu trúc trong clause; 'i' để hoa đầu câu (\"Đường\"/\"Ngoại\"/\"Tam\") cũng\n// khớp — nhưng group đỉnh ([A-Z]) KHÔNG dùng 'i' (regex 'i' không tác động lên\n// lớp ký tự đã chỉ định HOA → vẫn chỉ khớp HOA, tránh nuốt chữ thường).\nconst CIRCUM_TRI = new RegExp(\n CIRCLE_KW + '\\\\s*' +\n CENTER +\n '\\\\s*ngoại\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\n\n// \"đường tròn [ (I)/tâm I ] nội tiếp tam giác XYZ\" → incircle (inscribedIn).\nconst INCIRCLE_TRI = new RegExp(\n CIRCLE_KW + '\\\\s*' +\n CENTER +\n '\\\\s*nội\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\n\n// \"tam giác XYZ nội tiếp (trong) đường tròn [ (O)/tâm O ]\" → circumcircle.\n// Tam giác đứng TRƯỚC, đường tròn đứng SAU. Center (nếu có) đứng sau \"đường tròn\".\nconst TRI_INSCRIBED_IN_CIRCLE = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?nội\\\\s*tiếp\\\\s+(?:trong\\\\s+)?' +\n CIRCLE_KW +\n '\\\\s*' +\n CENTER,\n 'giu',\n);\n\n// \"tam giác XYZ ngoại tiếp đường tròn [ (I)/tâm I ]\" → incircle (inscribedIn).\n// Tam giác NGOẠI tiếp (circumscribes) đường tròn = đường tròn NỘI tiếp tam giác.\n// \"đường tròn\" BẮT BUỘC NGAY sau \"ngoại tiếp\" (KHÔNG optional) để phân biệt với\n// \"đường tròn ngoại tiếp tam giác\" (circumcircle — đường tròn đứng TRƯỚC, \"ngoại\n// tiếp\" theo sau bởi \"tam giác\"). [^.]{0,40}? không vượt dấu '.' (không nhảy câu).\nconst TRI_CIRCUMSCRIBES_CIRCLE = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?ngoại\\\\s*tiếp\\\\s+' +\n CIRCLE_KW +\n '\\\\s*' +\n CENTER,\n 'giu',\n);\n\n// Dạng TẮT: \"(O)\"/\"(I)\" NGAY sau \"nội/ngoại tiếp\" — KHÔNG có chữ \"đường tròn\"\n// (vd \"tam giác ABC nội tiếp (O)\"). Phổ biến ở đề olympiad; thiếu nhánh này thì\n// circumcircle O không được tạo → arcMidpoint tham chiếu O fail (transpile).\n// Paren BẮT BUỘC (1 ký tự HOA trong ngoặc) để KHÔNG over-match \"nội tiếp\" trần.\n// Phân biệt với TRI_INSCRIBED_IN_CIRCLE/TRI_CIRCUMSCRIBES_CIRCLE: ở đó sau \"tiếp\"\n// là \"đường tròn\" → 2 nhánh không chồng (dedup theo spec:tri vẫn an toàn nếu có).\nconst TRI_INSCRIBED_IN_PAREN = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?nội\\\\s*tiếp\\\\s+(?:trong\\\\s+)?\\\\(\\\\s*([A-Z])\\\\s*\\\\)',\n 'giu',\n);\nconst TRI_CIRCUMSCRIBES_PAREN = new RegExp(\n 'tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?ngoại\\\\s*tiếp\\\\s+\\\\(\\\\s*([A-Z])\\\\s*\\\\)',\n 'giu',\n);\n\n// --- Ký hiệu ngoặc \"(O; R)\" quét TOÀN ĐỀ (segmenter cắt ';') ------------------\n// \"(đường tròn)? (O; R) ngoại/nội tiếp tam giác XYZ\" — circle ĐỨNG TRƯỚC. R là\n// CHỮ (bán kính ký hiệu) nên circleRadius bỏ qua (cần \\d). Guard\n// (?![^)]*[A-Z]\\s*[;,]) chặn paren méo nhiều dấu chấm phẩy \"(A; B; C)\".\nconst PAREN_CENTER =\n '(?:' + CIRCLE_KW + '\\\\s*)?\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)\\\\s*';\nconst CIRCUM_TRI_PAREN = new RegExp(\n PAREN_CENTER + 'ngoại\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\nconst INCIRCLE_TRI_PAREN = new RegExp(\n PAREN_CENTER + 'nội\\\\s*tiếp\\\\s+tam\\\\s*giác\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])',\n 'giu',\n);\n\n// === EN patterns (issue #46 group B) ========================================\n// Semantics đối xứng VN. Phân biệt through3 (circumcircle) vs inscribedIn\n// (incircle) bằng SUBJECT (triangle/circle) + verb:\n// - triangle inscribed in circle → through3 (circle ngoại tiếp tam giác)\n// - triangle circumscribes/circumscribed about circle → inscribedIn (incircle)\n// - circle inscribed in triangle → inscribedIn (incircle)\n// - circle circumscribes/circumscribed about triangle → through3 (circumcircle)\n//\n// KHÔNG cờ 'i' (sẽ nuốt chữ thường vào group nhãn/center [A-Z]). First-letter\n// flex bằng [Tt]riangle / [Cc]ircle / [Ii]nscribed / [Cc]ircumscrib. Group\n// nhãn/center [A-Z] STRICT. Gap token = [^.]{0,N}? (non-greedy, không vượt '.').\n//\n// Center EN sau \"circle\": \"(O)\" (paren) hoặc bare \"O\" (neo (?![A-Za-z])).\nconst EN_CIRCLE_CENTER = '[Cc]ircle\\\\s+(?:\\\\(\\\\s*([A-Z])\\\\s*\\\\)|([A-Z])(?![A-Za-z]))';\nconst EN_TRI = '[Tt]riangle\\\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])';\n\n// SUBJECT=triangle + \"inscribed in\" circle → through3 (circumcircle).\n// \"triangle ABC (is)? inscribed in (the)? circle (O)\".\nconst EN_TRI_INSCRIBED_IN_CIRCLE = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n EN_CIRCLE_CENTER,\n 'gu',\n);\n\n// SUBJECT=triangle + \"circumscribes / circumscribed about|around\" circle → inscribedIn.\nconst EN_TRI_CIRCUMSCRIBES_CIRCLE = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n EN_CIRCLE_CENTER,\n 'gu',\n);\n\n// SUBJECT=circle + \"inscribed in\" triangle → inscribedIn (incircle).\nconst EN_CIRCLE_INSCRIBED_IN_TRI = new RegExp(\n EN_CIRCLE_CENTER +\n '[^.]{0,12}?[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// SUBJECT=circle + \"circumscribes / circumscribed about|around\" triangle → through3.\nconst EN_CIRCLE_CIRCUMSCRIBES_TRI = new RegExp(\n EN_CIRCLE_CENTER +\n '[^.]{0,12}?[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// --- EN paren whole-problem (segmenter cắt ';' trong \"(O; R)\") ----------------\n// Mirror VN PAREN: center \"(O\" bị cắt khỏi \"R)\". circle ĐỨNG TRƯỚC hoặc SAU.\n// Center = \"(\" + 1 ký tự HOA + \";\"/\",\" (KHÔNG đóng ngoặc cùng clause vì bị cắt).\n// Guard (?![^)]*[A-Z]\\s*[;,]) chặn paren méo nhiều dấu chấm phẩy.\nconst EN_PAREN_CIRCLE =\n '[Cc]ircle\\\\s+\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)\\\\s*';\n\n// \"triangle XYZ inscribed in circle (O; R)\" → through3.\nconst EN_TRI_INSCRIBED_PAREN = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n '[Cc]ircle\\\\s+\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)',\n 'gu',\n);\n\n// \"circle (O; R) circumscribes triangle XYZ\" → through3.\nconst EN_PAREN_CIRCLE_CIRCUMSCRIBES_TRI = new RegExp(\n EN_PAREN_CIRCLE +\n '[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// \"circle (I; r) inscribed in triangle XYZ\" → inscribedIn.\nconst EN_PAREN_CIRCLE_INSCRIBED_TRI = new RegExp(\n EN_PAREN_CIRCLE +\n '[Ii]nscribed\\\\s+in\\\\s+(?:the\\\\s+)?' +\n EN_TRI,\n 'gu',\n);\n\n// \"triangle XYZ circumscribes circle (I; r)\" → inscribedIn.\nconst EN_TRI_CIRCUMSCRIBES_PAREN = new RegExp(\n EN_TRI +\n '[^.]{0,12}?[Cc]ircumscrib(?:es|ed)\\\\s+(?:about\\\\s+|around\\\\s+)?' +\n '[Cc]ircle\\\\s+\\\\(\\\\s*([A-Z])\\\\s*[;,]\\\\s*(?![^)]*[A-Z]\\\\s*[;,])[^()]*?\\\\)',\n 'gu',\n);\n\n// Prefilter EN (NON-global cho .test). Chỉ \"inscribed\"/\"circumscrib\" mới quan tâm.\nconst HAS_INSCRIBE_EN = /[Ii]nscribed|[Cc]ircumscrib/u;\n\ninterface CircHit {\n index: number;\n spec: 'through3' | 'inscribedIn';\n tri: [string, string, string];\n /** tên tâm; '' nếu không khai báo (default 'O' khi emit). */\n center: string;\n}\n\nfunction pushAll(\n text: string,\n re: RegExp,\n spec: 'through3' | 'inscribedIn',\n // index của 3 group đỉnh trong match; center luôn group 1+2.\n triStart: number,\n out: CircHit[],\n): void {\n re.lastIndex = 0;\n for (const m of text.matchAll(re)) {\n const center = m[1] ?? m[2] ?? '';\n out.push({\n index: m.index ?? 0,\n spec,\n tri: [m[triStart], m[triStart + 1], m[triStart + 2]],\n center,\n });\n }\n}\n\n/**\n * Quét MỌI cấu trúc \"(đường tròn) ngoại/nội tiếp tam giác XYZ\" trong 1 clause.\n * Vùng text [start,end) đã thuộc 1 cấu trúc thì cấu trúc khác bỏ qua (tránh\n * trùng — \"tam giác XYZ nội tiếp đường tròn\" KHÔNG bị INCIRCLE_TRI quét lại).\n */\nfunction scanClause(text: string): CircHit[] {\n const hits: CircHit[] = [];\n // CIRCUM_TRI / INCIRCLE_TRI: center là group 1|2, đỉnh là group 3,4,5.\n pushAll(text, CIRCUM_TRI, 'through3', 3, hits);\n pushAll(text, INCIRCLE_TRI, 'inscribedIn', 3, hits);\n // TRI_INSCRIBED_IN_CIRCLE: đỉnh là group 1,2,3, center là group 4|5.\n TRI_INSCRIBED_IN_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(TRI_INSCRIBED_IN_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'through3',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n // TRI_CIRCUMSCRIBES_CIRCLE: tam giác ngoại tiếp đường tròn → incircle (inscribedIn).\n TRI_CIRCUMSCRIBES_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(TRI_CIRCUMSCRIBES_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'inscribedIn',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n // Dạng tắt \"(O)\"/\"(I)\" không kèm \"đường tròn\": center là group 4.\n TRI_INSCRIBED_IN_PAREN.lastIndex = 0;\n for (const m of text.matchAll(TRI_INSCRIBED_IN_PAREN)) {\n hits.push({ index: m.index ?? 0, spec: 'through3', tri: [m[1], m[2], m[3]], center: m[4] ?? '' });\n }\n TRI_CIRCUMSCRIBES_PAREN.lastIndex = 0;\n for (const m of text.matchAll(TRI_CIRCUMSCRIBES_PAREN)) {\n hits.push({ index: m.index ?? 0, spec: 'inscribedIn', tri: [m[1], m[2], m[3]], center: m[4] ?? '' });\n }\n\n // --- EN (issue #46 group B) ---------------------------------------------\n // SUBJECT=triangle (group 1,2,3) → center group 4|5.\n EN_TRI_INSCRIBED_IN_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(EN_TRI_INSCRIBED_IN_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'through3',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n EN_TRI_CIRCUMSCRIBES_CIRCLE.lastIndex = 0;\n for (const m of text.matchAll(EN_TRI_CIRCUMSCRIBES_CIRCLE)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'inscribedIn',\n tri: [m[1], m[2], m[3]],\n center: m[4] ?? m[5] ?? '',\n });\n }\n // SUBJECT=circle (center group 1|2) → triangle group 3,4,5.\n EN_CIRCLE_INSCRIBED_IN_TRI.lastIndex = 0;\n for (const m of text.matchAll(EN_CIRCLE_INSCRIBED_IN_TRI)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'inscribedIn',\n tri: [m[3], m[4], m[5]],\n center: m[1] ?? m[2] ?? '',\n });\n }\n EN_CIRCLE_CIRCUMSCRIBES_TRI.lastIndex = 0;\n for (const m of text.matchAll(EN_CIRCLE_CIRCUMSCRIBES_TRI)) {\n hits.push({\n index: m.index ?? 0,\n spec: 'through3',\n tri: [m[3], m[4], m[5]],\n center: m[1] ?? m[2] ?? '',\n });\n }\n\n // Khử trùng: 2 hit cùng 3 đỉnh + cùng spec → giữ 1 (vd câu vừa khớp\n // CIRCUM_TRI lẫn TRI_INSCRIBED_IN_CIRCLE hiếm khi xảy ra, nhưng an toàn).\n const seen = new Set<string>();\n const dedup: CircHit[] = [];\n hits.sort((a, b) => a.index - b.index);\n for (const h of hits) {\n const key = `${h.spec}:${h.tri.join('')}`;\n if (seen.has(key)) continue;\n seen.add(key);\n dedup.push(h);\n }\n return dedup;\n}\n\ninterface ParenHit {\n spec: 'through3' | 'inscribedIn';\n tri: [string, string, string];\n center: string;\n /** text khớp trên TOÀN đề (để gán clauseId qua substring-inclusion). */\n matchedText: string;\n}\n\n/**\n * Quét TOÀN đề cho ký hiệu ngoặc \"(O; R) ngoại/nội tiếp tam giác XYZ\" — dạng bị\n * segmenter cắt ngang ';' nên per-clause không bắt được. circle ĐỨNG TRƯỚC.\n */\nfunction scanProblemParen(problem: string): ParenHit[] {\n const out: ParenHit[] = [];\n const push = (re: RegExp, spec: 'through3' | 'inscribedIn') => {\n re.lastIndex = 0;\n for (const m of problem.matchAll(re)) {\n out.push({\n spec,\n tri: [m[2], m[3], m[4]],\n center: m[1] ?? '',\n matchedText: m[0],\n });\n }\n };\n push(CIRCUM_TRI_PAREN, 'through3');\n push(INCIRCLE_TRI_PAREN, 'inscribedIn');\n\n // --- EN (issue #46 group B): center group khác vị trí tuỳ SUBJECT ----------\n // SUBJECT=triangle (group 1,2,3) → center group 4.\n const pushTriFirst = (re: RegExp, spec: 'through3' | 'inscribedIn') => {\n re.lastIndex = 0;\n for (const m of problem.matchAll(re)) {\n out.push({ spec, tri: [m[1], m[2], m[3]], center: m[4] ?? '', matchedText: m[0] });\n }\n };\n pushTriFirst(EN_TRI_INSCRIBED_PAREN, 'through3');\n pushTriFirst(EN_TRI_CIRCUMSCRIBES_PAREN, 'inscribedIn');\n // SUBJECT=circle (center group 1) → triangle group 2,3,4.\n push(EN_PAREN_CIRCLE_CIRCUMSCRIBES_TRI, 'through3');\n push(EN_PAREN_CIRCLE_INSCRIBED_TRI, 'inscribedIn');\n return out;\n}\n\nfunction intentFor(spec: 'through3' | 'inscribedIn', tri: string[], center: string) {\n const name = center || 'O';\n return spec === 'inscribedIn'\n ? drawCircle(name, 'inscribedIn', { triangle: tri })\n : drawCircle(name, 'through3', { points: tri });\n}\n\n/**\n * Mỗi clause: quét emit-all các \"(đường tròn) nội/ngoại tiếp tam giác XYZ\".\n * - circumcircle (through3): \"đường tròn ngoại tiếp tam giác ABC\",\n * \"tam giác ABC nội tiếp đường tròn (O)\".\n * - incircle (inscribedIn): \"đường tròn nội tiếp tam giác ABC\",\n * \"tam giác ABC ngoại tiếp đường tròn (I)\".\n * Cộng nhánh TOÀN đề cho ký hiệu \"(O; R) ngoại/nội tiếp tam giác\" (bị cắt ';').\n * \"ngoại/nội tiếp\" mà KHÔNG có \"tam giác XYZ\" ngay sau (vd \"tứ giác\", \"hình\n * ...\", hoặc \"nội tiếp\" trần) → KHÔNG claim → escalate AI.\n */\nexport const circleTriangleRule: LanguageRule = {\n id: 'circleTriangle',\n priority: 72,\n languages: ['vi', 'en'],\n patterns: [HAS_INSCRIBE, HAS_INSCRIBE_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n const emitted = new Set<string>(); // \"spec:tri\" — dedup cross per-clause/paren.\n\n // 1) Per-clause (VN giữ nguyên hành vi cũ; EN thêm qua HAS_INSCRIBE_EN).\n for (const c of ctx.clauses) {\n if (!HAS_INSCRIBE.test(c.text) && !HAS_INSCRIBE_EN.test(c.text)) continue;\n const hits = scanClause(c.text);\n if (hits.length === 0) continue; // có \"ngoại/nội tiếp\" nhưng không tam giác\n for (const h of hits) emitted.add(`${h.spec}:${h.tri.join('')}`);\n out.push({\n ruleId: 'circleTriangle',\n clauseIds: [c.id],\n intents: hits.map((h) => intentFor(h.spec, h.tri, h.center)),\n });\n }\n\n // 2) Toàn đề: ký hiệu \"(O; R)\" (segmenter cắt ';'). Bỏ qua nếu (spec:tri) đã\n // emit ở per-clause. clauseId = mọi clause là substring của đoạn khớp\n // (đoạn này trải qua nhiều clause do bị cắt) → coverage tính phủ cả 2.\n for (const h of scanProblemParen(ctx.problem)) {\n const key = `${h.spec}:${h.tri.join('')}`;\n if (emitted.has(key)) continue;\n emitted.add(key);\n const clauseIds = ctx.clauses\n .filter((c) => h.matchedText.includes(c.text))\n .map((c) => c.id);\n out.push({\n ruleId: 'circleTriangle',\n clauseIds,\n intents: [intentFor(h.spec, h.tri, h.center)],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/tangentFromExt.ts\n//\n// Tiếp tuyến TỪ điểm NGOÀI đường tròn (2 nhánh):\n// \"Kẻ hai tiếp tuyến từ A đến (O)\" → drawLine(t, tangentFromExt, {from:'A', circle:'O', which:'both'})\n// \"Vẽ tiếp tuyến từ điểm A tới đường tròn O\" → drawLine(t, tangentFromExt, {from:'A', circle:'O', which:'both'})\n// \"Từ A vẽ tiếp tuyến với (O)\" → drawLine(t, tangentFromExt, {from:'A', circle:'O', which:'both'})\n//\n// Phân biệt với tangentAt (\"tiếp tuyến TẠI A của (O)\") — chỗ đó dùng \"tại\",\n// còn ở đây là \"từ <điểm ngoài>\". Rule này CHỈ match \"từ\"/\"Từ ... vẽ tiếp tuyến\".\n//\n// GOTCHA: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\n// from / circle là 1 ký tự HOA; name của line default 't' (LabelZ cho phép).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawLine, addPoint } from './_shared';\n\n// Prefilter toàn đề: phải có \"tiếp tuyến\".\nconst HAS_TANGENT = /tiếp\\s*tuyến/u;\n\n// Target đường tròn: PHẢI có dấu hiệu đường tròn — \"(X)\" hoặc \"đường tròn X\".\n// KHÔNG nhận chữ HOA TRẦN (vd \"tiếp tuyến từ A đến BC\": \"BC\" là đoạn thẳng, không\n// phải đường tròn → không claim, escalate). Hai alternative → 2 capture nhóm,\n// caller lấy nhóm nào khớp.\nconst CIRCLE_TARGET = String.raw`(?:đường\\s*tròn\\s*([A-Z])(?:['′]?)|\\(\\s*([A-Z])(?:['′]?)\\s*\\))`;\n\n// \"(kẻ|vẽ) (hai)? tiếp tuyến từ (điểm)? A (đến|tới|với) <đường tròn>\"\n// - động từ kẻ/vẽ BẮT BUỘC: chặn ngữ cảnh TÍNH/giả thiết (\"Độ dài tiếp tuyến\n// từ A đến (O) bằng 5\" → không có kẻ/vẽ → không match, escalate).\n// - \"hai\"/\"một\" optional (1 hay 2 nhánh vẫn coi là tiếp tuyến từ điểm ngoài).\n// - from = 1 ký tự HOA sau \"từ (điểm)?\".\n// - giới từ đến/tới/với nối qua đường tròn (bắt buộc có dấu hiệu — CIRCLE_TARGET).\nconst FROM_FORM = new RegExp(\n String.raw`(?:[Kk]ẻ|[Vv]ẽ)\\s+(?:một\\s+|hai\\s+)?tiếp\\s*tuyến\\s+từ\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)\\s+(?:đến|tới|với)\\s+` +\n CIRCLE_TARGET,\n 'u',\n);\n\n// Biến thể đảo: \"Từ (điểm)? A ... (kẻ|vẽ) (hai)? tiếp tuyến (đến|tới|với) <đường tròn>\".\n// - kẻ|vẽ vẫn bắt buộc (đã có sẵn trong cú pháp đảo).\nconst TU_FORM = new RegExp(\n String.raw`(?<!\\p{L})[Tt]ừ\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)(?!\\p{L})[^.]{0,40}?(?:[Kk]ẻ|[Vv]ẽ)\\s+(?:một\\s+|hai\\s+)?tiếp\\s*tuyến\\s+(?:đến|tới|với)\\s+` +\n CIRCLE_TARGET,\n 'u',\n);\n\n// === EN patterns (issue #46 group B) ========================================\n// Target đường tròn EN: \"(X)\" (language-agnostic, giống VN) HOẶC \"circle X\" /\n// \"circle (X)\". KHÔNG nhận chữ HOA TRẦN (\"from A to BC\": BC là đoạn → không\n// claim → escalate). Hai alternative → 2 capture nhóm (caller lấy nhóm nào khớp).\n// - nhóm 1: ([A-Z]) sau \"circle\" (có thể bọc \"(...)\").\n// - nhóm 2: ([A-Z]) trong \"(...)\" trần (không từ \"circle\").\n// First-letter flex [Cc]; KHÔNG cờ 'i' (giữ [A-Z] strict cho nhãn).\nconst CIRCLE_TARGET_EN = String.raw`(?:[Cc]ircle\\s*\\(?\\s*([A-Z])(?:['′]?)\\s*\\)?|\\(\\s*([A-Z])(?:['′]?)\\s*\\))`;\n\n// \"(Draw|Construct) (the|two)? tangent(s)? (lines)? from (the)? A to (the)? <circle>\"\n// - động từ Draw/Construct BẮT BUỘC: chặn ngữ cảnh TÍNH (\"The length of the\n// tangent from A to (O) is 5\" → không có Draw/Construct → không match,\n// escalate). Mirror ràng buộc verb của FROM_FORM (VN).\n// - giới từ \"from <A> to <circle>\" BẮT BUỘC: phân biệt với tangentAt\n// (\"tangent ... at A\" → không có \"from ... to\" → không match ở đây).\n// - from = 1 ký tự HOA sau \"from (the)?\".\n// - circle bắt buộc có dấu hiệu (CIRCLE_TARGET_EN — \"(X)\" hoặc \"circle X\").\n// GROUP INDEX: from = nhóm 1; circle = nhóm 2 (\"circle X\") HOẶC nhóm 3 (\"(X)\").\nconst FROM_FORM_EN = new RegExp(\n String.raw`(?:[Dd]raw|[Cc]onstruct)\\s+(?:the\\s+|two\\s+|the\\s+two\\s+)?tangents?(?:\\s+lines?)?\\s+from\\s+(?:the\\s+)?([A-Z])(?:['′]?)\\s+to\\s+(?:the\\s+)?` +\n CIRCLE_TARGET_EN,\n 'u',\n);\n\n// Biến thể đảo EN: \"From (the)? A, ... (draw|construct) (the|two)? tangent(s)?\n// (lines)? to (the)? <circle>\".\n// - verb draw/construct vẫn bắt buộc (nằm sau \"From A\").\n// - \"from A ... to <circle>\" vẫn đầy đủ (from ở đầu, to trước circle).\n// GROUP INDEX: from = nhóm 1; circle = nhóm 2 (\"circle X\") HOẶC nhóm 3 (\"(X)\").\nconst FROM_INV_EN = new RegExp(\n String.raw`(?<![A-Za-z])[Ff]rom\\s+(?:the\\s+)?([A-Z])(?:['′]?)(?![A-Za-z])[^.]{0,40}?(?:[Dd]raw|[Cc]onstruct)\\s+(?:the\\s+|two\\s+|the\\s+two\\s+)?tangents?(?:\\s+lines?)?\\s+to\\s+(?:the\\s+)?` +\n CIRCLE_TARGET_EN,\n 'u',\n);\n\n// === NAMED tangent points (issue #46) =======================================\n// \"Vẽ hai tiếp tuyến AB, AC từ A đến (O)\" — B, C LÀ tiếp điểm (named). Khác với\n// nhánh UNNAMED ở trên (regex unnamed FAIL vì \"AB, AC\" chen giữa \"tiếp tuyến\" và\n// \"từ\"). Hai regex dưới bắt 2 đoạn tiếp tuyến + đường tròn trong 1 match.\n// GROUP INDEX (cả VN & EN): m[1]=chữ đầu đoạn 1 (điểm ngoài x1),\n// m[2]=tiếp điểm 1 (B), m[3]=chữ đầu đoạn 2 (x2), m[4]=tiếp điểm 2 (C),\n// m[5]/m[6] = circle (qua CIRCLE_TARGET / CIRCLE_TARGET_EN).\nconst NAMED_FROM_VN = new RegExp(\n String.raw`(?:[Kk]ẻ|[Vv]ẽ)\\s+(?:một\\s+|hai\\s+)?tiếp\\s*tuyến\\s+([A-Z])([A-Z])\\s*(?:,|và)\\s*([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?(?:đến|tới|với)\\s+` +\n CIRCLE_TARGET,\n 'u',\n);\nconst NAMED_FROM_EN = new RegExp(\n String.raw`(?:[Dd]raw|[Cc]onstruct)\\s+(?:the\\s+|two\\s+|the\\s+two\\s+)?tangents?(?:\\s+lines?)?\\s+([A-Z])([A-Z])\\s*(?:,|and)\\s*([A-Z])([A-Z])(?![A-Z])[^.]{0,40}?to\\s+(?:the\\s+)?` +\n CIRCLE_TARGET_EN,\n 'u',\n);\n\nexport const tangentFromExtRule: LanguageRule = {\n id: 'tangentFromExt',\n priority: 65,\n languages: ['vi', 'en'],\n // EN prefilter \"tangent\" để runRules (prefilter qua patterns[], bỏ qua\n // languages) chạy match() cho đề EN thuần (không có \"tiếp tuyến\").\n patterns: [HAS_TANGENT, /[Tt]angent/u],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n // === NAMED tangent points (issue #46): \"tiếp tuyến AB, AC ... (O)\" → dựng\n // tiếp điểm B,C (tangentPointExt) cộng với 2 tiếp tuyến. from = chữ cái đầu\n // CHUNG của 2 đoạn (điểm ngoài); tiếp điểm = chữ cái thứ 2 mỗi đoạn.\n const named = NAMED_FROM_VN.exec(c.text) ?? NAMED_FROM_EN.exec(c.text);\n if (named) {\n const from = named[1];\n const tpB = named[2];\n const x2 = named[3];\n const tpC = named[4];\n const circle = named[5] ?? named[6];\n // Hợp lệ: cùng điểm ngoài (m1===m3), 2 tiếp điểm phân biệt & khác điểm ngoài.\n if (\n circle && from === x2 &&\n tpB !== from && tpC !== from && tpB !== tpC\n ) {\n out.push({\n ruleId: 'tangentFromExt',\n clauseIds: [c.id],\n intents: [\n drawLine('t', 'tangentFromExt', { from, circle, which: 'both' }),\n addPoint(tpB, { kind: 'tangentPoint', from, circle, which: 0 }),\n addPoint(tpC, { kind: 'tangentPoint', from, circle, which: 1 }),\n ],\n });\n continue; // clause handled — skip unnamed path\n }\n // not valid named form → fall through to unnamed logic (will likely escalate)\n }\n // VN trước (FROM_FORM / TU_FORM), giữ nguyên hành vi cũ; EN sau (FROM_FORM_EN\n // / FROM_INV_EN). circle bắt qua 1 trong các alternative capture group.\n const m =\n FROM_FORM.exec(c.text) ??\n TU_FORM.exec(c.text) ??\n FROM_FORM_EN.exec(c.text) ??\n FROM_INV_EN.exec(c.text);\n if (!m) continue;\n const from = m[1];\n // circle bắt qua 1 trong 2 alternative:\n // VN: \"đường tròn X\" = m[2], \"(X)\" = m[3].\n // EN: \"circle X\" = m[2], \"(X)\" = m[3] (cùng index — cả 2 dạng đều có\n // circle ở nhóm 2/3 vì from luôn là nhóm 1, CIRCLE_TARGET(_EN) có 2\n // alternative nhóm 2 & 3).\n const circle = m[2] ?? m[3];\n // Không xác định được from hoặc circle → bỏ qua (escalate AI).\n if (!from || !circle) continue;\n out.push({\n ruleId: 'tangentFromExt',\n clauseIds: [c.id],\n intents: [\n drawLine('t', 'tangentFromExt', { from, circle, which: 'both' }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/externalPoint.ts\n//\n// Điểm nằm NGOÀI đường tròn (free external point):\n// \"Lấy điểm A nằm ngoài đường tròn (O)\" → addPoint(A, {externalToCircle, circle:'O'})\n// \"Lấy điểm A ở ngoài (O)\" → addPoint(A, {externalToCircle, circle:'O'})\n// \"Gọi A là điểm nằm ngoài (O)\" → addPoint(A, {externalToCircle, circle:'O'})\n// \"Take a point A outside the circle (O).\" (EN) → addPoint(A, {externalToCircle, circle:'O'})\n//\n// Mục đích: UNBLOCK tangentFromExt render END-TO-END. tangentFromExt emit\n// drawLine(from:'A', circle:'O') nhưng KHÔNG rule nào dựng điểm A ngoài circle\n// → transpile UNKNOWN_REF A → escalate. Rule này dựng A (qua builder\n// externalToCircle, đọc tâm+bán kính từ build state, đặt A free ngoài circle).\n//\n// PRIORITY 68: sau circleRadius (75) / circleTriangle (72) để circle build\n// TRƯỚC, trước tangentFromExt (65) để A build TRƯỚC tangent. Build order:\n// circle → A → tangent (đúng phụ thuộc).\n//\n// GOTCHA \\b: ký tự Việt \"ngoài\" → KHÔNG dùng \\b. Cờ 'u' cho mọi regex.\n// `[^.A-Z]` giữa name và \"ngoài\"/\"outside\" chặn nhảy qua nhãn HOA khác / dấu chấm.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// VN: \"(Lấy|Gọi) (điểm)? A ... ngoài (đường tròn (X) | (X))\".\n// - from = nhóm 1 (1 ký tự HOA).\n// - circle = nhóm 2 (\"đường tròn X\") HOẶC nhóm 3 (\"(X)\").\n// - [^.A-Z]{0,14}? cho \"nằm\"/\"ở\" chen giữa, chặn dấu chấm / nhãn HOA khác.\nconst VN_FORM = new RegExp(\n String.raw`(?:[Ll]ấy|[Gg]ọi)\\s+(?:điểm\\s+)?([A-Z])(?:['′]?)[^.A-Z]{0,14}?ngoài\\s+(?:đường\\s*tròn\\s*\\(?\\s*([A-Z])\\s*\\)?|\\(\\s*([A-Z])\\s*\\))`,\n 'u',\n);\n\n// EN: \"(Take|Let|Mark|Choose|Pick) (a)? (point)? A ... outside (the)? (circle (X) | (X))\".\n// - from = nhóm 1; circle = nhóm 2 (\"circle X\") HOẶC nhóm 3 (\"(X)\").\n// - [^.A-Z]{0,24}? cho \"be a point\"/\"nằm\" chen giữa, chặn dấu chấm / nhãn HOA.\nconst EN_FORM = new RegExp(\n String.raw`(?:[Tt]ake|[Ll]et|[Mm]ark|[Cc]hoose|[Pp]ick)\\s+(?:a\\s+)?(?:point\\s+)?([A-Z])(?:['′]?)[^.A-Z]{0,24}?outside\\s+(?:the\\s+)?(?:[Cc]ircle\\s*\\(?\\s*([A-Z])\\s*\\)?|\\(\\s*([A-Z])\\s*\\))`,\n 'u',\n);\n\nexport const externalPointRule: LanguageRule = {\n id: 'externalPoint',\n priority: 68,\n languages: ['vi', 'en'],\n // Prefilter toàn đề (runRules prefilter qua patterns[], BỎ QUA languages):\n // cần bắt cả VN (\"ngoài\") lẫn EN (\"outside\"). match() mới có regex chặt.\n patterns: [/ngoài/u, /[Oo]utside/u],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const m = VN_FORM.exec(c.text) ?? EN_FORM.exec(c.text);\n if (!m) continue;\n const from = m[1];\n const circle = m[2] ?? m[3];\n if (!from || !circle) continue; // escalate-safe\n out.push({\n ruleId: 'externalPoint',\n clauseIds: [c.id],\n intents: [addPoint(from, { kind: 'externalToCircle', circle })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/arcMidpoint.ts\n//\n// Điểm chính giữa cung: \"Gọi M là điểm chính giữa cung BC (không chứa A)\".\n// → add-point M {kind:'arcMidpoint', circle:'O', a:'B', b:'C', notContaining:'A'}\n//\n// circle lấy từ toàn đề (\"(O)\" / \"đường tròn (tâm) O\"); KHÔNG có circle → bỏ qua\n// (escalate AI — không thể dựng cung mà không biết đường tròn).\n//\n// notContaining (PHẢI là đỉnh thứ 3, ∉ {a,b}):\n// - \"không chứa X\" → X (chỉ nhận nếu X ∉ {a,b}; X∈{a,b} vô nghĩa → bỏ qua)\n// - không nêu nhưng có tam giác → đỉnh thứ 3 (đỉnh tam giác không thuộc cặp cung)\n// - cả hai đều không suy được → bỏ qua (escalate)\n//\n// CHỈ xử lý cú pháp \"cung (nhỏ)? <PAIR> không chứa <Z>\" (containment ÂM, cung nhỏ).\n// Vượt scope → bỏ qua (escalate, an toàn — đừng mis-render):\n// - \"cung lớn <PAIR>\" → cung lớn, ngữ nghĩa cung đối → defer\n// - \"chứa X\" (containment DƯƠNG, không có \"không\" đứng trước) → defer\n//\n// Tên điểm qua extractPointName / ký tự HOA trước \"(là) điểm chính giữa\"; không\n// trích được tên → bỏ qua (đừng bịa tên).\n//\n// EN (issue #46 group B): hỗ trợ thêm các dạng tiếng Anh tương đương —\n// \"Let M be the midpoint of arc BC not containing A\"\n// \"M is the midpoint of the (minor) arc BC\" (suy notContaining từ \"Triangle ABC\")\n// \"major arc\" → defer (mirror \"cung lớn\"); \"containing X\" dương → defer.\n// Tên điểm EN qua \"X is/be the midpoint of … arc\" (extractPointName là VN-only).\n// Collision midpoint EN (rule prio 50): KHÔNG xảy ra — midpoint EN cần\n// \"midpoint of (segment|side)? [A-Z][A-Z]\", nhưng sau \"of\" ở đây là \"arc\" (chữ\n// thường) → [A-Z] fail → midpoint không grab \"BC\".\n//\n// GOTCHA \\b: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\",\"ạ\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { addPoint, drawCircle, extractPointName, pairFromToken } from './_shared';\n\n// Prefilter toàn đề: \"chính giữa cung\" hoặc \"trung điểm cung\".\nconst ARC_MID = /(?:chính\\s+giữa|trung\\s*điểm)\\s+(?:của\\s+)?cung/u;\n\n// Cụm cung + cặp đỉnh: \"điểm chính giữa cung (nhỏ|lớn) BC\".\n// \"nhỏ|lớn\" optional; \"của\" optional. Cặp đỉnh = 2 ký tự HOA liền.\nconst ARC_PAIR =\n /(?:chính\\s+giữa|trung\\s*điểm)\\s+(?:của\\s+)?cung\\s+(?:nhỏ\\s+|lớn\\s+)?([A-Z])([A-Z])/u;\n\n// Tên điểm đứng TRƯỚC cụm: \"M (là) (điểm) (chính giữa|trung điểm) cung\".\nconst NAME_BEFORE =\n /([A-Z])(?:['′]?)\\s+(?:là\\s+)?(?:điểm\\s+)?(?:chính\\s+giữa|trung\\s*điểm)\\s+(?:của\\s+)?cung/u;\n\n// \"không chứa X\" → X.\nconst NOT_CONTAINING = /không\\s+chứa\\s+([A-Z])/u;\n\n// Tam giác trong toàn đề → 3 đỉnh (dùng suy notContaining khi đề không nêu).\nconst TRI = /tam giác\\s+([A-Z])([A-Z])([A-Z])/u;\n\n// Tên đường tròn trong toàn đề: \"đường tròn (tâm) O\" / \"(O)\".\n// - \"đường tròn tâm O\" / \"đường tròn O\" → O\n// - \"(O)\" đứng riêng (1 ký tự HOA trong ngoặc, không phải cặp đỉnh / số)\nconst CIRCLE_WORDS = /đường\\s*tròn\\s*(?:\\(\\s*)?(?:tâm\\s+)?([A-Z])(?![A-Z])/u;\nconst CIRCLE_PAREN = /\\(\\s*([A-Z])\\s*\\)/u;\n\n// === EN patterns (issue #46 group B) =========================================\n// First-letter case-flex [Mm]/[Tt]; KHÔNG cờ 'i' (phá nhãn [A-Z]). Nhãn STRICT\n// [A-Z] + neo (?![A-Za-z]) cuối cặp đỉnh (chặn \"BCD\" 3 chữ → escalate-safe).\n// Prefilter EN: \"midpoint of (the)? (minor|major)? arc\".\nconst ARC_MID_EN = /[Mm]idpoint\\s+of\\s+(?:the\\s+)?(?:minor\\s+|major\\s+)?arc/u;\n// Cụm cung + cặp đỉnh EN.\nconst ARC_PAIR_EN =\n /[Mm]idpoint\\s+of\\s+(?:the\\s+)?(?:minor\\s+|major\\s+)?arc\\s+([A-Z])([A-Z])(?![A-Za-z])/u;\n// Tên đứng TRƯỚC: \"M is/be the midpoint of arc\". (EN không có lời dẫn VN; extractPointName VN-only.)\nconst NAME_BEFORE_EN =\n /([A-Z])(?:['′]?)\\s+(?:is|be)\\s+the\\s+midpoint\\s+of\\s+(?:the\\s+)?(?:minor\\s+|major\\s+)?arc/u;\n// \"not containing (the)? (point|vertex)? X\".\nconst NOT_CONTAINING_EN = /not\\s+containing\\s+(?:the\\s+)?(?:point\\s+|vertex\\s+)?([A-Z])(?![A-Za-z])/u;\n// Tam giác EN (suy notContaining khi không nêu \"not containing\").\nconst TRI_EN = /[Tt]riangle\\s+([A-Z])([A-Z])([A-Z])(?![A-Za-z])/u;\n// Scope guard: \"major arc\" → defer (mirror VN \"cung lớn\").\nconst MAJOR_ARC_EN = /major\\s+arc/u;\n\n/** Tên đường tròn từ toàn đề; undefined nếu không tìm thấy. */\nfunction resolveCircle(problem: string): string | undefined {\n const w = CIRCLE_WORDS.exec(problem);\n if (w) return w[1];\n const p = CIRCLE_PAREN.exec(problem);\n if (p) return p[1];\n return undefined;\n}\n\n/**\n * Tên cho circumcircle NGẦM (khi đề không nêu \"(O)\"): ưu tiên 'O' (quy ước), né\n * nếu đã là token HOA đứng riêng trong đề (vd điểm O); else 'O1'/'O2'/'W'.\n */\nfunction synthCircleName(problem: string): string {\n for (const cand of ['O', 'O1', 'O2', 'W']) {\n if (!new RegExp(`(?<!\\\\p{L})${cand}(?![\\\\p{L}\\\\d])`, 'u').test(problem)) return cand;\n }\n return 'O'; // fallback (resolveCircleNameCollisions sẽ dedup nếu cần)\n}\n\n/**\n * \"Gọi M là điểm chính giữa cung nhỏ BC không chứa A\" → add-point M\n * {kind:'arcMidpoint', circle, a:'B', b:'C', notContaining:'A'}.\n *\n * Một clause khớp khi: trích được tên điểm, cặp đỉnh cung, đường tròn, và\n * notContaining (nêu \"không chứa X\" hoặc suy từ đỉnh thứ 3 của tam giác). Thiếu\n * bất kỳ thành phần nào → bỏ qua clause (escalate AI thay vì đoán sai).\n */\nexport const arcMidpointRule: LanguageRule = {\n id: 'arcMidpoint',\n priority: 60,\n languages: ['vi', 'en'],\n patterns: [ARC_MID, ARC_MID_EN],\n match(ctx) {\n const explicitCircle = resolveCircle(ctx.problem);\n const tri = TRI.exec(ctx.problem);\n const triEnM0 = TRI_EN.exec(ctx.problem);\n // Tam giác để suy circumcircle NGẦM khi đề KHÔNG nêu \"(O)\" (VN ưu tiên, EN fallback).\n const circumTri: string[] | null = tri\n ? [tri[1], tri[2], tri[3]]\n : triEnM0\n ? [triEnM0[1], triEnM0[2], triEnM0[3]]\n : null;\n // \"(O)\" tường minh thắng; else circumcircle ngầm của tam giác (tên synth).\n const circle = explicitCircle ?? (circumTri ? synthCircleName(ctx.problem) : undefined);\n if (!circle) return []; // không circle tường minh + không tam giác → escalate\n const usesCircum = !explicitCircle;\n\n const out: RuleMatch[] = [];\n // Khi dùng circumcircle ngầm, prepend drawCircle(through3) vào arcMidpoint ĐẦU\n // TIÊN dùng nó → circle emit TRƯỚC điểm (transpile resolve ref theo thứ tự).\n let circumEmitted = false;\n const withCircum = (ap: IntentT): IntentT[] => {\n if (usesCircum && !circumEmitted && circumTri) {\n circumEmitted = true;\n return [drawCircle(circle, 'through3', { points: circumTri }), ap];\n }\n return [ap];\n };\n // Circumcircle ngầm chỉ hợp lệ khi 2 đầu mút cung LÀ đỉnh tam giác.\n const arcOnCircum = (a: string, b: string): boolean =>\n !usesCircum || (!!circumTri && circumTri.includes(a) && circumTri.includes(b));\n\n for (const c of ctx.clauses) {\n if (!ARC_MID.test(c.text)) continue;\n\n // Vượt scope (chỉ xử lý \"cung (nhỏ) PAIR không chứa Z\"):\n // - \"cung lớn\" → cung đối, defer → escalate\n // - \"chứa X\" containment DƯƠNG (không có \"không\" trước) → defer → escalate\n if (/cung\\s+lớn/u.test(c.text)) continue;\n if (/chứa/u.test(c.text) && !/không\\s+chứa/u.test(c.text)) continue;\n\n const pairM = ARC_PAIR.exec(c.text);\n if (!pairM) continue;\n const pair = pairFromToken(pairM[1] + pairM[2]);\n if (pair.length !== 2) continue;\n const [a, b] = pair;\n if (!arcOnCircum(a, b)) continue; // circumcircle ngầm: cung phải là 2 đỉnh tam giác\n\n // Tên điểm: lời dẫn \"Gọi/Lấy X là …\" ưu tiên, fallback HOA trước cụm.\n const before = NAME_BEFORE.exec(c.text);\n const name = extractPointName(c.text) ?? (before ? before[1] : undefined);\n if (!name) continue; // không trích được tên → bỏ qua\n\n // notContaining: \"không chứa X\" hoặc đỉnh thứ 3 của tam giác.\n let notContaining: string | undefined;\n const nc = NOT_CONTAINING.exec(c.text);\n if (nc) {\n notContaining = nc[1];\n // notContaining = endpoint của cung (a/b) → vô nghĩa hình học → escalate.\n if (notContaining === a || notContaining === b) continue;\n } else if (tri) {\n const verts = [tri[1], tri[2], tri[3]];\n notContaining = verts.find((v) => v !== a && v !== b);\n }\n if (!notContaining) continue; // không suy được → bỏ qua\n\n out.push({\n ruleId: 'arcMidpoint',\n clauseIds: [c.id],\n intents: withCircum(addPoint(name, { kind: 'arcMidpoint', circle, a, b, notContaining })),\n });\n }\n\n // --- EN (issue #46 group B) ---------------------------------------------------\n // Tam giác EN để suy notContaining (đỉnh thứ 3) khi đề không nêu \"not containing\".\n const triEnVerts = triEnM0 ? [triEnM0[1], triEnM0[2], triEnM0[3]] : undefined;\n\n for (const c of ctx.clauses) {\n if (!ARC_MID_EN.test(c.text)) continue;\n // Vượt scope (mirror VN): \"major arc\" → cung đối, defer → escalate.\n if (MAJOR_ARC_EN.test(c.text)) continue;\n // \"containing X\" DƯƠNG (không có \"not\" trước) → defer → escalate.\n if (/containing/u.test(c.text) && !/not\\s+containing/u.test(c.text)) continue;\n\n const pairM = ARC_PAIR_EN.exec(c.text);\n if (!pairM) continue;\n const pair = pairFromToken(pairM[1] + pairM[2]);\n if (pair.length !== 2) continue;\n const [a, b] = pair;\n if (!arcOnCircum(a, b)) continue; // circumcircle ngầm: cung phải là 2 đỉnh tam giác\n\n // Tên điểm: \"M is/be the midpoint of arc\" (HOA trước). Không có → bỏ qua.\n const before = NAME_BEFORE_EN.exec(c.text);\n const name = before ? before[1] : undefined;\n if (!name) continue;\n\n // notContaining: \"not containing X\" tường minh, hoặc đỉnh thứ 3 của tam giác EN.\n let notContaining: string | undefined;\n const nc = NOT_CONTAINING_EN.exec(c.text);\n if (nc) {\n notContaining = nc[1];\n if (notContaining === a || notContaining === b) continue; // endpoint cung → vô nghĩa\n } else if (triEnVerts) {\n notContaining = triEnVerts.find((v) => v !== a && v !== b);\n }\n if (!notContaining) continue;\n\n out.push({\n ruleId: 'arcMidpoint',\n clauseIds: [c.id],\n intents: withCircum(addPoint(name, { kind: 'arcMidpoint', circle, a, b, notContaining })),\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/excenter.ts\n//\n// Tâm đường tròn bàng tiếp (excenter): \"J là tâm bàng tiếp góc A\".\n// → add-point J {kind:'excenter', of:['A','B','C'], opposite:'A'}\n//\n// excenter cần BỘ 3 đỉnh tam giác (of) + ĐỈNH ĐỐI DIỆN (opposite — góc mà đường\n// tròn bàng tiếp ứng với). DSL/intent/render đã support; rule này chỉ lo NLU.\n//\n// Tam giác: nêu trong clause → lấy; else tam giác DUY NHẤT toàn đề; nhập nhằng /\n// không có → bỏ qua (escalate). Đỉnh đối PHẢI thuộc tam giác (else escalate).\n//\n// Tên tâm: ký tự HOA đứng TRƯỚC \"(là) tâm (đường tròn)? bàng tiếp\" (cục bộ, KHÔNG\n// quét lời dẫn toàn clause). Không trích được tên → bỏ qua (đừng bịa).\n//\n// KHÔNG dùng extractPointName (_shared) ở đây: NAME_LA của nó dùng `là\\b` (ASCII\n// \\b sau 'à' không khớp) nên không bắt được \"X là …\". Rule tự neo qua NAME_BEFORE.\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt. Regex chứa ký\n// tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\n//\n// Chỉ dựng ĐIỂM tâm (excenter). \"Vẽ đường tròn bàng tiếp\" (excircle) chưa có\n// intent path → clause không đặt tên tâm sẽ KHÔNG match → escalate (an toàn).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// Prefilter toàn đề.\nconst EXCENTER_KW = /bàng\\s*tiếp/u;\n\n// Tam giác (1 lần) trong 1 đoạn text.\nconst TRI = /tam\\s*giác\\s+([A-Z])([A-Z])([A-Z])/u;\nconst TRI_G = /tam\\s*giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// Đỉnh đối diện: \"bàng tiếp (trong)? (góc|đỉnh|ứng với (đỉnh)?|đối diện (đỉnh)?) X\".\nconst OPPOSITE =\n /bàng\\s*tiếp\\s+(?:trong\\s+)?(?:góc|đỉnh|ứng\\s+với(?:\\s+đỉnh)?|đối\\s+diện(?:\\s+đỉnh)?)\\s+([A-Z])(?!\\p{L})/u;\n\n// Tên tâm đứng TRƯỚC: \"J (là)? tâm (của)? (đường tròn)? bàng tiếp\".\nconst NAME_BEFORE =\n /([A-Z])(?:['′]?)\\s+(?:là\\s+)?(?:tâm\\s+)?(?:(?:của\\s+)?đường\\s*tròn\\s+)?bàng\\s*tiếp/u;\n\n/**\n * of=[A,B,C] cho 1 clause: ưu tiên tam giác nêu trong clause; else tam giác DUY\n * NHẤT toàn đề (dedup theo bộ đỉnh). Nhiều tam giác khác nhau / không có →\n * undefined (escalate).\n */\nfunction resolveTriangleOf(clauseText: string, problem: string): string[] | undefined {\n const inClause = TRI.exec(clauseText);\n if (inClause) return [inClause[1], inClause[2], inClause[3]];\n TRI_G.lastIndex = 0;\n const all: string[] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) all.push(m[1] + m[2] + m[3]);\n const distinct = new Set(all);\n if (distinct.size === 1) {\n const t = all[0];\n return [t[0], t[1], t[2]];\n }\n return undefined;\n}\n\n/**\n * \"J là tâm bàng tiếp góc A\" → add-point J {kind:'excenter', of:[A,B,C], opposite:'A'}.\n * Thiếu đỉnh đối / tam giác / tên → bỏ qua clause (escalate AI thay vì đoán sai).\n */\nexport const excenterRule: LanguageRule = {\n id: 'excenter',\n priority: 60,\n languages: ['vi'],\n patterns: [EXCENTER_KW],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!EXCENTER_KW.test(c.text)) continue;\n\n const oppM = OPPOSITE.exec(c.text);\n if (!oppM) continue; // không xác định đỉnh đối → escalate\n const opposite = oppM[1];\n\n const of = resolveTriangleOf(c.text, ctx.problem);\n if (!of) continue; // không có/nhập nhằng tam giác → escalate\n if (!of.includes(opposite)) continue; // đỉnh đối phải thuộc tam giác\n\n const nameM = NAME_BEFORE.exec(c.text);\n const name = nameM ? nameM[1] : undefined;\n if (!name) continue; // không trích được tên → bỏ qua (đừng bịa)\n\n out.push({\n ruleId: 'excenter',\n clauseIds: [c.id],\n intents: [addPoint(name, { kind: 'excenter', of, opposite })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/parallelPerp.ts\n//\n// Đường thẳng QUA 1 điểm, song song / vuông góc với 1 đường (cặp đỉnh):\n// \"Qua A kẻ đường thẳng song song với BC\" → draw-line parallelThrough A→BC\n// \"Từ A vẽ đường thẳng vuông góc với BC\" → draw-line perpThrough A→BC\n//\n// Phân biệt với perpFoot (\"Kẻ AH vuông góc BC\" → chân H): rule này BẮT BUỘC mở\n// đầu \"Qua/Từ <P>\" (P = điểm đường thẳng đi qua, KHÔNG sinh chân). perpFoot\n// không có tiền tố \"Qua/Từ\" nên 2 rule không chồng.\n//\n// Tên line không nêu trong đề → synthesize (\"parA\"/\"prpA\"); guard chỉ track điểm\n// HOA nên line name không bị đòi. Nếu đề có \"cắt … tại N\" (giao điểm) → phần đó\n// KHÔNG được claim → coverage/guard escalate (an toàn) thay vì dựng thiếu N.\n//\n// GOTCHA \\b: dùng (?!\\p{L}) + cờ 'u' quanh ký tự Việt.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawLine } from './_shared';\n\n// \"Qua/Từ <P> [kẻ/vẽ/dựng đường thẳng (d)] song song|vuông góc [với] [cạnh|đoạn] <PAIR>\".\n// group1 = through point; group2 = kind keyword; group3+4 = cặp đỉnh đường tham chiếu.\n// [^.]{0,24}? bắc cầu cụm \"kẻ đường thẳng (d) \" nhưng KHÔNG vượt dấu '.'.\nconst RE = new RegExp(\n '(?:Qua|qua|Từ|từ)\\\\s+(?:điểm\\\\s+)?([A-Z])(?:[\\'′]?)(?!\\\\p{L})' +\n '[^.]{0,24}?(song\\\\s*song|vuông\\\\s*góc)\\\\s+(?:với\\\\s+)?(?:cạnh\\\\s+|đoạn(?:\\\\s+thẳng)?\\\\s+)?' +\n '([A-Z])([A-Z])(?!\\\\p{L})',\n 'gu',\n);\n\n// Prefilter toàn đề (NON-global cho .test).\nconst PREFILTER =\n /(?:Qua|qua|Từ|từ)\\s+(?:điểm\\s+)?[A-Z][^.]{0,24}?(?:song\\s*song|vuông\\s*góc)/u;\n\nexport const parallelPerpRule: LanguageRule = {\n id: 'parallelPerp',\n priority: 58,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n RE.lastIndex = 0;\n for (const m of c.text.matchAll(RE)) {\n const through = m[1];\n const isParallel = /song/.test(m[2]);\n const to = m[3] + m[4];\n // Song song với đường CHỨA chính điểm qua → trùng đường đó (degenerate) → bỏ.\n if (isParallel && to.includes(through)) continue;\n const kind = isParallel ? 'parallelThrough' : 'perpThrough';\n const name = (isParallel ? 'par' : 'prp') + through;\n out.push({\n ruleId: 'parallelPerp',\n clauseIds: [c.id],\n intents: [drawLine(name, kind, { through, to })],\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/reflection.ts\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, extractPointName } from './_shared';\n\n// LƯU Ý: \\b của JS dựa trên ASCII word-char nên KHÔNG khớp quanh ký tự Việt\n// (\"đ\",\"ề\"…). Mọi regex chứa ký tự Việt dùng cờ 'u' + tránh \\b.\n\n// Prefilter toàn đề: \"đối xứng\" (cho phép viết liền \"đốixứng\" hiếm gặp → giữ \\s*).\nconst REFLECT = /đối\\s*xứng/u;\n\n// Dạng A: tên điểm ĐỨNG TRƯỚC.\n// \"D đối xứng (với) H qua BC\"\n// \"D là (điểm) đối xứng (của|với) H qua (đường thẳng|cạnh|trục) <Z>\"\n// Z bắt mở (chữ cái + dấu phẩy/′), phân loại điểm/đường ở dưới.\nconst NAME_BEFORE =\n /([A-Z])(?:['′]?)\\s+(?:là\\s+)?(?:điểm\\s+)?đối\\s*xứng\\s+(?:của\\s+|với\\s+)?([A-Z])(?:['′]?)\\s+qua\\s+(?:đường\\s*thẳng\\s+|cạnh\\s+|đoạn\\s+|trục\\s+|trung\\s*điểm\\s+|điểm\\s+)?([A-Za-z][A-Za-z′']?)/u;\n\n// Dạng B: KHÔNG có tên dẫn trước \"đối xứng\" (lấy tên từ lời dẫn \"Gọi/Lấy …\").\n// \"Gọi D là điểm đối xứng của H qua BC\"\n// \"Lấy điểm đối xứng của H qua M\"\nconst NAME_AFTER =\n /(?:điểm\\s+)?đối\\s*xứng\\s+(?:của\\s+|với\\s+)?([A-Z])(?:['′]?)\\s+qua\\s+(?:đường\\s*thẳng\\s+|cạnh\\s+|đoạn\\s+|trục\\s+|trung\\s*điểm\\s+|điểm\\s+)?([A-Za-z][A-Za-z′']?)/u;\n\n// === EN (issue #46 group B) ===\n// \"<Name> is/be the reflection of <Of> (over|across|in|about|through) (the)? (line|point|segment)? <Z>\"\n// Name đứng TRƯỚC (qua \"is\"/\"be the\" — gồm \"Let D be the reflection...\"). KHÔNG cờ 'i'.\n// (?<![A-Za-z]) đảm bảo Name là nhãn đơn. Z phân loại bằng classifyThrough (reuse).\nconst REFLECT_EN =\n /(?<![A-Za-z])([A-Z])(?:['′]?)\\s+(?:is|be)\\s+the\\s+reflection\\s+of\\s+([A-Z])(?:['′]?)\\s+(?:over|across|in|about|through)\\s+(?:the\\s+)?(?:line\\s+|point\\s+|segment\\s+)?([A-Za-z][A-Za-z′']?)/u;\nconst REFLECT_EN_PRE = /[Rr]eflection/u;\n\n// Phân loại token Z (đã strip dấu phẩy/′):\n// \"M\" → điểm (1 ký tự HOA) → reflectPoint\n// \"BC\" → đường (cặp 2 ký tự HOA) → reflectLine\n// \"d\" → đường (tên đường, chữ thường) → reflectLine\nfunction classifyThrough(raw: string): { kind: 'point' | 'line'; value: string } | undefined {\n const z = raw.replace(/['′]/gu, '').trim();\n if (/^[A-Z]$/u.test(z)) return { kind: 'point', value: z };\n if (/^[A-Z][A-Z]$/u.test(z)) return { kind: 'line', value: z };\n // tên đường thẳng chữ thường (d, d1, a, xy…) → đường\n if (/^[a-z][A-Za-z0-9]*$/u.test(z)) return { kind: 'line', value: z };\n return undefined;\n}\n\n/**\n * Đối xứng (Cụm A reflection):\n * \"D đối xứng H qua BC\" → reflectLine (qua ĐƯỜNG: cặp đỉnh BC / tên đường d)\n * \"Q đối xứng P qua M\" → reflectPoint (qua ĐIỂM: 1 ký tự HOA)\n * \"D là điểm đối xứng của H qua đường thẳng d\" → reflectLine (through='d')\n *\n * name (điểm ảnh) = ký tự HOA đứng trước \"đối xứng\" (dạng A) hoặc lời dẫn\n * \"Gọi/Lấy …\" (dạng B). of = điểm gốc (X). through = Z, phân loại bằng\n * classifyThrough. Không trích đủ name / of / through hợp lệ → BỎ QUA clause\n * (đừng bịa tên) để pipeline escalate AI.\n */\nexport const reflectionRule: LanguageRule = {\n id: 'reflection',\n priority: 55,\n languages: ['vi', 'en'],\n patterns: [REFLECT, REFLECT_EN_PRE],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!REFLECT.test(c.text) && !REFLECT_EN_PRE.test(c.text)) continue;\n\n let name: string | undefined;\n let of: string | undefined;\n let throughRaw: string | undefined;\n\n const before = NAME_BEFORE.exec(c.text);\n if (before) {\n name = before[1];\n of = before[2];\n throughRaw = before[3];\n } else {\n const after = NAME_AFTER.exec(c.text);\n if (after) {\n // Không có tên đứng trước → lấy từ lời dẫn (\"Gọi D là …\").\n name = extractPointName(c.text);\n of = after[1];\n throughRaw = after[2];\n } else {\n // --- EN (issue #46 group B) — chỉ chạy khi cả 2 dạng VN fail. ---\n const en = REFLECT_EN.exec(c.text);\n if (en) {\n name = en[1];\n of = en[2];\n throughRaw = en[3];\n }\n }\n }\n\n if (!name || !of || !throughRaw) continue;\n\n const through = classifyThrough(throughRaw);\n if (!through) continue;\n\n const constraint =\n through.kind === 'point'\n ? { kind: 'reflectPoint', of, through: through.value }\n : { kind: 'reflectLine', of, through: through.value };\n\n out.push({\n ruleId: 'reflection',\n clauseIds: [c.id],\n intents: [addPoint(name, constraint)],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/pointAtDistance.ts\n//\n// Constraint METRIC: điểm trên tia kéo dài, cách mốc một khoảng cho trước.\n// C = through + d · unit(through − from) (xem spec 2026-06-06-point-at-distance)\n//\n// Phrasing phủ:\n// - \"trên tia đối của tia BA, lấy (điểm)? C sao cho BC = R\"\n// tia đối của tia BA = tia từ B ngược hướng A ⇒ hướng A→B kéo dài.\n// ⇒ from = A, through = B, điểm mới C nằm NGOÀI B.\n// - \"kéo dài AB (về phía B) lấy C sao cho BC = R\"\n// ⇒ from = A, through = B.\n// - EN (issue #46 group B):\n// \"On ray XY extended beyond Y, take D such that YD = …\" ⇒ from=X, through=Y.\n// \"Extend XY beyond Y to D such that YD = …\" ⇒ from=X, through=Y.\n// \"On the opposite ray of ray XY, take D such that XD …\" ⇒ from=Y, through=X.\n//\n// Hướng suy từ thứ tự token (from→through), KHÔNG cần field thừa. Điểm mốc đo\n// khoảng cách (through) trùng đỉnh đầu của cụm \"YZ = ...\" (Y = through, Z = tên\n// điểm mới). Ta dùng chính cặp này để chốt hướng + nguồn distance.\n//\n// distance (3 nguồn — discriminated union):\n// \"= R\" / \"= bán kính\" / \"= bán kính (O)\" → {kind:'circleRadius', circle}\n// \"= AB\" / \"= MN\" (2 ký tự HOA) → {kind:'segmentLength', p1, p2}\n// \"= 3\" / \"= 2,5\" / \"= 2 cm\" → {kind:'literal', value}\n//\n// GOTCHA \\b: \\b của JS dựa ASCII word-char nên KHÔNG khớp quanh ký tự Việt.\n// Mọi regex chứa ký tự Việt dùng cờ 'u' + lookaround \\p{L}.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// LƯU Ý: KHÔNG dùng cờ 'i' — nó làm [A-Z] khớp cả chữ thường, hỏng việc trích\n// tên điểm (đỉnh là CHỮ HOA). Clause có thể bắt đầu bằng chữ HOA (\"Kéo dài…\",\n// \"Trên tia đối…\") nên chữ cái đầu từ-khoá tiếng Việt dùng alternation [Kk]/[Tt].\n// --- Prefilter (toàn đề) ------------------------------------------------------\nconst KEYWORD = /(?:[Kk]éo\\s*dài|tia\\s*đối)/u;\n\n// --- Trigger trên clause ------------------------------------------------------\n// \"trên tia đối của tia BA\" → cặp [B, A] (B = gốc tia, A = hướng cũ). Hướng kéo\n// dài là tia đối ⇒ from = A, through = B.\nconst TIA_DOI =\n /tia\\s*đối\\s+của\\s+tia\\s+([A-Z])([A-Z])(?![A-Z])/u;\n// \"kéo dài AB\" → cặp [A, B]. Mặc định lấy điểm về phía B (đỉnh cuối) ⇒ from = A,\n// through = B. (\"về phía A\" hiếm + cần re-map; defer → bỏ qua để escalate.)\nconst KEO_DAI =\n /[Kk]éo\\s*dài\\s+(?:(?:đoạn|cạnh|tia)\\s+)?([A-Z])([A-Z])(?![A-Z])/u;\n\n// \"lấy (điểm)? C sao cho\" / \"lấy C\" / \"lấy C′\" → tên điểm mới (CAPTURE prime).\n// Issue #46 nhóm A: prime (' U+0027 / ′ U+2032) là PHẦN của tên — giữ lại để\n// \"C′\" ≠ đỉnh \"C\" (tránh addPoint dedup drop → escalate). Group 2 = prime char.\nconst TAKE_POINT =\n /lấy\\s+(?:điểm\\s+)?([A-Z])(['′]?)(?![A-Z])/u;\n\n// Normalize prime về 1 dạng: ′ (U+2032) → ' (U+0027). NameZ/serialize NAME_REGEX\n// cho phép ' nhưng KHÔNG cho phép ′ → chuẩn hoá để name \"C'\" chảy qua DSL/render\n// (label) không cần đổi schema. Trả về tên đầy đủ (chữ + prime đã normalize).\nfunction normalizePointName(letter: string, prime: string): string {\n return prime ? `${letter}'` : letter;\n}\n\n// \"về phía X\": hướng kéo dài. Mặc định through = đỉnh cuối cụm. Nếu \"về phía X\"\n// mà X KHÁC through (vd \"kéo dài AB về phía A\") → hướng đảo, rule không xử lý\n// đúng (defer) → skip để escalate.\nconst VE_PHIA = /về\\s+phía\\s+([A-Z])(?![A-Za-z])/u;\n\n// === EN (issue #46 group B) ==================================================\n// Additive — KHÔNG đụng building block VN ở trên. Nhãn STRICT [A-Z] (KHÔNG cờ\n// 'i' — sẽ nuốt chữ thường); first-letter flex của verb bằng [Ee]/[Tt]/[Mm]/…\n//\n// EN prefilter (runRules tests `patterns` against whole problem, IGNORING the\n// `languages` field — so an EN regex is REQUIRED here for EN-only problems to\n// reach match()). Broad but match() validates precisely → safe.\nconst PREFILTER_EN = /beyond|opposite\\s+ray/i;\n\n// \"ray XY extended beyond Z\" → ray X→Y extended past Z. from=X, through=Y;\n// require Z===Y (you extend past the FAR endpoint). Comma before \"extended\" ok.\nconst RAY_EXTENDED_EN =\n /ray\\s+([A-Z])([A-Z])(?![A-Z])\\s*,?\\s*extended\\s+beyond\\s+([A-Z])(?![A-Z])/u;\n// \"extend(ed)? (segment|line|side)? XY beyond Z\" (no \"ray\"). from=X, through=Y;\n// require Z===Y.\nconst EXTEND_SEG_EN =\n /[Ee]xtend(?:ed)?\\s+(?:segment\\s+|line\\s+|side\\s+)?([A-Z])([A-Z])(?![A-Z])\\s+beyond\\s+([A-Z])(?![A-Z])/u;\n// \"opposite ray of ray XY\" → mirror VN tia đối: from=Y(2nd), through=X(1st).\nconst OPPOSITE_RAY_EN =\n /opposite\\s+ray\\s+of\\s+ray\\s+([A-Z])([A-Z])(?![A-Z])/u;\n\n// New-point name (EN). \"take/mark/choose/pick D\" or \"to D\" (phrasing \"extend AB\n// beyond B TO D\"). Lookbehind (?<![A-Za-z]) stops \"to\" matching inside words\n// (into, photo). NO `i` flag — capture is [A-Z]; first-letter flex per verb.\n// group 1 = letter, group 2 = prime (mirror VN TAKE_POINT).\nconst TAKE_POINT_EN =\n /(?<![A-Za-z])(?:[Tt]ake|[Mm]ark|[Cc]hoose|[Pp]ick|to)\\s+(?:a\\s+|the\\s+)?(?:point\\s+)?([A-Z])(['′]?)(?![A-Z])/u;\n\n// Cụm chốt mốc + khoảng cách: \"BC = R\" / \"BC = AB\" / \"BC = 3\" / \"BC = 2,5 cm\".\n// Đỉnh đầu (m[1]) = mốc đo (through); đỉnh sau (m[2]) = điểm mới (Z); m[3] = prime\n// của điểm mới (CAPTURE — phải khớp tên điểm mới ở TAKE_POINT). Issue #46 nhóm A:\n// điểm mới có thể mang dấu phẩy/prime (\"BC′ = R\"); giữ prime để chốt mốc đúng.\n// Phần sau dấu \"=\" (m[4]) gom thô để parse riêng (radius / segment / số). KHÔNG\n// kết thúc trên ',' — dấu phẩy có thể là phân tách thập phân (\"2,5\"); clause đã\n// được segmentClauses tách trên dấu chấm/'; nên gom tới hết clause là an toàn.\nconst DIST_CLAUSE =\n /(?:sao\\s+cho\\s+)?([A-Z])([A-Z])(['′]?)(?![A-Z])\\s*=\\s*(.+?)\\s*(?:[.;]|$)/u;\n\n// --- Distance parsing ---------------------------------------------------------\nconst RADIUS_WORD = /(?<!\\p{L})(?:R|bán\\s*kính)(?!\\p{L})/u;\nconst CIRCLE_OF_RADIUS = /bán\\s*kính\\s*(?:\\(\\s*)?([A-Z])\\s*\\)?/u;\nconst SEGMENT_PAIR = /^\\s*([A-Z])([A-Z])(?![A-Z])\\s*$/u;\nconst NUMBER = /(\\d+(?:[.,]\\d+)?)/u;\n\n// Tâm đường tròn trong đề: \"(O;\" / \"(O)\" / \"đường tròn tâm O\" → tên circle.\nconst CIRCLE_NAME_PAREN = /\\(\\s*([A-Z])\\s*[;,)]/u;\nconst CIRCLE_NAME_WORDS = /đường\\s*tròn\\s*(?:tâm\\s+)?([A-Z])(?![A-Z])/u;\n\nfunction parseNum(raw: string): number {\n return Number(raw.replace(',', '.'));\n}\n\n/** Tên circle để gắn radius. Suy từ đề (ctx.problem); mặc định 'O'. */\nfunction resolveCircleName(problem: string): string {\n const w = CIRCLE_NAME_WORDS.exec(problem);\n if (w) return w[1];\n const p = CIRCLE_NAME_PAREN.exec(problem);\n if (p) return p[1];\n return 'O';\n}\n\ntype DistanceBase =\n | { kind: 'circleRadius'; circle: string }\n | { kind: 'segmentLength'; p1: string; p2: string }\n | { kind: 'literal'; value: number };\n\ntype Distance = DistanceBase & { scale?: number; offset?: number };\n\n// --- Hệ số/bội/offset (Issue #46 nhóm C) -------------------------------------\n// Tách \"<scale>·base ± offset\". scale = số đứng TRƯỚC base (qua dấu nhân ·/./×/*\n// hoặc dán liền \"2AB\"/\"2R\" hoặc cách \"2 AB\"). offset = \"± số\" đứng SAU base.\n// \"2R\" → scale 2, base R\n// \"2·AB\" → scale 2, base AB\n// \"R + 1\" → base R, offset +1\n// \"2R + 1\" → scale 2, base R, offset +1\n// base có thể là R/bán kính, cặp đỉnh (AB), hoặc số literal.\n//\n// Hệ số đứng trước base: \"2\", \"2·\", \"2.\", \"2×\", \"2*\", \"2 \" (số rồi base).\nconst COEF_PREFIX = /^(\\d+(?:[.,]\\d+)?)\\s*[·.×*]?\\s*(?=[A-Z]|bán)/u;\n// Offset đứng cuối: \"± số\" (chỉ số literal, không nhân thêm đại lượng).\nconst OFFSET_SUFFIX = /([+-])\\s*(\\d+(?:[.,]\\d+)?)\\s*$/u;\n// Dấu nhân CHỈ giữa 2 đại lượng (vd \"R·AB\", \"AB·MN\"): tích 2 đại lượng → mơ hồ.\n// Phát hiện: có dấu nhân mà 2 BÊN đều KHÔNG phải số → reject.\nconst MUL_TWO_QUANTITIES = /[A-Z](?:\\s*['′])?\\s*[·×*]\\s*[A-Z]/u;\n\n/** Parse phần sau dấu \"=\" → DistanceSpec hoặc undefined (không nhận dạng được). */\nfunction parseDistance(raw: string, problem: string): Distance | undefined {\n let text = raw.trim();\n\n // 0. TỪ CHỐI ngay các biểu thức KHÔNG xử lý được:\n if (/\\//u.test(text)) return undefined; // chia: \"AB/2\", \"1/2 AB\" → defer\n if (/\\blần\\b/u.test(text)) return undefined; // \"2 lần bán kính\" → defer\n if (MUL_TWO_QUANTITIES.test(text)) return undefined; // tích 2 đại lượng \"R·AB\"\n // '-' đứng đầu (giá trị âm trực tiếp \"-3\") → defer. ('-' offset xử lý ở dưới.)\n if (/^-/u.test(text)) return undefined;\n\n // 1. Tách offset \"± số\" ở cuối (literal). Không nhân thêm đại lượng.\n let offset: number | undefined;\n const off = OFFSET_SUFFIX.exec(text);\n if (off) {\n const sign = off[1] === '-' ? -1 : 1;\n offset = sign * parseNum(off[2]);\n text = text.slice(0, off.index).trim();\n }\n // Sau khi bóc offset, KHÔNG còn được phép có toán tử +/- (vd \"1 + 2 + R\" lạ).\n if (/[+]/u.test(text)) return undefined;\n if (/-\\s*\\d/u.test(text)) return undefined;\n\n // 2. Tách hệ số (scale) đứng trước base. Chỉ nhận khi PHÍA SAU là base\n // (đỉnh HOA / \"bán\"). \"3\" đơn lẻ KHÔNG khớp (→ literal value).\n let scale: number | undefined;\n const coef = COEF_PREFIX.exec(text);\n if (coef) {\n scale = parseNum(coef[1]);\n if (!(Number.isFinite(scale) && scale > 0)) return undefined;\n text = text.slice(coef[0].length).trim();\n }\n\n // Còn sót dấu nhân lẻ (vd \"·R\" do tách lỗi) → mơ hồ.\n if (/[·×*]/u.test(text)) return undefined;\n\n const withCoef = (base: DistanceBase): Distance => {\n const d: Distance = { ...base };\n if (scale !== undefined) d.scale = scale;\n if (offset !== undefined) d.offset = offset;\n return d;\n };\n\n // 3. base = bán kính: \"R\" / \"bán kính\" / \"bán kính (O)\".\n if (RADIUS_WORD.test(text)) {\n const co = CIRCLE_OF_RADIUS.exec(text);\n const circle = co ? co[1] : resolveCircleName(problem);\n return withCoef({ kind: 'circleRadius', circle });\n }\n // 4. base = đoạn = 2 ký tự HOA liền (\"AB\", \"MN\").\n const seg = SEGMENT_PAIR.exec(text);\n if (seg) return withCoef({ kind: 'segmentLength', p1: seg[1], p2: seg[2] });\n // 5. base = số literal (board units). \"2 cm\" → 2 (cm-mapping defer).\n // Lưu ý: nếu đã tách scale thì KHÔNG còn base số (scale·số vô nghĩa) → defer.\n if (scale === undefined) {\n const num = NUMBER.exec(text);\n if (num) {\n const value = parseNum(num[1]);\n if (Number.isFinite(value) && value > 0) return withCoef({ kind: 'literal', value });\n }\n }\n return undefined;\n}\n\n/**\n * \"kéo dài AB lấy C sao cho BC = R\" / \"trên tia đối của tia BA, lấy C sao cho\n * BC = R\" → add-point C kind:pointAtDistance. Hướng (from→through) suy từ token\n * cặp + mốc đo (đỉnh đầu cụm \"YZ = …\"). Không parse đủ (thiếu tên điểm mới /\n * distance không nhận dạng / mốc không khớp) → bỏ qua để escalate AI.\n *\n * EN (issue #46 group B) — mirror VN, chỉ chạy khi VN không xác định được hướng:\n * \"ray XY extended beyond Y, take D such that YD = …\" → from=X, through=Y\n * \"extend XY beyond Y to D such that YD = …\" → from=X, through=Y\n * \"opposite ray of ray XY, take D such that XD = …\" → from=Y, through=X\n */\nexport const pointAtDistanceRule: LanguageRule = {\n id: 'pointAtDistance',\n priority: 55,\n languages: ['vi', 'en'],\n patterns: [KEYWORD, PREFILTER_EN],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n let from: string | undefined;\n let through: string | undefined;\n let name: string | undefined;\n let isEn = false;\n\n // --- Hướng VN (from → through) ---\n const doi = TIA_DOI.exec(c.text);\n if (doi) {\n // tia đối của tia BA: B = gốc, A = hướng cũ ⇒ kéo dài về B ⇒ from=A, through=B.\n from = doi[2];\n through = doi[1];\n } else {\n const kd = KEO_DAI.exec(c.text);\n if (kd) {\n // kéo dài AB (về phía B mặc định) ⇒ from=A, through=B.\n from = kd[1];\n through = kd[2];\n }\n }\n\n if (from && through) {\n // VN name (GIỮ prime, normalize ′→').\n const take = TAKE_POINT.exec(c.text);\n name = take ? normalizePointName(take[1], take[2]) : undefined;\n } else {\n // --- EN direction (additive; chỉ khi VN không xác định được hướng) ---\n const opp = OPPOSITE_RAY_EN.exec(c.text);\n const ray = RAY_EXTENDED_EN.exec(c.text);\n const ext = EXTEND_SEG_EN.exec(c.text);\n if (opp) {\n // opposite ray of ray XY → mirror VN tia đối: from=Y, through=X.\n from = opp[2];\n through = opp[1];\n } else if (ray && ray[3] === ray[2]) {\n // ray XY extended beyond Z (Z must = Y): from=X, through=Y.\n from = ray[1];\n through = ray[2];\n } else if (ext && ext[3] === ext[2]) {\n // extend XY beyond Z (Z must = Y): from=X, through=Y.\n from = ext[1];\n through = ext[2];\n }\n if (from && through) {\n isEn = true;\n const takeEn = TAKE_POINT_EN.exec(c.text);\n name = takeEn ? normalizePointName(takeEn[1], takeEn[2]) : undefined;\n }\n }\n\n if (!from || !through || !name) continue;\n\n // VE_PHIA: chỉ VN (EN không có \"về phía\"). Giữ outcome VN byte-identical.\n if (!isEn) {\n const vp = VE_PHIA.exec(c.text);\n if (vp && vp[1] !== through) continue;\n }\n\n // --- Mốc đo + khoảng cách (\"YZ = …\") — language-agnostic (DIST_CLAUSE) ---\n const dc = DIST_CLAUSE.exec(c.text);\n if (!dc) continue;\n const anchor = dc[1]; // Y = mốc đo (phải trùng through; đỉnh đơn)\n const newPt = normalizePointName(dc[2], dc[3]); // Z = điểm mới (phải trùng name)\n // Mốc đo phải là through; đỉnh sau là điểm mới ta vừa lấy (so theo tên đã\n // normalize ⇒ \"BC′\" khớp điểm \"C'\", \"BD′\" KHÔNG khớp điểm \"C'\").\n if (anchor !== through || newPt !== name) continue;\n\n const distance = parseDistance(dc[4], ctx.problem);\n if (!distance) continue;\n\n out.push({\n ruleId: 'pointAtDistance',\n clauseIds: [c.id],\n intents: [addPoint(name, { kind: 'pointAtDistance', from, through, distance })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/eulerLine.ts\n//\n// Đường thẳng Euler (issue #47, construct 1): đường thẳng đi qua 3 tâm tam giác\n// THẲNG HÀNG — trọng tâm G, trực tâm H, tâm đường tròn ngoại tiếp O. KHÔNG phải\n// kind DSL riêng — compose từ 3 tâm (centroid/orthocenter/circumcenter, đã có)\n// + kind tổng quát `lineThrough([G,H,O])`.\n//\n// Fail-safe (escalate, KHÔNG dựng sai):\n// - \"đường tròn Euler\" (đường tròn 9 điểm) → KHÔNG khớp (regex chỉ nhận\n// \"đường (thẳng) Euler\", không có \"tròn\").\n// - Tam giác đều (\"đều\") → G≡H≡O suy biến, đường Euler không xác định → bỏ qua.\n// - Không có tam giác / >1 tam giác (nhập nhằng) → bỏ qua.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, drawLine } from './_shared';\n\n// \"đường thẳng Euler\" / \"đường Euler\" — \"thẳng\" optional. KHÔNG khớp \"đường tròn\n// Euler\" (vì \"tròn\" KHÔNG phải nhánh optional \"thẳng\"). \\p{L} lookaround vì \\b\n// không khớp quanh ký tự Việt.\nconst EULER_LINE_KW = /(?<!\\p{L})đường\\s+(?:thẳng\\s+)?[Ee]uler(?!\\p{L})/u;\n\n// Tam giác (global): quét mọi tam giác nêu trong đề.\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// Tam giác đều → 3 tâm trùng → đường Euler suy biến.\nconst EQUILATERAL_KW = /(?<!\\p{L})đều(?!\\p{L})/u;\n\n/** Bộ 3 đỉnh duy nhất toàn đề; undefined nếu 0 hoặc >1 tam giác phân biệt. */\nfunction uniqueTriangle(problem: string): [string, string, string] | undefined {\n TRI_G.lastIndex = 0;\n const tris: string[][] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) {\n tris.push([m[1], m[2], m[3]]);\n }\n const distinct = new Set(tris.map((t) => t.join('')));\n if (distinct.size !== 1) return undefined;\n const t = tris[0];\n return [t[0], t[1], t[2]];\n}\n\nexport const eulerLineRule: LanguageRule = {\n id: 'eulerLine',\n priority: 68,\n languages: ['vi'],\n patterns: [EULER_LINE_KW],\n match(ctx) {\n // Suy biến tam giác đều → escalate (G≡H≡O → đường Euler không xác định).\n if (EQUILATERAL_KW.test(ctx.problem)) return [];\n\n const tri = uniqueTriangle(ctx.problem);\n if (!tri) return []; // 0 hoặc >1 tam giác → nhập nhằng → escalate.\n const [A, B, C] = tri;\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!EULER_LINE_KW.test(c.text)) continue;\n out.push({\n ruleId: 'eulerLine',\n clauseIds: [c.id],\n intents: [\n addPoint('G', { kind: 'centroid', of: [A, B, C] }),\n addPoint('H', { kind: 'orthocenter', of: [A, B, C] }),\n addPoint('O', { kind: 'circumcenter', of: [A, B, C] }),\n drawLine('euler' + A + B + C, 'lineThrough', { points: ['G', 'H', 'O'] }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/radicalAxis.ts\n//\n// Trục đẳng phương 2 đường tròn (issue #47, construct 2): đường ⊥ đường nối tâm\n// O₁O₂, mọi điểm trên nó có lũy thừa (power) bằng nhau với 2 đường tròn. KHÔNG\n// phải kind point — compose từ kind tổng quát `radicalAxis(circle1, circle2)`\n// (tham chiếu 2 CIRCLE đã được circleRadius dựng theo center letter).\n//\n// Fail-safe (escalate, KHÔNG dựng sai):\n// - Đồng tâm \"(O;3) và (O;5)\" → {O} (1 center phân biệt) → bỏ qua (suy biến,\n// trục không xác định).\n// - 0 hoặc 1 đường tròn có bán kính → không đủ 2 → bỏ qua.\n// - >2 đường tròn → nhập nhằng (cặp nào?) → bỏ qua.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { drawLine } from './_shared';\n\n// \"trục đẳng phương\" / \"đẳng phương\" — \"trục\" optional. \\p{L} lookaround vì \\b\n// không khớp quanh ký tự Việt.\nconst RADICAL_KW = /(?<!\\p{L})(?:trục\\s+)?đẳng\\s*phương(?!\\p{L})/u;\n\n// Đường tròn CÓ BÁN KÍNH (số hoặc ký hiệu R/r) — khớp những gì circleRadius\n// dựng qua centerRadius. \"(O; 3)\" / \"(I, 2.5)\" / \"(O; R)\". Global: nhiều đường\n// tròn / đề. Group 1 = center letter.\nconst CIRCLE_R_G = /\\(\\s*([A-Z])\\s*[;,]\\s*(?:\\d|[Rr])/gu;\n\n/** Các center letter phân biệt của đường tròn-có-bán-kính nêu trong đề. */\nfunction circleCentersWithRadius(problem: string): string[] {\n CIRCLE_R_G.lastIndex = 0;\n const centers = new Set<string>();\n let m: RegExpExecArray | null;\n while ((m = CIRCLE_R_G.exec(problem)) !== null) {\n centers.add(m[1]);\n }\n return [...centers];\n}\n\nexport const radicalAxisRule: LanguageRule = {\n id: 'radicalAxis',\n priority: 66,\n languages: ['vi'],\n patterns: [RADICAL_KW],\n match(ctx) {\n const centers = circleCentersWithRadius(ctx.problem);\n // Cần ĐÚNG 2 đường tròn phân biệt. Đồng tâm → 1 center → escalate. >2 → mơ hồ.\n if (centers.length !== 2) return [];\n const [c1, c2] = centers;\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!RADICAL_KW.test(c.text)) continue;\n out.push({\n ruleId: 'radicalAxis',\n clauseIds: [c.id],\n intents: [drawLine('rad' + c1 + c2, 'radicalAxis', { circle1: c1, circle2: c2 })],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/simson.ts\n//\n// Đường thẳng Simson (issue #47, construct 3): P trên đường tròn ngoại tiếp tam\n// giác ABC → 3 chân vuông góc hạ từ P xuống 3 cạnh (BC, CA, AB) THẲNG HÀNG\n// (định lý Simson). KHÔNG kind DSL riêng — compose:\n// - P = onCircle (glider trên đường tròn ngoại tiếp, theta cố định 0.7).\n// - 3 chân = perpFoot (chiếu trực giao xuống đường vô hạn BC/CA/AB).\n// - đường Simson = lineThrough([chân1, chân2, chân3]).\n//\n// Fail-safe (escalate, KHÔNG dựng sai):\n// - Không có đường tròn ngoại tiếp khai báo → KHÔNG đặt được P → bỏ qua.\n// - 0 hoặc >1 tam giác phân biệt (nhập nhằng) → bỏ qua.\n// - P trùng đỉnh (Simson của A) → 3 chân suy biến → bỏ qua.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, drawLine } from './_shared';\n\n// \"Simson\" — danh từ riêng. \\b không khớp quanh ký tự ASCII letter ổn, nhưng\n// dùng lookaround [A-Za-z] để chắc chắn không khớp trong từ khác.\nconst SIMSON_KW = /(?<![A-Za-z])[Ss]imson(?![A-Za-z])/u;\n\n// Tam giác (global): quét mọi tam giác nêu trong đề.\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\n// Tên tâm đường tròn ngoại tiếp: \"(O)\" — dạng ngoặc 1 chữ HOA.\nconst CIRCLE_CENTER = /\\(\\s*([A-Z])\\s*\\)/u;\n\n// P của Simson: \"Simson của (điểm) P\".\nconst SIMSON_OF = /[Ss]imson\\s+của\\s+(?:điểm\\s+)?([A-Z])(?![A-Za-z])/u;\n\n/** Bộ 3 đỉnh duy nhất toàn đề; undefined nếu 0 hoặc >1 tam giác phân biệt. */\nfunction uniqueTriangle(problem: string): [string, string, string] | undefined {\n TRI_G.lastIndex = 0;\n const tris: string[][] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) {\n tris.push([m[1], m[2], m[3]]);\n }\n const distinct = new Set(tris.map((t) => t.join('')));\n if (distinct.size !== 1) return undefined;\n const t = tris[0];\n return [t[0], t[1], t[2]];\n}\n\nexport const simsonRule: LanguageRule = {\n id: 'simson',\n priority: 64,\n languages: ['vi'],\n patterns: [SIMSON_KW],\n match(ctx) {\n const tri = uniqueTriangle(ctx.problem);\n if (!tri) return []; // 0 hoặc >1 tam giác → nhập nhằng → escalate.\n const [A, B, C] = tri;\n\n // Đường tròn ngoại tiếp PHẢI được khai báo (vd \"(O)\") — circleTriangle dựng\n // circle tên theo chữ trong \"(O)\". Thiếu → KHÔNG đặt được P → escalate.\n const cm = CIRCLE_CENTER.exec(ctx.problem);\n if (!cm) return [];\n const O = cm[1];\n\n // P của Simson.\n const pm = SIMSON_OF.exec(ctx.problem);\n if (!pm) return []; // không xác định được P → escalate.\n const P = pm[1];\n\n // Suy biến: P là 1 đỉnh tam giác → 3 chân trùng → đường Simson suy biến.\n if (P === A || P === B || P === C) return [];\n\n const f1 = 'S' + A + B + C + '1';\n const f2 = 'S' + A + B + C + '2';\n const f3 = 'S' + A + B + C + '3';\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!SIMSON_KW.test(c.text)) continue;\n out.push({\n ruleId: 'simson',\n clauseIds: [c.id],\n intents: [\n addPoint(P, { kind: 'onCircle', circle: O, theta: 0.7 }),\n addPoint(f1, { kind: 'perpFoot', from: P, onLine: B + C }),\n addPoint(f2, { kind: 'perpFoot', from: P, onLine: C + A }),\n addPoint(f3, { kind: 'perpFoot', from: P, onLine: A + B }),\n drawLine('simson' + P, 'lineThrough', { points: [f1, f2, f3] }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/ninePoint.ts\n//\n// Đường tròn chín điểm / đường tròn Euler (issue #47, construct 4): đường tròn qua\n// 3 trung điểm cạnh (= cũng qua 3 chân đường cao + 3 trung điểm đỉnh-trực tâm;\n// bán kính R/2). Dựng = circle3 qua 3 TRUNG ĐIỂM CẠNH — TRÁNH radius-scaling.\n// Compose midpoint×3 + circle3, KHÔNG kind DSL mới.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, drawCircle } from './_shared';\n\n// \"đường tròn chín điểm\" / \"đường tròn Euler\" / \"chín điểm\". KHÔNG khớp \"đường\n// thẳng Euler\" (yêu cầu \"tròn\" trước Euler — đó là đường thẳng Euler, construct 1).\nconst NINE_KW = /(?<!\\p{L})(?:đường\\s*tròn\\s+Euler|(?:đường\\s*tròn\\s+)?chín\\s*điểm)(?!\\p{L})/u;\nconst TRI_G = /tam giác\\s+([A-Z])([A-Z])([A-Z])/gu;\n\nfunction uniqueTriangle(problem: string): [string, string, string] | undefined {\n TRI_G.lastIndex = 0;\n const tris: string[][] = [];\n let m: RegExpExecArray | null;\n while ((m = TRI_G.exec(problem)) !== null) tris.push([m[1], m[2], m[3]]);\n const distinct = new Set(tris.map((t) => t.join('')));\n if (distinct.size !== 1) return undefined;\n const t = tris[0];\n return [t[0], t[1], t[2]];\n}\n\nexport const ninePointRule: LanguageRule = {\n id: 'ninePoint',\n priority: 63,\n languages: ['vi'],\n patterns: [NINE_KW],\n match(ctx) {\n const tri = uniqueTriangle(ctx.problem);\n if (!tri) return []; // 0 hoặc >1 tam giác → escalate.\n const [A, B, C] = tri;\n const mAB = 'M' + A + B, mBC = 'M' + B + C, mCA = 'M' + C + A;\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n if (!NINE_KW.test(c.text)) continue;\n out.push({\n ruleId: 'ninePoint',\n clauseIds: [c.id],\n intents: [\n addPoint(mAB, { kind: 'midpoint', of: A + B }),\n addPoint(mBC, { kind: 'midpoint', of: B + C }),\n addPoint(mCA, { kind: 'midpoint', of: C + A }),\n drawCircle('N9', 'through3', { points: [mAB, mBC, mCA] }),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/diameterCirclePairwise.ts\n//\n// Đề \"đường tròn đường kính đôi một cắt nhau lần thứ hai\" (whole-problem construct):\n//\n// Cho đường tròn (O) và ba dây cung AB, AC, AD bất kì. Các đường tròn đường\n// kính AB, AC, AD đôi một cắt nhau lần thứ hai tại M, N, P.\n//\n// Bản chất: (đ.kính AX)∩(đ.kính AY) lần 2 = chân vuông góc hạ từ A xuống XY\n// (∠ nhìn AX,AY = 90°). M,N,P = 3 chân Simson của A với ΔBCD. Đề gốc chỉ là\n// GIẢ THIẾT → hình tối giản: (O)+O, A/B/C/D, dây AX, 3 đường tròn đường kính,\n// M/N/P (giao điểm thứ hai, loại điểm chung A).\n//\n// Fail-safe (escalate, KHÔNG dựng sai): thiếu tâm \"(O)\"; <2 đường kính chung\n// apex; đầu mút/kết quả trùng; số tên kết quả ≠ số đường kính.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, drawCircle, DUONG_KW } from './_shared';\n\n// Tâm đường tròn: \"(O)\" — ngoặc 1 chữ HOA.\nconst CIRCLE_CENTER = /\\(\\s*([A-Z])\\s*\\)/u;\n// Prefilter: phải có \"đường kính\" + dấu hiệu \"đôi một\"/\"cắt nhau\".\nconst KW_DIAMETER = new RegExp(DUONG_KW + '\\\\s*kính', 'u');\nconst KW_PAIRWISE = /đôi một|cắt nhau/u;\n\n// Góc đặt điểm (radian) — apex trên cao, các đầu mút còn lại rải cung dưới ở\n// vị trí TỔNG QUÁT (tránh suy biến chân vuông góc trùng nhau).\nconst APEX_THETA = 2.0;\nconst OTHER_THETAS = [5.5, 4.0, 0.6, 3.3, 1.1, 5.0] as const;\n\ninterface Parsed {\n center: string;\n apex: string;\n others: string[];\n results: string[];\n}\n\nfunction parse(problem: string): Parsed | undefined {\n const cm = CIRCLE_CENTER.exec(problem);\n if (!cm) return undefined;\n const center = cm[1];\n\n // Vùng sau \"đường kính\" tới khi gặp \"đôi một\"/\"cắt nhau\" (cùng câu).\n const dm = new RegExp(DUONG_KW + '\\\\s*kính\\\\s+([^.;\\n]*)', 'u').exec(problem);\n if (!dm) return undefined;\n let region = dm[1];\n const cut = region.search(/đôi một|cắt nhau/u);\n if (cut >= 0) region = region.slice(0, cut);\n const pairs = region.match(/[A-Z][A-Z]/g) ?? [];\n if (pairs.length < 2) return undefined;\n\n // apex = chữ xuất hiện trong MỌI cặp.\n const counts = new Map<string, number>();\n for (const pr of pairs) {\n counts.set(pr[0], (counts.get(pr[0]) ?? 0) + 1);\n counts.set(pr[1], (counts.get(pr[1]) ?? 0) + 1);\n }\n const apexEntries = [...counts].filter(([, n]) => n === pairs.length);\n if (apexEntries.length !== 1) return undefined; // 0 → không chung; >1 → nhập nhằng\n const apex = apexEntries[0][0];\n const others = pairs.map((pr) => (pr[0] === apex ? pr[1] : pr[0]));\n if (new Set(others).size !== others.length) return undefined; // đầu mút trùng\n if (others.includes(apex)) return undefined;\n\n // Tên kết quả sau \"tại\": các chữ HOA đơn lẻ (M, N, P, ...).\n const rm = /\\btại\\s+([A-Z][^.;\\n]*)/u.exec(problem);\n if (!rm) return undefined;\n const results = rm[1].match(/\\b[A-Z]\\b/g) ?? [];\n // \"đôi một cắt nhau\" của n đường kính chung apex = TẤT CẢ C(n,2) cặp → C(n,2)\n // giao điểm. Số tên kết quả phải khớp đúng (n=3 → 3; n=4 → 6; ...).\n const numPairs = (others.length * (others.length - 1)) / 2;\n if (results.length !== numPairs) return undefined;\n if (new Set(results).size !== results.length) return undefined;\n\n return { center, apex, others, results };\n}\n\nexport const diameterCirclePairwiseRule: LanguageRule = {\n id: 'diameter-circle-pairwise',\n priority: 66,\n languages: ['vi'],\n patterns: [KW_DIAMETER],\n match(ctx) {\n if (!KW_PAIRWISE.test(ctx.problem)) return [];\n const p = parse(ctx.problem);\n if (!p) return [];\n const { center, apex, others, results } = p;\n\n const circOf = (other: string) => `k${apex}${other}`;\n const oCircle = `k${center}`; // tên entity đường tròn (O) (khác điểm tâm O)\n\n // Tất cả cặp (i<j) theo thứ tự từ điển — \"đôi một\" = mọi cặp đường kính.\n const allPairs: Array<[number, number]> = [];\n for (let i = 0; i < others.length; i++)\n for (let j = i + 1; j < others.length; j++) allPairs.push([i, j]);\n\n const intents = [\n // (O): tâm `center` (free) + bán kính cố định.\n drawCircle(oCircle, 'centerRadius', { center, radius: 4 }),\n // apex + các đầu mút = glider trên (O), vị trí tổng quát.\n addPoint(apex, { kind: 'onCircle', circle: oCircle, theta: APEX_THETA }),\n ...others.map((o, i) =>\n addPoint(o, { kind: 'onCircle', circle: oCircle, theta: OTHER_THETAS[i % OTHER_THETAS.length] }),\n ),\n // Dây cung apex–đầu mút.\n ...others.map((o) => connect(apex, o, 'segment')),\n // Đường tròn đường kính apex–đầu mút.\n ...others.map((o) => drawCircle(circOf(o), 'diameter', { endpoints: [apex, o] })),\n // Giao điểm thứ hai của TỪNG cặp đường tròn đường kính, loại điểm chung apex.\n ...results.map((r, k) =>\n addPoint(r, {\n kind: 'circleSecondIntersection',\n c1: circOf(others[allPairs[k][0]]),\n c2: circOf(others[allPairs[k][1]]),\n exclude: apex,\n }),\n ),\n ];\n\n const out: RuleMatch[] = [{\n ruleId: 'diameter-circle-pairwise',\n // Whole-problem construct: claim mọi clause để coverage gate đầy đủ.\n clauseIds: ctx.clauses.map((c) => c.id),\n intents,\n }];\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/angleBisectorFoot.ts\n//\n// Chân đường phân giác (trong/ngoài) hạ từ một đỉnh xuống cạnh đối:\n// \"D là chân đường phân giác từ A\" → onLine = cạnh đối A (suy từ tam giác)\n// \"D là chân đường phân giác trong kẻ từ A đến BC\" → onLine = BC (nêu rõ)\n// \"D là chân phân giác góc A\" → onLine = cạnh đối A\n// \"D là chân đường phân giác ngoài từ A\" → externalAngleBisectorFoot\n// → add-point D {kind:'angleBisectorFoot', from:'A', onLine:'BC'} (builder dựng\n// tia phân giác ∠(onLine[0])-from-(onLine[1]) ∩ đoạn onLine).\n//\n// Phân biệt (KHÔNG chồng rule khác):\n// - cevian (\"phân giác AD\" — đỉnh+chân dạng cặp HOA NGAY sau \"phân giác\"): rule\n// này BẮT BUỘC chữ \"chân\" mở đầu cụm → cevian không khớp.\n// - perpFoot (\"chân đường vuông góc / cao\"): keyword khác (\"vuông góc\"/\"cao\").\n// - angleBisectorAngle (\"phân giác góc A\" — vẽ tia VISIBLE, không foot): rule\n// đó tự né khi có \"chân\" đứng trước (guard CHAN_BEFORE bên angleBisectorAngle).\n//\n// Cần TAM GIÁC để suy cạnh đối khi đề KHÔNG nêu cạnh (\"đến BC\"); nêu rõ thì dùng\n// luôn. Tên chân (HOA) bind cục bộ qua \"X là\" NGAY TRƯỚC cụm. Thiếu tên / không\n// suy được cạnh đối → bỏ qua clause (escalate AI thay vì đoán sai).\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt (\"đ\",\"ề\",\"ạ\"…).\n// Regex chứa ký tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\n\n// Tam giác toàn đề (suy cạnh đối). Bổ ngữ \"vuông|cân|đều|nhọn|tù\" optional.\nconst TRI = /tam\\s*giác(?:\\s+(?:vuông|cân|đều|nhọn|tù))?\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\n\n// onLine token: tên đường 1 ký tự HOA HOẶC cặp đỉnh 2 ký tự HOA. Tiền tố tuỳ chọn.\nconst LINE = '(?:đường\\\\s*thẳng\\\\s+|cạnh\\\\s+|đoạn\\\\s+)?([A-Z]{1,2})(?![A-Z])';\n// Giới từ dẫn tới cạnh đáy.\nconst PREP_TO = '(?:đến|tới|xuống|trên|ra)';\n// Đỉnh: \"từ (đỉnh)? X\" | \"của góc X\" | \"góc X\" | \"tại (đỉnh)? X\" | \"đỉnh X\".\nconst VERTEX =\n '(?:từ\\\\s+(?:đỉnh\\\\s+)?|của\\\\s+góc\\\\s+|góc\\\\s+|tại\\\\s+(?:đỉnh\\\\s+)?|đỉnh\\\\s+)([A-Z])(?![A-Z])';\n\n// \"chân (của)? (đường|tia)? phân giác (trong|ngoài)? (hạ|kẻ|vẽ|dựng)? VERTEX (PREP_TO LINE)?\".\n// group1 = trong|ngoài (optional); group2 = vertex; group3 = onLine (optional).\nconst CORE = new RegExp(\n 'chân\\\\s+(?:của\\\\s+)?(?:đường\\\\s*|tia\\\\s+)?phân\\\\s*giác\\\\s+(?:(trong|ngoài)\\\\s+)?' +\n '(?:(?:hạ|kẻ|vẽ|dựng)\\\\s+)?' +\n VERTEX +\n `(?:\\\\s+${PREP_TO}\\\\s+${LINE})?`,\n 'gu',\n);\n\n// Tên chân đứng TRƯỚC: \"X là \" NGAY TRƯỚC cụm \"chân … phân giác\".\nconst NAME_BEFORE = /([A-Z])(?:['′]?)\\s+là\\s+$/u;\n\n// Prefilter toàn đề.\nconst PREFILTER = /chân\\s+(?:của\\s+)?(?:đường\\s*|tia\\s+)?phân\\s*giác/u;\n\n/** Cạnh đối diện đỉnh V trong tam giác = 2 đỉnh còn lại, join token (vd \"BC\"). */\nfunction opposite(tri: readonly string[], vertex: string): string | undefined {\n const rest = tri.filter((v) => v !== vertex);\n return rest.length === 2 ? rest[0] + rest[1] : undefined;\n}\n\n/**\n * Mỗi clause → 0..n add-point angleBisectorFoot / externalAngleBisectorFoot.\n * onLine ưu tiên cạnh nêu rõ (\"đến BC\"); else suy cạnh đối từ tam giác. Tên chân\n * bind cục bộ. Thiếu tên / không suy được cạnh → bỏ qua (escalate).\n */\nexport const angleBisectorFootRule: LanguageRule = {\n id: 'angleBisectorFoot',\n priority: 63,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const triM = TRI.exec(ctx.problem);\n const tri = triM ? [triM[1], triM[2], triM[3]] : null;\n\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n CORE.lastIndex = 0;\n for (const m of c.text.matchAll(CORE)) {\n const external = m[1] === 'ngoài';\n const vertex = m[2];\n let onLine: string | undefined = m[3]; // cạnh nêu rõ (optional)\n if (!onLine) {\n if (!tri || !tri.includes(vertex)) continue; // không suy được cạnh đối → escalate\n onLine = opposite(tri, vertex);\n }\n if (!onLine) continue; // không có cạnh (nêu rõ/suy ra) → escalate\n // Tên chân: \"X là\" NGAY TRƯỚC cụm; không có → escalate (đừng bịa).\n const nm = NAME_BEFORE.exec(c.text.slice(0, m.index));\n if (!nm) continue;\n const name = nm[1];\n if (onLine.includes(name)) continue; // chân trùng đầu mút cạnh đáy → degenerate\n const kind = external ? 'externalAngleBisectorFoot' : 'angleBisectorFoot';\n out.push({\n ruleId: 'angleBisectorFoot',\n clauseIds: [c.id],\n intents: [addPoint(name, { kind, from: vertex, onLine })],\n });\n }\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/intersection.ts\n//\n// Giao điểm GENERIC của 2 đường thẳng/đoạn cho bởi CẶP ĐỈNH (2 ký tự HOA):\n// \"D là giao điểm của AB và CE\" → tên TRƯỚC (\"X là …\")\n// \"AM cắt CN tại K\" → tên SAU (\"… tại D\")\n// \"AC và BD cắt nhau tại O\" → tên SAU, dạng \"cắt nhau\"\n// → add-point D {kind:'intersection', of:['AB','CE']} (builder ensure 2 segment\n// rồi lấy giao). Mỗi ref = 1 đường qua 2 điểm đã có; thiếu điểm → transpile-fail\n// → escalate (fail-safe).\n//\n// CHỈ nhận ref CẶP ĐỈNH \"AB\" (2 ký tự HOA). KHÔNG nhận:\n// - giao 2 ĐƯỜNG TRÒN \"(O) và (O')\" → kind circleIntersection (rule khác/defer);\n// ref \"(O)\" có ngoặc nên [A-Z]{2} không khớp → tự loại.\n// - line∩circle \"AB cắt (O) tại M\" → secondIntersection (defer); \"(O)\" không\n// phải cặp đỉnh → tự loại.\n// - \"đôi một cắt nhau\" (diameterCirclePairwise) → \"đôi một\" chen giữa cặp đỉnh\n// và \"cắt nhau\" phá khớp dạng C; dạng dùng dấu phẩy (không \"và\") cũng không khớp.\n//\n// Guard degenerate (fail-safe — thà escalate còn hơn dựng điểm vô nghĩa):\n// - 4 đầu mút phải PHÂN BIỆT: chia sẻ đỉnh → 2 đường gặp tại đỉnh chung (không\n// phải điểm mới) → bỏ qua.\n// - tên điểm cần dựng KHÔNG được nằm trong ref (định nghĩa vòng) → bỏ qua.\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt. Regex chứa ký\n// tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { addPoint, DUONG_KW } from './_shared';\n\n// Ref = cặp đỉnh \"AB\" (đúng 2 ký tự HOA, cho phép khoảng trắng ở giữa \"A B\", neo (?![A-Z]) chặn cụm 3+).\n// Tiền tố \"đường thẳng|đoạn|tia|cạnh\" optional.\nconst REF =\n '(?:' +\n DUONG_KW +\n '\\\\s*thẳng\\\\s+|đoạn(?:\\\\s+thẳng)?\\\\s+|tia\\\\s+|cạnh\\\\s+)?([A-Z]\\\\s*[A-Z])(?![A-Z])';\nconst CONN = '(?:và|với)';\n\n// A: \"giao điểm (của)? REF1 (và|với) REF2\" — tên đứng TRƯỚC qua \"X là\".\nconst GIAO_DIEM = new RegExp(`giao\\\\s*điểm\\\\s+(?:của\\\\s+)?${REF}\\\\s*${CONN}\\\\s*${REF}`, 'gu');\n// B: \"REF1 cắt REF2 tại D\" — tên SAU.\nconst CAT_TAI = new RegExp(`${REF}\\\\s+cắt\\\\s+${REF}\\\\s+tại\\\\s+([A-Z])(?![A-Z])`, 'gu');\n// C: \"REF1 (và|với) REF2 (cắt|giao) nhau tại D\" — tên SAU. REF2 NGAY trước \"cắt\n// nhau\" → \"đôi một\" (diameterCirclePairwise) chen vào sẽ phá khớp.\nconst CAT_NHAU = new RegExp(\n `${REF}\\\\s*${CONN}\\\\s*${REF}\\\\s+(?:cắt|giao)\\\\s+nhau\\\\s+tại\\\\s+([A-Z])(?![A-Z])`,\n 'gu',\n);\n// D: \"E, F lần lượt là giao điểm của AB và CD, của AD và BC\" → zip 2 tên với 2 cặp.\nconst DISTRIB_TWO = new RegExp(\n `([A-Z])\\\\s*,\\\\s*([A-Z])\\\\s+lần\\\\s*lượt\\\\s+là\\\\s+giao\\\\s*điểm\\\\s+của\\\\s+${REF}\\\\s*${CONN}\\\\s*${REF}\\\\s*,\\\\s*của\\\\s+${REF}\\\\s*${CONN}\\\\s*${REF}`,\n 'gu',\n);\n\n// Tên điểm đứng TRƯỚC (pattern A): \"X là \" NGAY TRƯỚC \"giao điểm\".\nconst NAME_BEFORE = /([A-Z])(?:['′]?)\\s+là\\s+$/u;\n\n// Prefilter toàn đề.\nconst PREFILTER = /giao\\s*điểm|cắt|giao\\s+nhau/u;\n\n/**\n * Build intent intersection nếu hợp lệ: 4 đầu mút phân biệt (không chia sẻ đỉnh)\n * + tên không nằm trong ref. Ngược lại trả null (escalate).\n */\nfunction makeIntent(name: string, ref1: string, ref2: string): IntentT | null {\n ref1 = ref1.replace(/\\s+/g, '');\n ref2 = ref2.replace(/\\s+/g, '');\n const ends = [ref1[0], ref1[1], ref2[0], ref2[1]];\n if (new Set(ends).size !== 4) return null; // chia sẻ đỉnh / ref trùng → degenerate\n if (ends.includes(name)) return null; // ref chứa chính điểm cần dựng → vô nghĩa\n return addPoint(name, { kind: 'intersection', of: [ref1, ref2] });\n}\n\nexport const intersectionRule: LanguageRule = {\n id: 'intersection',\n // THẤP HƠN mọi rule tạo điểm (midpoint=50 thấp nhất, perpFoot/cevian/center…\n // đều ≥50): intentsToDsl xử lý intent THEO THỨ TỰ priority DESC (không topo-sort)\n // → các điểm đầu mút (vd M,N trung điểm trong \"AM cắt CN tại K\") phải được dựng\n // TRƯỚC khi intersection tham chiếu chúng. Đặt 45 (>connect 40) để chạy sau cùng.\n priority: 45,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const seen = new Set<string>(); // tên đã claim trong clause (tránh trùng tên)\n const emit = (name: string, ref1: string, ref2: string) => {\n if (seen.has(name)) return;\n const intent = makeIntent(name, ref1, ref2);\n if (!intent) return;\n seen.add(name);\n out.push({ ruleId: 'intersection', clauseIds: [c.id], intents: [intent] });\n };\n\n DISTRIB_TWO.lastIndex = 0;\n for (const m of c.text.matchAll(DISTRIB_TWO)) {\n emit(m[1], m[3], m[4]);\n emit(m[2], m[5], m[6]);\n }\n\n // A: tên TRƯỚC — \"X là giao điểm của REF1 và REF2\".\n GIAO_DIEM.lastIndex = 0;\n for (const m of c.text.matchAll(GIAO_DIEM)) {\n const nm = NAME_BEFORE.exec(c.text.slice(0, m.index));\n if (nm) emit(nm[1], m[1], m[2]);\n }\n // B: \"REF1 cắt REF2 tại D\".\n CAT_TAI.lastIndex = 0;\n for (const m of c.text.matchAll(CAT_TAI)) emit(m[3], m[1], m[2]);\n // C: \"REF1 và REF2 cắt nhau tại D\".\n CAT_NHAU.lastIndex = 0;\n for (const m of c.text.matchAll(CAT_NHAU)) emit(m[3], m[1], m[2]);\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/chord.ts\n//\n// Dây cung của đường tròn (chord):\n// \"Cho đường tròn (O), dây AB\" → circle O + A,B ∈ (O) + đoạn AB\n// \"đường tròn tâm O. Dây cung MN\" → circle O + M,N ∈ (O) + đoạn MN\n// \"AB là dây của (O)\" → reverse\n// → drawCircle(O, centerRadius default) + onCircle A,B + connect A-B (dây).\n//\n// \"(O)\" KHÔNG có bán kính (circleRadius cố ý BỎ QUA \"(O)\" trơ). Dây cần MỘT đường\n// tròn để minh hoạ → emit circleCR tâm O bán kính CANONICAL (SYMBOLIC_RADIUS), y\n// như cách xử lý \"(O; R)\" ký hiệu. 2 đầu mút dây là glider onCircle (theta phân\n// biệt) → nằm ĐÚNG trên đường tròn; đoạn nối = dây.\n//\n// Nếu đường tròn O đã được rule khác (circleRadius) dựng với bán kính cụ thể →\n// addShape idempotent theo TÊN + circleRadius priority cao hơn ⇒ định nghĩa cụ\n// thể THẮNG, circle ở đây bị bỏ (không chồng). onCircle/connect vẫn dùng O đó.\n//\n// Circle emit TRƯỚC (RuleMatch đầu) để onCircle tham chiếu O đã tồn tại (transpile\n// xử lý theo thứ tự). Claim cả clause khai báo đường tròn để coverage không sót.\n//\n// Thiếu đường tròn / đầu mút dây trùng tâm / cặp trùng → bỏ qua (escalate).\n//\n// GOTCHA \\b: \\b của JS theo ASCII nên KHÔNG khớp quanh ký tự Việt. Regex chứa ký\n// tự Việt dùng cờ 'u' + lookaround (?!\\p{L}).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { Clause } from '../deterministic/coverage';\nimport { addPoint, connect, drawCircle, CIRCLE_KW } from './_shared';\nimport { SYMBOLIC_RADIUS } from './circleRadius';\n\n// Tên đường tròn toàn đề: \"đường tròn (tâm) O\" / \"(O)\".\n// Hỗ trợ cả tên chữ (alpha, omega...).\nconst CIRCLE_WORDS = new RegExp(CIRCLE_KW + '\\\\s*(?:\\\\(\\\\s*)?(?:tâm\\\\s+)?([^\\\\s;,).:]+)(?![A-Z])', 'u');\nconst CIRCLE_PAREN = /\\(\\s*([^\\\\s;,).:]+)\\s*\\)/u;\n\n// \"dây (cung)? AB\" (forward) / \"AB là (một)? dây (cung)?\" (reverse). Cặp đỉnh 2\n// ký tự HOA liền, neo (?![A-Z]) chặn cụm 3+.\n// [Dd]ây: \"Dây\" HOA đầu câu (sau dấu '.') cũng khớp; nhãn cặp đỉnh vẫn STRICT HOA.\nconst CHORD_FWD = /[Dd]ây\\s+(?:cung\\s+)?([A-Z])([A-Z])(?![A-Z])/gu;\nconst CHORD_REV = /([A-Z])([A-Z])(?![A-Z])\\s+là\\s+(?:một\\s+)?dây(?:\\s+cung)?(?!\\p{L})/gu;\n\n// Glider angle cho 2 đầu mút dây (radian) — phân biệt để A≠B, dây trải phần trên.\nconst THETA_A = 2.3;\nconst THETA_B = 0.7;\n\n// Prefilter toàn đề (\"Dây\" HOA đầu câu cũng khớp).\nconst PREFILTER = /[Dd]ây/u;\n\n/** Clause id chứa khai báo đường tròn (CIRCLE_WORDS hoặc \"(O)\"). */\nfunction findCircleClauseId(clauses: readonly Clause[], circle: string): number | undefined {\n const frag = new RegExp(CIRCLE_KW + `|\\\\(\\\\s*${circle}\\\\s*\\\\)`, 'u');\n for (const c of clauses) if (frag.test(c.text)) return c.id;\n return undefined;\n}\n\n/**\n * Resolve tên đường tròn từ toàn đề; undefined nếu không có.\n */\nfunction resolveCircle(problem: string): string | undefined {\n const w = CIRCLE_WORDS.exec(problem);\n if (w) return w[1];\n const p = CIRCLE_PAREN.exec(problem);\n if (p) return p[1];\n return undefined;\n}\n\nexport const chordRule: LanguageRule = {\n id: 'chord',\n // Dưới circleRadius (75) — nếu circle O có bán kính cụ thể, định nghĩa đó thắng.\n priority: 52,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const circle = resolveCircle(ctx.problem);\n if (!circle) return []; // không có đường tròn → escalate\n\n // Gom các dây hợp lệ.\n interface Chord {\n clauseId: number;\n a: string;\n b: string;\n }\n const chords: Chord[] = [];\n const seen = new Set<string>(); // \"a|b\" (chuẩn hoá thứ tự) tránh trùng\n for (const c of ctx.clauses) {\n const collect = (re: RegExp) => {\n re.lastIndex = 0;\n for (const m of c.text.matchAll(re)) {\n const a = m[1];\n const b = m[2];\n if (a === b) continue; // cặp trùng → degenerate\n if (a === circle || b === circle) continue; // đầu mút trùng tâm → degenerate\n const key = [a, b].sort().join('|');\n if (seen.has(key)) continue;\n seen.add(key);\n chords.push({ clauseId: c.id, a, b });\n }\n };\n collect(CHORD_FWD);\n collect(CHORD_REV);\n }\n if (chords.length === 0) return []; // không trích được dây → escalate\n\n const out: RuleMatch[] = [];\n // 1) Đường tròn (centerRadius default) — TRƯỚC, claim clause khai báo đường\n // tròn để coverage không sót clause \"Cho đường tròn (O)\".\n const circleClauseId = findCircleClauseId(ctx.clauses, circle);\n out.push({\n ruleId: 'chord',\n clauseIds: circleClauseId === undefined ? [] : [circleClauseId],\n intents: [drawCircle(circle, 'centerRadius', { center: circle, radius: SYMBOLIC_RADIUS })],\n });\n // 2) Mỗi dây: A,B glider onCircle (theta phân biệt) + đoạn nối.\n for (const ch of chords) {\n out.push({\n ruleId: 'chord',\n clauseIds: [ch.clauseId],\n intents: [\n addPoint(ch.a, { kind: 'onCircle', circle, theta: THETA_A }),\n addPoint(ch.b, { kind: 'onCircle', circle, theta: THETA_B }),\n connect(ch.a, ch.b, 'segment'),\n ],\n });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/incircleTangency.ts\n//\n// Tiếp điểm của đường tròn nội tiếp với các cạnh tam giác:\n// \"Đường tròn (I) nội tiếp tam giác ABC tiếp xúc với các cạnh BC, CA, AB\n// tại các điểm D, E, G\"\n// → D/E/G = tangencyPoint(circle I, onLine BC/CA/AB).\nimport type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint } from './_shared';\nimport type { IntentT } from '../intent';\nimport type { Clause } from '../deterministic/coverage';\n\nconst PREFILTER = /tiếp\\s*xúc/u;\n\nconst INCIRCLE_IN_CLAUSE = /đường\\s*tròn\\s*(?:\\(\\s*([A-Z])\\s*\\)|tâm\\s+([A-Z]))?\\s*nội\\s*tiếp\\s+tam\\s*giác\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/iu;\n\nconst SIDE_POINT_LIST = /tiếp\\s*xúc\\s+(?:với\\s+)?(?:các\\s+)?(?:cạnh|đoạn)\\s+([A-Z]{2}(?:\\s*,\\s*[A-Z]{2})*)\\s+(?:lần\\s*lượt\\s+)?tại\\s+(?:các\\s+)?(?:điểm\\s+)?([A-Z](?:\\s*,\\s*[A-Z])*)(?![A-Za-z])/iu;\n\nfunction splitCsv(blob: string): string[] {\n return blob\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nfunction normalizeSpaces(text: string): string {\n return text.replace(/\\s+/gu, ' ').trim();\n}\n\nfunction logicalChunks(problem: string, clauses: readonly Clause[]): Array<{ text: string; clauseIds: number[] }> {\n return problem\n .split(/[.;]+/u)\n .map((text) => normalizeSpaces(text))\n .filter(Boolean)\n .map((text) => ({\n text,\n clauseIds: clauses\n .filter((c) => text.includes(normalizeSpaces(c.text)))\n .map((c) => c.id),\n }));\n}\n\nfunction parseIncircleName(text: string): string | undefined {\n const m = INCIRCLE_IN_CLAUSE.exec(text);\n if (!m) return undefined;\n return m[1] ?? m[2] ?? 'O';\n}\n\nfunction parseTangencies(text: string, circle: string): IntentT[] {\n const m = SIDE_POINT_LIST.exec(text);\n if (!m) return [];\n\n const sides = splitCsv(m[1]);\n const names = splitCsv(m[2]);\n if (sides.length === 0 || sides.length !== names.length) return [];\n\n return names.map((name, i) => (\n addPoint(name, { kind: 'tangencyPoint', circle, onLine: sides[i] })\n ));\n}\n\nexport const incircleTangencyRule: LanguageRule = {\n id: 'incircleTangency',\n priority: 71,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const chunk of logicalChunks(ctx.problem, ctx.clauses)) {\n const circle = parseIncircleName(chunk.text);\n if (!circle) continue;\n\n const intents = parseTangencies(chunk.text, circle);\n if (intents.length === 0) continue;\n\n out.push({ ruleId: 'incircleTangency', clauseIds: chunk.clauseIds, intents });\n }\n return out;\n },\n};\n","import type { LanguageRule, RuleMatch } from './_types';\nimport { addPoint, connect, drawCircle, drawShape, CIRCLE_KW, DUONG_KW } from './_shared';\n\nconst TRI = /tam\\s*giác(?:[^A-Z.;\\n]*)\\s+([A-Z])([A-Z])([A-Z])(?![A-Z])/u;\nconst ALTITUDES = /các\\s+đường\\s*cao\\s+([A-Z])([A-Z])\\s*,\\s*([A-Z])([A-Z])(?![A-Z])/u;\nconst DIAMETER_INTERSECTION = new RegExp(\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])\\\\s+và\\\\s+' +\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])[^.;\\n]*?tại\\\\s+các\\\\s+điểm\\\\s+([A-Z])\\\\s*,\\\\s*([A-Z])(?![A-Z])',\n 'u',\n);\nconst SEGMENT_CIRCLE = new RegExp(\n '[Đđ]oạn\\\\s+thẳng\\\\s+([A-Z])([A-Z])\\\\s+cắt\\\\s+' +\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])\\\\s+tại\\\\s+điểm\\\\s+([A-Z])(?![A-Z])',\n 'gu',\n);\nconst LINE_LINE =\n /[Cc]ác\\s+đường\\s+thẳng\\s+([A-Z])([A-Z])\\s+và\\s+([A-Z])([A-Z])\\s+cắt\\s+nhau\\s+tại\\s+([A-Z])(?![A-Z])/u;\n\nfunction opposite(triangle: readonly string[], apex: string): string | undefined {\n const rest = triangle.filter((v) => v !== apex);\n return rest.length === 2 ? rest[0] + rest[1] : undefined;\n}\n\nexport const altitudeDiameterCirclesRule: LanguageRule = {\n id: 'altitude-diameter-circles',\n priority: 67,\n languages: ['vi'],\n patterns: [new RegExp(DUONG_KW + '\\\\s*cao', 'u'), new RegExp(DUONG_KW + '\\\\s*kính', 'u')],\n match(ctx) {\n const tri = TRI.exec(ctx.problem);\n const alts = ALTITUDES.exec(ctx.problem);\n const circles = DIAMETER_INTERSECTION.exec(ctx.problem);\n if (!tri || !alts || !circles) return [];\n\n const triangle = [tri[1], tri[2], tri[3]] as const;\n const altPairs = [\n [alts[1], alts[2]],\n [alts[3], alts[4]],\n ] as const;\n\n const altitudeIntents = [];\n for (const [apex, foot] of altPairs) {\n if (!triangle.includes(apex) || triangle.includes(foot)) return [];\n const opp = opposite(triangle, apex);\n if (!opp) return [];\n altitudeIntents.push(\n addPoint(foot, { kind: 'perpFoot', from: apex, onLine: opp }),\n connect(apex, foot, 'segment'),\n );\n }\n\n const dia1 = circles[1] + circles[2];\n const dia2 = circles[3] + circles[4];\n const known = new Set(altPairs.map(([a, f]) => `${a}${f}`));\n if (!known.has(dia1) || !known.has(dia2) || dia1 === dia2) return [];\n\n const c1 = `k${dia1}`;\n const c2 = `k${dia2}`;\n const x = circles[5];\n const y = circles[6];\n if (x === y) return [];\n\n const segCircles = [...ctx.problem.matchAll(SEGMENT_CIRCLE)];\n const extraPointIntents = [];\n for (const m of segCircles) {\n const line = `${m[1]}${m[2]}`;\n const dia = `${m[3]}${m[4]}`;\n const point = m[5];\n if (line === dia || point === line[0] || point === line[1]) return [];\n const circle = dia === dia1 ? c1 : dia === dia2 ? c2 : undefined;\n if (!circle) return [];\n extraPointIntents.push(\n addPoint(point, { kind: 'intersection', of: [line, circle], branch: 0 }),\n );\n }\n\n const lineLine = LINE_LINE.exec(ctx.problem);\n if (lineLine) {\n extraPointIntents.push(\n addPoint(lineLine[5], {\n kind: 'intersection',\n of: [`${lineLine[1]}${lineLine[2]}`, `${lineLine[3]}${lineLine[4]}`],\n }),\n );\n }\n\n const intents = [\n drawShape('triangle', [...triangle], 'any'),\n ...altitudeIntents,\n drawCircle(c1, 'diameter', { endpoints: [dia1[0], dia1[1]] }),\n drawCircle(c2, 'diameter', { endpoints: [dia2[0], dia2[1]] }),\n addPoint(x, { kind: 'circleIntersection', c1, c2, which: 0 }),\n addPoint(y, { kind: 'circleIntersection', c1, c2, which: 1 }),\n ...extraPointIntents,\n ];\n\n const out: RuleMatch[] = [{\n ruleId: 'altitude-diameter-circles',\n clauseIds: ctx.clauses.map((c) => c.id),\n intents,\n }];\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/diameterCircleCutsSides.ts\n//\n// \"Đường tròn đường kính BC cắt AB, AC tại M và N\" — đường tròn đường kính một\n// cạnh cắt hai cạnh kề tại các điểm phái sinh (phân phối 1-1):\n//\n// Cho tam giác ABC nhọn, đường tròn đường kính BC cắt AB, AC tại M và N.\n//\n// Bản chất: đường tròn đường kính PQ đi qua P, Q. Cạnh AB (chứa B ∈ đường kính)\n// cắt đường tròn tại B và một điểm thứ hai M (= chân đường cao hạ từ C, ∠BMC=90°\n// Thales). Vì luôn biết điểm chung (đỉnh dùng chung giữa cạnh và đường kính), ta\n// dựng M bằng `secondIntersection` (JSXGraph otherintersection loại điểm chung) —\n// robust hơn `intersection`+branch (không phụ thuộc thứ tự index JSXGraph).\n//\n// Phân phối: \"cắt L1, L2 tại X, Y\" → zip L1↔X, L2↔Y (kèm biến thể \"lần lượt\",\n// nối \"và\", tiền tố \"cạnh\"/\"các cạnh\"). Đường tròn KHÔNG tự dựng tam giác (triangle\n// rule lo) — chỉ emit đường tròn + các giao điểm.\n//\n// Fail-safe (escalate, thà thiếu hơn dựng sai):\n// - số cạnh ≠ số điểm → bỏ qua.\n// - cạnh không chia sẻ ĐÚNG 1 đỉnh với đường kính (0 → không biết điểm chung;\n// 2 → cạnh trùng đường kính, suy biến) → bỏ qua.\n// - tên điểm trùng đỉnh cạnh/đường kính (định nghĩa vòng) → bỏ qua.\n//\n// GOTCHA \\b: \\b của JS theo ASCII. Vùng tên điểm (\"M và N\", \"M, N\") các chữ HOA\n// luôn cách bởi dấu cách/phẩy nên \\b[A-Z]\\b an toàn; vẫn dùng cờ 'u'.\nimport type { LanguageRule, RuleMatch } from './_types';\nimport type { IntentT } from '../intent';\nimport { addPoint, drawCircle, CIRCLE_KW, DUONG_KW } from './_shared';\n\n// Anchor \"đường tròn đường kính PQ cắt <cạnh…> (lần lượt)? tại <điểm…>\".\n// lineRegion lazy tới \"tại\" đầu tiên; pointRegion tới hết clause (không . ; \\n).\nconst PATTERN = new RegExp(\n CIRCLE_KW +\n '\\\\s+' +\n DUONG_KW +\n '\\\\s*kính\\\\s+([A-Z])([A-Z])(?![A-Z])\\\\s+cắt\\\\s+([^.;\\\\n]*?)\\\\s+(?:lần\\\\s*lượt\\\\s+)?tại\\\\s+([^.;\\n]*)',\n 'u',\n);\n\nconst PREFILTER = new RegExp(DUONG_KW + '\\\\s*kính', 'u');\n\n/** Đỉnh chung DUY NHẤT giữa cạnh \"AB\" và đường kính \"BC\" (vd \"B\"). */\nfunction sharedVertex(line: string, dia: string): string | undefined {\n const shared = [line[0], line[1]].filter((ch) => dia.includes(ch));\n return shared.length === 1 ? shared[0] : undefined;\n}\n\nexport const diameterCircleCutsSidesRule: LanguageRule = {\n // THẤP HƠN triangle (100): cần A,B,C dựng trước khi secondIntersection tham\n // chiếu cạnh/đỉnh. Đặt 66 (cùng họ diameterCirclePairwise) — đủ thấp so với 100.\n id: 'diameter-circle-cuts-sides',\n priority: 66,\n languages: ['vi'],\n patterns: [PREFILTER],\n match(ctx) {\n const out: RuleMatch[] = [];\n for (const c of ctx.clauses) {\n const m = PATTERN.exec(c.text);\n if (!m) continue;\n\n const d0 = m[1];\n const d1 = m[2];\n const dia = d0 + d1; // \"BC\"\n const lines = m[3].match(/[A-Z][A-Z](?![A-Z])/gu) ?? [];\n const points = m[4].match(/\\b[A-Z]\\b/gu) ?? [];\n\n // Phân phối 1-1: cần ≥1 cạnh và số cạnh == số điểm.\n if (lines.length === 0 || lines.length !== points.length) continue;\n\n const circle = `k${dia}`;\n const intents: IntentT[] = [\n drawCircle(circle, 'diameter', { endpoints: [d0, d1] }),\n ];\n\n let ok = true;\n const seen = new Set<string>();\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const pt = points[i];\n const other = sharedVertex(line, dia);\n // Cần đúng 1 đỉnh chung (điểm đã biết trên cả cạnh lẫn đường tròn).\n if (!other) { ok = false; break; }\n // Tên điểm phải MỚI, không trùng đỉnh cạnh/đường kính.\n if (line.includes(pt) || dia.includes(pt) || seen.has(pt)) { ok = false; break; }\n seen.add(pt);\n intents.push(addPoint(pt, { kind: 'secondIntersection', line, circle, other }));\n }\n if (!ok) continue;\n\n out.push({ ruleId: 'diameter-circle-cuts-sides', clauseIds: [c.id], intents });\n }\n return out;\n },\n};\n","// src/stamps/geometry-2d/ai/rules/registry.ts\n//\n// Đăng ký rule + engine chạy theo priority. Thêm construct mới = import module\n// + thêm vào ALL_RULES (không sửa engine).\nimport type { LanguageRule, RuleContext, RuleMatch } from './_types';\nimport { triangleRule } from './triangle';\nimport { quadRule } from './quad';\nimport { connectRule } from './connect';\nimport { midpointRule } from './midpoint';\nimport { perpBisectorRule } from './perpBisector';\nimport { cevianRule } from './cevian';\nimport { angleBisectorAngleRule } from './angleBisectorAngle';\nimport { centersRule } from './centers';\nimport { perpFootRule } from './perpFoot';\nimport { circleRadiusRule } from './circleRadius';\nimport { circleTriangleRule } from './circleTriangle';\nimport { tangentFromExtRule } from './tangentFromExt';\nimport { externalPointRule } from './externalPoint';\nimport { arcMidpointRule } from './arcMidpoint';\nimport { excenterRule } from './excenter';\nimport { parallelPerpRule } from './parallelPerp';\nimport { reflectionRule } from './reflection';\nimport { pointAtDistanceRule } from './pointAtDistance';\nimport { eulerLineRule } from './eulerLine';\nimport { radicalAxisRule } from './radicalAxis';\nimport { simsonRule } from './simson';\nimport { ninePointRule } from './ninePoint';\nimport { diameterCirclePairwiseRule } from './diameterCirclePairwise';\nimport { angleBisectorFootRule } from './angleBisectorFoot';\nimport { intersectionRule } from './intersection';\nimport { chordRule } from './chord';\nimport { incircleTangencyRule } from './incircleTangency';\nimport { altitudeDiameterCirclesRule } from './altitudeDiameterCircles';\nimport { diameterCircleCutsSidesRule } from './diameterCircleCutsSides';\n\nconst RULES: readonly LanguageRule[] = [\n triangleRule,\n quadRule,\n connectRule,\n midpointRule,\n perpBisectorRule,\n cevianRule,\n angleBisectorAngleRule,\n centersRule,\n perpFootRule,\n circleRadiusRule,\n circleTriangleRule,\n tangentFromExtRule,\n externalPointRule,\n arcMidpointRule,\n excenterRule,\n parallelPerpRule,\n reflectionRule,\n pointAtDistanceRule,\n eulerLineRule,\n radicalAxisRule,\n simsonRule,\n ninePointRule,\n diameterCirclePairwiseRule,\n angleBisectorFootRule,\n intersectionRule,\n chordRule,\n incircleTangencyRule,\n altitudeDiameterCirclesRule,\n diameterCircleCutsSidesRule,\n];\n\n/** Sắp xếp priority giảm dần (cao chạy trước) — tính 1 lần ở module load. */\nexport const ALL_RULES: readonly LanguageRule[] = [...RULES].sort(\n (a, b) => b.priority - a.priority,\n);\n\nexport function runRules(ctx: RuleContext): RuleMatch[] {\n const matches: RuleMatch[] = [];\n for (const rule of ALL_RULES) {\n if (!rule.patterns.some((p) => p.test(ctx.problem))) continue;\n matches.push(...rule.match(ctx));\n }\n return matches;\n}\n","// src/stamps/geometry-2d/ai/deterministic/runDeterministicIntents.ts\n//\n// Track A orchestrator: rule engine → IntentT[] + coverage gate.\n// Chỉ lo NLU; gate transpile/verify do router (buildFigureIntent) áp dụng sau.\nimport type { IntentT } from '../intent';\nimport { segmentClauses, computeCoverage, type Clause, type CoverageReport } from './coverage';\nimport { runRules } from '../rules/registry';\n\nexport type DetIntentResult =\n | { ok: true; intents: IntentT[]; coverage: CoverageReport }\n | {\n ok: false;\n reason: 'incomplete-coverage' | 'no-match';\n coverage: CoverageReport;\n };\n\ninterface Collected {\n /** Intent từ MỌI clause có rule claim, deduped theo JSON. */\n intents: IntentT[];\n coverage: CoverageReport;\n matchCount: number;\n}\n\n// Segment → rules → coverage → dedup. Dùng chung cho gate đầy đủ\n// (runDeterministicIntents) lẫn partial (tryPartialDeterministic).\n// Dedupe intent y hệt nhau: nhiều rule cùng tham chiếu 1 hình (vd \"tam giác ABC\"\n// xuất hiện ở nhiều clause → triangle rule emit lặp; centers/cevian cũng cần nó).\nfunction collectDeterministic(problem: string): Collected {\n const clauses = segmentClauses(problem);\n const matches = runRules({ problem, clauses });\n const coverage = computeCoverage(clauses, matches);\n\n const seen = new Set<string>();\n const intents = matches\n .flatMap((m) => m.intents)\n .filter((i) => {\n const key = JSON.stringify(i);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n return { intents, coverage, matchCount: matches.length };\n}\n\nexport function runDeterministicIntents(problem: string): DetIntentResult {\n const { intents, coverage, matchCount } = collectDeterministic(problem);\n\n if (matchCount === 0) return { ok: false, reason: 'no-match', coverage };\n if (!coverage.complete) return { ok: false, reason: 'incomplete-coverage', coverage };\n return { ok: true, intents, coverage };\n}\n\nexport interface PartialDeterministicResult {\n /** Intent deterministic từ các clause đã được rule claim (deduped). */\n detIntents: IntentT[];\n /** Clause geo CHƯA được phủ — phần LLM cần bù (hybrid Phase 2). */\n uncovered: Clause[];\n coverage: CoverageReport;\n /**\n * true khi deterministic phủ MỘT PHẦN: có rule match + ≥1 intent NHƯNG coverage\n * CHƯA đầy đủ. Đây là điều kiện kích hoạt hybrid (Phase 2 gọi LLM bù `uncovered`\n * rồi mergeIntents). false khi: complete (Track A lo đủ) hoặc no-match/0 intent\n * (full LLM Track B).\n */\n hasPartial: boolean;\n}\n\n/**\n * Deterministic-only (KHÔNG LLM): thu intent phần đã phủ + clause còn thiếu, kể\n * cả khi coverage incomplete. Nền cho hybrid partial-coverage — Phase 2 sẽ gọi\n * LLM bù `uncovered` rồi `mergeIntents(detIntents, llmIntents)`.\n */\nexport function tryPartialDeterministic(problem: string): PartialDeterministicResult {\n const { intents, coverage, matchCount } = collectDeterministic(problem);\n return {\n detIntents: intents,\n uncovered: coverage.uncovered,\n coverage,\n hasPartial: matchCount > 0 && !coverage.complete && intents.length > 0,\n };\n}\n","// src/stamps/geometry-2d/ai/deterministic/guards.ts\n//\n// Hai guard fail-safe cho deterministic-first: nếu DSL dựng được KHÔNG trung thành\n// với đề, router escalate AI thay vì render hình sai/thiếu. Bổ sung cho coverage\n// clause-level (vốn coarse, dễ bỏ lọt khi 1 clause chứa nhiều construct).\nimport type { DslInputT } from '../../dsl/schema';\nimport type { IntentT } from '../intent';\n\n// ── Guard 1: named-entity present ────────────────────────────────────────────\n// Mọi đỉnh/điểm được ĐẶT TÊN hay KHAI BÁO trong đề phải tồn tại trong DSL.\n// KHÔNG dùng \\b (ASCII) quanh ký tự Việt.\n\n// Tên điểm dẫn nhập 1 ký tự HOA: \"Gọi M\", \"lấy điểm D\", \"cắt … tại D\", \"N là …\",\n// \"H, K lần lượt\", \"và P là\".\n// Issue #46 nhóm A: prime (' U+0027 / ′ U+2032) là PHẦN của tên (\"D′\" ≠ \"D\").\n// Group prime đứng ngay sau chữ cái — collect bằng letter + normalize(prime) để\n// expected-name khớp DSL (rule pointAtDistance giữ prime → DSL có \"D'\").\nconst NAMED_INTRO = /(?:Gọi|gọi|Lấy|lấy|Dựng|dựng|Đặt|đặt|tại|điểm|và)\\s+(?:điểm\\s+)?([A-Z])(['′]?)(?![A-Za-z])/gu;\n// LƯU Ý: KHÔNG dùng `là\\b` — `\\b` của JS theo ASCII, mà 'à' (U+00E0) là\n// non-word-char ASCII → `\\b` sau 'là' KHÔNG khớp khi theo sau là space/dấu câu\n// → pattern chết, bỏ sót mọi \"X là <construct>\" (bug silent-incomplete). Dùng\n// lookahead non-letter Unicode (?!\\p{L}) để neo cuối \"là\".\nconst NAMED_LA = /([A-Z])(['′]?)(?![A-Za-z])\\s+là(?!\\p{L})/gu;\nconst NAMED_LANLUOT = /([A-Z])(['′]?)(?![A-Za-z])\\s*,\\s*([A-Z])(['′]?)(?![A-Za-z])\\s+lần lượt/gu;\n\n// Ghép chữ cái + prime đã normalize (′→') thành tên đầy đủ. Đồng bộ với\n// rules/pointAtDistance.ts normalizePointName — giữ naming layer nhất quán.\nfunction joinPrime(letter: string | undefined, prime: string | undefined): string | undefined {\n if (!letter) return undefined;\n return prime ? `${letter}'` : letter;\n}\n\n// Đỉnh của hình khai báo: \"tam giác ABC\", \"tứ giác ABCD\", \"hình vuông/… ABCD\".\n// Bắt cụm 3-4 ký tự HOA LIỀN ngay sau tên hình (mỗi đỉnh phải có trong DSL).\nconst SHAPE_TRI = /tam giác\\s+([A-Z]{3})(?![A-Z])/gu;\nconst SHAPE_QUAD = /(?:tứ giác|hình\\s+(?:vuông|chữ nhật|bình hành|thoi|thang))\\s+([A-Z]{4})(?![A-Z])/gu;\n\nexport interface NamedEntityReport {\n ok: boolean;\n missing: string[];\n}\n\nfunction collectExpectedNames(problem: string): Set<string> {\n const names = new Set<string>();\n // Mỗi entry [letterGroup, primeGroup]: tên = letter + normalize(prime).\n const add = (re: RegExp, groups: [number, number][]) => {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(problem)) !== null) {\n for (const [lg, pg] of groups) {\n const name = joinPrime(m[lg], m[pg]);\n if (name) names.add(name);\n }\n }\n };\n add(NAMED_INTRO, [[1, 2]]);\n add(NAMED_LA, [[1, 2]]);\n add(NAMED_LANLUOT, [[1, 2], [3, 4]]);\n // Đỉnh hình: tách cụm 3/4 ký tự thành từng đỉnh.\n for (const re of [SHAPE_TRI, SHAPE_QUAD]) {\n re.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = re.exec(problem)) !== null) {\n for (const ch of m[1]) names.add(ch);\n }\n }\n return names;\n}\n\nexport function allNamedEntitiesPresent(problem: string, dsl: DslInputT): NamedEntityReport {\n const present = new Set<string>();\n for (const p of dsl.points) present.add(p.name);\n for (const s of dsl.shapes) present.add(s.name);\n\n const missing: string[] = [];\n for (const name of collectExpectedNames(problem)) {\n if (!present.has(name)) missing.push(name);\n }\n return { ok: missing.length === 0, missing };\n}\n\n// ── Guard 2: intent → DSL fidelity ───────────────────────────────────────────\n// Mỗi add-point intent dựng điểm phái sinh (không phải 'free') PHẢI hiện diện\n// trong DSL đúng dạng. Builder idempotent DROP add-point khi tên trùng đỉnh sẵn\n// có (vd \"đường cao AB\" → foot B trùng vertex B) → điểm để 'free' → guard bắt.\n\nexport interface FidelityReport {\n ok: boolean;\n dropped: string[];\n}\n\nexport function verifyIntentFidelity(intents: readonly IntentT[], dsl: DslInputT): FidelityReport {\n const byName = new Map<string, { kind: string }>();\n for (const p of dsl.points) byName.set(p.name, p as unknown as { kind: string });\n\n const dropped: string[] = [];\n for (const intent of intents) {\n if (intent.op !== 'add-point') continue;\n const kind = (intent as { constraint?: { kind?: string } }).constraint?.kind;\n // free point không phải construct phái sinh → skip fidelity.\n // externalToCircle CỐ TÌNH dựng FREE point ngoài circle (như fixture canonical\n // tangent-from-external-named.ts): builder đặt A kind 'free' tại coord ngoài\n // circle, KHÔNG phải điểm phái sinh đặc thù bị drop. Nếu builder fail-safe skip\n // (circle thiếu / tâm không free) → A missing → guard allNamedEntitiesPresent\n // bắt (named-missing). Vì vậy bỏ externalToCircle khỏi fidelity check.\n if (!kind || kind === 'free' || kind === 'externalToCircle') continue;\n const name = (intent as { name: string }).name;\n const pt = byName.get(name);\n // Thiếu hẳn, hoặc bị builder hạ về 'free' (đã bị drop bởi vertex trùng tên).\n if (!pt || pt.kind === 'free') dropped.push(name);\n }\n return { ok: dropped.length === 0, dropped };\n}\n","// src/stamps/geometry-2d/ai/normalizeIntent.ts\n//\n// Post-LLM variant normalizer cho Intent pipeline.\n//\n// Mục đích: fix 2 nhóm bias quan sát được trong eval gemma3:12b:\n// 1. LLM emit isoceles variant SAI position (vd \"cân tại A\" → 'isoceles-AB'\n// thay vì 'isoceles-BC') vì naming rule canonical không trực giác.\n// 2. LLM follow prompt \"rectangle: wide | tall\" → emit 'wide' trong khi\n// eval + đa số sản phẩm muốn 'standard' (rendering identical với 'wide').\n//\n// Pure function, không mutate input.\n\nimport type { IntentT, DrawShapeIntentT, DrawLineIntentT } from './intent';\n\nconst CAN_TAI_RE = /c[aâ]n\\s+t[aạ]i\\s+([A-Z])/i;\nconst ISOCELES_AT_RE = /isoceles\\s+(?:at|with\\s+apex)\\s+([A-Z])/i;\nconst TALL_RECT_RE = /(cao|hẹp|thin|tall|portrait)/i;\n\n/**\n * Apply variant normalization. Returns new array; input unmodified.\n *\n * Rules áp dụng (chỉ override khi MATCH chắc; otherwise pass-through):\n * - triangle + \"cân tại X\" → variant theo position của X trong labels\n * - rectangle: default 'standard' (giữ 'tall' khi đề có \"cao\"/\"hẹp\")\n * - square|rhombus|parallelogram: ép 'standard' (chỉ 1 variant hợp lệ)\n */\nexport function normalizeIntents(\n intents: readonly IntentT[],\n problem: string,\n): IntentT[] {\n // Đếm tam giác: chỉ normalize \"cân tại X\" khi đề có ĐÚNG 1 tam giác — đa tam\n // giác thì không thể bind \"cân tại X\" toàn-problem cho đúng tam giác, mà rule\n // deterministic (window) / LLM đã set variant per-intent → tin theo đó.\n const triangleCount = intents.filter(\n (i) => i.op === 'draw-shape' && i.shape === 'triangle',\n ).length;\n return intents.map((intent) => {\n if (intent.op === 'draw-shape') return normalizeShape(intent, problem, triangleCount);\n if (intent.op === 'draw-line') return normalizeLine(intent);\n return intent;\n });\n}\n\n// Builder enforce strict field per kind. LLM nhầm field giữa các kind cùng\n// schema (through/from/to/circle/which đều optional). Fix: swap field khi\n// pattern rõ ràng (no ambiguity).\n//\n// Rules:\n// - tangentAt cần `through` (điểm trên đường tròn). Nếu LLM dùng `from` → swap.\n// - tangentFromExt cần `from` (điểm ngoài). Nếu LLM dùng `through` → swap.\n// - perpThrough / parallelThrough cần `through` (điểm) + `to` (line).\n// Nếu LLM dùng `from` thay `through` → swap.\nfunction normalizeLine(intent: DrawLineIntentT): DrawLineIntentT {\n if (intent.kind === 'tangentAt' && intent.from && !intent.through) {\n const { from, ...rest } = intent;\n return { ...rest, through: from };\n }\n if (intent.kind === 'tangentFromExt' && intent.through && !intent.from) {\n const { through, ...rest } = intent;\n return { ...rest, from: through };\n }\n if (\n (intent.kind === 'perpThrough' || intent.kind === 'parallelThrough') &&\n intent.from &&\n !intent.through\n ) {\n const { from, ...rest } = intent;\n return { ...rest, through: from };\n }\n return intent;\n}\n\nfunction normalizeShape(\n intent: DrawShapeIntentT,\n problem: string,\n triangleCount: number,\n): IntentT {\n switch (intent.shape) {\n case 'triangle':\n return normalizeTriangle(intent, problem, triangleCount);\n case 'rectangle':\n return normalizeRectangle(intent, problem);\n case 'square':\n case 'rhombus':\n case 'parallelogram':\n return forceStandard(intent);\n default:\n return intent;\n }\n}\n\nfunction normalizeRectangle(\n intent: DrawShapeIntentT,\n problem: string,\n): DrawShapeIntentT {\n if (intent.variant === 'tall' && TALL_RECT_RE.test(problem)) return intent;\n if (intent.variant === 'standard') return intent;\n return { ...intent, variant: 'standard' };\n}\n\nfunction forceStandard(intent: DrawShapeIntentT): DrawShapeIntentT {\n if (intent.variant === 'standard') return intent;\n return { ...intent, variant: 'standard' };\n}\n\nfunction normalizeTriangle(\n intent: DrawShapeIntentT,\n problem: string,\n triangleCount: number,\n): DrawShapeIntentT {\n // Đa tam giác: không clobber — variant đã được set đúng per-intent ở nguồn.\n if (triangleCount !== 1) return intent;\n const m = problem.match(CAN_TAI_RE) ?? problem.match(ISOCELES_AT_RE);\n if (!m) return intent;\n const apex = m[1].toUpperCase();\n const i = intent.labels.indexOf(apex);\n if (i < 0) return intent;\n // Variant POSITIONAL theo INDEX apex (builder: isoceles-BC ⇒ apex=vertex[0]).\n // KHÔNG dùng chữ-cái-nhãn để đúng cho nhãn ≠ ABC.\n const variantByPos: Record<number, DrawShapeIntentT['variant']> = {\n 0: 'isoceles-BC',\n 1: 'isoceles-CA',\n 2: 'isoceles-AB',\n };\n const target = variantByPos[i];\n if (!target || intent.variant === target) return intent;\n return { ...intent, variant: target };\n}\n","// src/stamps/geometry-2d/ai/resolveCircleNames.ts\n//\n// Preprocessor giải quyết naming collision giữa circle name và point ref.\n// DSL schema enforce global-unique name (point + shape share namespace), nên\n// circle X + point X không cùng tồn tại được. Notation Việt \"(O)\" thường ám\n// chỉ TÂM (point) của đường tròn, nhưng Claude/LLM hay đặt circle name là \"O\"\n// → connect M→O segment fail KIND_MISMATCH.\n//\n// Pure function — không gọi AI, idempotent:\n// 1. Detect circle names được reference như point trong intent khác\n// 2. Inject add-point center (circumcenter/incenter dựa trên spec) BEFORE circle\n// 3. Rename circle \"X\" → \"X_c\"\n// 4. Rewrite các CIRCLE-context ref tới circle name → \"X_c\"\n\nimport type { IntentT } from './intent';\n\nexport function resolveCircleNameCollisions(intents: readonly IntentT[]): IntentT[] {\n const circleNames = new Set<string>();\n for (const i of intents) {\n if (i.op === 'draw-circle') circleNames.add(i.name);\n }\n if (circleNames.size === 0) return [...intents];\n\n const pointRefs = collectPointRefs(intents);\n\n const existingPoints = new Set<string>();\n for (const i of intents) {\n if (i.op === 'draw-shape') {\n for (const l of i.labels) existingPoints.add(l);\n } else if (i.op === 'add-point') {\n existingPoints.add(i.name);\n }\n }\n\n const collisions = new Set<string>();\n for (const name of circleNames) {\n if (pointRefs.has(name)) collisions.add(name);\n }\n if (collisions.size === 0) return [...intents];\n\n const rename = new Map<string, string>();\n for (const name of collisions) {\n rename.set(name, `${name}_c`);\n }\n\n const result: IntentT[] = [];\n for (const i of intents) {\n if (i.op === 'draw-circle' && collisions.has(i.name)) {\n if (!existingPoints.has(i.name)) {\n const centerIntent = makeCenterIntent(i);\n if (centerIntent) {\n result.push(centerIntent);\n existingPoints.add(i.name);\n }\n }\n result.push({ ...i, name: rename.get(i.name)! });\n } else {\n result.push(rewriteCircleRefs(i, rename));\n }\n }\n\n return result;\n}\n\nfunction makeCenterIntent(circle: Extract<IntentT, { op: 'draw-circle' }>): IntentT | null {\n if (circle.spec === 'through3' && circle.points) {\n return {\n op: 'add-point',\n name: circle.name,\n constraint: { kind: 'circumcenter', of: circle.points },\n };\n }\n if (circle.spec === 'inscribedIn' && circle.triangle) {\n return {\n op: 'add-point',\n name: circle.name,\n constraint: { kind: 'incenter', of: circle.triangle },\n };\n }\n // centerThrough/centerRadius: AI nhiều khi đặt `center === name` (vd `(O)` =\n // circle \"O\" có center \"O\") — cần inject `add-point name=center kind=free`\n // để point tồn tại sau khi circle được rename. Trường hợp center khác name\n // thì caller phải đảm bảo point center đã tồn tại (preprocessor không derive).\n if (\n (circle.spec === 'centerThrough' || circle.spec === 'centerRadius') &&\n circle.center === circle.name\n ) {\n return {\n op: 'add-point',\n name: circle.name,\n constraint: { kind: 'free' },\n };\n }\n return null;\n}\n\nfunction collectPointRefs(intents: readonly IntentT[]): Set<string> {\n const refs = new Set<string>();\n // 2-letter line/edge ref (vd \"BC\", \"AO\") → tách thành single-letter chars.\n // Cần thiết để detect collision khi line ref CHỨA tên circle (vd `line:\"AO\"`\n // + circle name \"O\" → O dùng như point ở \"AO\", phải inject center O).\n const addEdgeRef = (ref: string) => {\n if (/^[A-Za-z]{2}$/.test(ref)) {\n refs.add(ref[0]);\n refs.add(ref[1]);\n }\n };\n for (const i of intents) {\n if (i.op === 'connect') {\n refs.add(i.from);\n refs.add(i.to);\n } else if (i.op === 'add-point') {\n const c = i.constraint;\n if (c.kind === 'centroid' || c.kind === 'circumcenter' || c.kind === 'incenter' || c.kind === 'orthocenter') {\n for (const v of c.of) refs.add(v);\n } else if (c.kind === 'perpFoot' || c.kind === 'angleBisectorFoot') {\n refs.add(c.from);\n addEdgeRef(c.onLine);\n } else if (c.kind === 'tangentPoint') {\n refs.add(c.from);\n } else if (c.kind === 'secondIntersection') {\n refs.add(c.other);\n addEdgeRef(c.line);\n } else if (c.kind === 'tangencyPoint') {\n addEdgeRef(c.onLine);\n } else if (c.kind === 'midpoint' || c.kind === 'onSegment') {\n addEdgeRef(c.of);\n } else if (c.kind === 'intersection') {\n for (const r of c.of) addEdgeRef(r);\n }\n } else if (i.op === 'draw-circle') {\n if (i.center) refs.add(i.center);\n if (i.through) refs.add(i.through);\n if (i.points) for (const p of i.points) refs.add(p);\n if (i.triangle) for (const p of i.triangle) refs.add(p);\n } else if (i.op === 'draw-line') {\n if (i.through) refs.add(i.through);\n if (i.from) refs.add(i.from);\n if (i.to) addEdgeRef(i.to);\n // i.circle là circle ref — skip.\n } else if (i.op === 'mark-shape') {\n for (const l of i.labels) refs.add(l);\n }\n }\n return refs;\n}\n\nfunction rewriteCircleRefs(intent: IntentT, rename: Map<string, string>): IntentT {\n if (intent.op === 'add-point') {\n const c = intent.constraint;\n if (\n c.kind === 'tangencyPoint' ||\n c.kind === 'tangentPoint' ||\n c.kind === 'secondIntersection' ||\n c.kind === 'externalToCircle' ||\n c.kind === 'onCircle'\n ) {\n const newCircle = rename.get(c.circle);\n if (newCircle) {\n return { ...intent, constraint: { ...c, circle: newCircle } };\n }\n } else if (c.kind === 'circleIntersection') {\n const newC1 = rename.get(c.c1) ?? c.c1;\n const newC2 = rename.get(c.c2) ?? c.c2;\n if (newC1 !== c.c1 || newC2 !== c.c2) {\n return { ...intent, constraint: { ...c, c1: newC1, c2: newC2 } };\n }\n }\n } else if (intent.op === 'draw-line') {\n if (intent.circle && rename.has(intent.circle)) {\n return { ...intent, circle: rename.get(intent.circle)! };\n }\n if (intent.kind === 'radicalAxis') {\n const n1 = intent.circle1 ? rename.get(intent.circle1) : undefined;\n const n2 = intent.circle2 ? rename.get(intent.circle2) : undefined;\n if (n1 || n2) {\n return { ...intent, circle1: n1 ?? intent.circle1, circle2: n2 ?? intent.circle2 };\n }\n }\n }\n return intent;\n}\n","import type { DslPointT, DslShapeT } from '../dsl/schema';\n\n// Reposition auto-injected circle centers so two circles referenced by a\n// `circleIntersection` point actually cross at TWO points.\n//\n// Bối cảnh: builder inject free coord cho circle center theo bảng spread cách\n// nhau ~6 unit. Hai circle centerRadius cùng r=3 → distance = 6 = r1+r2 →\n// tiếp xúc ngoài (1 điểm) → JSXGraph intersection branch 0/1 trùng nhau hoặc\n// NaN → cascade hỏng (bug eval cau-08). Disjoint (d > r1+r2) còn tệ hơn.\n//\n// Điều kiện 2 giao điểm: |r1-r2| < d < r1+r2.\n// Khi d nằm ngoài \"vùng an toàn\" (sát biên tiếp xúc / disjoint), dời 1 center\n// FREE dọc theo hướng hiện tại về khoảng cách mục tiêu = trung điểm của khoảng\n// hợp lệ = (|r1-r2| + r1+r2)/2 = max(r1, r2). Giữ nguyên hướng để bố cục tương\n// đối không đảo lộn.\n\ntype FreePoint = Extract<DslPointT, { kind: 'free' }>;\n\n/** Resolve toạ độ tĩnh cho center (free hoặc midpoint của free/midpoint). */\nfunction resolveCoord(points: DslPointT[], name: string): [number, number] | null {\n const p = points.find((x) => x.name === name);\n if (!p) return null;\n if (p.kind === 'free') return [p.x, p.y];\n if (p.kind === 'midpoint') {\n const a = resolveCoord(points, p.p1);\n const b = resolveCoord(points, p.p2);\n if (!a || !b) return null;\n return [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n }\n return null;\n}\n\nexport function repairCircleIntersections(points: DslPointT[], shapes: DslShapeT[]): void {\n const shapeByName = new Map(shapes.map((s) => [s.name, s]));\n\n for (const pt of points) {\n if (pt.kind !== 'circleIntersection') continue;\n const c1 = shapeByName.get(pt.c1);\n const c2 = shapeByName.get(pt.c2);\n if (!c1 || !c2 || c1.kind !== 'circleCR' || c2.kind !== 'circleCR') continue;\n\n const r1 = c1.radius;\n const r2 = c2.radius;\n const lower = Math.abs(r1 - r2);\n const upper = r1 + r2;\n\n const coord1 = resolveCoord(points, c1.center);\n const coord2 = resolveCoord(points, c2.center);\n if (!coord1 || !coord2) continue;\n\n const d = Math.hypot(coord1[0] - coord2[0], coord1[1] - coord2[1]);\n const safeLow = lower * 1.05 + 1e-6;\n const safeHigh = upper * 0.95;\n if (d > safeLow && d < safeHigh) continue; // đã cắt 2 điểm gọn gàng\n\n // Cần 1 center FREE để dời. Ưu tiên center của c2 (thường inject sau), fallback c1.\n const p1 = points.find((p) => p.name === c1.center);\n const p2 = points.find((p) => p.name === c2.center);\n let mover: FreePoint | undefined;\n let anchor: [number, number] | undefined;\n if (p2?.kind === 'free') { mover = p2; anchor = coord1; }\n else if (p1?.kind === 'free') { mover = p1; anchor = coord2; }\n if (!mover || !anchor) continue; // không có center free để dời an toàn\n\n const targetD = (lower + upper) / 2; // = max(r1, r2)\n let dx = mover.x - anchor[0];\n let dy = mover.y - anchor[1];\n const len = Math.hypot(dx, dy);\n if (len < 1e-9) { dx = 1; dy = 0; }\n const norm = Math.hypot(dx, dy) || 1;\n mover.x = anchor[0] + (targetD * dx) / norm;\n mover.y = anchor[1] + (targetD * dy) / norm;\n }\n}\n","// src/stamps/geometry-2d/dsl/names.ts\nimport { z } from 'zod';\n\n// Label-style name: chữ cái Latin đầu, cho phép unicode prime (') + subscript ₀-₉.\n// Max length 12 ký tự. Phân biệt hoa/thường.\nexport const NameZ = z\n .string()\n .regex(/^[A-Za-z][A-Za-z0-9_'₀-₉]{0,11}$/);\n","// src/stamps/geometry-2d/dsl/kinds/_types.ts\nimport type { z } from 'zod';\nimport type { SceneObject } from '../../../../core/scene/types';\n\nexport type KindRole =\n | 'point'\n | 'segment'\n | 'line'\n | 'ray'\n | 'lineConstruction'\n | 'circle'\n | 'polygon';\n\nexport type KindCategory = 'points' | 'lines' | 'polygons' | 'circles' | 'compound';\n\n/** Vai trò ref mà một field của kind yêu cầu — dùng cho validateRefs registry-driven. */\nexport type RefRole =\n | 'point'\n | 'line-like'\n | 'circle'\n | 'segment'\n | 'shape'\n | 'any-existing';\n\nexport interface RefSpec {\n /** Tên field trên entity chứa ref (vd 'from', 'circle', 'vertices'). */\n field: string;\n role: RefRole;\n /** field là mảng tên (vd vertices[]). */\n many?: boolean;\n}\n\nexport interface EmitContext {\n /** Look up the scene-object id assigned to a DSL symbol name. */\n resolveId(name: string): string;\n /** Hint lookup for intersection-style emit needing to know what a referenced symbol is. */\n hintOf(name: string): KindRole;\n /** Generate a unique auxiliary id for an internal entity (not addressable from DSL). */\n mintAuxId(parentName: string, suffix: string): string;\n}\n\nexport interface EmittedEntity {\n /** The first emitted entity per kind MUST have role 'primary'. */\n role: 'primary' | 'auxiliary';\n object: SceneObject;\n}\n\nexport interface DslKindModule<TKind extends string = string, TInput = unknown> {\n kind: TKind;\n role: KindRole;\n category: KindCategory;\n prefix: string;\n schema: z.ZodObject<any>;\n collectRefs: (entity: TInput) => string[];\n /**\n * Khai báo ref requirements để validateRefs kiểm tra unknown/mismatch mà không\n * cần switch theo kind. Dạng hàm cho kind có ref phụ thuộc discriminated union\n * (vd pointAtDistance.distance). Kind chưa khai → validateRefs dùng legacy switch.\n */\n refSpecs?: readonly RefSpec[] | ((entity: TInput) => readonly RefSpec[]);\n emit: (entity: TInput, ctx: EmitContext) => EmittedEntity[];\n}\n\n/**\n * Factory that widens a typed module into the registry's generic shape.\n * Each kind module exports its module via this factory so `ALL_MODULES`\n * in registry.ts can be typed as ReadonlyArray<DslKindModule> without a cast.\n */\nexport function defineModule<TKind extends string, TInput>(\n m: DslKindModule<TKind, TInput>,\n): DslKindModule {\n return m as DslKindModule;\n}\n","// src/stamps/geometry-2d/dsl/kinds/_shared.ts\nimport type { SceneObject } from '../../../../core/scene/types';\nimport type { EmitContext } from './_types';\n\nexport const POINT_BASE_FIELDS = {\n visible: true,\n locked: false,\n layer: 'default',\n schemaVersion: 1,\n} as const;\n\n/** Wrap a Constraint2D-style attrs into a primary 'point' SceneObject. */\nexport function emitPointObject(\n id: string,\n name: string,\n constraint: Record<string, unknown>,\n visible = true,\n): SceneObject {\n return {\n id,\n kind: 'point',\n label: name,\n ...POINT_BASE_FIELDS,\n visible,\n attrs: { constraint },\n };\n}\n\n/** Resolve a triangle's 3 vertex ids. */\nexport function resolveTriangleVertices(\n ctx: EmitContext,\n vertices: readonly [string, string, string],\n): [string, string, string] {\n return [ctx.resolveId(vertices[0]), ctx.resolveId(vertices[1]), ctx.resolveId(vertices[2])];\n}\n\nexport const SHAPE_BASE_FIELDS = {\n visible: true,\n locked: false,\n layer: 'default',\n schemaVersion: 1,\n} as const;\n","// src/stamps/geometry-2d/dsl/kinds/points/free.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'free' }>;\n\nexport const freeModule = defineModule<'free', Input>({\n kind: 'free',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('free'),\n x: z.number().finite(),\n y: z.number().finite(),\n }),\n collectRefs: () => [],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, { kind: 'free', x: e.x, y: e.y }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/midpoint.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'midpoint' }>;\n\nexport const midpointModule = defineModule<'midpoint', Input>({\n kind: 'midpoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('midpoint'),\n p1: NameZ,\n p2: NameZ,\n visible: z.boolean().optional(),\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'midpoint', p1: ctx.resolveId(e.p1), p2: ctx.resolveId(e.p2) },\n e.visible ?? true,\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/onSegment.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'onSegment' }>;\n\nexport const onSegmentModule = defineModule<'onSegment', Input>({\n kind: 'onSegment',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('onSegment'),\n segmentId: NameZ,\n t: z.number().min(0).max(1),\n }),\n collectRefs: (e) => [e.segmentId],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'onSegment', segmentId: ctx.resolveId(e.segmentId), t: e.t },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/onLine.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'onLine' }>;\n\nexport const onLineModule = defineModule<'onLine', Input>({\n kind: 'onLine',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('onLine'),\n lineId: NameZ,\n t: z.number().finite(),\n }),\n collectRefs: (e) => [e.lineId],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'onLine', lineId: ctx.resolveId(e.lineId), t: e.t },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/onCircle.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'onCircle' }>;\n\nexport const onCircleModule = defineModule<'onCircle', Input>({\n kind: 'onCircle',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('onCircle'),\n circleId: NameZ,\n theta: z.number().finite(),\n }),\n collectRefs: (e) => [e.circleId],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'onCircle', circleId: ctx.resolveId(e.circleId), theta: e.theta },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/perpFoot.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'perpFoot' }>;\n\nexport const perpFootModule = defineModule<'perpFoot', Input>({\n kind: 'perpFoot',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('perpFoot'),\n from: NameZ,\n onLine: NameZ,\n }),\n collectRefs: (e) => [e.from, e.onLine],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'perpFoot', from: ctx.resolveId(e.from), onLine: ctx.resolveId(e.onLine) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/circumcenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'circumcenter' }>;\n\nexport const circumcenterModule = defineModule<'circumcenter', Input>({\n kind: 'circumcenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circumcenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'circumcenter', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/incenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'incenter' }>;\n\nexport const incenterModule = defineModule<'incenter', Input>({\n kind: 'incenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('incenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'incenter', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/centroid.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'centroid' }>;\n\nexport const centroidModule = defineModule<'centroid', Input>({\n kind: 'centroid',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('centroid'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'centroid', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/orthocenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'orthocenter' }>;\n\nexport const orthocenterModule = defineModule<'orthocenter', Input>({\n kind: 'orthocenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('orthocenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n { kind: 'orthocenter', vertices: resolveTriangleVertices(ctx, e.vertices) },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/intersection.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { POINT_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'intersection' }>;\n\nexport const intersectionModule = defineModule<'intersection', Input>({\n kind: 'intersection',\n role: 'point',\n category: 'points',\n prefix: 'i',\n schema: z.object({\n name: NameZ,\n kind: z.literal('intersection'),\n ref1: NameZ,\n ref2: NameZ,\n branch: z.union([z.literal(0), z.literal(1)]).optional(),\n }),\n collectRefs: (e) => [e.ref1, e.ref2],\n emit: (e, ctx) => {\n const r1IsCircle = ctx.hintOf(e.ref1) === 'circle';\n const r2IsCircle = ctx.hintOf(e.ref2) === 'circle';\n let intersectKind: 'lineLine' | 'lineCircle' | 'circleCircle';\n if (r1IsCircle && r2IsCircle) intersectKind = 'circleCircle';\n else if (r1IsCircle || r2IsCircle) intersectKind = 'lineCircle';\n else intersectKind = 'lineLine';\n\n const attrs: Record<string, unknown> = {\n kind: intersectKind,\n ref1: ctx.resolveId(e.ref1),\n ref2: ctx.resolveId(e.ref2),\n };\n if (intersectKind !== 'lineLine') {\n attrs.branch = e.branch ?? 0;\n }\n return [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'intersection',\n label: e.name,\n ...POINT_BASE_FIELDS,\n attrs,\n },\n }];\n },\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/segment.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'segment' }>;\n\nexport const segmentModule = defineModule<'segment', Input>({\n kind: 'segment',\n role: 'segment',\n category: 'lines',\n prefix: 's',\n schema: z.object({\n name: NameZ,\n kind: z.literal('segment'),\n p1: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'segment',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { p1: ctx.resolveId(e.p1), p2: ctx.resolveId(e.p2) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/line.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'line' }>;\n\nexport const lineModule = defineModule<'line', Input>({\n kind: 'line',\n role: 'line',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('line'),\n p1: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { p1: ctx.resolveId(e.p1), p2: ctx.resolveId(e.p2) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/ray.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'ray' }>;\n\nexport const rayModule = defineModule<'ray', Input>({\n kind: 'ray',\n role: 'ray',\n category: 'lines',\n prefix: 'r',\n schema: z.object({\n name: NameZ,\n kind: z.literal('ray'),\n origin: NameZ,\n through: NameZ,\n }),\n collectRefs: (e) => [e.origin, e.through],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'ray',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { origin: ctx.resolveId(e.origin), through: ctx.resolveId(e.through) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/perpendicular.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'perpendicular' }>;\n\nexport const perpendicularModule = defineModule<'perpendicular', Input>({\n kind: 'perpendicular',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('perpendicular'),\n throughPoint: NameZ,\n toLine: NameZ,\n }),\n collectRefs: (e) => [e.throughPoint, e.toLine],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'perpendicular',\n throughPoint: ctx.resolveId(e.throughPoint),\n toLine: ctx.resolveId(e.toLine),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/parallel.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'parallel' }>;\n\nexport const parallelModule = defineModule<'parallel', Input>({\n kind: 'parallel',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('parallel'),\n throughPoint: NameZ,\n toLine: NameZ,\n }),\n collectRefs: (e) => [e.throughPoint, e.toLine],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'parallel',\n throughPoint: ctx.resolveId(e.throughPoint),\n toLine: ctx.resolveId(e.toLine),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/perpBisector.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'perpBisector' }>;\n\nexport const perpBisectorModule = defineModule<'perpBisector', Input>({\n kind: 'perpBisector',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('perpBisector'),\n p1: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'perpBisector',\n p1: ctx.resolveId(e.p1),\n p2: ctx.resolveId(e.p2),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/angleBisector.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'angleBisector' }>;\n\nexport const angleBisectorModule = defineModule<'angleBisector', Input>({\n kind: 'angleBisector',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('angleBisector'),\n p1: NameZ,\n vertex: NameZ,\n p2: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.vertex, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'angleBisector',\n p1: ctx.resolveId(e.p1),\n vertex: ctx.resolveId(e.vertex),\n p2: ctx.resolveId(e.p2),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/lineThrough.ts\n//\n// Đường thẳng qua ≥2 điểm đồng tuyến (vd 3 tâm Euler G/H/O). Render là đường\n// VÔ HẠN qua 2 điểm xa nhau nhất (ổn định số học). Kind tổng quát role\n// 'lineConstruction' — tái dùng cho Euler line (issue #47) và sau này Simson.\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport type { RefSpec } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'lineThrough' }>;\n\nexport const lineThroughModule = defineModule<'lineThrough', Input>({\n kind: 'lineThrough',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('lineThrough'),\n points: z.array(NameZ).min(2),\n }),\n collectRefs: (e) => [...e.points],\n refSpecs: [{ field: 'points', role: 'point', many: true }] as readonly RefSpec[],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'lineThrough',\n points: e.points.map((p) => ctx.resolveId(p)),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/radicalAxis.ts\n//\n// Trục đẳng phương 2 đường tròn (issue #47, construct 2): đường ⊥ đường nối tâm\n// O₁O₂, mọi điểm trên nó có lũy thừa (power) bằng nhau với 2 đường tròn. Kind\n// role 'lineConstruction' nhưng tham chiếu 2 CIRCLE (không phải điểm) — mirror\n// `lineThrough` về cấu trúc, khác ở refSpecs role 'circle'.\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport type { RefSpec } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'radicalAxis' }>;\n\nexport const radicalAxisModule = defineModule<'radicalAxis', Input>({\n kind: 'radicalAxis',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('radicalAxis'),\n circle1: NameZ,\n circle2: NameZ,\n }),\n collectRefs: (e) => [e.circle1, e.circle2],\n refSpecs: [\n { field: 'circle1', role: 'circle' },\n { field: 'circle2', role: 'circle' },\n ] as readonly RefSpec[],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'radicalAxis',\n circle1: ctx.resolveId(e.circle1),\n circle2: ctx.resolveId(e.circle2),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/lines/tangent.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'tangent' }>;\n\nexport const tangentModule = defineModule<'tangent', Input>({\n kind: 'tangent',\n role: 'lineConstruction',\n category: 'lines',\n prefix: 'l',\n schema: z.object({\n name: NameZ,\n kind: z.literal('tangent'),\n throughPoint: NameZ,\n toCircle: NameZ,\n branch: z.union([z.literal(0), z.literal(1), z.literal('on')]).optional(),\n }),\n collectRefs: (e) => [e.throughPoint, e.toCircle],\n emit: (e, ctx) => {\n const construction: Record<string, unknown> = {\n kind: 'tangent',\n throughPoint: ctx.resolveId(e.throughPoint),\n toCircle: ctx.resolveId(e.toCircle),\n };\n if (e.branch !== undefined) construction.branch = e.branch;\n return [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'line',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { construction },\n },\n }];\n },\n});\n","// src/stamps/geometry-2d/dsl/kinds/polygons/polygon.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'polygon' }>;\n\nexport const polygonModule = defineModule<'polygon', Input>({\n kind: 'polygon',\n role: 'polygon',\n category: 'polygons',\n prefix: 'poly',\n schema: z.object({\n name: NameZ,\n kind: z.literal('polygon'),\n vertices: z.array(NameZ).min(3),\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'polygon',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { vertices: e.vertices.map((v) => ctx.resolveId(v)) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/circles/circleCP.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circleCP' }>;\n\nexport const circleCPModule = defineModule<'circleCP', Input>({\n kind: 'circleCP',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleCP'),\n center: NameZ,\n surfacePoint: NameZ,\n visible: z.boolean().optional(),\n }),\n collectRefs: (e) => [e.center, e.surfacePoint],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n visible: e.visible ?? true,\n attrs: { center: ctx.resolveId(e.center), surfacePoint: ctx.resolveId(e.surfacePoint) },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/circles/circle3.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circle3' }>;\n\nexport const circle3Module = defineModule<'circle3', Input>({\n kind: 'circle3',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circle3'),\n p1: NameZ,\n p2: NameZ,\n p3: NameZ,\n }),\n collectRefs: (e) => [e.p1, e.p2, e.p3],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'circumscribed',\n p1: ctx.resolveId(e.p1),\n p2: ctx.resolveId(e.p2),\n p3: ctx.resolveId(e.p3),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/circles/circleDiameter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circleDiameter' }>;\n\n// Đường tròn đường kính p1p2 — tâm = trung điểm, bán kính = |p1p2|/2.\n// Emit circle với construction 'diameter'; renderer dựng midpoint ẩn + circle qua p2.\nexport const circleDiameterModule = defineModule<'circleDiameter', Input>({\n kind: 'circleDiameter',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleDiameter'),\n p1: NameZ,\n p2: NameZ,\n visible: z.boolean().optional(),\n }),\n collectRefs: (e) => [e.p1, e.p2],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n visible: e.visible ?? true,\n attrs: {\n construction: {\n kind: 'diameter',\n p1: ctx.resolveId(e.p1),\n p2: ctx.resolveId(e.p2),\n },\n },\n },\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'secondIntersection' }>;\n\nexport const secondIntersectionModule = defineModule<'secondIntersection', Input>({\n kind: 'secondIntersection',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('secondIntersection'),\n line: NameZ,\n circle: NameZ,\n other: NameZ,\n }),\n collectRefs: (e) => [e.line, e.circle, e.other],\n refSpecs: [\n { field: 'line', role: 'line-like' },\n { field: 'circle', role: 'circle' },\n { field: 'other', role: 'point' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'secondIntersection',\n line: ctx.resolveId(e.line),\n circle: ctx.resolveId(e.circle),\n other: ctx.resolveId(e.other),\n },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/circleIntersection.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'circleIntersection' }>;\n\nexport const circleIntersectionModule = defineModule<'circleIntersection', Input>({\n kind: 'circleIntersection',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleIntersection'),\n c1: NameZ,\n c2: NameZ,\n which: z.union([z.literal(0), z.literal(1)]),\n }),\n collectRefs: (e) => [e.c1, e.c2],\n refSpecs: [\n { field: 'c1', role: 'circle' },\n { field: 'c2', role: 'circle' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'circleIntersection',\n c1: ctx.resolveId(e.c1),\n c2: ctx.resolveId(e.c2),\n which: e.which,\n },\n ),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/circleSecondIntersection.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'circleSecondIntersection' }>;\n\n// Giao điểm THỨ HAI của 2 đường tròn (c1 ∩ c2), biết điểm chung `exclude`.\n// Renderer: JSXGraph 'otherintersection' → nghiệm KHÁC `exclude`.\nexport const circleSecondIntersectionModule = defineModule<'circleSecondIntersection', Input>({\n kind: 'circleSecondIntersection',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleSecondIntersection'),\n c1: NameZ,\n c2: NameZ,\n exclude: NameZ,\n }),\n collectRefs: (e) => [e.c1, e.c2, e.exclude],\n refSpecs: [\n { field: 'c1', role: 'circle' },\n { field: 'c2', role: 'circle' },\n { field: 'exclude', role: 'point' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'circleSecondIntersection',\n c1: ctx.resolveId(e.c1),\n c2: ctx.resolveId(e.c2),\n exclude: ctx.resolveId(e.exclude),\n },\n ),\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'tangencyPoint' }>;\n\nexport const tangencyPointModule = defineModule<'tangencyPoint', Input>({\n kind: 'tangencyPoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('tangencyPoint'),\n circle: NameZ,\n onLine: NameZ,\n }),\n collectRefs: (e) => [e.circle, e.onLine],\n refSpecs: [\n { field: 'circle', role: 'circle' },\n { field: 'onLine', role: 'line-like' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'tangencyPoint',\n circle: ctx.resolveId(e.circle),\n onLine: ctx.resolveId(e.onLine),\n },\n ),\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'tangentPointExt' }>;\n\nexport const tangentPointExtModule = defineModule<'tangentPointExt', Input>({\n kind: 'tangentPointExt',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('tangentPointExt'),\n from: NameZ,\n circle: NameZ,\n which: z.union([z.literal(0), z.literal(1)]),\n }),\n collectRefs: (e) => [e.from, e.circle],\n refSpecs: [\n { field: 'from', role: 'point' },\n { field: 'circle', role: 'circle' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(\n ctx.resolveId(e.name),\n e.name,\n {\n kind: 'tangentPointExt',\n from: ctx.resolveId(e.from),\n circle: ctx.resolveId(e.circle),\n which: e.which,\n },\n ),\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'circleCR' }>;\n\nexport const circleCRModule = defineModule<'circleCR', Input>({\n kind: 'circleCR',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('circleCR'),\n center: NameZ,\n radius: z.number().positive(),\n }),\n collectRefs: (e) => [e.center],\n refSpecs: [{ field: 'center', role: 'point' }],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: { center: ctx.resolveId(e.center), radius: e.radius },\n },\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'incircle' }>;\n\nexport const incircleModule = defineModule<'incircle', Input>({\n kind: 'incircle',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('incircle'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n }),\n collectRefs: (e) => [...e.vertices],\n refSpecs: [{ field: 'vertices', role: 'point', many: true }],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n kind: 'incircle',\n vertices: [\n ctx.resolveId(e.vertices[0]),\n ctx.resolveId(e.vertices[1]),\n ctx.resolveId(e.vertices[2]),\n ],\n },\n },\n }],\n});\n","import { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslShapeT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { SHAPE_BASE_FIELDS } from '../_shared';\n\ntype Input = Extract<DslShapeT, { kind: 'excircle' }>;\n\nexport const excircleModule = defineModule<'excircle', Input>({\n kind: 'excircle',\n role: 'circle',\n category: 'circles',\n prefix: 'c',\n schema: z.object({\n name: NameZ,\n kind: z.literal('excircle'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n opposite: NameZ,\n }),\n collectRefs: (e) => [...e.vertices],\n refSpecs: [\n { field: 'vertices', role: 'point', many: true },\n { field: 'opposite', role: 'point' },\n ],\n emit: (e, ctx) => [{\n role: 'primary',\n object: {\n id: ctx.resolveId(e.name),\n kind: 'circle',\n label: e.name,\n ...SHAPE_BASE_FIELDS,\n attrs: {\n construction: {\n kind: 'excircle',\n p1: ctx.resolveId(e.vertices[0]),\n p2: ctx.resolveId(e.vertices[1]),\n p3: ctx.resolveId(e.vertices[2]),\n opposite: ctx.resolveId(e.opposite),\n },\n },\n },\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/arcMidpoint.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'arcMidpoint' }>;\n\nexport const arcMidpointModule = defineModule<'arcMidpoint', Input>({\n kind: 'arcMidpoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('arcMidpoint'),\n circle: NameZ,\n a: NameZ,\n b: NameZ,\n notContaining: NameZ,\n }),\n collectRefs: (e) => [e.circle, e.a, e.b, e.notContaining],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'arcMidpoint',\n circle: ctx.resolveId(e.circle),\n a: ctx.resolveId(e.a),\n b: ctx.resolveId(e.b),\n notContaining: ctx.resolveId(e.notContaining),\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/excenter.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject, resolveTriangleVertices } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'excenter' }>;\n\nexport const excenterModule = defineModule<'excenter', Input>({\n kind: 'excenter',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('excenter'),\n vertices: z.tuple([NameZ, NameZ, NameZ]),\n opposite: NameZ,\n }),\n collectRefs: (e) => [...e.vertices],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'excenter',\n vertices: resolveTriangleVertices(ctx, e.vertices),\n opposite: ctx.resolveId(e.opposite),\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/reflectPoint.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'reflectPoint' }>;\n\nexport const reflectPointModule = defineModule<'reflectPoint', Input>({\n kind: 'reflectPoint',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({ name: NameZ, kind: z.literal('reflectPoint'), of: NameZ, through: NameZ }),\n collectRefs: (e) => [e.of, e.through],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'transformed',\n source: ctx.resolveId(e.of),\n transform: { kind: 'reflectPoint', center: ctx.resolveId(e.through) },\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/reflectLine.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'reflectLine' }>;\n\nexport const reflectLineModule = defineModule<'reflectLine', Input>({\n kind: 'reflectLine',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({ name: NameZ, kind: z.literal('reflectLine'), of: NameZ, through: NameZ }),\n collectRefs: (e) => [e.of, e.through],\n emit: (e, ctx) => [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'transformed',\n source: ctx.resolveId(e.of),\n transform: { kind: 'reflectLine', line: ctx.resolveId(e.through) },\n }),\n }],\n});\n","// src/stamps/geometry-2d/dsl/kinds/points/pointAtDistance.ts\nimport { z } from 'zod';\nimport { NameZ } from '../../names';\nimport type { DslPointT } from '../../schema';\nimport { defineModule } from '../_types';\nimport { emitPointObject } from '../_shared';\n\ntype Input = Extract<DslPointT, { kind: 'pointAtDistance' }>;\n\n// scale/offset OPTIONAL (Issue #46 nhóm C): d = scale·base + offset. scale phải\n// > 0; offset bất kỳ (âm OK — guard d>0 ở render). Absent → giữ form cũ (additive).\nconst ScaleOffsetZ = {\n scale: z.number().positive().optional(),\n offset: z.number().optional(),\n};\nconst DistanceZ = z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('circleRadius'), circle: NameZ, ...ScaleOffsetZ }),\n z.object({ kind: z.literal('segmentLength'), p1: NameZ, p2: NameZ, ...ScaleOffsetZ }),\n z.object({ kind: z.literal('literal'), value: z.number().positive(), ...ScaleOffsetZ }),\n]);\n\n/** Chỉ chèn scale/offset khi có giá trị → object cũ KHÔNG mọc key (additive). */\nfunction withScaleOffset<T extends object>(base: T, d: { scale?: number; offset?: number }): T {\n const out = { ...base } as T & { scale?: number; offset?: number };\n if (d.scale !== undefined) out.scale = d.scale;\n if (d.offset !== undefined) out.offset = d.offset;\n return out;\n}\n\nexport const pointAtDistanceModule = defineModule<'pointAtDistance', Input>({\n kind: 'pointAtDistance',\n role: 'point',\n category: 'points',\n prefix: 'p',\n schema: z.object({\n name: NameZ,\n kind: z.literal('pointAtDistance'),\n from: NameZ,\n through: NameZ,\n distance: DistanceZ,\n }),\n collectRefs: (e) => {\n const d = e.distance;\n const extra = d.kind === 'circleRadius' ? [d.circle]\n : d.kind === 'segmentLength' ? [d.p1, d.p2] : [];\n return [e.from, e.through, ...extra];\n },\n // TODO(Mức 1 defer): distance.{circle,p1,p2} là nested trong `distance` — refSpec\n // phẳng đọc top-level không với tới, validate riêng nếu cần. Hiện validate from/through.\n refSpecs: [\n { field: 'from', role: 'point' },\n { field: 'through', role: 'point' },\n ],\n emit: (e, ctx) => {\n const d = e.distance;\n const distance = d.kind === 'circleRadius'\n ? withScaleOffset({ kind: 'circleRadius', circle: ctx.resolveId(d.circle) }, d)\n : d.kind === 'segmentLength'\n ? withScaleOffset({ kind: 'segmentLength', p1: ctx.resolveId(d.p1), p2: ctx.resolveId(d.p2) }, d)\n : withScaleOffset({ kind: 'literal', value: d.value }, d);\n return [{\n role: 'primary',\n object: emitPointObject(ctx.resolveId(e.name), e.name, {\n kind: 'pointAtDistance',\n from: ctx.resolveId(e.from),\n through: ctx.resolveId(e.through),\n distance,\n }),\n }];\n },\n});\n","// src/stamps/geometry-2d/dsl/registry.ts\nimport { z } from 'zod';\nimport type { DslKindModule } from './kinds/_types';\nimport { freeModule } from './kinds/points/free';\nimport { midpointModule } from './kinds/points/midpoint';\nimport { onSegmentModule } from './kinds/points/onSegment';\nimport { onLineModule } from './kinds/points/onLine';\nimport { onCircleModule } from './kinds/points/onCircle';\nimport { perpFootModule } from './kinds/points/perpFoot';\nimport { circumcenterModule } from './kinds/points/circumcenter';\nimport { incenterModule } from './kinds/points/incenter';\nimport { centroidModule } from './kinds/points/centroid';\nimport { orthocenterModule } from './kinds/points/orthocenter';\nimport { intersectionModule } from './kinds/points/intersection';\nimport { segmentModule } from './kinds/lines/segment';\nimport { lineModule } from './kinds/lines/line';\nimport { rayModule } from './kinds/lines/ray';\nimport { perpendicularModule } from './kinds/lines/perpendicular';\nimport { parallelModule } from './kinds/lines/parallel';\nimport { perpBisectorModule } from './kinds/lines/perpBisector';\nimport { angleBisectorModule } from './kinds/lines/angleBisector';\nimport { lineThroughModule } from './kinds/lines/lineThrough';\nimport { radicalAxisModule } from './kinds/lines/radicalAxis';\nimport { tangentModule } from './kinds/lines/tangent';\nimport { polygonModule } from './kinds/polygons/polygon';\nimport { circleCPModule } from './kinds/circles/circleCP';\nimport { circle3Module } from './kinds/circles/circle3';\nimport { circleDiameterModule } from './kinds/circles/circleDiameter';\nimport { secondIntersectionModule } from './kinds/points/secondIntersection';\nimport { circleIntersectionModule } from './kinds/points/circleIntersection';\nimport { circleSecondIntersectionModule } from './kinds/points/circleSecondIntersection';\nimport { tangencyPointModule } from './kinds/points/tangencyPoint';\nimport { tangentPointExtModule } from './kinds/points/tangentPointExt';\nimport { circleCRModule } from './kinds/circles/circleCR';\nimport { incircleModule } from './kinds/circles/incircle';\nimport { excircleModule } from './kinds/circles/excircle';\nimport { arcMidpointModule } from './kinds/points/arcMidpoint';\nimport { excenterModule } from './kinds/points/excenter';\nimport { reflectPointModule } from './kinds/points/reflectPoint';\nimport { reflectLineModule } from './kinds/points/reflectLine';\nimport { pointAtDistanceModule } from './kinds/points/pointAtDistance';\n\nconst ALL_MODULES: ReadonlyArray<DslKindModule> = [\n freeModule, midpointModule, onSegmentModule, onLineModule, onCircleModule,\n perpFootModule, circumcenterModule, incenterModule, centroidModule,\n orthocenterModule, intersectionModule,\n // NEW Tier 4+5 points\n secondIntersectionModule, circleIntersectionModule, circleSecondIntersectionModule,\n tangencyPointModule, tangentPointExtModule,\n segmentModule, lineModule, rayModule,\n perpendicularModule, parallelModule, perpBisectorModule,\n angleBisectorModule, lineThroughModule, radicalAxisModule, tangentModule,\n polygonModule,\n circleCPModule, circle3Module, circleDiameterModule,\n // NEW Tier 4+5 circles\n circleCRModule, incircleModule, excircleModule,\n // Cụm A points\n arcMidpointModule, excenterModule, reflectPointModule, reflectLineModule,\n // Cụm B points\n pointAtDistanceModule,\n];\n\nexport const KIND_REGISTRY: ReadonlyMap<string, DslKindModule> =\n new Map(ALL_MODULES.map((m) => [m.kind, m]));\n\nexport const POINT_KINDS: ReadonlySet<string> = new Set(\n ALL_MODULES.filter((m) => m.role === 'point').map((m) => m.kind),\n);\n\nexport const LINE_LIKE_SHAPE_KINDS: ReadonlySet<string> = new Set(\n ALL_MODULES.filter(\n (m) =>\n m.role === 'segment' ||\n m.role === 'line' ||\n m.role === 'ray' ||\n m.role === 'lineConstruction',\n ).map((m) => m.kind),\n);\n\nexport const CIRCLE_KINDS: ReadonlySet<string> = new Set(\n ALL_MODULES.filter((m) => m.role === 'circle').map((m) => m.kind),\n);\n\n// Top-level entity discriminated union — used internally by schema.ts for building DslPoint/DslShape.\nexport const DslEntitySchema = z.discriminatedUnion(\n 'kind',\n ALL_MODULES.map((m) => m.schema) as unknown as [z.ZodObject<any>, z.ZodObject<any>, ...z.ZodObject<any>[]],\n);\n","// src/stamps/geometry-2d/dsl/transpile/errors.ts\nimport type { State } from '../../../../core/scene/types';\n\nexport type TranspileErrorCode =\n | 'SCHEMA'\n | 'DUPLICATE_NAME'\n | 'UNKNOWN_REF'\n | 'KIND_MISMATCH'\n | 'CYCLE';\n\nexport interface TranspileError {\n code: TranspileErrorCode;\n message: string;\n path?: string[];\n hint?: string;\n}\n\nexport type TranspileResult =\n | { ok: true; state: State }\n | { ok: false; errors: TranspileError[] };\n\nexport function mkError(\n code: TranspileErrorCode,\n message: string,\n opts?: { path?: string[]; hint?: string },\n): TranspileError {\n return { code, message, path: opts?.path, hint: opts?.hint };\n}\n","// src/stamps/geometry-2d/dsl/transpile/refs.ts\nimport type { DslInputT, DslPointT, DslShapeT } from '../schema';\nimport { KIND_REGISTRY, LINE_LIKE_SHAPE_KINDS, CIRCLE_KINDS } from '../registry';\nimport type { RefRole, RefSpec } from '../kinds/_types';\nimport type { Symbol } from './symbols';\nimport { mkError, type TranspileError } from './errors';\n\nfunction isPointLike(sym: Symbol | undefined): boolean {\n return !!sym && sym.role === 'point';\n}\n\nfunction isLineLike(sym: Symbol | undefined): boolean {\n if (!sym || sym.role !== 'shape') return false;\n return LINE_LIKE_SHAPE_KINDS.has((sym.entity as DslShapeT).kind);\n}\n\nfunction isCircleLike(sym: Symbol | undefined): boolean {\n if (!sym || sym.role !== 'shape') return false;\n return CIRCLE_KINDS.has((sym.entity as DslShapeT).kind);\n}\n\nfunction isSegmentExact(sym: Symbol | undefined): boolean {\n return !!sym && sym.role === 'shape' && (sym.entity as DslShapeT).kind === 'segment';\n}\n\nconst ROLE_PREDICATE: Record<RefRole, (s: Symbol | undefined) => boolean> = {\n point: isPointLike,\n 'line-like': isLineLike,\n circle: isCircleLike,\n segment: isSegmentExact,\n shape: (s) => !!s && s.role === 'shape',\n 'any-existing': (s) => !!s,\n};\nconst ROLE_EXPECTED: Record<RefRole, string> = {\n point: 'point',\n 'line-like': 'line-like',\n circle: 'circle',\n segment: 'segment',\n shape: 'shape',\n 'any-existing': 'tồn tại',\n};\n\nexport interface RefsResult {\n errors: TranspileError[];\n}\n\nexport function validateRefs(dsl: DslInputT, symbols: Map<string, Symbol>): RefsResult {\n const errors: TranspileError[] = [];\n\n const check = (\n owner: string,\n field: string,\n refName: string,\n predicate: (s: Symbol | undefined) => boolean,\n expected: string,\n ) => {\n const sym = symbols.get(refName);\n if (!sym) {\n errors.push(mkError('UNKNOWN_REF',\n `${owner}.${field} tham chiếu \"${refName}\" không tồn tại`,\n { path: [owner, field] }));\n return;\n }\n if (!predicate(sym)) {\n errors.push(mkError('KIND_MISMATCH',\n `${owner}.${field}=\"${refName}\" sai kiểu (cần ${expected}, gặp ${sym.role === 'point' ? 'point' : (sym.entity as DslShapeT).kind})`,\n { path: [owner, field] }));\n }\n };\n\n // Registry-driven pass: kind nào khai refSpecs thì validate ở đây, switch bỏ qua.\n const handledByRegistry = new Set<string>();\n const runSpecs = (owner: string, entity: DslPointT | DslShapeT): boolean => {\n const mod = KIND_REGISTRY.get(entity.kind);\n const raw = mod?.refSpecs;\n if (!raw) return false;\n const specs: readonly RefSpec[] =\n typeof raw === 'function' ? raw(entity as never) : raw;\n for (const spec of specs) {\n const val = (entity as Record<string, unknown>)[spec.field];\n const names: string[] = spec.many\n ? ((val as string[]) ?? [])\n : val == null\n ? []\n : [val as string];\n names.forEach((refName, i) => {\n const field = spec.many ? `${spec.field}[${i}]` : spec.field;\n check(owner, field, refName, ROLE_PREDICATE[spec.role], ROLE_EXPECTED[spec.role]);\n });\n }\n handledByRegistry.add(owner);\n return true;\n };\n for (const p of dsl.points) runSpecs(p.name, p);\n for (const s of dsl.shapes) runSpecs(s.name, s);\n\n for (const p of dsl.points) {\n if (handledByRegistry.has(p.name)) continue;\n switch (p.kind) {\n case 'free': break;\n case 'midpoint':\n check(p.name, 'p1', p.p1, isPointLike, 'point');\n check(p.name, 'p2', p.p2, isPointLike, 'point');\n break;\n case 'onSegment':\n check(p.name, 'segmentId', p.segmentId, isSegmentExact, 'segment');\n break;\n case 'onLine':\n check(p.name, 'lineId', p.lineId, isLineLike, 'line-like');\n break;\n case 'onCircle':\n check(p.name, 'circleId', p.circleId, isCircleLike, 'circle');\n break;\n case 'perpFoot':\n check(p.name, 'from', p.from, isPointLike, 'point');\n check(p.name, 'onLine', p.onLine, isLineLike, 'line-like');\n break;\n case 'circumcenter':\n case 'incenter':\n case 'centroid':\n case 'orthocenter':\n for (let i = 0; i < 3; i++) {\n check(p.name, `vertices[${i}]`, p.vertices[i], isPointLike, 'point');\n }\n break;\n case 'intersection': {\n const refPredicate = (s: Symbol | undefined) => isLineLike(s) || isCircleLike(s);\n check(p.name, 'ref1', p.ref1, refPredicate, 'line-like hoặc circle');\n check(p.name, 'ref2', p.ref2, refPredicate, 'line-like hoặc circle');\n break;\n }\n case 'arcMidpoint':\n check(p.name, 'circle', p.circle, isCircleLike, 'circle');\n check(p.name, 'a', p.a, isPointLike, 'point');\n check(p.name, 'b', p.b, isPointLike, 'point');\n check(p.name, 'notContaining', p.notContaining, isPointLike, 'point');\n break;\n case 'excenter':\n for (let i = 0; i < 3; i++) {\n check(p.name, `vertices[${i}]`, p.vertices[i], isPointLike, 'point');\n }\n check(p.name, 'opposite', p.opposite, isPointLike, 'point');\n break;\n case 'reflectPoint':\n check(p.name, 'of', p.of, isPointLike, 'point');\n check(p.name, 'through', p.through, isPointLike, 'point');\n break;\n case 'reflectLine':\n check(p.name, 'of', p.of, isPointLike, 'point');\n check(p.name, 'through', p.through, isLineLike, 'line-like');\n break;\n }\n }\n\n for (const s of dsl.shapes) {\n if (handledByRegistry.has(s.name)) continue;\n switch (s.kind) {\n case 'segment':\n case 'line':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n break;\n case 'ray':\n check(s.name, 'origin', s.origin, isPointLike, 'point');\n check(s.name, 'through', s.through, isPointLike, 'point');\n break;\n case 'polygon':\n s.vertices.forEach((v, i) =>\n check(s.name, `vertices[${i}]`, v, isPointLike, 'point'));\n break;\n case 'perpendicular':\n case 'parallel':\n check(s.name, 'throughPoint', s.throughPoint, isPointLike, 'point');\n check(s.name, 'toLine', s.toLine, isLineLike, 'line-like');\n break;\n case 'perpBisector':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n break;\n case 'angleBisector':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'vertex', s.vertex, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n break;\n case 'tangent':\n check(s.name, 'throughPoint', s.throughPoint, isPointLike, 'point');\n check(s.name, 'toCircle', s.toCircle, isCircleLike, 'circle');\n break;\n case 'circleCP':\n check(s.name, 'center', s.center, isPointLike, 'point');\n check(s.name, 'surfacePoint', s.surfacePoint, isPointLike, 'point');\n break;\n case 'circle3':\n check(s.name, 'p1', s.p1, isPointLike, 'point');\n check(s.name, 'p2', s.p2, isPointLike, 'point');\n check(s.name, 'p3', s.p3, isPointLike, 'point');\n break;\n }\n }\n\n return { errors };\n}\n\n// Helper export cho cycles.ts: collect refs cho mỗi entity (name) trả về list ref names.\nexport function collectRefs(entity: DslPointT | DslShapeT): string[] {\n const mod = KIND_REGISTRY.get(entity.kind);\n if (!mod) throw new Error(`collectRefs: no registry entry for kind \"${entity.kind}\"`);\n return mod.collectRefs(entity as never);\n}\n","// src/stamps/geometry-2d/ai/layout/disjointOffset.ts\n//\n// Layout pass (issue #46 nhóm D, D1, Mức 1): tách các component RỜI NHAU (không\n// chia điểm/ref) theo trục ngang để không render chồng tại canonical origin.\n//\n// Pure, mutate in place (giống repairCircleIntersections). Chỉ dịch free point\n// (kind:'free' — điểm DUY NHẤT có x/y); điểm phái sinh KHÔNG có coord → transpile\n// tính lại từ ref đã dịch → tự đúng. Bất biến: ≤1 component → no-op (đề 1-figure\n// byte-identical).\n\nimport type { DslPointT, DslShapeT } from '../../dsl/schema';\nimport { collectRefs } from '../../dsl/transpile/refs';\n\nconst GAP = 2; // board-unit giữa 2 component liền kề\n\ntype FreePoint = Extract<DslPointT, { kind: 'free' }>;\ninterface Bbox { minX: number; maxX: number; minY: number; maxY: number; }\n\nexport function layoutDisjointComponents(points: DslPointT[], shapes: DslShapeT[]): void {\n // --- union-find trên mọi entity name (point + shape) ---\n const parent = new Map<string, string>();\n const find = (x: string): string => {\n const r = parent.get(x);\n if (r === undefined) { parent.set(x, x); return x; }\n if (r === x) return x;\n const root = find(r);\n parent.set(x, root);\n return root;\n };\n const union = (a: string, b: string) => {\n const ra = find(a), rb = find(b);\n if (ra !== rb) parent.set(ra, rb);\n };\n\n const entities: (DslPointT | DslShapeT)[] = [...points, ...shapes];\n for (const e of entities) {\n find(e.name); // đảm bảo node tồn tại\n for (const ref of collectRefs(e)) union(e.name, ref);\n }\n\n // --- free point + thứ tự xuất hiện trong mảng points ---\n const freeByName = new Map<string, { p: FreePoint; index: number }>();\n points.forEach((p, i) => {\n if (p.kind === 'free') freeByName.set(p.name, { p, index: i });\n });\n if (freeByName.size === 0) return;\n\n // --- gom free point theo component root + min free-index ---\n const compFree = new Map<string, { p: FreePoint; index: number }[]>();\n const compMinIndex = new Map<string, number>();\n for (const [name, rec] of freeByName) {\n const root = find(name);\n if (!compFree.has(root)) { compFree.set(root, []); compMinIndex.set(root, rec.index); }\n compFree.get(root)!.push(rec);\n compMinIndex.set(root, Math.min(compMinIndex.get(root)!, rec.index));\n }\n\n // --- bất biến: ≤1 component có free point → no-op ---\n if (compFree.size <= 1) return;\n\n // --- thứ tự component theo min free-index (= thứ tự đọc đề) ---\n const roots = [...compFree.keys()].sort(\n (a, b) => compMinIndex.get(a)! - compMinIndex.get(b)!,\n );\n\n // --- bbox per-component: free-point coords + mở rộng bán kính khi tâm là free ---\n const bboxOf = (root: string): Bbox => {\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n const ext = (x: number, y: number) => {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n };\n for (const { p } of compFree.get(root)!) ext(p.x, p.y);\n for (const s of shapes) {\n if (find(s.name) !== root) continue;\n if (s.kind === 'circleCR') {\n const c = freeByName.get(s.center);\n if (c) { ext(c.p.x - s.radius, c.p.y - s.radius); ext(c.p.x + s.radius, c.p.y + s.radius); }\n } else if (s.kind === 'circleCP') {\n const c = freeByName.get(s.center);\n const sp = freeByName.get(s.surfacePoint);\n if (c && sp) {\n const r = Math.hypot(c.p.x - sp.p.x, c.p.y - sp.p.y);\n ext(c.p.x - r, c.p.y - r); ext(c.p.x + r, c.p.y + r);\n }\n }\n }\n return { minX, maxX, minY, maxY };\n };\n\n // --- pack ngang trái→phải (anchor giữ gốc, dx=0) ---\n let cursorX = bboxOf(roots[0]).maxX + GAP;\n for (let i = 1; i < roots.length; i++) {\n const root = roots[i];\n const bb = bboxOf(root);\n const dx = cursorX - bb.minX;\n for (const { p } of compFree.get(root)!) p.x += dx;\n cursorX = bb.maxX + dx + GAP;\n }\n}\n","// src/stamps/geometry-2d/ai/intent-builders/_types.ts\n//\n// Shared types cho intent-builders: BuildState (mutable build context),\n// newState() factory, IntentBuilderError, và IntentBuilder signature.\n// Tách ra từ intentToDsl.ts (Phase 2a, #45) — không đổi logic.\n\nimport type { DslPointT, DslShapeT } from '../../dsl/schema';\nimport type { IntentT } from '../intent';\n\nexport interface BuildState {\n points: DslPointT[];\n shapes: DslShapeT[];\n /** Map label → ensures uniqueness. */\n pointNames: Set<string>;\n shapeNames: Set<string>;\n /** Map \"AB\"/\"BA\" → segment shape name, dùng cho lookup of='BC'. */\n segmentByEnds: Map<string, string>;\n}\n\nexport function newState(): BuildState {\n return {\n points: [],\n shapes: [],\n pointNames: new Set(),\n shapeNames: new Set(),\n segmentByEnds: new Map(),\n };\n}\n\nexport class IntentBuilderError extends Error {\n constructor(\n message: string,\n public readonly intent: IntentT,\n public readonly cause?: string,\n ) {\n super(message);\n this.name = 'IntentBuilderError';\n }\n}\n\n/** Builder mutate BuildState theo 1 intent op (idempotent, giữ thứ tự gọi). */\nexport type IntentBuilder<T extends IntentT = IntentT> = (s: BuildState, intent: T) => void;\n","// src/stamps/geometry-2d/ai/intent-builders/shared.ts\n//\n// Shared helpers + canonical coord tables + SHAPE_VARIANTS cho intent-builders.\n// Move verbatim từ intentToDsl.ts (Phase 2a, #45) — không đổi logic.\n\nimport type { DslPointT, DslShapeT } from '../../dsl/schema';\nimport type { BuildState } from './_types';\n\n// ---------------------------------------------------------------------------\n// Canonical coord tables\n// ---------------------------------------------------------------------------\n\nexport type Pt = readonly [number, number];\n\nexport const SQRT3 = 1.7320508075688772;\n\nexport function triangleCanonical(variant: string): readonly [Pt, Pt, Pt] {\n switch (variant) {\n case 'equilateral':\n return [[0, 0], [4, 0], [2, 2 * SQRT3]];\n case 'isoceles-AB':\n // AB là đáy, C đỉnh cân\n return [[0, 0], [4, 0], [2, 3]];\n case 'isoceles-BC':\n // BC là đáy, A đỉnh cân\n return [[0, 3], [-2, 0], [2, 0]];\n case 'isoceles-CA':\n // CA là đáy, B đỉnh cân\n return [[0, 0], [2, 3], [4, 0]];\n case 'right-at-A':\n return [[0, 0], [4, 0], [0, 3]];\n case 'right-at-B':\n return [[0, 0], [4, 0], [4, 3]];\n case 'right-at-C':\n // C ở (4,3); AC ⊥ BC\n // chọn A=(0,0), C=(4,3), B=(7.36,1.92) sao cho CA·CB=0\n // Đơn giản hơn: A=(0,0), B=(7,0), C=(0,4) → vuông tại A. Wait — đó là right-at-A.\n // Cần vuông tại C: chọn 3 đỉnh sao cho (CA)·(CB)=0.\n // A=(0,0), B=(7,0), C=(3,4). Check: CA=(−3,−4), CB=(4,−4), dot=−12+16=4 ≠0. Sửa.\n // A=(0,0), C=(3,3), B=(6,0): CA=(−3,−3), CB=(3,−3), dot=−9+9=0 ✓\n return [[0, 0], [6, 0], [3, 3]];\n case 'any':\n default:\n // Tam giác scalene cố định, tránh vuông tại gốc\n return [[0, 0], [5, 0], [2, 3]];\n }\n}\n\nexport function squareCanonical(): readonly [Pt, Pt, Pt, Pt] {\n // Cạnh 4, gốc tại đỉnh đầu (counter-clockwise)\n return [[0, 0], [4, 0], [4, 4], [0, 4]];\n}\n\nexport function rectangleCanonical(variant: string): readonly [Pt, Pt, Pt, Pt] {\n if (variant === 'tall') return [[0, 0], [2.5, 0], [2.5, 4], [0, 4]];\n // wide / standard (default)\n return [[0, 0], [4, 0], [4, 2.5], [0, 2.5]];\n}\n\nexport function rhombusCanonical(): readonly [Pt, Pt, Pt, Pt] {\n // Đường chéo nằm trên trục, 4 đỉnh trên trục: (±2, 0) và (0, ±1.5)\n return [[-2, 0], [0, -1.5], [2, 0], [0, 1.5]];\n}\n\nexport function trapezoidCanonical(variant: string): readonly [Pt, Pt, Pt, Pt] {\n switch (variant) {\n case 'right':\n // Vuông tại A và D\n return [[0, 0], [5, 0], [3, 3], [0, 3]];\n case 'isoceles':\n // Cân — AB đáy lớn, CD đáy nhỏ\n return [[0, 0], [5, 0], [4, 3], [1, 3]];\n case 'general':\n default:\n return [[0, 0], [5, 0], [3.5, 3], [1, 3]];\n }\n}\n\nexport function parallelogramCanonical(): readonly [Pt, Pt, Pt, Pt] {\n return [[0, 0], [4, 0], [5, 3], [1, 3]];\n}\n\nexport function quadrilateralCanonical(): readonly [Pt, Pt, Pt, Pt] {\n return [[0, 0], [5, 0], [4.5, 3.5], [0.5, 3]];\n}\n\n// ---------------------------------------------------------------------------\n// Build helpers\n// ---------------------------------------------------------------------------\n\nexport function addPoint(s: BuildState, p: DslPointT) {\n if (s.pointNames.has(p.name)) return; // idempotent\n s.points.push(p);\n s.pointNames.add(p.name);\n}\n\n// Default coord cho free point khi LLM không truyền `at`. Spread theo thứ tự\n// thêm để tránh nhiều free point collide tại (3, 3) → segment degenerate,\n// circle radius=0, intersection NaN cascade (bug eval cau-14: A=B=D=(3,3)).\n// Pattern: 8 vị trí phân bố xung quanh gốc, vòng lại khi >8.\nexport const FREE_DEFAULT_SPREAD: readonly [number, number][] = [\n [3, 3],\n [-3, 3],\n [3, -3],\n [-3, -3],\n [4, 0],\n [-4, 0],\n [0, 4],\n [0, -4],\n];\n\nexport function defaultFreeCoord(s: BuildState): [number, number] {\n // Đếm số free point đã add (cả từ polygon vertices + add-point free).\n // Position trong array trùng index modulo SPREAD.\n let count = 0;\n for (const p of s.points) if (p.kind === 'free') count++;\n return [...FREE_DEFAULT_SPREAD[count % FREE_DEFAULT_SPREAD.length]];\n}\n\nexport function addShape(s: BuildState, sh: DslShapeT) {\n if (s.shapeNames.has(sh.name)) return;\n s.shapes.push(sh);\n s.shapeNames.add(sh.name);\n}\n\nexport function uniqueShapeName(s: BuildState, base: string): string {\n if (!s.shapeNames.has(base)) return base;\n let i = 2;\n while (s.shapeNames.has(`${base}${i}`)) i++;\n return `${base}${i}`;\n}\n\nexport function uniquePointName(s: BuildState, base: string): string {\n if (!s.pointNames.has(base)) return base;\n let i = 2;\n while (s.pointNames.has(`${base}${i}`)) i++;\n return `${base}${i}`;\n}\n\nexport function ensureSegment(s: BuildState, a: string, b: string): string {\n const k1 = `${a}-${b}`;\n const k2 = `${b}-${a}`;\n const existing = s.segmentByEnds.get(k1) ?? s.segmentByEnds.get(k2);\n if (existing) return existing;\n const name = uniqueShapeName(s, `${a}${b}`);\n addShape(s, { name, kind: 'segment', p1: a, p2: b });\n s.segmentByEnds.set(k1, name);\n return name;\n}\n\n// Resolve line ref cho draw-line (perpThrough/parallelThrough) với fallback:\n// LLM nhiều khi nhầm \"Đường vuông góc với AB tại B\" → to:\"A\" (1 chữ — POINT)\n// thay vì to:\"AB\" (2 chữ — LINE). Khi `ref` là 1 chữ POINT và `anchor` cũng\n// 1 chữ POINT khác, auto build segment qua 2 điểm (alphabetize canonical).\nexport function resolveLineRefWithFallback(s: BuildState, ref: string, anchor: string): string {\n // Single-letter point swap fallback — chỉ áp dụng khi cả 2 đều là POINT\n // đã định nghĩa và khác nhau.\n if (\n /^[A-Za-z]$/.test(ref) && /^[A-Za-z]$/.test(anchor) && ref !== anchor &&\n s.pointNames.has(ref) && s.pointNames.has(anchor)\n ) {\n const [a, b] = ref < anchor ? [ref, anchor] : [anchor, ref];\n return ensureSegment(s, a, b);\n }\n // Path bình thường: 2-char shorthand hoặc tên shape đã có.\n return resolveSegmentRef(s, ref);\n}\n\nexport function resolveSegmentRef(s: BuildState, ref: string): string {\n // ref có thể là tên segment ('AB') hoặc shape name đã có.\n // Nếu là 2 ký tự label đều đã tồn tại → ensure segment 2 đỉnh đó.\n if (s.shapeNames.has(ref)) return ref;\n // Tách \"AB\" → A,B\n if (ref.length === 2 && s.pointNames.has(ref[0]) && s.pointNames.has(ref[1])) {\n return ensureSegment(s, ref[0], ref[1]);\n }\n // Pattern \"A-B\" / \"AB\"\n const dashMatch = ref.match(/^([A-Za-z][A-Za-z0-9'_]*)[-_]?([A-Za-z][A-Za-z0-9'_]*)$/);\n if (dashMatch && s.pointNames.has(dashMatch[1]) && s.pointNames.has(dashMatch[2])) {\n return ensureSegment(s, dashMatch[1], dashMatch[2]);\n }\n // Trả về ref gốc (transpile sẽ báo lỗi nếu invalid)\n return ref;\n}\n\nexport function parseEnds(ref: string): [string, string] | null {\n if (ref.length === 2) return [ref[0], ref[1]];\n const m = ref.match(/^([A-Za-z][A-Za-z0-9'_]*)[-_]?([A-Za-z][A-Za-z0-9'_]*)$/);\n if (m) return [m[1], m[2]];\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// draw-shape variants\n// ---------------------------------------------------------------------------\n\n// Map shape → allowed variants (runtime check, schema cho phép enum chung)\nexport const SHAPE_VARIANTS: Record<string, readonly string[]> = {\n triangle: ['any', 'equilateral', 'isoceles-AB', 'isoceles-BC', 'isoceles-CA', 'right-at-A', 'right-at-B', 'right-at-C'],\n square: ['standard'],\n rectangle: ['standard', 'wide', 'tall'],\n rhombus: ['standard'],\n trapezoid: ['right', 'isoceles', 'general'],\n parallelogram: ['standard'],\n quadrilateral: ['any'],\n};\n","// src/stamps/geometry-2d/ai/intent-builders/draw-shape.ts\n//\n// op: draw-shape — move verbatim từ intentToDsl.ts handleDrawShape (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport {\n addPoint, addShape, uniqueShapeName,\n SHAPE_VARIANTS, triangleCanonical, squareCanonical, rectangleCanonical,\n rhombusCanonical, trapezoidCanonical, parallelogramCanonical, quadrilateralCanonical,\n type Pt,\n} from './shared';\nimport type { DrawShapeIntentT } from '../intent';\n\nexport const buildDrawShape: IntentBuilder<DrawShapeIntentT> = (s, intent) => {\n const labels = intent.labels;\n const explicit = intent.explicitCoords ?? {};\n\n // Validate variant ∈ allowed\n const allowed = SHAPE_VARIANTS[intent.shape];\n if (!allowed || !allowed.includes(intent.variant)) {\n // Fallback to default variant cho shape thay vì throw\n intent = { ...intent, variant: (allowed?.[0] ?? 'any') as typeof intent.variant };\n }\n\n let coords: readonly Pt[];\n switch (intent.shape) {\n case 'triangle': coords = triangleCanonical(intent.variant); break;\n case 'square': coords = squareCanonical(); break;\n case 'rectangle': coords = rectangleCanonical(intent.variant); break;\n case 'rhombus': coords = rhombusCanonical(); break;\n case 'trapezoid': coords = trapezoidCanonical(intent.variant); break;\n case 'parallelogram': coords = parallelogramCanonical(); break;\n case 'quadrilateral': coords = quadrilateralCanonical(); break;\n default:\n throw new IntentBuilderError(`Shape không hỗ trợ: ${intent.shape}`, intent);\n }\n\n if (coords.length !== labels.length) {\n throw new IntentBuilderError(\n `Shape ${intent.shape} cần ${coords.length} labels, nhận ${labels.length}`,\n intent,\n );\n }\n\n labels.forEach((label, i) => {\n const ec = explicit[label];\n const [x, y] = ec ?? coords[i];\n addPoint(s, { name: label, kind: 'free', x, y });\n });\n\n const polyName = uniqueShapeName(s, labels.join(''));\n addShape(s, { name: polyName, kind: 'polygon', vertices: [...labels] });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/midpoint.ts\n//\n// add-point constraint.kind=midpoint — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { IntentBuilderError } from '../_types';\nimport { addPoint, ensureSegment, parseEnds } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildMidpoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'midpoint') return;\n const name = intent.name;\n const ends = parseEnds(c.of);\n if (!ends) throw new IntentBuilderError(`midpoint.of không parse được: ${c.of}`, intent);\n // Ensure segment for the midpoint reference (optional but nice for rendering)\n ensureSegment(s, ends[0], ends[1]);\n addPoint(s, { name, kind: 'midpoint', p1: ends[0], p2: ends[1] });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/perpFoot.ts\n//\n// add-point constraint.kind=perpFoot — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildPerpFoot = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'perpFoot') return;\n const name = intent.name;\n const lineName = resolveSegmentRef(s, c.onLine);\n addPoint(s, { name, kind: 'perpFoot', from: c.from, onLine: lineName });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/centers.ts\n//\n// add-point centers: centroid/circumcenter/incenter/orthocenter/excenter\n// — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildCentroid = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'centroid') return;\n addPoint(s, { name: intent.name, kind: 'centroid', vertices: c.of });\n};\n\nexport const buildCircumcenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'circumcenter') return;\n addPoint(s, { name: intent.name, kind: 'circumcenter', vertices: c.of });\n};\n\nexport const buildIncenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'incenter') return;\n addPoint(s, { name: intent.name, kind: 'incenter', vertices: c.of });\n};\n\nexport const buildOrthocenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'orthocenter') return;\n addPoint(s, { name: intent.name, kind: 'orthocenter', vertices: c.of });\n};\n\nexport const buildExcenter = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'excenter') return;\n addPoint(s, { name: intent.name, kind: 'excenter', vertices: c.of, opposite: c.opposite });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/intersections.ts\n//\n// add-point intersections: intersection/secondIntersection/circleIntersection\n// — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'intersection') return;\n const r1 = resolveSegmentRef(s, c.of[0]);\n const r2 = resolveSegmentRef(s, c.of[1]);\n addPoint(s, {\n name: intent.name,\n kind: 'intersection',\n ref1: r1,\n ref2: r2,\n ...(c.branch !== undefined ? { branch: c.branch } : {}),\n });\n};\n\nexport const buildSecondIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'secondIntersection') return;\n const lineRef = resolveSegmentRef(s, c.line);\n addPoint(s, {\n name: intent.name, kind: 'secondIntersection',\n line: lineRef, circle: c.circle, other: c.other,\n });\n};\n\nexport const buildCircleIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'circleIntersection') return;\n addPoint(s, {\n name: intent.name, kind: 'circleIntersection',\n c1: c.c1, c2: c.c2, which: c.which,\n });\n};\n\nexport const buildCircleSecondIntersection = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'circleSecondIntersection') return;\n addPoint(s, {\n name: intent.name, kind: 'circleSecondIntersection',\n c1: c.c1, c2: c.c2, exclude: c.exclude,\n });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/tangency.ts\n//\n// add-point tangency: tangencyPoint/tangentPoint — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildTangencyPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'tangencyPoint') return;\n const lineRef = resolveSegmentRef(s, c.onLine);\n addPoint(s, {\n name: intent.name, kind: 'tangencyPoint',\n circle: c.circle, onLine: lineRef,\n });\n};\n\nexport const buildTangentPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'tangentPoint') return;\n addPoint(s, {\n name: intent.name, kind: 'tangentPointExt',\n from: c.from, circle: c.circle, which: c.which,\n });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/onSegment-free.ts\n//\n// add-point onSegment/free — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, defaultFreeCoord, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildOnSegment = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'onSegment') return;\n const ref = resolveSegmentRef(s, c.of);\n addPoint(s, { name: intent.name, kind: 'onSegment', segmentId: ref, t: c.t ?? 0.5 });\n};\n\nexport const buildFree = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'free') return;\n const [x, y] = c.at ?? defaultFreeCoord(s);\n addPoint(s, { name: intent.name, kind: 'free', x, y });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/angleBisectorFoot.ts\n//\n// add-point constraint.kind=angleBisectorFoot — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n// Multi-emit: angleBisector shape + ensureSegment + intersection point.\n\nimport type { BuildState } from '../_types';\nimport { IntentBuilderError } from '../_types';\nimport { addPoint, addShape, ensureSegment, parseEnds, resolveSegmentRef, uniqueShapeName } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildAngleBisectorFoot = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'angleBisectorFoot') return;\n const name = intent.name;\n const ends = parseEnds(c.onLine);\n if (!ends) throw new IntentBuilderError(`angleBisectorFoot.onLine không parse: ${c.onLine}`, intent);\n const bisName = uniqueShapeName(s, `ab_${c.from}${c.onLine}`);\n addShape(s, { name: bisName, kind: 'angleBisector', p1: ends[0], vertex: c.from, p2: ends[1] });\n ensureSegment(s, ends[0], ends[1]);\n addPoint(s, { name, kind: 'intersection', ref1: bisName, ref2: resolveSegmentRef(s, c.onLine) });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/externalAngleBisectorFoot.ts\n//\n// add-point constraint.kind=externalAngleBisectorFoot — phân giác NGOÀI (Issue #46 nhóm A).\n// Mirror buildAngleBisectorFoot, nhưng phân giác ngoài = đường VUÔNG GÓC với phân\n// giác trong tại đỉnh `from`. Multi-emit:\n// 1. angleBisector shape (phân giác TRONG — helper, làm cơ sở dựng);\n// 2. perpendicular shape qua `from`, ⊥ phân giác trong = phân giác NGOÀI;\n// 3. ensureSegment(onLine) — cạnh đối (kéo dài) để giao;\n// 4. intersection point = phân giác ngoài ∩ đường thẳng cạnh đối.\n\nimport type { BuildState } from '../_types';\nimport { IntentBuilderError } from '../_types';\nimport { addPoint, addShape, ensureSegment, parseEnds, resolveSegmentRef, uniqueShapeName } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildExternalAngleBisectorFoot = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'externalAngleBisectorFoot') return;\n const name = intent.name;\n const ends = parseEnds(c.onLine);\n if (!ends) throw new IntentBuilderError(`externalAngleBisectorFoot.onLine không parse: ${c.onLine}`, intent);\n // Phân giác trong (helper, cơ sở dựng phân giác ngoài).\n const bisName = uniqueShapeName(s, `ab_${c.from}${c.onLine}`);\n addShape(s, { name: bisName, kind: 'angleBisector', p1: ends[0], vertex: c.from, p2: ends[1] });\n // Phân giác ngoài = đường vuông góc với phân giác trong tại đỉnh `from`.\n const extName = uniqueShapeName(s, `abx_${c.from}${c.onLine}`);\n addShape(s, { name: extName, kind: 'perpendicular', throughPoint: c.from, toLine: bisName });\n ensureSegment(s, ends[0], ends[1]);\n addPoint(s, { name, kind: 'intersection', ref1: extName, ref2: resolveSegmentRef(s, c.onLine) });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/rightAngleViewing.ts\n//\n// add-point constraint.kind=rightAngleViewing — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n// Multi-emit: hidden midpoint + hidden circleCP (Thales diameter) + intersection line∩circle.\n\nimport type { BuildState } from '../_types';\nimport { addPoint, addShape, resolveSegmentRef, uniquePointName, uniqueShapeName } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildRightAngleViewing = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'rightAngleViewing') return;\n const name = intent.name;\n // ∠ a-name-b = 90° ⇔ name trên đường tròn đường kính ab (Thales).\n // Dựng: midpoint(ab) ẩn → circleCP đường kính ab ẩn → giao line∩circle.\n const midName = uniquePointName(s, `mid_${c.a}${c.b}`);\n addPoint(s, { name: midName, kind: 'midpoint', p1: c.a, p2: c.b, visible: false });\n const circName = uniqueShapeName(s, `dia_${c.a}${c.b}`);\n addShape(s, { name: circName, kind: 'circleCP', center: midName, surfacePoint: c.a, visible: false });\n const lineRef = resolveSegmentRef(s, c.onLine);\n addPoint(s, { name, kind: 'intersection', ref1: lineRef, ref2: circName, branch: c.which ?? 0 });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/arcMidpoint.ts\n//\n// add-point constraint.kind=arcMidpoint (Cụm A) — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildArcMidpoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'arcMidpoint') return;\n addPoint(s, { name: intent.name, kind: 'arcMidpoint', circle: c.circle, a: c.a, b: c.b, notContaining: c.notContaining });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/reflect.ts\n//\n// add-point reflectPoint/reflectLine (Cụm A) — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n\nimport type { BuildState } from '../_types';\nimport { addPoint, resolveSegmentRef } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildReflectPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'reflectPoint') return;\n addPoint(s, { name: intent.name, kind: 'reflectPoint', of: c.of, through: c.through });\n};\n\nexport const buildReflectLine = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'reflectLine') return;\n const lineRef = resolveSegmentRef(s, c.through);\n addPoint(s, { name: intent.name, kind: 'reflectLine', of: c.of, through: lineRef });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/pointAtDistance.ts\n//\n// add-point constraint.kind=pointAtDistance (Cụm B) — move verbatim từ handleAddPoint switch (Phase 2b, #45).\n// Multi-emit: ensureSegment + pointAtDistance point.\n\nimport type { BuildState } from '../_types';\nimport { addPoint, ensureSegment } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildPointAtDistance = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'pointAtDistance') return;\n ensureSegment(s, c.from, c.through);\n addPoint(s, { name: intent.name, kind: 'pointAtDistance', from: c.from, through: c.through, distance: c.distance });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/externalToCircle.ts\n//\n// add-point externalToCircle — điểm A nằm NGOÀI đường tròn `circle` (free\n// external point). Builder đọc circle shape từ build state, tính tâm+bán kính,\n// rồi đặt A = free tại [cx + d, cy] với d = max(r*2, r+2) (đảm bảo distance > r\n// → A NGOÀI). Unblock tangentFromExt render END-TO-END (đề \"Lấy A ngoài (O), kẻ\n// 2 tiếp tuyến\").\n//\n// Fail-safe (skip → A KHÔNG add → tangent UNKNOWN_REF / named-missing →\n// escalate, KHÔNG render sai):\n// - circle shape không tồn tại trong build state.\n// - tâm/bán kính không xác định được (tâm không phải free, surfacePoint thiếu).\n//\n// Field name theo dsl/schema.ts: circleCR = { center, radius }; circleCP =\n// { center, surfacePoint } (KHÔNG phải `through`).\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildExternalToCircle = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'externalToCircle') return;\n const circle = s.shapes.find((sh) => sh.name === c.circle);\n if (!circle) return; // fail-safe: A không add → escalate\n\n let cx: number | undefined;\n let cy: number | undefined;\n let r: number | undefined;\n\n if (circle.kind === 'circleCR') {\n const center = s.points.find((p) => p.name === circle.center);\n if (center && center.kind === 'free') {\n cx = center.x;\n cy = center.y;\n r = circle.radius;\n }\n } else if (circle.kind === 'circleCP') {\n const center = s.points.find((p) => p.name === circle.center);\n const surf = s.points.find((p) => p.name === circle.surfacePoint);\n if (center && center.kind === 'free' && surf && surf.kind === 'free') {\n cx = center.x;\n cy = center.y;\n r = Math.hypot(surf.x - cx, surf.y - cy);\n }\n }\n\n if (cx === undefined || cy === undefined || r === undefined || !(r > 0)) return; // fail-safe\n const d = Math.max(r * 2, r + 2);\n addPoint(s, { name: intent.name, kind: 'free', x: cx + d, y: cy });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/onCircle.ts\n//\n// add-point constraint.kind=onCircle — điểm trên đường tròn `circle` tại góc\n// `theta` (glider). Map intent.circle → DSL circleId, theta default 0. Dùng cho\n// đường thẳng Simson (issue #47): P trên đường tròn ngoại tiếp tam giác.\n\nimport type { BuildState } from '../_types';\nimport { addPoint } from '../shared';\nimport type { AddPointIntentT } from '../../intent';\n\nexport const buildOnCircle = (s: BuildState, intent: AddPointIntentT): void => {\n const c = intent.constraint;\n if (c.kind !== 'onCircle') return;\n addPoint(s, { name: intent.name, kind: 'onCircle', circleId: c.circle, theta: c.theta ?? 0 });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/add-point/index.ts\n//\n// Dispatcher cho op add-point: map constraint.kind → builder (Phase 2b, #45).\n// ADD_POINT_BUILDERS được export cho Phase 6 matrix script.\n\nimport type { BuildState } from '../_types';\nimport type { AddPointIntentT } from '../../intent';\nimport { buildMidpoint } from './midpoint';\nimport { buildPerpFoot } from './perpFoot';\nimport { buildCentroid, buildCircumcenter, buildIncenter, buildOrthocenter, buildExcenter } from './centers';\nimport { buildIntersection, buildSecondIntersection, buildCircleIntersection, buildCircleSecondIntersection } from './intersections';\nimport { buildTangencyPoint, buildTangentPoint } from './tangency';\nimport { buildOnSegment, buildFree } from './onSegment-free';\nimport { buildAngleBisectorFoot } from './angleBisectorFoot';\nimport { buildExternalAngleBisectorFoot } from './externalAngleBisectorFoot';\nimport { buildRightAngleViewing } from './rightAngleViewing';\nimport { buildArcMidpoint } from './arcMidpoint';\nimport { buildReflectPoint, buildReflectLine } from './reflect';\nimport { buildPointAtDistance } from './pointAtDistance';\nimport { buildExternalToCircle } from './externalToCircle';\nimport { buildOnCircle } from './onCircle';\n\nexport const ADD_POINT_BUILDERS: Record<string, (s: BuildState, intent: AddPointIntentT) => void> = {\n midpoint: buildMidpoint, perpFoot: buildPerpFoot,\n centroid: buildCentroid, circumcenter: buildCircumcenter, incenter: buildIncenter,\n orthocenter: buildOrthocenter, excenter: buildExcenter,\n intersection: buildIntersection, secondIntersection: buildSecondIntersection, circleIntersection: buildCircleIntersection,\n circleSecondIntersection: buildCircleSecondIntersection,\n tangencyPoint: buildTangencyPoint, tangentPoint: buildTangentPoint,\n onSegment: buildOnSegment, free: buildFree,\n angleBisectorFoot: buildAngleBisectorFoot, externalAngleBisectorFoot: buildExternalAngleBisectorFoot,\n rightAngleViewing: buildRightAngleViewing,\n arcMidpoint: buildArcMidpoint, reflectPoint: buildReflectPoint, reflectLine: buildReflectLine,\n pointAtDistance: buildPointAtDistance,\n externalToCircle: buildExternalToCircle,\n onCircle: buildOnCircle,\n};\n\nexport const buildAddPoint = (s: BuildState, intent: AddPointIntentT): void => {\n const fn = ADD_POINT_BUILDERS[intent.constraint.kind];\n if (fn) fn(s, intent);\n};\n","// src/stamps/geometry-2d/ai/intent-builders/connect.ts\n//\n// op: connect — move verbatim từ intentToDsl.ts handleConnect (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { ensureSegment, addShape, uniqueShapeName } from './shared';\nimport type { ConnectIntentT } from '../intent';\n\nexport const buildConnect: IntentBuilder<ConnectIntentT> = (s, intent) => {\n const { from, to, style } = intent;\n switch (style) {\n case 'segment':\n ensureSegment(s, from, to);\n break;\n case 'line':\n addShape(s, { name: uniqueShapeName(s, `l_${from}${to}`), kind: 'line', p1: from, p2: to });\n break;\n case 'ray':\n addShape(s, { name: uniqueShapeName(s, `r_${from}${to}`), kind: 'ray', origin: from, through: to });\n break;\n case 'perpBisector':\n addShape(s, { name: uniqueShapeName(s, `pb_${from}${to}`), kind: 'perpBisector', p1: from, p2: to });\n break;\n case 'angleBisector':\n // angleBisector cần 3 điểm (p1, vertex, p2). connect chỉ có 2 điểm → bỏ qua,\n // caller nên dùng intent.add-point với incenter/internalBisector.\n throw new IntentBuilderError(\n 'connect.style=angleBisector cần 3 điểm; dùng add-point/incenter thay',\n intent,\n );\n }\n};\n","// src/stamps/geometry-2d/ai/intent-builders/draw-circle.ts\n//\n// op: draw-circle — move verbatim từ intentToDsl.ts handleDrawCircle (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { addPoint, addShape, defaultFreeCoord } from './shared';\nimport type { DrawCircleIntentT } from '../intent';\n\nexport const buildDrawCircle: IntentBuilder<DrawCircleIntentT> = (s, intent) => {\n if (intent.spec === 'centerThrough') {\n if (!intent.center || !intent.through) {\n throw new IntentBuilderError('centerThrough cần center + through', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'circleCP',\n center: intent.center,\n surfacePoint: intent.through,\n });\n } else if (intent.spec === 'through3') {\n if (!intent.points) {\n throw new IntentBuilderError('through3 cần points', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'circle3',\n p1: intent.points[0],\n p2: intent.points[1],\n p3: intent.points[2],\n });\n } else if (intent.spec === 'centerRadius') {\n if (!intent.center || intent.radius === undefined) {\n throw new IntentBuilderError('centerRadius cần center + radius', intent);\n }\n if (!s.points.find((p) => p.name === intent.center)) {\n const [x, y] = defaultFreeCoord(s);\n addPoint(s, { name: intent.center!, kind: 'free', x, y });\n }\n addShape(s, { name: intent.name, kind: 'circleCR', center: intent.center, radius: intent.radius });\n } else if (intent.spec === 'diameter') {\n if (!intent.endpoints) {\n throw new IntentBuilderError('diameter cần endpoints', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'circleDiameter',\n p1: intent.endpoints[0],\n p2: intent.endpoints[1],\n });\n } else if (intent.spec === 'inscribedIn') {\n if (!intent.triangle) throw new IntentBuilderError('inscribedIn cần triangle', intent);\n for (const v of intent.triangle) {\n if (!s.points.find((p) => p.name === v)) {\n throw new IntentBuilderError(`inscribedIn: vertex ${v} chưa định nghĩa`, intent);\n }\n }\n addShape(s, { name: intent.name, kind: 'incircle', vertices: intent.triangle });\n }\n};\n","// src/stamps/geometry-2d/ai/intent-builders/draw-line.ts\n//\n// op: draw-line — move verbatim từ intentToDsl.ts handleDrawLine (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { addShape, resolveLineRefWithFallback } from './shared';\nimport type { DrawLineIntentT } from '../intent';\n\nexport const buildDrawLine: IntentBuilder<DrawLineIntentT> = (s, intent) => {\n switch (intent.kind) {\n case 'perpThrough': {\n if (!intent.through || !intent.to) throw new IntentBuilderError('perpThrough cần through + to', intent);\n const toLine = resolveLineRefWithFallback(s, intent.to, intent.through);\n addShape(s, { name: intent.name, kind: 'perpendicular', throughPoint: intent.through, toLine });\n break;\n }\n case 'parallelThrough': {\n if (!intent.through || !intent.to) throw new IntentBuilderError('parallelThrough cần through + to', intent);\n const toLine = resolveLineRefWithFallback(s, intent.to, intent.through);\n addShape(s, { name: intent.name, kind: 'parallel', throughPoint: intent.through, toLine });\n break;\n }\n case 'tangentAt': {\n if (!intent.through || !intent.circle) throw new IntentBuilderError('tangentAt cần through + circle', intent);\n addShape(s, { name: intent.name, kind: 'tangent', throughPoint: intent.through, toCircle: intent.circle, branch: 'on' });\n break;\n }\n case 'tangentFromExt': {\n if (!intent.from || !intent.circle) throw new IntentBuilderError('tangentFromExt cần from + circle', intent);\n if (intent.which === 'both') {\n addShape(s, { name: `${intent.name}_0`, kind: 'tangent', throughPoint: intent.from, toCircle: intent.circle, branch: 0 });\n addShape(s, { name: `${intent.name}_1`, kind: 'tangent', throughPoint: intent.from, toCircle: intent.circle, branch: 1 });\n } else {\n const branch = intent.which === 'second' ? 1 : 0;\n addShape(s, { name: intent.name, kind: 'tangent', throughPoint: intent.from, toCircle: intent.circle, branch });\n }\n break;\n }\n case 'angleBisector': {\n // Phân giác TRONG của góc ∠(p1·vertex·p2), VISIBLE, KHÔNG sinh chân\n // (khác cevian \"phân giác AD\" → foot). vertex = đỉnh góc. Issue #46 nhóm A.\n if (!intent.p1 || !intent.vertex || !intent.p2) {\n throw new IntentBuilderError('angleBisector cần p1 + vertex + p2', intent);\n }\n addShape(s, {\n name: intent.name,\n kind: 'angleBisector',\n p1: intent.p1,\n vertex: intent.vertex,\n p2: intent.p2,\n });\n break;\n }\n case 'lineThrough': {\n // Đường qua ≥2 điểm đồng tuyến (vd Euler line qua G/H/O — issue #47).\n if (!intent.points || intent.points.length < 2) {\n throw new IntentBuilderError('lineThrough cần ≥2 điểm', intent);\n }\n addShape(s, { name: intent.name, kind: 'lineThrough', points: intent.points });\n break;\n }\n case 'radicalAxis': {\n // Trục đẳng phương 2 đường tròn (issue #47, construct 2).\n if (!intent.circle1 || !intent.circle2) {\n throw new IntentBuilderError('radicalAxis cần circle1 + circle2', intent);\n }\n addShape(s, { name: intent.name, kind: 'radicalAxis', circle1: intent.circle1, circle2: intent.circle2 });\n break;\n }\n }\n};\n","// src/stamps/geometry-2d/ai/intent-builders/mark-shape.ts\n//\n// op: mark-shape — move verbatim từ intentToDsl.ts handleMarkShape (Phase 2b, #45).\n\nimport type { IntentBuilder } from './_types';\nimport { IntentBuilderError } from './_types';\nimport { addShape, uniqueShapeName } from './shared';\nimport type { MarkShapeIntentT } from '../intent';\n\nexport const buildMarkShape: IntentBuilder<MarkShapeIntentT> = (s, intent) => {\n for (const label of intent.labels) {\n if (!s.points.find((p) => p.name === label)) {\n throw new IntentBuilderError(`mark-shape: label ${label} chưa định nghĩa`, intent);\n }\n }\n const polyName = uniqueShapeName(s, intent.labels.join(''));\n addShape(s, { name: polyName, kind: 'polygon', vertices: [...intent.labels] });\n};\n","// src/stamps/geometry-2d/ai/intent-builders/registry.ts\n//\n// OP_BUILDERS: map intent.op → builder (Phase 2b, #45).\n// Thêm 1 op = 1 builder module + 1 dòng ở đây, không sửa switch trung tâm.\n\nimport type { BuildState } from './_types';\nimport type { IntentT } from '../intent';\nimport { buildDrawShape } from './draw-shape';\nimport { buildAddPoint } from './add-point';\nimport { buildConnect } from './connect';\nimport { buildDrawCircle } from './draw-circle';\nimport { buildDrawLine } from './draw-line';\nimport { buildMarkShape } from './mark-shape';\n\nexport const OP_BUILDERS: Record<IntentT['op'], (s: BuildState, intent: any) => void> = {\n 'draw-shape': buildDrawShape,\n 'add-point': buildAddPoint,\n 'connect': buildConnect,\n 'draw-circle': buildDrawCircle,\n 'draw-line': buildDrawLine,\n 'mark-shape': buildMarkShape,\n};\n","// src/stamps/geometry-2d/ai/intentToDsl.ts\n//\n// Stage 2: deterministic Intent[] → DslInputT builder.\n//\n// Pure function. Không gọi AI. Mỗi Intent op map sang 1 hoặc nhiều DSL entries\n// với canonical coords cố định per variant. Builder rejects intent không hợp lệ\n// (vd connect to point chưa tồn tại) thay vì silent skip.\n//\n// Phase 2b (#45): orchestrator mỏng — dispatch qua OP_BUILDERS registry.\n// Thứ tự loop intents giữ nguyên (ordering dependency: draw-shape trước add-point\n// tham chiếu điểm của nó). repairCircleIntersections chạy post-dispatch.\n\nimport type { DslInputT } from '../dsl/schema';\nimport type { IntentT } from './intent';\nimport { repairCircleIntersections } from './repairCircleIntersections';\nimport { layoutDisjointComponents } from './layout/disjointOffset';\nimport { newState } from './intent-builders/_types';\nimport { OP_BUILDERS } from './intent-builders/registry';\n\nexport { IntentBuilderError } from './intent-builders/_types';\n\nexport function intentsToDsl(intents: readonly IntentT[]): DslInputT {\n const s = newState();\n for (const intent of intents) {\n const build = OP_BUILDERS[intent.op];\n if (build) build(s, intent);\n }\n // Geometric repair: đảm bảo circle dùng cho circleIntersection thực sự cắt\n // nhau 2 điểm (dời center auto-inject nếu tiếp xúc/rời nhau).\n repairCircleIntersections(s.points, s.shapes);\n // Layout: tách các component RỜI NHAU theo trục ngang (không chồng origin).\n layoutDisjointComponents(s.points, s.shapes);\n return { version: 1, points: s.points, shapes: s.shapes };\n}\n","// src/stamps/geometry-2d/dsl/schema.ts\nimport { z } from 'zod';\nimport { NameZ } from './names';\nimport { KIND_REGISTRY, POINT_KINDS } from './registry';\n\n// Re-export NameZ for backward compat with consumers.\nexport { NameZ } from './names';\n\nfunction asTuple(arr: z.ZodObject<any>[]): [z.ZodObject<any>, z.ZodObject<any>, ...z.ZodObject<any>[]] {\n if (arr.length < 2) throw new Error('schema: need at least 2 variants for discriminatedUnion');\n return arr as never;\n}\n\nconst pointSchemas = Array.from(KIND_REGISTRY.values())\n .filter((m) => POINT_KINDS.has(m.kind))\n .map((m) => m.schema);\n\nconst shapeSchemas = Array.from(KIND_REGISTRY.values())\n .filter((m) => !POINT_KINDS.has(m.kind))\n .map((m) => m.schema);\n\n// Runtime schemas assembled from the registry (Phase 6).\nexport const DslPoint = z.discriminatedUnion('kind', asTuple(pointSchemas));\nexport const DslShape = z.discriminatedUnion('kind', asTuple(shapeSchemas));\n\nexport const DslInput = z.object({\n version: z.literal(1),\n points: z.array(DslPoint),\n shapes: z.array(DslShape).default([]),\n});\n\n// -----------------------------------------------------------------------------\n// Static types\n//\n// We cannot derive these via `z.infer<typeof DslPoint>` because the kind\n// modules use `Extract<DslPointT, { kind: '...' }>` to type their `emit` /\n// `collectRefs` callbacks. That creates a type-graph cycle\n// (schema.ts -> registry.ts -> kinds/* -> schema.ts) which TypeScript collapses\n// to `any` (and `Extract<any, ...>` to `never`) because the registry stores\n// schemas as the erased `z.ZodObject<any>`.\n//\n// Keeping the discriminated union types listed explicitly here breaks the cycle\n// while still letting `DslPoint`/`DslShape` (runtime) be registry-assembled.\n// Adding a new kind = 1 new module file + 1 entry in registry.ts + 1 variant\n// listed below (a single object literal — much smaller than duplicating the\n// full Zod schema).\n// -----------------------------------------------------------------------------\n\ntype Name = z.infer<typeof NameZ>;\n\n// scale/offset OPTIONAL (Issue #46 nhóm C): d = scale·base + offset. Absent →\n// d = base như cũ (additive, serialize/golden không đổi).\nexport type DslDistanceSpec =\n | { kind: 'circleRadius'; circle: Name; scale?: number; offset?: number }\n | { kind: 'segmentLength'; p1: Name; p2: Name; scale?: number; offset?: number }\n | { kind: 'literal'; value: number; scale?: number; offset?: number };\n\nexport type DslPointT =\n | { name: Name; kind: 'free'; x: number; y: number }\n | { name: Name; kind: 'midpoint'; p1: Name; p2: Name; visible?: boolean }\n | { name: Name; kind: 'onSegment'; segmentId: Name; t: number }\n | { name: Name; kind: 'onLine'; lineId: Name; t: number }\n | { name: Name; kind: 'onCircle'; circleId: Name; theta: number }\n | { name: Name; kind: 'perpFoot'; from: Name; onLine: Name }\n | { name: Name; kind: 'circumcenter'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'incenter'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'centroid'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'orthocenter'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'intersection'; ref1: Name; ref2: Name; branch?: 0 | 1 }\n // NEW Tier 4+5\n | { name: Name; kind: 'secondIntersection'; line: Name; circle: Name; other: Name }\n | { name: Name; kind: 'circleIntersection'; c1: Name; c2: Name; which: 0 | 1 }\n | { name: Name; kind: 'circleSecondIntersection'; c1: Name; c2: Name; exclude: Name }\n | { name: Name; kind: 'tangencyPoint'; circle: Name; onLine: Name }\n | { name: Name; kind: 'tangentPointExt'; from: Name; circle: Name; which: 0 | 1 }\n // Cụm A\n | { name: Name; kind: 'arcMidpoint'; circle: Name; a: Name; b: Name; notContaining: Name }\n | { name: Name; kind: 'excenter'; vertices: [Name, Name, Name]; opposite: Name }\n | { name: Name; kind: 'reflectPoint'; of: Name; through: Name }\n | { name: Name; kind: 'reflectLine'; of: Name; through: Name }\n // Cụm B points\n | { name: Name; kind: 'pointAtDistance'; from: Name; through: Name; distance: DslDistanceSpec };\n\nexport type DslShapeT =\n | { name: Name; kind: 'segment'; p1: Name; p2: Name }\n | { name: Name; kind: 'line'; p1: Name; p2: Name }\n | { name: Name; kind: 'ray'; origin: Name; through: Name }\n | { name: Name; kind: 'polygon'; vertices: Name[] }\n | { name: Name; kind: 'perpendicular'; throughPoint: Name; toLine: Name }\n | { name: Name; kind: 'parallel'; throughPoint: Name; toLine: Name }\n | { name: Name; kind: 'perpBisector'; p1: Name; p2: Name }\n | { name: Name; kind: 'angleBisector'; p1: Name; vertex: Name; p2: Name }\n | { name: Name; kind: 'lineThrough'; points: Name[] }\n | { name: Name; kind: 'radicalAxis'; circle1: Name; circle2: Name }\n | { name: Name; kind: 'tangent'; throughPoint: Name; toCircle: Name; branch?: 0 | 1 | 'on' }\n | { name: Name; kind: 'circleCP'; center: Name; surfacePoint: Name; visible?: boolean }\n | { name: Name; kind: 'circle3'; p1: Name; p2: Name; p3: Name }\n | { name: Name; kind: 'circleDiameter'; p1: Name; p2: Name; visible?: boolean }\n // NEW Tier 4+5\n | { name: Name; kind: 'circleCR'; center: Name; radius: number }\n | { name: Name; kind: 'incircle'; vertices: [Name, Name, Name] }\n | { name: Name; kind: 'excircle'; vertices: [Name, Name, Name]; opposite: Name };\n\nexport type DslInputT = {\n version: 1;\n points: DslPointT[];\n shapes: DslShapeT[];\n};\n","// src/core/scene/types.ts\n\nexport type SceneObject<A = Record<string, unknown>> = {\n id: string;\n kind: string;\n label: string;\n visible: boolean;\n locked: boolean;\n layer: string;\n schemaVersion: number;\n attrs: A;\n};\n\n// View per domain — narrow theo `state.meta.domain`.\nexport type View2D = {\n readonly bbox: readonly [number, number, number, number]; // [xmin, ymax, xmax, ymin]\n readonly showAxis: boolean;\n readonly showGrid: boolean;\n};\n\nexport type View3D = {\n readonly bbox3D: readonly [number, number, number, number, number, number]; // [xmin, xmax, ymin, ymax, zmin, zmax]\n readonly azimuth: number;\n readonly elevation: number;\n};\n\nexport type ViewGraph2D = {\n readonly xMin: number;\n readonly xMax: number;\n readonly yMin: number;\n readonly yMax: number;\n readonly showAxis: boolean;\n readonly showGrid: boolean;\n};\n\n// Union of all view shapes — narrow qua state.meta.domain.\nexport type SceneView = View2D | View3D | ViewGraph2D;\n\n// Discriminated union: domain narrow → view shape narrow.\nexport type StateMeta =\n | { readonly domain: '2d'; readonly version: number; readonly view: View2D }\n | { readonly domain: '3d'; readonly version: number; readonly view: View3D }\n | { readonly domain: 'graph2d'; readonly version: number; readonly view: ViewGraph2D };\n\nexport type Domain = StateMeta['domain'];\n\n// Backward-compat alias: UPDATE_VIEW patch dùng graph-2d shape (chỉ graph-2d\n// dispatch action này hiện tại).\nexport type ViewSettings = ViewGraph2D;\n\nexport type State = {\n readonly objects: Readonly<Record<string, SceneObject>>;\n readonly order: readonly string[];\n readonly counter: number;\n readonly meta: StateMeta;\n};\n\nexport type Action =\n | { type: 'ADD'; payload: { obj: SceneObject } }\n | { type: 'UPDATE'; payload: { id: string; patch: Partial<Omit<SceneObject, 'id' | 'kind' | 'attrs'>> } }\n | { type: 'UPDATE_ATTRS'; payload: { id: string; patch: Record<string, unknown> } }\n | { type: 'DELETE'; payload: { id: string } }\n | { type: 'RESET' }\n | { type: 'LOAD'; payload: { state: State } }\n | { type: 'TRANSACTION'; payload: { actions: Action[] } }\n | { type: 'UPDATE_VIEW'; payload: { patch: Partial<ViewSettings> } };\n\nexport type RenderCtx = {\n jxg: unknown;\n resolveRef: (id: string) => unknown;\n defaults: Readonly<Record<string, unknown>>;\n /** Map tham số (parameter.label → parameter.value). Chỉ graph2d dùng. */\n paramMap?: Readonly<Record<string, number>>;\n};\n\nexport type KindDef<A = Record<string, unknown>> = {\n type: string;\n schemaVersion: number;\n migrate: Record<number, (prev: any) => any>;\n validate?: (attrs: A) => void;\n dependsOn: (attrs: A) => string[];\n describe: (obj: SceneObject<A>, state?: State) => string;\n measure?: (obj: SceneObject<A>, state: State) =>\n | { label: string; value: number }[]\n | null;\n render: (obj: SceneObject<A>, ctx: RenderCtx) => unknown;\n update?: (\n obj: SceneObject<A>,\n prev: SceneObject<A>,\n ctx: RenderCtx,\n existing: unknown,\n ) => void;\n};\n\nexport const DEFAULT_VIEW_2D: View2D = {\n bbox: [-10, 10, 10, -10],\n showAxis: false,\n showGrid: false,\n};\n\nexport const DEFAULT_VIEW_3D: View3D = {\n bbox3D: [-5, 5, -5, 5, -5, 5],\n azimuth: 60,\n elevation: 30,\n};\n\nexport const DEFAULT_VIEW_GRAPH2D: ViewGraph2D = {\n xMin: -10, xMax: 10, yMin: -10, yMax: 10,\n showAxis: true, showGrid: true,\n};\n\n// EMPTY_STATE giữ shape '3d' (legacy default). Dùng `createEmptyState(domain)`\n// khi cần state cụ thể cho domain — đảm bảo meta.view khớp domain.\nexport const EMPTY_STATE: State = {\n objects: {},\n order: [],\n counter: 0,\n meta: { domain: '3d', version: 1, view: DEFAULT_VIEW_3D },\n};\n\nexport function createEmptyState(domain: Domain): State {\n const base = { objects: {}, order: [], counter: 0 } as const;\n switch (domain) {\n case '2d':\n return { ...base, meta: { domain: '2d', version: 1, view: DEFAULT_VIEW_2D } };\n case '3d':\n return { ...base, meta: { domain: '3d', version: 1, view: DEFAULT_VIEW_3D } };\n case 'graph2d':\n return { ...base, meta: { domain: 'graph2d', version: 1, view: DEFAULT_VIEW_GRAPH2D } };\n }\n}\n","// src/stamps/geometry-2d/dsl/transpile/symbols.ts\nimport type { DslInputT, DslPointT, DslShapeT } from '../schema';\nimport { mkError, type TranspileError } from './errors';\n\nexport type Role = 'point' | 'shape';\n\nexport interface Symbol {\n name: string;\n role: Role;\n entity: DslPointT | DslShapeT;\n index: number; // vị trí trong list nguyên thuỷ (cho deterministic id assign sau)\n}\n\nexport interface SymbolResult {\n symbols: Map<string, Symbol>;\n errors: TranspileError[];\n}\n\nexport function buildSymbols(dsl: DslInputT): SymbolResult {\n const symbols = new Map<string, Symbol>();\n const errors: TranspileError[] = [];\n let counter = 0;\n\n for (const p of dsl.points) {\n if (symbols.has(p.name)) {\n errors.push(mkError('DUPLICATE_NAME', `Tên trùng: \"${p.name}\"`, { path: [p.name] }));\n continue;\n }\n symbols.set(p.name, { name: p.name, role: 'point', entity: p, index: counter++ });\n }\n\n for (const s of dsl.shapes) {\n if (symbols.has(s.name)) {\n errors.push(mkError('DUPLICATE_NAME', `Tên trùng: \"${s.name}\"`, { path: [s.name] }));\n continue;\n }\n symbols.set(s.name, { name: s.name, role: 'shape', entity: s, index: counter++ });\n }\n\n return { symbols, errors };\n}\n","// src/stamps/geometry-2d/dsl/transpile/cycles.ts\nimport type { Symbol } from './symbols';\nimport { collectRefs } from './refs';\nimport { mkError, type TranspileError } from './errors';\n\ntype Color = 'white' | 'gray' | 'black';\n\nexport interface CyclesResult {\n errors: TranspileError[];\n}\n\nexport function detectCycles(symbols: Map<string, Symbol>): CyclesResult {\n const color = new Map<string, Color>();\n const parent = new Map<string, string | null>();\n const errors: TranspileError[] = [];\n const reportedCycles = new Set<string>();\n\n for (const name of symbols.keys()) color.set(name, 'white');\n\n function reportCycle(start: string, hit: string) {\n // reconstruct chain hit ← ... ← start\n const chain: string[] = [start];\n let cur: string | null | undefined = parent.get(start);\n while (cur && cur !== hit && chain.length < symbols.size + 2) {\n chain.push(cur);\n cur = parent.get(cur);\n }\n chain.push(hit);\n // normalize cho dedupe (rotate min-first)\n const minIdx = chain.indexOf(chain.reduce((a, b) => (a < b ? a : b)));\n const rotated = [...chain.slice(minIdx), ...chain.slice(0, minIdx)];\n const key = rotated.join('→');\n if (reportedCycles.has(key)) return;\n reportedCycles.add(key);\n errors.push(mkError('CYCLE',\n `Phụ thuộc vòng: ${chain.reverse().join(' → ')}`,\n { path: [...chain], hint: 'Kiểm tra lại quan hệ midpoint/perpFoot/intersection.' }));\n }\n\n function dfs(name: string) {\n color.set(name, 'gray');\n const sym = symbols.get(name);\n if (sym) {\n for (const ref of collectRefs(sym.entity)) {\n if (!symbols.has(ref)) continue; // unknown — refs.ts handle\n const c = color.get(ref);\n if (c === 'gray') {\n reportCycle(name, ref);\n continue;\n }\n if (c === 'white') {\n parent.set(ref, name);\n dfs(ref);\n }\n }\n }\n color.set(name, 'black');\n }\n\n for (const name of symbols.keys()) {\n if (color.get(name) === 'white') {\n parent.set(name, null);\n dfs(name);\n }\n }\n\n return { errors };\n}\n","// src/stamps/geometry-2d/dsl/transpile/topology.ts\n//\n// Stable topological sort: preserve DSL insertion order khi không có constraint,\n// chỉ trì hoãn entity tới khi mọi reference đã emit. Fix bug render perpFoot\n// đứng trước segment dùng làm onLine.\n//\n// Khác DFS post-order (kéo deps lên trước): Kahn-style iterative đảm bảo\n// roundtrip stability — entity không có constraint phụ thuộc lẫn nhau giữ\n// đúng thứ tự DSL gốc.\n\nimport type { Symbol } from './symbols';\nimport { collectRefs } from './refs';\n\n/**\n * Trả về danh sách tên entity theo thứ tự topological STABLE:\n * - Mọi name X xuất hiện SAU mọi name X tham chiếu.\n * - Khi 2 entity không phụ thuộc lẫn nhau, giữ relative order từ symbols\n * (= DSL insertion order: points trước shapes, mỗi nhóm theo DSL order).\n *\n * Giả định cycles đã được loại bởi detectCycles trước đó. Nếu vẫn có cycle,\n * entity unresolved sẽ append cuối để output đủ count.\n */\nexport function topoSort(symbols: Map<string, Symbol>): string[] {\n const all = [...symbols.keys()];\n const emitted = new Set<string>();\n const order: string[] = [];\n\n // Pre-compute deps filtered xuống chỉ tên có trong symbols.\n const depsOf = new Map<string, string[]>();\n for (const name of all) {\n const sym = symbols.get(name);\n if (!sym) {\n depsOf.set(name, []);\n continue;\n }\n const refs = collectRefs(sym.entity).filter((r) => symbols.has(r));\n depsOf.set(name, refs);\n }\n\n // Lặp: mỗi vòng emit tất cả entity có deps đã emit, theo DSL order.\n // Worst case O(n^2) but n nhỏ (~20 entity/figure).\n let progressed = true;\n while (progressed) {\n progressed = false;\n for (const name of all) {\n if (emitted.has(name)) continue;\n const deps = depsOf.get(name)!;\n if (deps.every((d) => emitted.has(d))) {\n emitted.add(name);\n order.push(name);\n progressed = true;\n }\n }\n }\n\n // Cycle leftovers (defensive — detectCycles đáng lẽ catch): append đúng count.\n for (const name of all) {\n if (!emitted.has(name)) order.push(name);\n }\n\n return order;\n}\n","// src/stamps/geometry-2d/dsl/transpile/ids.ts\nimport type { Symbol } from './symbols';\nimport { KIND_REGISTRY } from '../registry';\n\nexport function assignIds(symbols: Map<string, Symbol>): Map<string, string> {\n const counters = new Map<string, number>();\n const ids = new Map<string, string>();\n for (const [name, sym] of symbols.entries()) {\n const mod = KIND_REGISTRY.get(sym.entity.kind);\n if (!mod) throw new Error(`assignIds: no registry entry for kind \"${sym.entity.kind}\"`);\n const prefix = mod.prefix;\n counters.set(prefix, (counters.get(prefix) ?? 0) + 1);\n ids.set(name, `${prefix}${counters.get(prefix)}`);\n }\n return ids;\n}\n","// src/stamps/geometry-2d/dsl/transpile.ts\nimport type { SceneObject, State } from '../../../core/scene/types';\nimport { createEmptyState } from '../../../core/scene/types';\nimport { DslInput, type DslInputT, type DslPointT, type DslShapeT } from './schema';\nimport { buildSymbols } from './transpile/symbols';\nimport { validateRefs } from './transpile/refs';\nimport { detectCycles } from './transpile/cycles';\nimport { topoSort } from './transpile/topology';\nimport { assignIds } from './transpile/ids';\nimport { mkError, type TranspileError, type TranspileResult } from './transpile/errors';\nimport { KIND_REGISTRY } from './registry';\nimport type { EmitContext, EmittedEntity, KindRole } from './kinds/_types';\n\ntype EntityKindHint = 'point' | 'line' | 'segment' | 'ray' | 'lineConstruction' | 'circle';\n\nfunction hintOf(entity: DslPointT | DslShapeT): EntityKindHint {\n const mod = KIND_REGISTRY.get(entity.kind);\n if (!mod) throw new Error(`hintOf: no registry entry for kind \"${entity.kind}\"`);\n // 'polygon' role maps to 'point' for legacy MVP behavior (polygon never used as ref target).\n return mod.role === 'polygon' ? 'point' : (mod.role as EntityKindHint);\n}\n\nfunction buildEmitContext(\n ids: Map<string, string>,\n kindHints: Map<string, EntityKindHint>,\n): EmitContext {\n const auxCounters = new Map<string, number>();\n return {\n resolveId(name) {\n const id = ids.get(name);\n if (!id) throw new Error(`emit: id not assigned for \"${name}\"`);\n return id;\n },\n hintOf(name) {\n const hint = kindHints.get(name);\n if (!hint) throw new Error(`emit: hint not assigned for \"${name}\"`);\n // EntityKindHint and KindRole share these literals; safe to widen.\n return hint as KindRole;\n },\n mintAuxId(parentName, suffix) {\n const key = `${parentName}.${suffix}`;\n auxCounters.set(key, (auxCounters.get(key) ?? 0) + 1);\n const seq = auxCounters.get(key)!;\n return `aux_${parentName}_${suffix}${seq}`;\n },\n };\n}\n\nexport function transpile(dslRaw: unknown): TranspileResult {\n // Stage 1: schema parse\n const parsed = DslInput.safeParse(dslRaw);\n if (!parsed.success) {\n const errors: TranspileError[] = parsed.error.issues.map((iss) =>\n mkError('SCHEMA', iss.message, { path: iss.path.map(String) }),\n );\n return { ok: false, errors };\n }\n // Cast: parsed.data is statically `{[x: string]: any}[]` because the registry\n // stores schemas as the erased `z.ZodObject<any>`. Runtime parse already\n // validated the variant shape, so widening to DslInputT is safe.\n const dsl = parsed.data as DslInputT;\n\n // Stage 2-4: collect errors\n const { symbols, errors: dupErrors } = buildSymbols(dsl);\n const { errors: refErrors } = validateRefs(dsl, symbols);\n const { errors: cycleErrors } = detectCycles(symbols);\n\n const allErrors = [...dupErrors, ...refErrors, ...cycleErrors];\n if (allErrors.length > 0) return { ok: false, errors: allErrors };\n\n // Stage 5: id assignment\n const ids = assignIds(symbols);\n\n // Build kindHints (DSL name → EntityKindHint) cho intersection inference.\n const kindHints = new Map<string, EntityKindHint>();\n for (const [name, sym] of symbols.entries()) {\n kindHints.set(name, hintOf(sym.entity));\n }\n\n // Stage 6: emit via registry\n const objects: Record<string, SceneObject> = {};\n const order: string[] = [];\n const ctx = buildEmitContext(ids, kindHints);\n\n const emitEntity = (entity: DslPointT | DslShapeT) => {\n const mod = KIND_REGISTRY.get(entity.kind);\n if (!mod) throw new Error(`emit: no registry entry for kind \"${entity.kind}\"`);\n const emitted: EmittedEntity[] = mod.emit(entity as never, ctx);\n for (const ent of emitted) {\n objects[ent.object.id] = ent.object;\n order.push(ent.object.id);\n }\n };\n\n // Emit theo thứ tự topological — đảm bảo entity dependent emit SAU mọi\n // reference của nó (vd perpFoot point sau segment dùng làm onLine).\n const sortedNames = topoSort(symbols);\n for (const name of sortedNames) {\n const sym = symbols.get(name);\n if (sym) emitEntity(sym.entity);\n }\n\n const empty = createEmptyState('2d');\n const state: State = {\n objects,\n order,\n counter: order.length,\n meta: empty.meta,\n };\n return { ok: true, state };\n}\n","// src/stamps/geometry-2d/ai/verify.ts\n//\n// Stage 4 verifier. Sau khi Intent[] → DSL → render, kiểm tra 3 trục:\n// - đủ (missing): intent expected nhưng DSL không có\n// - đúng (wrong): variant/labels mismatch\n// - không thừa (extra): DSL có entity không tương ứng intent nào\n//\n// Hai chế độ dùng:\n// 1. eval mode: so sánh actualIntents vs expectedIntents (golden)\n// 2. runtime mode: tự verify pipeline (intent→DSL, không có golden)\n\nimport type { DslInputT } from '../dsl/schema';\nimport type { IntentT, DrawShapeIntentT, AddPointIntentT } from './intent';\n\nexport interface VerifyIssue {\n readonly axis: 'missing' | 'wrong' | 'extra';\n readonly detail: string;\n}\n\nexport interface VerifyReport {\n readonly ok: boolean;\n readonly missing: readonly VerifyIssue[];\n readonly wrong: readonly VerifyIssue[];\n readonly extra: readonly VerifyIssue[];\n readonly geometric?: readonly VerifyIssue[];\n}\n\n// ---------------------------------------------------------------------------\n// Eval-mode: compare actual intents vs golden expected\n// ---------------------------------------------------------------------------\n\nexport function compareIntents(\n expected: readonly IntentT[],\n actual: readonly IntentT[],\n): VerifyReport {\n const expectedKey = expected.map(intentKey);\n const actualKey = actual.map(intentKey);\n\n const missing: VerifyIssue[] = [];\n const extra: VerifyIssue[] = [];\n const wrong: VerifyIssue[] = [];\n\n // Track which expected/actual entries matched.\n const matchedActual = new Set<number>();\n for (let i = 0; i < expectedKey.length; i++) {\n const ek = expectedKey[i];\n // Exact match first\n const exactIdx = actualKey.findIndex((ak, idx) => !matchedActual.has(idx) && ak === ek);\n if (exactIdx >= 0) {\n matchedActual.add(exactIdx);\n continue;\n }\n // Partial match: same op + same shape/name → \"wrong\"\n const partialIdx = actualKey.findIndex((ak, idx) =>\n !matchedActual.has(idx) && samePrefix(ak, ek, 2),\n );\n if (partialIdx >= 0) {\n matchedActual.add(partialIdx);\n wrong.push({\n axis: 'wrong',\n detail: `expected ${ek}, got ${actualKey[partialIdx]}`,\n });\n continue;\n }\n // No match → missing\n missing.push({ axis: 'missing', detail: ek });\n }\n // Unmatched actual entries → extra\n for (let i = 0; i < actualKey.length; i++) {\n if (!matchedActual.has(i)) {\n extra.push({ axis: 'extra', detail: actualKey[i] });\n }\n }\n\n return {\n ok: missing.length === 0 && wrong.length === 0 && extra.length === 0,\n missing,\n wrong,\n extra,\n };\n}\n\n// \"draw-shape/triangle/equilateral/A,B,C\" — canonical short string for compare.\nfunction intentKey(intent: IntentT): string {\n switch (intent.op) {\n case 'draw-shape':\n return [\n 'draw-shape',\n intent.shape,\n (intent as DrawShapeIntentT).variant,\n intent.labels.join(','),\n ].join('/');\n case 'add-point':\n return ['add-point', intent.name, intent.constraint.kind, constraintKey(intent.constraint)].join('/');\n case 'connect':\n return ['connect', intent.style, intent.from, intent.to].join('/');\n case 'draw-circle': {\n if (intent.spec === 'centerThrough') return `draw-circle/${intent.name}/centerThrough/${intent.center}/${intent.through}`;\n if (intent.spec === 'through3') return `draw-circle/${intent.name}/through3/${intent.points?.join(',') ?? ''}`;\n if (intent.spec === 'centerRadius') return `draw-circle/${intent.name}/centerRadius/${intent.center}/${intent.radius}`;\n if (intent.spec === 'inscribedIn') return `draw-circle/${intent.name}/inscribedIn/${intent.triangle?.join(',') ?? ''}`;\n return `draw-circle/${intent.name}/${(intent as any).spec}`;\n }\n case 'draw-line': {\n const base = [\n 'draw-line', intent.name, intent.kind,\n intent.through ?? '', intent.to ?? '', intent.from ?? '', intent.circle ?? '', intent.which ?? '',\n ].join('/');\n if (intent.kind === 'lineThrough') return `${base}/${(intent.points ?? []).join('+')}`;\n if (intent.kind === 'radicalAxis') return `${base}/${intent.circle1 ?? ''}+${intent.circle2 ?? ''}`;\n return base;\n }\n case 'mark-shape':\n return ['mark-shape', intent.shape, intent.labels.join(',')].join('/');\n }\n}\n\nfunction constraintKey(c: AddPointIntentT['constraint']): string {\n switch (c.kind) {\n case 'midpoint': return c.of;\n case 'perpFoot': return `${c.from}->${c.onLine}`;\n case 'centroid':\n case 'circumcenter':\n case 'incenter':\n case 'orthocenter':\n return c.of.join(',');\n case 'intersection': return c.of.join('×');\n case 'onSegment': return `${c.of}@${c.t ?? 'mid'}`;\n case 'free': return c.at ? c.at.join(',') : '*';\n case 'secondIntersection': return `secondIntersection:${c.line}:${c.circle}:${c.other}`;\n case 'circleIntersection': return `circleIntersection:${c.c1}:${c.c2}:${c.which}`;\n case 'circleSecondIntersection': return `circleSecondIntersection:${c.c1}:${c.c2}:${c.exclude}`;\n case 'tangencyPoint': return `tangencyPoint:${c.circle}:${c.onLine}`;\n case 'tangentPoint': return `tangentPoint:${c.from}:${c.circle}:${c.which}`;\n case 'angleBisectorFoot': return `angleBisectorFoot:${c.from}:${c.onLine}`;\n case 'externalAngleBisectorFoot': return `externalAngleBisectorFoot:${c.from}:${c.onLine}`;\n case 'arcMidpoint': return `arcMidpoint:${c.circle}:${c.a}:${c.b}:${c.notContaining}`;\n case 'reflectPoint': return `reflectPoint:${c.of}:${c.through}`;\n case 'reflectLine': return `reflectLine:${c.of}:${c.through}`;\n case 'excenter': return `excenter:${c.of.join(',')}:${c.opposite}`;\n case 'rightAngleViewing': return `rightAngleViewing:${c.a}:${c.b}:${c.onLine}:${c.which ?? 0}`;\n case 'pointAtDistance': {\n const d = c.distance;\n const dKey = d.kind === 'circleRadius' ? `r:${d.circle}`\n : d.kind === 'segmentLength' ? `seg:${d.p1}:${d.p2}`\n : `lit:${d.value}`;\n return `pointAtDistance:${c.from}:${c.through}:${dKey}`;\n }\n case 'externalToCircle': return `externalToCircle:${c.circle}`;\n case 'onCircle': return `onCircle:${c.circle}:${c.theta ?? ''}`;\n }\n}\n\nfunction samePrefix(a: string, b: string, depth: number): boolean {\n const aP = a.split('/').slice(0, depth).join('/');\n const bP = b.split('/').slice(0, depth).join('/');\n return aP === bP;\n}\n\n// ---------------------------------------------------------------------------\n// Intent metric: recall / precision / F1 (for eval)\n// ---------------------------------------------------------------------------\n\nexport interface IntentMetrics {\n recall: number;\n precision: number;\n f1: number;\n matched: number;\n expected: number;\n actual: number;\n}\n\nexport function computeIntentMetrics(\n expected: readonly IntentT[],\n actual: readonly IntentT[],\n): IntentMetrics {\n const expectedKeys = expected.map(intentKey);\n const actualKeys = actual.map(intentKey);\n const matched = new Set<number>();\n let hit = 0;\n for (const ek of expectedKeys) {\n const idx = actualKeys.findIndex((ak, i) => !matched.has(i) && ak === ek);\n if (idx >= 0) { matched.add(idx); hit++; }\n }\n const recall = expectedKeys.length === 0 ? 1 : hit / expectedKeys.length;\n const precision = actualKeys.length === 0 ? 1 : hit / actualKeys.length;\n const f1 = (recall + precision) === 0 ? 0 : (2 * recall * precision) / (recall + precision);\n return {\n recall, precision, f1,\n matched: hit,\n expected: expectedKeys.length,\n actual: actualKeys.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Geometric verification on DSL with resolved coords (scope: on-circle only;\n// tangent-touch / concyclic / collinear deferred until JSXGraph runtime hook).\n// ---------------------------------------------------------------------------\n\nconst GEOM_TOL = 1e-3;\n\nfunction resolveCoord(dsl: DslInputT, name: string): [number, number] | null {\n const p = dsl.points.find((x) => x.name === name);\n if (!p) return null;\n if (p.kind === 'free') return [p.x, p.y];\n if (p.kind === 'midpoint') {\n const a = resolveCoord(dsl, p.p1);\n const b = resolveCoord(dsl, p.p2);\n if (!a || !b) return null;\n return [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n }\n // Other kinds: computed by JSXGraph at runtime — skip static check.\n return null;\n}\n\nexport function verifyGeometric(dsl: DslInputT): VerifyReport {\n const geometric: VerifyIssue[] = [];\n\n for (const shape of dsl.shapes) {\n if (shape.kind !== 'circleCR') continue;\n // on-circle check: any point with onCircle constraint referencing this circle\n for (const p of dsl.points) {\n if (p.kind !== 'onCircle') continue;\n if (p.circleId !== shape.name) continue;\n const c = resolveCoord(dsl, shape.center);\n const pp = resolveCoord(dsl, p.name);\n if (!c || !pp) continue;\n const d = Math.hypot(pp[0] - c[0], pp[1] - c[1]);\n if (Math.abs(d - shape.radius) > GEOM_TOL) {\n geometric.push({\n axis: 'wrong',\n detail: `on-circle: |${p.name}-${shape.name}|=${d.toFixed(3)} ≠ R=${shape.radius}`,\n });\n }\n }\n }\n\n return {\n ok: geometric.length === 0,\n missing: [],\n wrong: [],\n extra: [],\n geometric,\n } as VerifyReport;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime-mode: verify DSL geometry constraints\n// ---------------------------------------------------------------------------\n\nexport function verifyGeometry(intents: readonly IntentT[], dsl: DslInputT): VerifyReport {\n const issues: VerifyIssue[] = [];\n\n // Check right-triangle variant has actual right angle at named vertex.\n for (const intent of intents) {\n if (intent.op !== 'draw-shape' || intent.shape !== 'triangle') continue;\n const variant = intent.variant;\n if (!variant.startsWith('right-at-')) continue;\n const apex = variant.slice('right-at-'.length); // 'A' | 'B' | 'C'\n const [A, B, C] = intent.labels;\n const ptByName = new Map(\n dsl.points.filter((p) => p.kind === 'free').map((p) => [p.name, [p.x, p.y] as [number, number]]),\n );\n const pA = ptByName.get(A);\n const pB = ptByName.get(B);\n const pC = ptByName.get(C);\n if (!pA || !pB || !pC) continue;\n const apexP = apex === 'A' ? pA : apex === 'B' ? pB : pC;\n const other1 = apex === 'A' ? pB : apex === 'B' ? pA : pA;\n const other2 = apex === 'A' ? pC : apex === 'B' ? pC : pB;\n const v1 = [other1[0] - apexP[0], other1[1] - apexP[1]];\n const v2 = [other2[0] - apexP[0], other2[1] - apexP[1]];\n const dot = v1[0] * v2[0] + v1[1] * v2[1];\n if (Math.abs(dot) > 1e-6) {\n issues.push({\n axis: 'wrong',\n detail: `triangle ${A}${B}${C} variant=right-at-${apex} không vuông (dot=${dot.toFixed(3)})`,\n });\n }\n }\n\n return {\n ok: issues.length === 0,\n missing: [],\n wrong: issues,\n extra: [],\n };\n}\n","// src/stamps/geometry-2d/ai/deterministic/tryDeterministicFigure.ts\n//\n// Track A đầy đủ: rule NLU → coverage gate → normalize → resolve circle collisions\n// → build DSL → transpile → verifyGeometry → named-entity guard. Trả figure SẴN\n// RENDER nếu qua HẾT 4 lớp gate; ngược lại { ok:false } để router escalate AI.\n//\n// Tách khỏi buildFigureIntent để test độc lập toàn bộ logic quyết định.\nimport type { IntentT } from '../intent';\nimport type { DslInputT } from '../../dsl/schema';\nimport type { TranspileResult } from '../../dsl/transpile/errors';\nimport type { VerifyReport } from '../verify';\nimport type { CoverageReport } from './coverage';\nimport { runDeterministicIntents } from './runDeterministicIntents';\nimport { allNamedEntitiesPresent, verifyIntentFidelity } from './guards';\nimport { normalizeIntents } from '../normalizeIntent';\nimport { resolveCircleNameCollisions } from '../resolveCircleNames';\nimport { intentsToDsl } from '../intentToDsl';\nimport { transpile } from '../../dsl';\nimport { verifyGeometry } from '../verify';\n\nexport type DeterministicReason =\n | 'no-match'\n | 'incomplete-coverage'\n | 'build-throw'\n | 'transpile-throw'\n | 'transpile-fail'\n | 'verify-fail'\n | 'named-missing'\n | 'intent-dropped';\n\nexport interface DeterministicFigure {\n intents: IntentT[];\n dsl: DslInputT;\n transpile: Extract<TranspileResult, { ok: true }>;\n verify: VerifyReport;\n coverage: CoverageReport;\n}\n\nexport type TryDeterministicResult =\n | { ok: true; figure: DeterministicFigure }\n | { ok: false; reason: DeterministicReason; detail?: string; coverage?: CoverageReport };\n\nexport function tryDeterministicFigure(problem: string): TryDeterministicResult {\n const det = runDeterministicIntents(problem);\n if (!det.ok) return { ok: false, reason: det.reason, coverage: det.coverage };\n\n // Cùng các stage chuẩn hoá như Track B (LLM) để 2 path hội tụ.\n const intents = resolveCircleNameCollisions(normalizeIntents(det.intents, problem));\n\n let dsl: DslInputT;\n try {\n dsl = intentsToDsl(intents);\n } catch (e) {\n return { ok: false, reason: 'build-throw', detail: errMsg(e), coverage: det.coverage };\n }\n\n let tResult: TranspileResult;\n try {\n tResult = transpile(dsl);\n } catch (e) {\n return { ok: false, reason: 'transpile-throw', detail: errMsg(e), coverage: det.coverage };\n }\n if (!tResult.ok) {\n return {\n ok: false,\n reason: 'transpile-fail',\n detail: tResult.errors.map((x) => `${x.code}:${x.message}`).join('; '),\n coverage: det.coverage,\n };\n }\n\n const vReport = verifyGeometry(intents, dsl);\n if (!vReport.ok) {\n return { ok: false, reason: 'verify-fail', coverage: det.coverage };\n }\n\n // Guard 1: tên xuất hiện/khai báo trong đề phải có trong DSL (chống drop construct).\n const named = allNamedEntitiesPresent(problem, dsl);\n if (!named.ok) {\n return { ok: false, reason: 'named-missing', detail: named.missing.join(','), coverage: det.coverage };\n }\n\n // Guard 2: add-point phái sinh phải dựng trung thành (không bị builder drop vì\n // trùng tên đỉnh sẵn có → điểm thực tế là 'free' thay vì construct).\n const fidelity = verifyIntentFidelity(intents, dsl);\n if (!fidelity.ok) {\n return { ok: false, reason: 'intent-dropped', detail: fidelity.dropped.join(','), coverage: det.coverage };\n }\n\n return {\n ok: true,\n figure: { intents, dsl, transpile: tResult, verify: vReport, coverage: det.coverage },\n };\n}\n\nfunction errMsg(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\n}\n","// src/stamps/geometry-2d/ai/deterministic/describeMiss.ts\n//\n// Dịch lý do deterministic miss (mã kỹ thuật) → câu tiếng Việt dễ hiểu cho\n// chế độ deterministicOnly (\"dùng tạm rule base, tắt LLM\"). Phân 2 nhóm để người\n// tối ưu rule base phân biệt ngay:\n// - \"chưa phủ\" (no-match / incomplete-coverage / named-missing) → CẦN THÊM RULE.\n// - \"rule khớp nhưng dựng lỗi\" (build/transpile/verify/intent-dropped) → có thể LỖI RULE.\n// Hàm thuần, không I/O — message này được gán vào IntentFailureResult.message và\n// nổi lên AiFigureUiResult để consumer (hoctotbachkhoa) hiển thị / ghi log.\nimport type { DeterministicReason } from './tryDeterministicFigure';\nimport type { CoverageReport } from './coverage';\n\nexport interface DeterministicMiss {\n reason: DeterministicReason;\n /** Chi tiết kỹ thuật theo reason (tên thiếu, mã lỗi transpile, …). */\n detail?: string;\n /** Báo cáo coverage — dùng `uncovered[].text` để nêu cụm đề chưa phủ. */\n coverage?: CoverageReport;\n}\n\n/** \", \" sau detail nếu có (else chuỗi rỗng) — tránh \"(undefined)\". */\nfunction detailSuffix(detail?: string): string {\n const d = detail?.trim();\n return d ? `: ${d}` : '';\n}\n\n/** \"D,E\" → \"D, E\" (thêm khoảng trắng sau phẩy cho dễ đọc). */\nfunction formatNames(detail?: string): string {\n const names = (detail ?? '')\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n return names.length > 0 ? names.join(', ') : 'một số đối tượng';\n}\n\nexport function describeDeterministicMiss(miss: DeterministicMiss): string {\n const { reason, detail, coverage } = miss;\n switch (reason) {\n // === Nhóm \"chưa phủ\" → cần bổ sung rule ===\n case 'no-match':\n return 'Rule base chưa nhận ra cấu trúc hình học nào trong đề (cần bổ sung rule cho dạng này).';\n case 'incomplete-coverage': {\n const parts = (coverage?.uncovered ?? []).map((c) => `«${c.text}»`);\n if (parts.length === 0) {\n return 'Rule base mới phủ được một phần đề (cần bổ sung rule cho phần còn lại).';\n }\n return `Rule base mới phủ được một phần đề. Chưa dựng được: ${parts.join('; ')} (cần bổ sung rule).`;\n }\n case 'named-missing':\n return `Đề nhắc tới ${formatNames(detail)} nhưng rule base chưa dựng được (cần bổ sung rule).`;\n\n // === Nhóm \"rule khớp nhưng dựng lỗi\" → có thể lỗi rule ===\n case 'build-throw':\n return `Rule đã khớp nhưng dựng hình thất bại — có thể lỗi rule${detailSuffix(detail)}.`;\n case 'transpile-throw':\n case 'transpile-fail':\n return `Rule đã khớp nhưng biên dịch hình lỗi — có thể lỗi rule${detailSuffix(detail)}.`;\n case 'verify-fail':\n return 'Rule dựng được hình nhưng sai kiểm tra hình học — có thể lỗi rule.';\n case 'intent-dropped':\n return `Rule khớp nhưng một số điểm phái sinh bị bỏ (${formatNames(detail)}) — có thể lỗi rule.`;\n\n default: {\n // Exhaustive guard: thêm reason mới mà quên xử lý → type error tại compile.\n const _never: never = reason;\n return `Rule base chưa dựng được (${String(_never)}).`;\n }\n }\n}\n","// src/stamps/geometry-2d/ai/buildFigureIntent.ts\n//\n// Deterministic-only figure builder (rule-base, KHÔNG LLM).\n// Track A: tryDeterministicFigure() — rule engine + 4 gate\n// (coverage / transpile / verify / named-entity).\n// Success → trả figure (intents + dsl + transpile + verify).\n// Miss → trả failure `deterministic_miss` kèm lý do (describeDeterministicMiss)\n// để người tối ưu rule base thấy phần đề chưa phủ. KHÔNG fallback LLM.\n//\n// Trả về IntentGenerateResult tương thích shape cũ để consumer dùng được.\n\nimport type { TranspileResult } from '../dsl';\nimport { intentsToDsl } from './intentToDsl';\nimport type { IntentT } from './intent';\nimport { type VerifyReport } from './verify';\nimport { tryDeterministicFigure } from './deterministic/tryDeterministicFigure';\nimport { describeDeterministicMiss } from './deterministic/describeMiss';\n\nconst ZERO_USAGE: IntentTokenUsage = {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n};\n\nexport interface GenerateIntentOptions {\n signal?: AbortSignal;\n}\n\nexport interface IntentTokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n}\n\nexport interface IntentSuccessResult {\n ok: true;\n intents: readonly IntentT[];\n dsl: ReturnType<typeof intentsToDsl>;\n transpile: Extract<TranspileResult, { ok: true }>;\n verify: VerifyReport;\n usage: IntentTokenUsage;\n provider: string;\n}\n\nexport interface IntentFailureResult {\n ok: false;\n reason:\n | 'builder_error'\n | 'transpile_error'\n | 'verify_error'\n | 'deterministic_miss';\n message: string;\n intents?: readonly IntentT[];\n dsl?: ReturnType<typeof intentsToDsl>;\n usage?: IntentTokenUsage;\n provider?: string;\n}\n\nexport type IntentGenerateResult = IntentSuccessResult | IntentFailureResult;\n\nexport async function generateFigureIntent(\n problem: string,\n _opts: GenerateIntentOptions = {},\n): Promise<IntentGenerateResult> {\n // === Track A: deterministic ===\n // Rule engine + 4 lớp gate (coverage/transpile/verify/named-entity). Đề dễ→trung\n // bình dựng tại đây, KHÔNG tốn token. Miss → trả deterministic_miss (KHÔNG LLM).\n const det = tryDeterministicFigure(problem);\n if (det.ok) {\n return {\n ok: true,\n intents: det.figure.intents,\n dsl: det.figure.dsl,\n transpile: det.figure.transpile,\n verify: det.figure.verify,\n usage: ZERO_USAGE,\n provider: 'deterministic',\n };\n }\n\n // Miss → trả failure kèm lý do (det.reason) để người tối ưu rule base thấy gap.\n // (no-match / incomplete-coverage / transpile-fail / named-missing / verify-fail / …)\n return {\n ok: false,\n reason: 'deterministic_miss',\n message: describeDeterministicMiss(det),\n usage: ZERO_USAGE,\n provider: 'deterministic',\n };\n}\n","// Façade HTTP transport cho rule-engine intent pipeline (generateFigureIntent).\n// Map IntentGenerateResult → AiFigureUiResult ({ ok, state }) — shape mà\n// <Whiteboard generateGeometryFigure> + playground route dùng trực tiếp.\n//\n// 2026-06-09: repurpose từ path buildFigure (free-form DSL, đã xoá) sang intent\n// pipeline DETERMINISTIC-ONLY. generateFigureIntent chạy rule engine\n// (tryDeterministicFigure → 21 rule + 4 gate); miss → deterministic_miss (KHÔNG\n// LLM). Façade chỉ cần map kết quả. Contract AiFigureUiResult GIỮ NGUYÊN →\n// consumer (playground, hoctotbachkhoa) không phải đổi route.\n\nimport type { AiFigureUiResult } from '../../shared/types';\nimport {\n generateFigureIntent,\n type GenerateIntentOptions,\n type IntentGenerateResult,\n} from './buildFigureIntent';\n\nexport interface HandleGenerateFigureInput {\n /** Đề bài tiếng Việt từ teacher. */\n problem: string;\n}\n\nexport interface HandleGenerateFigureOptions extends GenerateIntentOptions {\n /**\n * Telemetry hook: gọi cho MỖI attempt với IntentGenerateResult nội bộ trước\n * khi map sang AiFigureUiResult — consumer dùng để log usage/cost/error.\n * Không throw từ logger (swallow để không vỡ response).\n *\n * @param result IntentGenerateResult của attempt\n * @param attempt 1-indexed (1 = lần đầu, 2 = retry, ...)\n */\n onResult?: (result: IntentGenerateResult, attempt: number) => void;\n /**\n * Số attempt tối đa khi build error (transpile/builder). Default 2 (1 retry).\n * Rule base deterministic → retry hiếm khi đổi kết quả, giữ để tương thích\n * contract cũ. Clamp [1,5].\n */\n maxAttempts?: number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 2;\n\n/**\n * Gọi rule-engine intent pipeline và trả về `AiFigureUiResult` mà\n * `<Whiteboard generateGeometryFigure>` chấp nhận trực tiếp.\n *\n * Deterministic rule base chạy trong `generateFigureIntent` — đề dễ→trung bình\n * dựng KHÔNG tốn token. Miss → `deterministic_miss` (KHÔNG LLM fallback).\n *\n * Auto-retry: chỉ retry khi `transpile_error`/`builder_error`. KHÔNG retry\n * `deterministic_miss` (rule base ổn định, retry vô nghĩa).\n *\n * Server-side caller giữ `IntentGenerateResult` đầy đủ qua `onResult` cho\n * telemetry/logging.\n */\nexport async function handleGenerateFigure(\n input: HandleGenerateFigureInput,\n opts: HandleGenerateFigureOptions = {},\n): Promise<AiFigureUiResult> {\n if (!input.problem.trim()) {\n return { ok: false, message: 'Đề bài rỗng' };\n }\n\n const { onResult, maxAttempts: rawMax, ...genOpts } = opts;\n const maxAttempts = clampAttempts(rawMax ?? DEFAULT_MAX_ATTEMPTS);\n\n let last: IntentGenerateResult | null = null;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const r = await generateFigureIntent(input.problem, genOpts);\n last = r;\n if (onResult) {\n try { onResult(r, attempt); } catch { /* swallow telemetry errors */ }\n }\n if (r.ok) return { ok: true, state: r.transpile.state };\n if ((r.reason === 'transpile_error' || r.reason === 'builder_error') && attempt < maxAttempts) {\n continue;\n }\n break;\n }\n return mapErrorToUi(last!);\n}\n\nfunction clampAttempts(n: number): number {\n if (!Number.isFinite(n)) return DEFAULT_MAX_ATTEMPTS;\n return Math.max(1, Math.min(5, Math.floor(n)));\n}\n\nfunction mapErrorToUi(result: IntentGenerateResult): AiFigureUiResult {\n if (result.ok) return { ok: true, state: result.transpile.state };\n\n switch (result.reason) {\n case 'builder_error':\n case 'transpile_error':\n case 'verify_error':\n return {\n ok: false,\n message:\n 'Không dựng được hình (đã thử lại). Vui lòng tách thành 1 yêu cầu/lần hoặc diễn đạt khác.',\n };\n case 'deterministic_miss':\n default:\n // Rule base chưa phủ đề này: `message` đã là câu tiếng Việt dễ hiểu từ\n // describeDeterministicMiss (nêu rõ cần bổ sung rule / có thể lỗi rule +\n // phần đề chưa phủ) → trả thẳng cho UI/log, không bọc jargon.\n return { ok: false, message: result.message };\n }\n}\n","// src/stamps/geometry-2d/ai/envelope.ts\n//\n// Envelope schema cho figure build I/O:\n// { decision: 'build', figure: <DslInput> }\n// { decision: 'refuse', reason: '...' }\n//\n// 1 schema, parse + validate ở 1 chỗ. Giữ cho advanced consumer muốn dùng\n// envelope build-side (FigureEnvelopeZ + envelopeBuildDsl) trực tiếp.\n\nimport { z } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { DslInput, type DslInputT } from '../dsl';\n\nexport const FigureEnvelopeZ = z\n .object({\n decision: z.enum(['build', 'refuse']),\n // figure: DslInput khi build; bỏ qua khi refuse.\n figure: DslInput.optional(),\n // reason: lý do từ chối (Việt) khi refuse; bỏ qua khi build.\n reason: z.string().optional(),\n })\n .refine(\n (e) => (e.decision === 'build' ? e.figure != null : e.reason != null && e.reason.length > 0),\n {\n message:\n 'decision=build cần `figure`; decision=refuse cần `reason` không rỗng',\n },\n );\n\nexport type FigureEnvelopeT = z.infer<typeof FigureEnvelopeZ>;\n\n// JSON Schema bản phẳng cho consumer cần schema constraint.\n// Note: refine() chỉ run ở Zod runtime; JSON Schema không representable.\n// Validate qua FigureEnvelopeZ để bắt vi phạm refine.\nexport function envelopeJsonSchema(): Record<string, unknown> {\n return zodToJsonSchema(FigureEnvelopeZ, {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n }) as Record<string, unknown>;\n}\n\n/** Helper: ép envelope build hợp lệ về DslInputT (sau khi đã validate). */\nexport function envelopeBuildDsl(env: FigureEnvelopeT): DslInputT {\n if (env.decision !== 'build' || env.figure == null) {\n throw new Error('envelopeBuildDsl: envelope không phải decision=build hoặc thiếu figure');\n }\n // Zod infer cho DslInput rộng `{[x: string]: any}[]` (discriminatedUnion từ\n // registry với schemas erased `ZodObject<any>`); runtime parse đã validate,\n // safe widen sang DslInputT (xem comment trong schema.ts).\n return env.figure as unknown as DslInputT;\n}\n","// src/stamps/geometry-2d/ai/intent.ts\n//\n// Intent schema — replacement for free-form DSL output.\n//\n// AI emit Intent[] thay vì DSL trực tiếp. Mỗi Intent là 1 \"lệnh vẽ\" cấp\n// semantic (\"vẽ tam giác đều ABC\", \"thêm trung điểm M của BC\"). Builder\n// (intentToDsl.ts) deterministic dịch Intent → DSL với canonical coords.\n//\n// Lợi ích:\n// - AI chỉ làm NLU (đọc-tách-lệnh), không tự đặt coord → 0% hallucinate coord\n// - Variant enum loại bỏ \"tam giác vuông tại A nhưng coord vuông tại B\"\n// - Schema explicit slot cho augmentations → guard \"không thừa\"\n\nimport { z } from 'zod';\n\n// Tên label/point — alphanumeric, 1-8 chars, không trùng kind enum.\nexport const LabelZ = z.string().min(1).max(8).regex(/^[A-Za-z][A-Za-z0-9'_]*$/);\n\n// ---------------------------------------------------------------------------\n// Shape variants per shape type\n// ---------------------------------------------------------------------------\n\n// triangle variants\nexport const TriangleVariantZ = z.enum([\n 'any', // tam giác bất kỳ (scalene cố định)\n 'equilateral', // tam giác đều\n 'isoceles-AB', // cân tại C (AB đáy)\n 'isoceles-BC', // cân tại A (BC đáy)\n 'isoceles-CA', // cân tại B (CA đáy)\n 'right-at-A', // vuông tại A\n 'right-at-B', // vuông tại B\n 'right-at-C', // vuông tại C\n]);\n\nexport const QuadVariantZ = z.enum([\n 'any', // tứ giác bất kỳ\n]);\n\nexport const SquareVariantZ = z.enum([\n 'standard', // canonical\n]);\n\nexport const RectangleVariantZ = z.enum([\n 'wide', // mặc định 4×2.5\n 'tall', // 2.5×4\n]);\n\nexport const RhombusVariantZ = z.enum([\n 'standard', // canonical (diagonals 4,2)\n]);\n\nexport const TrapezoidVariantZ = z.enum([\n 'right', // vuông\n 'isoceles', // cân\n 'general', // thường\n]);\n\nexport const ParallelogramVariantZ = z.enum([\n 'standard', // mặc định\n]);\n\n// ---------------------------------------------------------------------------\n// Intent ops\n// ---------------------------------------------------------------------------\n//\n// Note: zod's discriminatedUnion không cho phép duplicate discriminator value\n// (vd nhiều 'draw-shape' schemas khác nhau). Solution: flatten — mỗi op là 1\n// schema duy nhất với `shape` là enum, runtime check variant ∈ allowed-for-shape\n// trong builder. Đánh đổi: kém type-safety hơn variant-per-shape DSU, nhưng\n// schema flatter → JSON Schema rõ ràng hơn, không nested anyOf.\n\nconst ShapeNameZ = z.enum([\n 'triangle',\n 'square',\n 'rectangle',\n 'rhombus',\n 'trapezoid',\n 'parallelogram',\n 'quadrilateral',\n]);\n\n// Tất cả variant gộp 1 enum — runtime check ở builder.\nconst ShapeVariantZ = z.enum([\n // triangle\n 'any', 'equilateral',\n 'isoceles-AB', 'isoceles-BC', 'isoceles-CA',\n 'right-at-A', 'right-at-B', 'right-at-C',\n // square / rhombus / parallelogram\n 'standard',\n // rectangle\n 'wide', 'tall',\n // trapezoid\n 'right', 'isoceles', 'general',\n]);\n\n// op: draw-shape\nexport const DrawShapeIntentZ = z.object({\n op: z.literal('draw-shape'),\n shape: ShapeNameZ,\n labels: z.array(LabelZ).min(3).max(8),\n variant: ShapeVariantZ.default('any'),\n explicitCoords: z.record(LabelZ, z.tuple([z.number(), z.number()])).optional(),\n});\n\n// op: add-point\nexport const AddPointIntentZ = z.object({\n op: z.literal('add-point'),\n name: LabelZ,\n constraint: z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('midpoint'), of: z.string() }),\n z.object({ kind: z.literal('perpFoot'), from: LabelZ, onLine: z.string() }),\n z.object({ kind: z.literal('centroid'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({ kind: z.literal('circumcenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({ kind: z.literal('incenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({ kind: z.literal('orthocenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]) }),\n z.object({\n kind: z.literal('intersection'),\n of: z.tuple([z.string(), z.string()]),\n branch: z.union([z.literal(0), z.literal(1)]).optional(),\n }),\n z.object({ kind: z.literal('onSegment'), of: z.string(), t: z.number().min(0).max(1).optional() }),\n z.object({ kind: z.literal('free'), at: z.tuple([z.number(), z.number()]).optional() }),\n // Điểm A nằm NGOÀI đường tròn `circle` (free external point) — builder đọc\n // tâm+bán kính của circle từ build state rồi đặt A free tại coord ngoài\n // circle. Unblock tangentFromExt render (đề \"Lấy A ngoài (O), kẻ 2 tiếp tuyến\").\n z.object({ kind: z.literal('externalToCircle'), circle: LabelZ }),\n // Điểm trên đường tròn `circle` tại góc `theta` (mặc định 0) — glider.\n // Dùng cho đường thẳng Simson (issue #47): P trên đường tròn ngoại tiếp.\n z.object({ kind: z.literal('onCircle'), circle: LabelZ, theta: z.number().optional() }),\n // NEW Tier 4+5\n z.object({ kind: z.literal('secondIntersection'), line: z.string(), circle: LabelZ, other: LabelZ }),\n z.object({ kind: z.literal('circleIntersection'), c1: LabelZ, c2: LabelZ, which: z.union([z.literal(0), z.literal(1)]) }),\n // Giao điểm THỨ HAI của 2 đường tròn, loại điểm chung `exclude` (đề \"đường\n // tròn đường kính AB, AC đôi một cắt nhau lần thứ hai\" — điểm chung A).\n z.object({ kind: z.literal('circleSecondIntersection'), c1: LabelZ, c2: LabelZ, exclude: LabelZ }),\n z.object({ kind: z.literal('tangencyPoint'), circle: LabelZ, onLine: z.string() }),\n z.object({ kind: z.literal('tangentPoint'), from: LabelZ, circle: LabelZ, which: z.union([z.literal(0), z.literal(1)]) }),\n z.object({ kind: z.literal('angleBisectorFoot'), from: LabelZ, onLine: z.string() }),\n // Phân giác NGOÀI: chân phân giác ngoài đỉnh `from` trên đường thẳng `onLine`\n // (phân giác ngoài ⊥ phân giác trong tại `from`). Issue #46 nhóm A.\n z.object({ kind: z.literal('externalAngleBisectorFoot'), from: LabelZ, onLine: z.string() }),\n // Cụm A\n z.object({ kind: z.literal('arcMidpoint'), circle: LabelZ, a: LabelZ, b: LabelZ, notContaining: LabelZ }),\n z.object({ kind: z.literal('reflectPoint'), of: LabelZ, through: LabelZ }),\n z.object({ kind: z.literal('reflectLine'), of: LabelZ, through: z.string() }),\n z.object({ kind: z.literal('excenter'), of: z.tuple([LabelZ, LabelZ, LabelZ]), opposite: LabelZ }),\n // Góc vuông nhìn đoạn: M trên onLine sao cho ∠ a-name-b = 90°\n z.object({ kind: z.literal('rightAngleViewing'), a: LabelZ, b: LabelZ, onLine: z.string(), which: z.union([z.literal(0), z.literal(1)]).optional() }),\n z.object({\n kind: z.literal('pointAtDistance'),\n from: LabelZ,\n through: LabelZ,\n // scale/offset OPTIONAL (Issue #46 nhóm C): d = scale·base + offset.\n // scale > 0; absent → giữ d = base như cũ (additive).\n distance: z.discriminatedUnion('kind', [\n z.object({ kind: z.literal('circleRadius'), circle: LabelZ, scale: z.number().positive().optional(), offset: z.number().optional() }),\n z.object({ kind: z.literal('segmentLength'), p1: LabelZ, p2: LabelZ, scale: z.number().positive().optional(), offset: z.number().optional() }),\n z.object({ kind: z.literal('literal'), value: z.number().positive(), scale: z.number().positive().optional(), offset: z.number().optional() }),\n ]),\n }),\n ]),\n});\n\n// op: connect\nexport const ConnectIntentZ = z.object({\n op: z.literal('connect'),\n from: LabelZ,\n to: LabelZ,\n style: z.enum([\n 'segment',\n 'line',\n 'ray',\n 'perpBisector',\n 'angleBisector',\n ]).default('segment'),\n});\n\n// op: draw-circle — single schema, spec là enum, points conditional\nexport const DrawCircleIntentZ = z.object({\n op: z.literal('draw-circle'),\n name: LabelZ,\n spec: z.enum(['centerThrough', 'through3', 'centerRadius', 'inscribedIn', 'diameter']),\n center: LabelZ.optional(),\n through: LabelZ.optional(),\n points: z.tuple([LabelZ, LabelZ, LabelZ]).optional(),\n // NEW Tier 4+5\n radius: z.number().positive().optional(),\n triangle: z.tuple([LabelZ, LabelZ, LabelZ]).optional(),\n // spec 'diameter' — đường tròn đường kính nối 2 đầu mút.\n endpoints: z.tuple([LabelZ, LabelZ]).optional(),\n});\n\n// op: draw-line\nexport const DrawLineIntentZ = z.object({\n op: z.literal('draw-line'),\n name: LabelZ,\n kind: z.enum(['perpThrough', 'parallelThrough', 'tangentAt', 'tangentFromExt', 'angleBisector', 'lineThrough', 'radicalAxis']),\n through: LabelZ.optional(),\n to: LabelZ.optional(),\n from: LabelZ.optional(),\n circle: LabelZ.optional(),\n which: z.enum(['first', 'second', 'both']).optional(),\n // lineThrough (đường qua ≥2 điểm đồng tuyến — vd Euler line G/H/O, issue #47).\n points: z.array(LabelZ).optional(),\n // radicalAxis (trục đẳng phương 2 đường tròn — issue #47, construct 2).\n circle1: LabelZ.optional(),\n circle2: LabelZ.optional(),\n // angleBisector (phân giác TRONG của góc ∠p1·vertex·p2, VISIBLE, không foot —\n // Issue #46 nhóm A). vertex = đỉnh góc.\n p1: LabelZ.optional(),\n vertex: LabelZ.optional(),\n p2: LabelZ.optional(),\n});\n\n// op: mark-shape (sub-shape từ điểm đã có, không tạo coord mới)\nexport const MarkShapeIntentZ = z.object({\n op: z.literal('mark-shape'),\n shape: z.enum(['triangle', 'quadrilateral']),\n labels: z.array(LabelZ).min(3).max(4),\n});\n\n// Master discriminated union — 6 variants theo op\nexport const IntentZ = z.discriminatedUnion('op', [\n DrawShapeIntentZ,\n AddPointIntentZ,\n ConnectIntentZ,\n DrawCircleIntentZ,\n DrawLineIntentZ, // NEW\n MarkShapeIntentZ, // NEW\n]);\n\n// Re-export variant enums cho consumer (vd UI dropdown)\nexport {\n TriangleVariantZ as TriangleVariants,\n SquareVariantZ as SquareVariants,\n RectangleVariantZ as RectangleVariants,\n RhombusVariantZ as RhombusVariants,\n TrapezoidVariantZ as TrapezoidVariants,\n ParallelogramVariantZ as ParallelogramVariants,\n QuadVariantZ as QuadVariants,\n};\n\nexport type IntentT = z.infer<typeof IntentZ>;\nexport type DrawShapeIntentT = z.infer<typeof DrawShapeIntentZ>;\nexport type AddPointIntentT = z.infer<typeof AddPointIntentZ>;\nexport type ConnectIntentT = z.infer<typeof ConnectIntentZ>;\nexport type DrawCircleIntentT = z.infer<typeof DrawCircleIntentZ>;\nexport type DrawLineIntentT = z.infer<typeof DrawLineIntentZ>;\nexport type MarkShapeIntentT = z.infer<typeof MarkShapeIntentZ>;\n\n// ---------------------------------------------------------------------------\n// Envelope — wraps intents[] + decision\n// ---------------------------------------------------------------------------\n\nexport const IntentEnvelopeZ = z\n .object({\n decision: z.enum(['build', 'refuse']),\n intents: z.array(IntentZ).optional(),\n reason: z.string().optional(),\n })\n .refine(\n (e) =>\n e.decision === 'build'\n ? Array.isArray(e.intents) && e.intents.length > 0\n : e.reason != null && e.reason.length > 0,\n {\n message:\n 'decision=build cần intents non-empty; decision=refuse cần reason',\n },\n );\n\nexport type IntentEnvelopeT = z.infer<typeof IntentEnvelopeZ>;\n","// src/stamps/geometry-2d/ai/intentEnvelope.ts\n//\n// JSON Schema helper cho Intent envelope (giữ cho advanced consumer cần\n// schema constraint). Refine() check ở Zod runtime; JSON Schema không representable.\n\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { IntentEnvelopeZ, type IntentEnvelopeT } from './intent';\nimport type { IntentT } from './intent';\n\nexport function intentEnvelopeJsonSchema(): Record<string, unknown> {\n return zodToJsonSchema(IntentEnvelopeZ, {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n }) as Record<string, unknown>;\n}\n\nexport function envelopeIntentList(env: IntentEnvelopeT): readonly IntentT[] {\n if (env.decision !== 'build' || env.intents == null) {\n throw new Error(\n 'envelopeIntentList: envelope không phải decision=build hoặc thiếu intents',\n );\n }\n return env.intents;\n}\n","// src/stamps/geometry-2d/ai/intentPrompt.ts\n//\n// System prompt cho Intent extraction (Stage 1). AI chỉ làm NLU — đọc đề\n// (VN hoặc EN), tách thành Intent[]. KHÔNG sinh DSL, KHÔNG đặt tọa độ.\n//\n// Khác prompt cũ (prompt.ts):\n// - Output là `intents: Intent[]` thay vì `figure: DSL`\n// - Bilingual: ví dụ cả VN + EN\n// - Anti-pattern explicit: AI không tự thêm intent ngoài đề\n//\n// IntentEnvelopeZ.refine() guards build/refuse semantics.\n\nimport type { IntentT, IntentEnvelopeT } from './intent';\n\ninterface IntentFixture {\n problem: string;\n intents: IntentT[];\n}\n\n// Tier 0+1 sample fixtures (in-prompt examples).\n// Note: chỉ shape examples — augmentation examples thêm khi mở Tier 1.\nconst FIXTURES: IntentFixture[] = [\n {\n problem: 'Tam giác ABC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n ],\n },\n {\n problem: 'Tam giác đều ABC cạnh 4.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'equilateral' },\n ],\n },\n {\n problem: 'Tam giác ABC vuông tại A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'right-at-A' },\n ],\n },\n {\n problem: 'Hình vuông MNPQ.',\n intents: [\n { op: 'draw-shape', shape: 'square', labels: ['M', 'N', 'P', 'Q'], variant: 'standard' },\n ],\n },\n {\n problem: 'Hình chữ nhật ABCD.',\n intents: [\n { op: 'draw-shape', shape: 'rectangle', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n ],\n },\n // \"cân tại X\" → X là đỉnh cân, cạnh đối diện là đáy\n {\n problem: 'Tam giác ABC cân tại A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'isoceles-BC' },\n ],\n },\n {\n problem: 'Tam giác MNP cân tại N.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['M', 'N', 'P'], variant: 'isoceles-CA' },\n ],\n },\n {\n problem: 'Hình thoi ABCD.',\n intents: [\n { op: 'draw-shape', shape: 'rhombus', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n ],\n },\n {\n problem: 'Hình bình hành ABCD.',\n intents: [\n { op: 'draw-shape', shape: 'parallelogram', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n ],\n },\n {\n problem: 'Hình thang ABCD cân, AB là đáy lớn.',\n intents: [\n { op: 'draw-shape', shape: 'trapezoid', labels: ['A', 'B', 'C', 'D'], variant: 'isoceles' },\n ],\n },\n // Tier 1 examples\n {\n problem: 'Tam giác ABC, M là trung điểm BC, vẽ đoạn AM.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'M', constraint: { kind: 'midpoint', of: 'BC' } },\n { op: 'connect', from: 'A', to: 'M', style: 'segment' },\n ],\n },\n {\n problem: 'Tam giác ABC, H là chân đường cao từ A xuống BC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'H', constraint: { kind: 'perpFoot', from: 'A', onLine: 'BC' } },\n { op: 'connect', from: 'A', to: 'H', style: 'segment' },\n ],\n },\n {\n problem: 'Triangle ABC with M the midpoint of BC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'M', constraint: { kind: 'midpoint', of: 'BC' } },\n ],\n },\n {\n problem: 'Triangle ABC, G is the centroid.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'G', constraint: { kind: 'centroid', of: ['A', 'B', 'C'] } },\n ],\n },\n // Compound: triangle + circumcircle (cần CẢ HAI intent)\n {\n problem: 'Đường tròn đi qua 3 điểm A, B, C.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n ],\n },\n {\n problem: 'Tam giác ABC nội tiếp đường tròn O.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n ],\n },\n // Compound: parallelogram with diagonals + intersection\n {\n problem: 'Hình bình hành ABCD, hai đường chéo AC và BD cắt nhau tại O.',\n intents: [\n { op: 'draw-shape', shape: 'parallelogram', labels: ['A', 'B', 'C', 'D'], variant: 'standard' },\n { op: 'connect', from: 'A', to: 'C', style: 'segment' },\n { op: 'connect', from: 'B', to: 'D', style: 'segment' },\n { op: 'add-point', name: 'O', constraint: { kind: 'intersection', of: ['AC', 'BD'] } },\n ],\n },\n // Build examples — đề có MỆNH LỆNH proof/tính NHƯNG mô tả hình → vẫn build\n {\n problem: 'Cho tam giác ABC vuông tại A. Chứng minh rằng AB² + AC² = BC².',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'right-at-A' },\n ],\n },\n {\n problem: 'Cho tứ giác ABCD nội tiếp (O). Chứng minh rằng AC.BD = AB.CD + AD.BC.',\n intents: [\n { op: 'draw-shape', shape: 'quadrilateral', labels: ['A', 'B', 'C', 'D'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n { op: 'connect', from: 'A', to: 'C', style: 'segment' },\n { op: 'connect', from: 'B', to: 'D', style: 'segment' },\n ],\n },\n // draw-line: perpThrough — đường vuông góc với LINE, đi qua POINT\n {\n problem: 'Tam giác ABC. Vẽ đường thẳng d vuông góc với AB tại B.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-line', name: 'd', kind: 'perpThrough', through: 'B', to: 'AB' },\n ],\n },\n // draw-line: tangentAt — tiếp tuyến TẠI POINT trên CIRCLE\n {\n problem: 'Tam giác ABC nội tiếp đường tròn (O). Vẽ tiếp tuyến tại A của (O).',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n { op: 'draw-line', name: 'tA', kind: 'tangentAt', through: 'A', circle: 'O' },\n ],\n },\n // draw-line: tangentFromExt — tiếp tuyến TỪ POINT ngoài CIRCLE (chọn nhánh)\n {\n problem: 'Cho đường tròn (O) và điểm P ngoài đường tròn. Vẽ hai tiếp tuyến PT₁ và PT₂ từ P tới (O).',\n intents: [\n { op: 'draw-circle', name: 'O', spec: 'centerRadius', center: 'O', radius: 3 },\n { op: 'add-point', name: 'P', constraint: { kind: 'free' } },\n { op: 'draw-line', name: 'PT1', kind: 'tangentFromExt', from: 'P', circle: 'O', which: 'first' },\n { op: 'draw-line', name: 'PT2', kind: 'tangentFromExt', from: 'P', circle: 'O', which: 'second' },\n ],\n },\n // Refuse examples — đề THUẦN tính / KHÔNG mô tả hình hình học\n {\n problem: 'Tính sin(30°) + cos(60°).',\n intents: [],\n },\n {\n problem: 'Vẽ con mèo.',\n intents: [],\n },\n {\n problem: 'Giải phương trình x² - 5x + 6 = 0.',\n intents: [],\n },\n {\n problem: 'Tam giác ABC nội tiếp (O). M là trung điểm cung BC không chứa A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'draw-circle', name: 'O', spec: 'through3', points: ['A', 'B', 'C'] },\n { op: 'add-point', name: 'M', constraint: { kind: 'arcMidpoint', circle: 'O', a: 'B', b: 'C', notContaining: 'A' } },\n ],\n },\n {\n problem: 'Tam giác ABC trực tâm H. D là điểm đối xứng của H qua BC.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'H', constraint: { kind: 'orthocenter', of: ['A', 'B', 'C'] } },\n { op: 'add-point', name: 'D', constraint: { kind: 'reflectLine', of: 'H', through: 'BC' } },\n ],\n },\n {\n problem: 'Tam giác ABC, J là tâm bàng tiếp góc A.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'J', constraint: { kind: 'excenter', of: ['A', 'B', 'C'], opposite: 'A' } },\n ],\n },\n {\n problem: 'Cho tam giác nhọn ABC, đường cao CK, H là trực tâm. Gọi M là một điểm trên CK sao cho góc AMB = 90°.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'C'], variant: 'any' },\n { op: 'add-point', name: 'K', constraint: { kind: 'perpFoot', from: 'C', onLine: 'AB' } },\n { op: 'add-point', name: 'H', constraint: { kind: 'orthocenter', of: ['A', 'B', 'C'] } },\n { op: 'connect', from: 'C', to: 'K', style: 'segment' },\n { op: 'add-point', name: 'M', constraint: { kind: 'rightAngleViewing', a: 'A', b: 'B', onLine: 'CK' } },\n ],\n },\n {\n problem: 'Cho đoạn AB và đường thẳng d. Điểm M trên d sao cho góc AMB = 90°.',\n intents: [\n { op: 'draw-shape', shape: 'triangle', labels: ['A', 'B', 'D'], variant: 'any' },\n { op: 'add-point', name: 'M', constraint: { kind: 'rightAngleViewing', a: 'A', b: 'B', onLine: 'd' } },\n ],\n },\n];\n\nexport function buildIntentSystemPrompt(): string {\n const examples = FIXTURES.map((f, i) => {\n const envelope: IntentEnvelopeT =\n f.intents.length > 0\n ? { decision: 'build', intents: f.intents }\n : { decision: 'refuse', reason: 'Đề không phải hình học — không vẽ được hình.' };\n return `### Ví dụ ${i + 1}\n**Đề:** ${f.problem}\n**Output:**\n${JSON.stringify(envelope, null, 2)}`;\n }).join('\\n\\n');\n\n return `Bạn là trợ lý tách lệnh vẽ hình học 2D cho học sinh THCS / lớp 10.\nChấp nhận đề bài tiếng Việt HOẶC tiếng Anh.\n\n## Nhiệm vụ\nĐọc đề → tách thành danh sách \"intents\" (lệnh vẽ cấp cao). KHÔNG sinh tọa độ,\nKHÔNG sinh DSL chi tiết — chỉ tách lệnh.\n\n## Output format (CHỈ JSON, KHÔNG markdown, KHÔNG text khác)\n{ \"decision\": \"build\", \"intents\": [ ... ] }\nhoặc\n{ \"decision\": \"refuse\", \"reason\": \"lý do tiếng Việt\" }\n\n## Quy tắc tuyệt đối\n\n1. **MỘT intent = MỘT đối tượng nêu trong đề.** Đề nói gì, emit intent đó.\n KHÔNG tự thêm trung tuyến/đường cao/tâm nếu đề không nói.\n\n2. **Shape variant phải khớp đề:**\n - \"đều\" → variant: \"equilateral\"\n - \"vuông tại X\" → variant: \"right-at-X\" (X là label đầu tiên trong labels[] khớp đề)\n - \"cân tại X\" — X là ĐỈNH CÂN, base là cạnh đối diện:\n * \"tam giác ABC cân tại A\" → variant: \"isoceles-BC\" (BC là đáy, A là apex)\n * \"tam giác MNP cân tại N\" → variant: \"isoceles-CA\" (CA là đáy theo canonical position)\n * Rule: variant đặt tên theo position trong labels[], KHÔNG phải tên literal.\n apex ở position 0 → \"isoceles-BC\"; position 1 → \"isoceles-CA\"; position 2 → \"isoceles-AB\".\n - không có từ khoá đặc biệt → variant: \"any\"\n\n3. **Labels phải đúng đề:** \"tam giác MNP\" → labels: [\"M\",\"N\",\"P\"], không tự đổi sang ABC.\n\n4. **Augmentations (Tier 1) dùng add-point + connect:**\n - \"M trung điểm BC\" → add-point name=M, constraint=midpoint of=BC\n - \"H chân đường cao từ A xuống BC\" → add-point name=H, constraint=perpFoot from=A onLine=BC\n - \"vẽ đoạn AM\" → connect from=A to=M\n - Trọng tâm/tâm ngoại/nội/trực tâm → add-point constraint=centroid/circumcenter/incenter/orthocenter\n\n5. **KHÔNG bịa.** Nếu đề mơ hồ hoặc không thuộc hình học 2D phổ thông → decision=refuse.\n\n6. **Đặt tên draw-circle**: nếu đề có ký hiệu rõ ràng \"(X)\" (vd \"(O)\", \"(I)\", \"(I1)\") → dùng đúng ký hiệu đó làm name. KHÔNG thêm hậu tố như \"Ic\", \"In\", \"Oc\". Nếu đề không có ký hiệu thì name tự do (preprocessor xử lý mọi collision).\n\n7. **Mệnh lệnh \"Chứng minh\" / \"Tính\" / \"Tìm\" / \"Hỏi\" KHÔNG ảnh hưởng quyết định build/refuse.** Quyết định CHỈ dựa vào việc đề có MÔ TẢ hình vẽ được hay không. Nếu đề bắt đầu / kết thúc bằng \"Chứng minh rằng …\" hoặc \"Tính …\" nhưng phần MÔ TẢ (giả thiết) có hình (tam giác, tứ giác, đường tròn, giao điểm …) → vẫn decision=build, vẽ phần giả thiết. KẾT QUẢ proof / phép tính KHÔNG cần biểu diễn. Chỉ refuse khi đề THUẦN tính / đại số không kèm mô tả hình (vd \"Tính sin(30°)+cos(60°)\", \"Giải x²-5x+6=0\").\n\n## Variant enum (chỉ dùng giá trị này)\n- triangle: any | equilateral | isoceles-AB | isoceles-BC | isoceles-CA | right-at-A | right-at-B | right-at-C\n- square: standard\n- rectangle: standard (default) | wide | tall\n- rhombus: standard\n- trapezoid: right | isoceles | general\n- parallelogram: standard\n- quadrilateral: any\n\n## Constraint kinds (cho add-point)\nmidpoint, perpFoot, centroid, circumcenter, incenter, orthocenter, intersection, onSegment, free, secondIntersection, circleIntersection, tangencyPoint, tangentPoint, angleBisectorFoot, externalAngleBisectorFoot, arcMidpoint, reflectPoint, reflectLine, excenter, rightAngleViewing, pointAtDistance\n\n## Style enum (cho connect)\nsegment, line, ray, perpBisector\n\n## draw-line — phân biệt field theo kind (RẤT QUAN TRỌNG, dễ sai)\n\ndraw-line dùng cho 4 loại đường thẳng đặc biệt. Mỗi kind có schema field khác\nnhau — đặt đúng field, KHÔNG bỏ field bắt buộc, KHÔNG nhầm POINT với LINE:\n\n- **perpThrough** — đường vuông góc với một đường thẳng, đi qua một điểm.\n Fields: \\`through\\` (POINT), \\`to\\` (LINE — ≥2 chữ, vd \"AB\", \"BC\").\n - Ví dụ: \"Đường vuông góc với AB tại B\" → \\`{kind:\"perpThrough\", through:\"B\", to:\"AB\"}\\`.\n - **SAI**: \\`{through:\"B\", to:\"A\"}\\` (A là 1 chữ → POINT, không phải LINE).\n - Nếu đề chỉ nói \"vuông góc với AB\" thì \\`to:\"AB\"\\` (2 chữ); KHÔNG đặt \\`to:\"A\"\\` hay \\`to:\"B\"\\`.\n\n- **parallelThrough** — đường song song với LINE, đi qua POINT. Field giống\n perpThrough: \\`through\\` (POINT), \\`to\\` (LINE 2+ chữ).\n - Ví dụ: \"qua M kẻ đường song song với BC\" → \\`{kind:\"parallelThrough\", through:\"M\", to:\"BC\"}\\`.\n\n- **tangentAt** — tiếp tuyến TẠI điểm trên đường tròn.\n Fields: \\`through\\` (POINT, phải nằm TRÊN circle), \\`circle\\` (CIRCLE name).\n - Ví dụ: \"Tiếp tuyến tại A của (O)\" → \\`{kind:\"tangentAt\", through:\"A\", circle:\"O\"}\\`.\n - KHÔNG dùng \\`from\\` ở đây — chỉ tangentFromExt mới dùng \\`from\\`.\n\n- **tangentFromExt** — tiếp tuyến TỪ điểm NGOÀI đường tròn (có 2 nhánh).\n Fields: \\`from\\` (POINT, ngoài circle), \\`circle\\` (CIRCLE), \\`which\\` ('first'|'second'|'both').\n - Ví dụ: \"Vẽ tiếp tuyến PA và PB từ P\" → 2 intent với \\`which:\"first\"\\` và \\`which:\"second\"\\`.\n\n## Cụm A — constraint hình học nâng cao (đặt ĐÚNG field)\n\n- **arcMidpoint** — trung điểm CUNG. Fields: \\`circle\\` (tên đường tròn), \\`a\\`, \\`b\\` (2 đầu cung), \\`notContaining\\` (đỉnh KHÔNG nằm trên cung đó).\n - Ví dụ: \"M là trung điểm cung BC không chứa A của (O)\" → \\`{kind:\"arcMidpoint\", circle:\"O\", a:\"B\", b:\"C\", notContaining:\"A\"}\\`.\n - LƯU Ý: phải có draw-circle tạo \\`circle\\` trước (vd đường tròn ngoại tiếp → spec:\"through3\", points:[A,B,C]).\n\n- **reflectPoint** — đối xứng qua một ĐIỂM. Fields: \\`of\\` (điểm gốc), \\`through\\` (tâm đối xứng, 1 chữ = POINT).\n - Ví dụ: \"Q đối xứng P qua trung điểm M\" → \\`{kind:\"reflectPoint\", of:\"P\", through:\"M\"}\\`.\n\n- **reflectLine** — đối xứng qua một ĐƯỜNG. Fields: \\`of\\` (điểm gốc), \\`through\\` (đường, 2 chữ = LINE vd \"BC\").\n - Ví dụ: \"D đối xứng H qua BC\" → \\`{kind:\"reflectLine\", of:\"H\", through:\"BC\"}\\`.\n\n- **excenter** — tâm BÀNG tiếp tam giác. Fields: \\`of\\` ([A,B,C]), \\`opposite\\` (đỉnh đối diện).\n - Ví dụ: \"J là tâm bàng tiếp góc A của tam giác ABC\" → \\`{kind:\"excenter\", of:[\"A\",\"B\",\"C\"], opposite:\"A\"}\\`.\n - KHÁC incenter (tâm NỘI tiếp): bàng tiếp nằm NGOÀI tam giác.\n\n- **rightAngleViewing** — điểm GÓC VUÔNG nhìn đoạn. Fields: \\`a\\`, \\`b\\` (2 mút đoạn), \\`onLine\\` (đường điểm nằm trên), \\`which\\` (0|1, optional — chọn giao điểm).\n - Dùng khi: \"M trên <đường> sao cho góc AMB = 90°\" / \"∠AMB = 90°\" / \"góc AMB vuông\" / \"MA ⊥ MB\" / \"M nhìn AB dưới góc vuông\".\n - Chữ GIỮA của góc = tên điểm (name); 2 chữ ngoài = \\`a\\`, \\`b\\`.\n - Ví dụ: \"M trên CK sao cho góc AMB = 90°\" → \\`{op:\"add-point\", name:\"M\", constraint:{kind:\"rightAngleViewing\", a:\"A\", b:\"B\", onLine:\"CK\"}}\\`.\n - KHÔNG tự tạo đường tròn phụ — chỉ phát ra constraint này, hệ thống tự dựng đường tròn đường kính AB (Thales).\n- **pointAtDistance** — điểm trên TIA kéo dài, cách mốc một khoảng cho trước. Fields: \\`from\\` (điểm gốc của tia), \\`through\\` (điểm mốc — điểm mới nằm BÊN NGOÀI \\`through\\` trên tia from→through), \\`distance\\` — một trong:\n - \\`{kind:\"circleRadius\", circle:\"O\"}\\` = bán kính R của đường tròn (O)\n - \\`{kind:\"segmentLength\", p1:\"O\", p2:\"A\"}\\` = độ dài đoạn OA\n - \\`{kind:\"literal\", value:2}\\` = số đo cho sẵn\n - Ví dụ: \"Kéo dài AB về phía B, lấy C sao cho BC = R của (O)\" → \\`{op:\"add-point\", name:\"C\", constraint:{kind:\"pointAtDistance\", from:\"A\", through:\"B\", distance:{kind:\"circleRadius\", circle:\"O\"}}}\\`.\n - Ví dụ: \"Trên tia đối của tia BA lấy D sao cho BD = AB\" (hướng từ B ra xa A) → \\`{op:\"add-point\", name:\"D\", constraint:{kind:\"pointAtDistance\", from:\"A\", through:\"B\", distance:{kind:\"segmentLength\", p1:\"A\", p2:\"B\"}}}\\`.\n - KHÁC reflectPoint (cho 2·through−from, không cần distance) và onSegment (nằm GIỮA hai điểm, t∈[0,1]).\n\n## Quy ước LINE name\n- 2 ký tự viết liền = SEGMENT/LINE qua 2 điểm: \"AB\", \"BC\", \"MN\" → \\`to: \"AB\"\\`.\n- 1 ký tự = POINT, KHÔNG dùng cho field \\`to\\` của perpThrough/parallelThrough.\n- Nếu đề chỉ nêu 2 điểm và bạn cần đường thẳng qua chúng, gọi nó là \"AB\"\n (alphabet order canonical), KHÔNG cần emit connect intent riêng — builder\n tự suy ra đoạn.\n\n---\n\n# ${FIXTURES.length} ví dụ\n\n${examples}\n`;\n}\n","// src/stamps/geometry-2d/ai/handleGenerateFigureIntent.ts\n//\n// Façade cho HTTP transport — wrap generateFigureIntent với error mapping\n// tới AiFigureIntentUiResult (pattern giống handleGenerateFigure cũ).\n\nimport { generateFigureIntent, type GenerateIntentOptions } from './buildFigureIntent';\nimport type { IntentT } from './intent';\nimport type { DslInputT } from '../dsl/schema';\n\nexport interface HandleGenerateFigureIntentOptions extends GenerateIntentOptions {}\n\nexport interface HandleGenerateFigureIntentInput {\n problem: string;\n}\n\nexport type AiFigureIntentUiResult =\n | {\n kind: 'success';\n dsl: DslInputT;\n intents: readonly IntentT[];\n svg?: string;\n usage: { inputTokens: number; outputTokens: number };\n }\n | {\n kind: 'refused';\n message: string;\n }\n | {\n kind: 'error';\n code: string;\n message: string;\n };\n\nexport async function handleGenerateFigureIntent(\n problem: string,\n opts: HandleGenerateFigureIntentOptions = {},\n): Promise<AiFigureIntentUiResult> {\n try {\n const r = await generateFigureIntent(problem, opts);\n if (r.ok) {\n return {\n kind: 'success',\n dsl: r.dsl,\n intents: r.intents,\n usage: {\n inputTokens: r.usage.inputTokens,\n outputTokens: r.usage.outputTokens,\n },\n };\n }\n return { kind: 'error', code: r.reason, message: r.message };\n } catch (e) {\n return {\n kind: 'error',\n code: 'unexpected',\n message: e instanceof Error ? e.message : String(e),\n };\n }\n}\n","// src/stamps/geometry-2d/ai/mergeIntents.ts\n//\n// Hybrid partial-coverage (Phase 1): gộp intent deterministic + intent LLM bù\n// phần clause chưa phủ. Hai quy tắc:\n// 1. Dedup exact (cùng JSON).\n// 2. Deterministic SỞ HỮU tên (đỉnh draw-shape / name add-point/draw-circle/\n// draw-line) → LLM KHÔNG được định nghĩa lại tên đó (drop bản LLM, det thắng).\n// intent tham chiếu (connect…) KHÔNG sở hữu tên → luôn giữ.\n//\n// Det luôn đứng trước, LLM (đã lọc) nối sau — giữ thứ tự dựng.\nimport type { IntentT } from './intent';\n\n/** Tên mà 1 intent ĐỊNH NGHĨA (tạo mới). connect/ref → [] (chỉ tham chiếu). */\nfunction intentOwnedNames(intent: IntentT): string[] {\n const i = intent as unknown as { op: string; labels?: unknown; name?: unknown };\n if (i.op === 'draw-shape') {\n return Array.isArray(i.labels) ? (i.labels as string[]) : [];\n }\n // add-point / draw-circle / draw-line đều có `name` định danh entity mới.\n if (typeof i.name === 'string') return [i.name];\n return [];\n}\n\n/**\n * Gộp intent deterministic (det) + intent LLM bù (llm). Det giữ nguyên; mỗi\n * intent LLM bị loại nếu: trùng JSON với intent đã có, HOẶC định nghĩa lại tên\n * mà det đã sở hữu (det thắng — phần deterministic đã đúng, đừng để LLM ghi đè).\n */\nexport function mergeIntents(det: readonly IntentT[], llm: readonly IntentT[]): IntentT[] {\n const detOwned = new Set<string>();\n for (const i of det) for (const n of intentOwnedNames(i)) detOwned.add(n);\n\n const seen = new Set<string>(det.map((i) => JSON.stringify(i)));\n const out: IntentT[] = [...det];\n\n for (const i of llm) {\n const key = JSON.stringify(i);\n if (seen.has(key)) continue; // trùng exact\n const owned = intentOwnedNames(i);\n if (owned.some((n) => detOwned.has(n))) continue; // redefine tên det → drop\n seen.add(key);\n out.push(i);\n }\n return out;\n}\n"]}
|