@xom11/whiteboard 0.24.1 → 0.25.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.
Files changed (85) hide show
  1. package/README.md +85 -12
  2. package/dist/ai.d.mts +472 -0
  3. package/dist/ai.d.ts +472 -0
  4. package/dist/ai.js +2156 -0
  5. package/dist/ai.js.map +1 -0
  6. package/dist/ai.mjs +1495 -0
  7. package/dist/ai.mjs.map +1 -0
  8. package/dist/catalog.json +4 -4
  9. package/dist/chunk-73Q7ADVL.mjs +35 -0
  10. package/dist/chunk-73Q7ADVL.mjs.map +1 -0
  11. package/dist/{chunk-BKSXPNPQ.mjs → chunk-AYSFWUPK.mjs} +4 -3
  12. package/dist/chunk-AYSFWUPK.mjs.map +1 -0
  13. package/dist/chunk-B4NJJZFR.mjs +18 -0
  14. package/dist/chunk-B4NJJZFR.mjs.map +1 -0
  15. package/dist/{chunk-LVNCYP4J.mjs → chunk-CJBLJUWG.mjs} +5 -5
  16. package/dist/{chunk-LVNCYP4J.mjs.map → chunk-CJBLJUWG.mjs.map} +1 -1
  17. package/dist/{chunk-YIPI3WUL.mjs → chunk-ESVPQWHX.mjs} +5 -5
  18. package/dist/{chunk-YIPI3WUL.mjs.map → chunk-ESVPQWHX.mjs.map} +1 -1
  19. package/dist/{chunk-IBTRMWD6.mjs → chunk-I24QOHPU.mjs} +3 -3
  20. package/dist/{chunk-IBTRMWD6.mjs.map → chunk-I24QOHPU.mjs.map} +1 -1
  21. package/dist/{chunk-ZBJBQKJ2.mjs → chunk-IHUFOV7L.mjs} +4 -19
  22. package/dist/chunk-IHUFOV7L.mjs.map +1 -0
  23. package/dist/{chunk-AZIARTGX.mjs → chunk-M42TGYT6.mjs} +3 -3
  24. package/dist/{chunk-AZIARTGX.mjs.map → chunk-M42TGYT6.mjs.map} +1 -1
  25. package/dist/{chunk-WWMQ2VHZ.mjs → chunk-NDEZJKNY.mjs} +4 -4
  26. package/dist/{chunk-WWMQ2VHZ.mjs.map → chunk-NDEZJKNY.mjs.map} +1 -1
  27. package/dist/{chunk-CSCF3YFZ.mjs → chunk-ONBCUWVI.mjs} +6 -4
  28. package/dist/chunk-ONBCUWVI.mjs.map +1 -0
  29. package/dist/{chunk-6V4SH4JJ.mjs → chunk-REIJZDVZ.mjs} +6 -35
  30. package/dist/chunk-REIJZDVZ.mjs.map +1 -0
  31. package/dist/{chunk-4D5CSIJO.mjs → chunk-TB4CL25L.mjs} +10 -8
  32. package/dist/chunk-TB4CL25L.mjs.map +1 -0
  33. package/dist/chunk-VNCCIV6O.mjs +938 -0
  34. package/dist/chunk-VNCCIV6O.mjs.map +1 -0
  35. package/dist/{chunk-MFOGFFIL.mjs → chunk-VRHWDZ66.mjs} +6 -5
  36. package/dist/chunk-VRHWDZ66.mjs.map +1 -0
  37. package/dist/{chunk-CRAPWQKJ.mjs → chunk-YSJOVBCD.mjs} +4 -4
  38. package/dist/{chunk-CRAPWQKJ.mjs.map → chunk-YSJOVBCD.mjs.map} +1 -1
  39. package/dist/geometry-2d.d.mts +2 -1
  40. package/dist/geometry-2d.d.ts +2 -1
  41. package/dist/geometry-2d.js +1383 -23
  42. package/dist/geometry-2d.js.map +1 -1
  43. package/dist/geometry-2d.mjs +7 -5
  44. package/dist/geometry-3d.d.mts +2 -1
  45. package/dist/geometry-3d.d.ts +2 -1
  46. package/dist/geometry-3d.js +2 -2
  47. package/dist/geometry-3d.js.map +1 -1
  48. package/dist/geometry-3d.mjs +6 -4
  49. package/dist/graph-2d.d.mts +2 -1
  50. package/dist/graph-2d.d.ts +2 -1
  51. package/dist/graph-2d.js +2 -2
  52. package/dist/graph-2d.js.map +1 -1
  53. package/dist/graph-2d.mjs +9 -7
  54. package/dist/{host-TLIXN4CF.mjs → host-A64ITWVX.mjs} +8 -6
  55. package/dist/host-A64ITWVX.mjs.map +1 -0
  56. package/dist/{host-DOAYVL35.mjs → host-L7FMFZUW.mjs} +228 -30
  57. package/dist/host-L7FMFZUW.mjs.map +1 -0
  58. package/dist/{host-GKNQBBUE.mjs → host-QK53UYMD.mjs} +12 -10
  59. package/dist/host-QK53UYMD.mjs.map +1 -0
  60. package/dist/index.d.mts +4 -616
  61. package/dist/index.d.ts +4 -616
  62. package/dist/index.js +8889 -8529
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +21 -1012
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/latex.d.mts +2 -1
  67. package/dist/latex.d.ts +2 -1
  68. package/dist/render-3WTY7NZB.mjs +9 -0
  69. package/dist/{render-SA4JTOW3.mjs.map → render-3WTY7NZB.mjs.map} +1 -1
  70. package/dist/serialize-SRJVKYUG.mjs +8 -0
  71. package/dist/{serialize-3NZS6A6Q.mjs.map → serialize-SRJVKYUG.mjs.map} +1 -1
  72. package/dist/{types-rA4slL08.d.ts → types-DWRyCa2m.d.mts} +139 -1
  73. package/dist/{types-rA4slL08.d.mts → types-DWRyCa2m.d.ts} +139 -1
  74. package/package.json +6 -1
  75. package/dist/chunk-4D5CSIJO.mjs.map +0 -1
  76. package/dist/chunk-6V4SH4JJ.mjs.map +0 -1
  77. package/dist/chunk-BKSXPNPQ.mjs.map +0 -1
  78. package/dist/chunk-CSCF3YFZ.mjs.map +0 -1
  79. package/dist/chunk-MFOGFFIL.mjs.map +0 -1
  80. package/dist/chunk-ZBJBQKJ2.mjs.map +0 -1
  81. package/dist/host-DOAYVL35.mjs.map +0 -1
  82. package/dist/host-GKNQBBUE.mjs.map +0 -1
  83. package/dist/host-TLIXN4CF.mjs.map +0 -1
  84. package/dist/render-SA4JTOW3.mjs +0 -8
  85. package/dist/serialize-3NZS6A6Q.mjs +0 -6
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/stamps/geometry-2d/dsl/schema.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/ids.ts","../src/stamps/geometry-2d/dsl/transpile.ts","../src/stamps/geometry-2d/ai/envelope.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-equilateral.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-median.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-altitude.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-centroid.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-orthocenter.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-circumcircle.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-incircle.ts","../src/stamps/geometry-2d/dsl/fixtures/parallelogram.ts","../src/stamps/geometry-2d/dsl/fixtures/two-circles-intersect.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-angle-bisector.ts","../src/stamps/geometry-2d/dsl/fixtures/triangle-median-altitude.ts","../src/stamps/geometry-2d/dsl/fixtures/trapezoid.ts","../src/stamps/geometry-2d/dsl/fixtures/rhombus.ts","../src/stamps/geometry-2d/dsl/fixtures/right-triangle-altitude.ts","../src/stamps/geometry-2d/dsl/fixtures/tangent-from-point.ts","../src/stamps/geometry-2d/dsl/fixtures/internal-external-bisector.ts","../src/stamps/geometry-2d/ai/prompt.ts","../src/stamps/geometry-2d/ai/providers/anthropic.ts","../src/stamps/geometry-2d/ai/providers/ollama.ts","../src/stamps/geometry-2d/ai/providers/index.ts","../src/stamps/geometry-2d/ai/buildFigure.ts","../src/stamps/geometry-2d/ai/handleGenerateFigure.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"],"names":["z","fixture","toUsage","zodToJsonSchema","DEFAULT_MAX_TOKENS","tResult","DEFAULT_MAX_ATTEMPTS","clampAttempts","mapErrorToUi"],"mappings":"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","file":"ai.mjs","sourcesContent":["// 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\nexport type DslPointT =\n | { name: Name; kind: 'free'; x: number; y: number }\n | { name: Name; kind: 'midpoint'; p1: Name; p2: Name }\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\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: 'tangent'; throughPoint: Name; toCircle: Name; branch?: 0 | 1 | 'on' }\n | { name: Name; kind: 'circleCP'; center: Name; surfacePoint: Name }\n | { name: Name; kind: 'circle3'; p1: Name; p2: Name; p3: Name };\n\nexport type DslInputT = {\n version: 1;\n points: DslPointT[];\n shapes: DslShapeT[];\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 { 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\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 for (const p of dsl.points) {\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 }\n }\n\n for (const s of dsl.shapes) {\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/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 { 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 for (const p of dsl.points) emitEntity(p);\n for (const s of dsl.shapes) emitEntity(s);\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/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/dsl/fixtures/triangle-equilateral.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Cho tam giác đều ABC cạnh 4.',\n dsl: {\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: 2, y: 3.464 },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-median.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, M là trung điểm BC. Vẽ AM.',\n dsl: {\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 { name: 'M', kind: 'midpoint', p1: 'B', p2: 'C' },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'AM', kind: 'segment', p1: 'A', p2: 'M' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-altitude.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, AH là đường cao xuống BC.',\n dsl: {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: 1, y: 3 },\n { name: 'B', kind: 'free', x: -2, y: 0 },\n { name: 'C', kind: 'free', x: 3, y: 0 },\n { name: 'H', kind: 'perpFoot', from: 'A', onLine: 'BC' },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'BC', kind: 'segment', p1: 'B', p2: 'C' },\n { name: 'AH', kind: 'segment', p1: 'A', p2: 'H' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-centroid.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, G là trọng tâm.',\n dsl: {\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 { name: 'G', kind: 'centroid', vertices: ['A', 'B', 'C'] },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-orthocenter.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, H là trực tâm.',\n dsl: {\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 { name: 'H', kind: 'orthocenter', vertices: ['A', 'B', 'C'] },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-circumcircle.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC nội tiếp đường tròn tâm O.',\n dsl: {\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 { name: 'O', kind: 'circumcenter', vertices: ['A', 'B', 'C'] },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'k', kind: 'circle3', p1: 'A', p2: 'B', p3: 'C' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-incircle.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, I là tâm nội tiếp, đường tròn (I) tiếp xúc BC tại D.',\n dsl: {\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 { name: 'I', kind: 'incenter', vertices: ['A', 'B', 'C'] },\n { name: 'D', kind: 'perpFoot', from: 'I', onLine: 'BC' },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'BC', kind: 'segment', p1: 'B', p2: 'C' },\n { name: 'incircle', kind: 'circleCP', center: 'I', surfacePoint: 'D' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/parallelogram.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Hình bình hành ABCD, hai đường chéo AC, BD cắt nhau tại O.',\n dsl: {\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: 5, y: 2 },\n { name: 'D', kind: 'free', x: 1, y: 2 },\n { name: 'O', kind: 'intersection', ref1: 'AC', ref2: 'BD' },\n ],\n shapes: [\n { name: 'ABCD', kind: 'polygon', vertices: ['A', 'B', 'C', 'D'] },\n { name: 'AC', kind: 'segment', p1: 'A', p2: 'C' },\n { name: 'BD', kind: 'segment', p1: 'B', p2: 'D' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/two-circles-intersect.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Hai đường tròn (O₁), (O₂) cắt nhau tại P, Q.',\n dsl: {\n version: 1,\n points: [\n { name: 'O1', kind: 'free', x: 0, y: 0 },\n { name: 'A1', kind: 'free', x: 2, y: 0 },\n { name: 'O2', kind: 'free', x: 3, y: 0 },\n { name: 'A2', kind: 'free', x: 5, y: 0 },\n { name: 'P', kind: 'intersection', ref1: 'k1', ref2: 'k2', branch: 0 },\n { name: 'Q', kind: 'intersection', ref1: 'k1', ref2: 'k2', branch: 1 },\n ],\n shapes: [\n { name: 'k1', kind: 'circleCP', center: 'O1', surfacePoint: 'A1' },\n { name: 'k2', kind: 'circleCP', center: 'O2', surfacePoint: 'A2' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-angle-bisector.ts\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, AD là phân giác góc A (D thuộc BC).',\n dsl: {\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 // D = giao của đường phân giác góc A với BC. KHÔNG dùng segment AD\n // vì AD lại tham chiếu D → cycle.\n { name: 'D', kind: 'intersection', ref1: 'bisA', ref2: 'BC' },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'BC', kind: 'segment', p1: 'B', p2: 'C' },\n // Đường phân giác (line construction), chứ không phải segment.\n { name: 'bisA', kind: 'angleBisector', p1: 'B', vertex: 'A', p2: 'C' },\n // Sau khi đã có D, mới dựng được segment AD.\n { name: 'AD', kind: 'segment', p1: 'A', p2: 'D' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/triangle-median-altitude.ts\n//\n// Compound fixture (2 yêu cầu trong cùng đề): trung điểm + đường cao trên cùng\n// cạnh BC. Mục đích dạy AI:\n// - M (midpoint) và H (perpFoot) là 2 điểm RIÊNG, không nhầm nhau.\n// - Có thể tham chiếu chung shape 'BC' (segment) cho cả derivation.\n// - Order points an toàn: A,B,C free → M midpoint → H perpFoot.\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, M là trung điểm BC và AH là đường cao xuống BC.',\n dsl: {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: 1, y: 3 },\n { name: 'B', kind: 'free', x: -2, y: 0 },\n { name: 'C', kind: 'free', x: 3, y: 0 },\n // M = trung điểm B và C. KHÔNG dùng perpFoot ở đây — đó là H.\n { name: 'M', kind: 'midpoint', p1: 'B', p2: 'C' },\n // H = chân đường vuông góc từ A xuống cạnh BC.\n { name: 'H', kind: 'perpFoot', from: 'A', onLine: 'BC' },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'BC', kind: 'segment', p1: 'B', p2: 'C' },\n { name: 'AM', kind: 'segment', p1: 'A', p2: 'M' },\n { name: 'AH', kind: 'segment', p1: 'A', p2: 'H' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/trapezoid.ts\n//\n// Hình thang ABCD với AB // CD. Toạ độ chọn sao cho AB và CD song song\n// (cùng đi theo trục y = constant). AI học pattern \"polygon với 2 cạnh\n// song song bằng cách chọn coord trùng y\" — không cần emit `parallel` shape.\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Hình thang ABCD có AB song song CD.',\n dsl: {\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: 5, y: 3 },\n { name: 'D', kind: 'free', x: -1, y: 3 },\n ],\n shapes: [\n { name: 'ABCD', kind: 'polygon', vertices: ['A', 'B', 'C', 'D'] },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/rhombus.ts\n//\n// Hình thoi ABCD: 4 cạnh bằng nhau, 2 đường chéo cắt nhau tại tâm O.\n// Coord chọn sao cho ABCD đối xứng qua O và độ dài 4 cạnh bằng nhau.\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Hình thoi ABCD, hai đường chéo AC, BD cắt nhau tại O.',\n dsl: {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: 0, y: 2 },\n { name: 'B', kind: 'free', x: 3, y: 0 },\n { name: 'C', kind: 'free', x: 0, y: -2 },\n { name: 'D', kind: 'free', x: -3, y: 0 },\n { name: 'O', kind: 'intersection', ref1: 'AC', ref2: 'BD' },\n ],\n shapes: [\n { name: 'ABCD', kind: 'polygon', vertices: ['A', 'B', 'C', 'D'] },\n { name: 'AC', kind: 'segment', p1: 'A', p2: 'C' },\n { name: 'BD', kind: 'segment', p1: 'B', p2: 'D' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/right-triangle-altitude.ts\n//\n// Tam giác ABC vuông tại A, AH là đường cao xuống cạnh huyền BC.\n// Coord: A ở gốc, AB trục y, AC trục x → góc vuông tại A.\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC vuông tại A, AH là đường cao xuống cạnh huyền BC.',\n dsl: {\n version: 1,\n points: [\n { name: 'A', kind: 'free', x: 0, y: 0 },\n { name: 'B', kind: 'free', x: 0, y: 3 },\n { name: 'C', kind: 'free', x: 4, y: 0 },\n { name: 'H', kind: 'perpFoot', from: 'A', onLine: 'BC' },\n ],\n shapes: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'BC', kind: 'segment', p1: 'B', p2: 'C' },\n { name: 'AH', kind: 'segment', p1: 'A', p2: 'H' },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/tangent-from-point.ts\n//\n// Từ điểm M ngoài đường tròn (O), kẻ 2 tiếp tuyến tới (O). Dùng\n// `tangent` shape với branch 0/1 để emit 2 đường tiếp tuyến đối xứng.\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Từ điểm M ngoài đường tròn (O), kẻ hai tiếp tuyến tới (O).',\n dsl: {\n version: 1,\n points: [\n { name: 'O', kind: 'free', x: 0, y: 0 },\n // P là điểm trên đường tròn dùng để định bán kính.\n { name: 'P', kind: 'free', x: 2, y: 0 },\n { name: 'M', kind: 'free', x: 5, y: 0 },\n ],\n shapes: [\n { name: 'k', kind: 'circleCP', center: 'O', surfacePoint: 'P' },\n { name: 't1', kind: 'tangent', throughPoint: 'M', toCircle: 'k', branch: 0 },\n { name: 't2', kind: 'tangent', throughPoint: 'M', toCircle: 'k', branch: 1 },\n ],\n },\n};\n","// src/stamps/geometry-2d/dsl/fixtures/internal-external-bisector.ts\n//\n// Tam giác ABC, tại đỉnh A có 2 tia phân giác: trong (angleBisector) và\n// ngoài (vuông góc với phân giác trong tại A). Dùng `perpendicular` shape\n// với throughPoint=A, toLine=bisIn.\nimport type { DslInputT } from '../schema';\n\nexport const fixture: { problem: string; dsl: DslInputT } = {\n problem: 'Tam giác ABC, vẽ tia phân giác trong và phân giác ngoài tại đỉnh A.',\n dsl: {\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: [\n { name: 'ABC', kind: 'polygon', vertices: ['A', 'B', 'C'] },\n { name: 'bisIn', kind: 'angleBisector', p1: 'B', vertex: 'A', p2: 'C' },\n // Phân giác ngoài = vuông góc với phân giác trong tại đỉnh A.\n { name: 'bisExt', kind: 'perpendicular', throughPoint: 'A', toLine: 'bisIn' },\n ],\n },\n};\n","// src/stamps/geometry-2d/ai/prompt.ts\n//\n// System prompt cho cả Anthropic + Ollama providers. AI luôn emit envelope\n// JSON: `{ decision: 'build', figure: <DslInput> }` hoặc\n// `{ decision: 'refuse', reason: '...' }`. Provider responsible cho việc\n// constrain schema (tool input_schema | Ollama format).\n\nimport { fixture as eq } from '../dsl/fixtures/triangle-equilateral';\nimport { fixture as md } from '../dsl/fixtures/triangle-median';\nimport { fixture as alt } from '../dsl/fixtures/triangle-altitude';\nimport { fixture as ce } from '../dsl/fixtures/triangle-centroid';\nimport { fixture as oc } from '../dsl/fixtures/triangle-orthocenter';\nimport { fixture as cc } from '../dsl/fixtures/triangle-circumcircle';\nimport { fixture as ic } from '../dsl/fixtures/triangle-incircle';\nimport { fixture as par } from '../dsl/fixtures/parallelogram';\nimport { fixture as two } from '../dsl/fixtures/two-circles-intersect';\nimport { fixture as bis } from '../dsl/fixtures/triangle-angle-bisector';\nimport { fixture as mdAlt } from '../dsl/fixtures/triangle-median-altitude';\nimport { fixture as trap } from '../dsl/fixtures/trapezoid';\nimport { fixture as rho } from '../dsl/fixtures/rhombus';\nimport { fixture as rta } from '../dsl/fixtures/right-triangle-altitude';\nimport { fixture as tan } from '../dsl/fixtures/tangent-from-point';\nimport { fixture as ieBis } from '../dsl/fixtures/internal-external-bisector';\n\nconst FIXTURES = [\n eq, md, alt, ce, oc, cc, ic, bis, mdAlt,\n rta, ieBis, tan, par, rho, trap, two,\n];\n\nexport function buildSystemPrompt(): string {\n const examples = FIXTURES.map((f, i) =>\n `### Ví dụ ${i + 1}\n**Đề:** ${f.problem}\n**Output:**\n${JSON.stringify({ decision: 'build', figure: f.dsl }, null, 2)}`,\n ).join('\\n\\n');\n\n return `Bạn là trợ lý vẽ hình học 2D cho học sinh THCS và lớp 10 Việt Nam.\n\n## Nhiệm vụ\nĐọc đề bài tiếng Việt → emit JSON envelope mô tả hình. Hệ thống sẽ render hình từ DSL.\n\n## Output format (CHỈ JSON, không markdown, không text khác)\n{ \"decision\": \"build\", \"figure\": { /* DSL */ } }\nhoặc\n{ \"decision\": \"refuse\", \"reason\": \"lý do tiếng Việt\" }\n\n## Quy tắc\n1. Vẽ được → decision=\"build\" + figure đầy đủ DSL.\n2. Đề ngoài phạm vi → decision=\"refuse\" + reason tiếng Việt cụ thể. Bao gồm:\n - Tính toán đại số / lượng giác / giải phương trình (không yêu cầu vẽ).\n - Hình 3D, lập thể, không gian.\n - Phép biến hình affine / tịnh tiến / vị tự / quay (lớp 11+).\n - Đề mô tả không đủ thông tin để dựng (vd \"điểm M bất kỳ trên mặt phẳng\").\n3. **Ưu tiên derived points** (midpoint, perpFoot, intersection, circumcenter, …) thay vì tự compute toạ độ. Chỉ dùng \\`free\\` cho điểm gốc tự do (A, B, C của tam giác — đặt coord -5..5).\n4. **Đường cao**: dùng \\`perpFoot\\` cho chân, KHÔNG free anchor.\n5. **Phân giác góc A đến BC**: emit line \\`angleBisector\\` (B, A, C) + segment BC + point D = \\`intersection\\` của 2 line đó. KHÔNG emit \\`onSegment\\` với segmentId chính là segment đang dựng (cycle).\n6. **Đường tròn ngoại tiếp**: dùng \\`circle3\\` (3 điểm), không phải \\`polygon\\`.\n7. **Đường tròn nội tiếp / tiếp xúc**: tâm bằng \\`incenter\\`, điểm tiếp xúc bằng \\`perpFoot\\` từ tâm xuống cạnh tương ứng, rồi \\`circleCP\\`.\n8. **Đường tròn (O; R) bán kính số**: emit free helper trên đường tròn rồi dùng \\`circleCP\\` (DSL không hỗ trợ radius numeric trực tiếp).\n9. **Đề ghép nhiều yêu cầu** (vd \"trung điểm M và đường cao AH\"): mỗi yêu cầu là 1 derived point riêng với kind đúng. KHÔNG đặt chung 1 point thoả nhiều ràng buộc. Vẽ thêm segment cho từng yêu cầu (AM, AH, ...) khi đề mô tả \"dựng\" hoặc \"vẽ\".\n\n## Anti-pattern (BẮT BUỘC tránh)\n- **Cycle / forward-ref**: KHÔNG được tham chiếu chéo. Nếu point D ∈ segment AD → cycle (AD cần D, D cần AD). Đúng pattern: D = intersection của line nào đó với BC, sau đó AD = segment(A, D).\n- **Mọi name bị reference phải được định nghĩa trước** (DSL topological sort: free → derived → shape).\n- **Đa giác polygon KHÔNG thay thế cho đường tròn**: nếu đề nói \"đường tròn qua 3 điểm\" mà bạn emit polygon thì sai.\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## ${FIXTURES.length} ví dụ\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/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 ProviderOutput,\n ProviderRequest,\n ProviderTokenUsage,\n} from './types';\n\nconst TOOL_NAME = 'emit_figure_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\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/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} 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 // Ollama v0.5+ structured outputs: model bị constrain emit JSON đúng schema.\n format: req.schema,\n stream: false,\n options: {\n // num_predict ≈ max_tokens\n num_predict: req.maxTokens,\n // temperature thấp cho output deterministic hơn (DSL cần consistent).\n temperature: 0.2,\n },\n };\n\n let resp: Response;\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 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) {\n let detail = '';\n try {\n detail = await resp.text();\n } catch {\n /* ignore */\n }\n return {\n kind: 'error',\n message: `Ollama 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 const err = e as { message?: string };\n return { kind: 'error', message: 'Ollama response không phải JSON: ' + (err.message ?? '?') };\n }\n\n const content = json.message?.content?.trim();\n if (!content) {\n return { kind: 'error', message: 'Ollama trả message.content rỗng' };\n }\n\n let data: unknown;\n try {\n data = JSON.parse(content);\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 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// - \"anthropic\": cần env ANTHROPIC_API_KEY\n// - \"ollama\" (default): không cần key, đọc OLLAMA_BASE_URL tùy chọn\n\nimport { AnthropicProvider } from './anthropic';\nimport { OllamaProvider } from './ollama';\nimport type { AIProvider } from './types';\n\nexport type { AIProvider, ProviderOutput, ProviderRequest, ProviderTokenUsage } from './types';\nexport { AnthropicProvider } from './anthropic';\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 /** 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 ?? 'ollama').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 === '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(`selectProvider: WHITEBOARD_AI_PROVIDER=\"${wanted}\" không hợp lệ (anthropic|ollama)`);\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/buildFigure.ts\n//\n// Orchestrator: chọn provider → gọi → parse envelope → transpile DSL → State.\n// Provider-agnostic; backward-compat với caller cũ truyền `apiKey`.\n\nimport type { State as SceneState } from '../../../core/scene/types';\nimport type { DslInputT, TranspileError } from '../dsl';\nimport { transpile } from '../dsl';\nimport {\n FigureEnvelopeZ,\n envelopeBuildDsl,\n envelopeJsonSchema,\n} from './envelope';\nimport { buildSystemPrompt } from './prompt';\nimport {\n selectProvider,\n type AIProvider,\n type ProviderTokenUsage,\n type SelectProviderOptions,\n} from './providers';\n\nconst DEFAULT_MAX_TOKENS = 8192;\n\nexport interface GenerateOptions extends SelectProviderOptions {\n /** Model id override (provider-specific). Mặc định: provider.defaultModel. */\n model?: string;\n maxTokens?: number;\n signal?: AbortSignal;\n}\n\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheCreationTokens: number;\n}\n\nexport type GenerateResult =\n | { ok: true; state: SceneState; dsl: DslInputT; usage: TokenUsage; provider: string }\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 | { ok: false; reason: 'transpile_error'; message: string; errors: TranspileError[]; dsl: unknown; usage?: TokenUsage; provider?: string }\n | { ok: false; reason: 'api_error'; message: string; status?: number; provider?: string };\n\nexport async function generateFigure(\n problem: string,\n opts: GenerateOptions = {},\n): Promise<GenerateResult> {\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 = buildSystemPrompt();\n const schema = envelopeJsonSchema();\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 // Validate envelope schema (refine: build cần figure, refuse cần reason).\n const parsed = FigureEnvelopeZ.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 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 // decision === 'build'\n const dsl = envelopeBuildDsl(env);\n const tResult = transpile(dsl);\n if (!tResult.ok) {\n return {\n ok: false,\n reason: 'transpile_error',\n message: 'DSL từ AI không hợp lệ',\n errors: tResult.errors,\n dsl,\n usage,\n provider: provider.name,\n };\n }\n\n return {\n ok: true,\n state: tResult.state,\n dsl,\n usage,\n provider: provider.name,\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","// Façade trên `generateFigure()` cho HTTP transport (Vite middleware,\n// Next.js route, Cloudflare Worker, ...). Gói luôn mapping\n// `GenerateResult` → `AiFigureUiResult` (shape client-safe) để mọi consumer\n// không phải lặp lại logic.\n\nimport type { AiFigureUiResult } from '../../shared/types';\nimport { generateFigure, type GenerateOptions, type GenerateResult } from './buildFigure';\n\nexport interface HandleGenerateFigureInput {\n /** Đề bài tiếng Việt từ teacher. */\n problem: string;\n}\n\nexport interface HandleGenerateFigureOptions extends GenerateOptions {\n /**\n * Optional telemetry hook. Gọi cho MỖI attempt với envelope nội bộ trước\n * khi map sang AiFigureUiResult — consumer dùng để log usage/cost/error.\n * Không throw từ logger — sẽ swallow để không vỡ response.\n *\n * @param result GenerateResult của attempt\n * @param attempt 1-indexed (1 = lần đầu, 2 = retry, ...)\n */\n onResult?: (result: GenerateResult, attempt: number) => void;\n /**\n * Số attempt tối đa khi nhận `transpile_error`. Default 2 (1 retry).\n * AI stochastic → lần 2 thường khá hơn. Min 1, max 5.\n */\n maxAttempts?: number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 2;\n\n/**\n * Gọi AI orchestrator và trả về kết quả ở dạng `AiFigureUiResult` mà\n * `<Whiteboard generateGeometryFigure>` chấp nhận trực tiếp.\n *\n * Auto-retry: chỉ retry khi `transpile_error` (DSL không hợp lệ — model\n * stochastic có cơ hội emit khá hơn lần 2). KHÔNG retry `refused` (AI cố ý\n * từ chối), `parse_error` (envelope sai schema — chắc chắn sai mọi lần),\n * hay `api_error` (network / config — không liên quan model).\n *\n * Mapping:\n * - ok=true → { ok: true, state }\n * - refused → { ok: false, message: <message AI gửi> }\n * - parse_error → { ok: false, message: 'AI trả JSON không hợp lệ…' }\n * - transpile_error → { ok: false, message: 'AI tạo hình không hợp lệ…' }\n * - api_error → { ok: false, message: <message gốc> }\n *\n * Server-side caller giữ `GenerateResult` đầy đủ qua `onResult` callback cho\n * mục đích telemetry/logging.\n */\nexport async function handleGenerateFigure(\n input: HandleGenerateFigureInput,\n opts: HandleGenerateFigureOptions = {},\n): Promise<AiFigureUiResult> {\n const { onResult, maxAttempts: rawMax, ...generateOpts } = opts;\n const maxAttempts = clampAttempts(rawMax ?? DEFAULT_MAX_ATTEMPTS);\n\n let lastResult: GenerateResult | null = null;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const result = await generateFigure(input.problem, 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 // Thành công → return ngay\n if (result.ok) {\n return { ok: true, state: result.state };\n }\n\n // Retry chỉ với transpile_error\n if (result.reason === 'transpile_error' && attempt < maxAttempts) {\n continue;\n }\n\n // Không retry-able hoặc đã hết attempt\n break;\n }\n\n // lastResult chắc chắn không null sau loop\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: GenerateResult): 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 đề bà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 'api_error':\n default:\n return { ok: false, message: result.message };\n }\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, biến hình lớp 11+, tính toán đại số).\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"]}
package/dist/catalog.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "generatedAt": "2026-05-26T06:25:42.573Z",
2
+ "generatedAt": "2026-06-01T09:22:26.477Z",
3
3
  "entries": [
4
4
  {
5
5
  "id": "geometry",
@@ -10,7 +10,7 @@
10
10
  "jsxgraph"
11
11
  ],
12
12
  "bundleSize": {
13
- "js": 60.33,
13
+ "js": 66.86,
14
14
  "css": 0
15
15
  }
16
16
  },
@@ -36,7 +36,7 @@
36
36
  "jsxgraph"
37
37
  ],
38
38
  "bundleSize": {
39
- "js": 50.73,
39
+ "js": 51.22,
40
40
  "css": 0
41
41
  }
42
42
  },
@@ -49,7 +49,7 @@
49
49
  "jsxgraph"
50
50
  ],
51
51
  "bundleSize": {
52
- "js": 42.91,
52
+ "js": 43.43,
53
53
  "css": 0
54
54
  }
55
55
  }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ // src/core/scene/types.ts
3
+ var DEFAULT_VIEW_2D = {
4
+ bbox: [-10, 10, 10, -10],
5
+ showAxis: false,
6
+ showGrid: false
7
+ };
8
+ var DEFAULT_VIEW_3D = {
9
+ bbox3D: [-5, 5, -5, 5, -5, 5],
10
+ azimuth: 60,
11
+ elevation: 30
12
+ };
13
+ var DEFAULT_VIEW_GRAPH2D = {
14
+ xMin: -10,
15
+ xMax: 10,
16
+ yMin: -10,
17
+ yMax: 10,
18
+ showAxis: true,
19
+ showGrid: true
20
+ };
21
+ function createEmptyState(domain) {
22
+ const base = { objects: {}, order: [], counter: 0 };
23
+ switch (domain) {
24
+ case "2d":
25
+ return { ...base, meta: { domain: "2d", version: 1, view: DEFAULT_VIEW_2D } };
26
+ case "3d":
27
+ return { ...base, meta: { domain: "3d", version: 1, view: DEFAULT_VIEW_3D } };
28
+ case "graph2d":
29
+ return { ...base, meta: { domain: "graph2d", version: 1, view: DEFAULT_VIEW_GRAPH2D } };
30
+ }
31
+ }
32
+
33
+ export { DEFAULT_VIEW_2D, DEFAULT_VIEW_3D, createEmptyState };
34
+ //# sourceMappingURL=chunk-73Q7ADVL.mjs.map
35
+ //# sourceMappingURL=chunk-73Q7ADVL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/scene/types.ts"],"names":[],"mappings":";AA8FO,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;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;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","file":"chunk-73Q7ADVL.mjs","sourcesContent":["// 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"]}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
- import { getKind, collectFreeVars } from './chunk-ZBJBQKJ2.mjs';
2
+ import { collectFreeVars } from './chunk-IHUFOV7L.mjs';
3
+ import { getKind } from './chunk-B4NJJZFR.mjs';
3
4
 
4
5
  // src/core/scene/render/types2d.ts
5
6
  var DEFAULT_THEME_2D = {
@@ -344,5 +345,5 @@ var JxgRenderer = class {
344
345
  };
345
346
 
346
347
  export { DEFAULT_THEME_2D, JxgRenderer };
347
- //# sourceMappingURL=chunk-BKSXPNPQ.mjs.map
348
- //# sourceMappingURL=chunk-BKSXPNPQ.mjs.map
348
+ //# sourceMappingURL=chunk-AYSFWUPK.mjs.map
349
+ //# sourceMappingURL=chunk-AYSFWUPK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/scene/render/types2d.ts","../src/core/scene/render/JxgRenderer.ts"],"names":[],"mappings":"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","file":"chunk-AYSFWUPK.mjs","sourcesContent":["// src/core/scene/render/types2d.ts\nimport type { RenderCtx } from '../types';\n\nexport type Theme2D = {\n stroke: string;\n fill: string;\n label: string;\n axis: string;\n grid: string;\n pointFill: string;\n};\n\nexport const DEFAULT_THEME_2D: Theme2D = {\n stroke: '#0f172a',\n fill: '#60a5fa',\n label: '#0f172a',\n axis: '#94a3b8',\n grid: '#e2e8f0',\n pointFill: '#1e40af',\n};\n\nexport type RenderCtx2D = RenderCtx & {\n theme: Theme2D;\n};\n","// src/core/scene/render/JxgRenderer.ts\nimport type { Store } from '../store';\nimport type { State, SceneObject, RenderCtx } from '../types';\nimport { getKind } from '../registry';\nimport { DEFAULT_THEME_2D, type Theme2D } from './types2d';\nimport { collectFreeVars } from '../expressions/parser';\n\nexport type JxgRendererOptions = { theme?: Theme2D };\n\nexport class JxgRenderer {\n private board: unknown;\n private store: Store;\n private theme: Theme2D;\n private elements = new Map<string, unknown>();\n private unsubscribe: () => void;\n private disposed = false;\n\n /** Chỉ dùng cho domain='graph2d': parameter.label → parameter.value */\n private paramMap: Record<string, number> = {};\n /** Chỉ dùng cho domain='graph2d': function2d.id → expression string */\n private functionExpr: Record<string, string> = {};\n\n constructor(store: Store, board: unknown, options: JxgRendererOptions = {}) {\n this.store = store;\n this.board = board;\n this.theme = options.theme ?? DEFAULT_THEME_2D;\n this.unsubscribe = store.subscribe((next, prev) => this.applyDiff(prev, next));\n // Render state hiện tại (vd LOAD chạy trước khi subscribe).\n this.applyDiff(undefined, store.getState());\n }\n\n private ctx(): RenderCtx {\n return {\n jxg: this.board,\n resolveRef: (id: string) => {\n // Synthetic \"<polyId>:border:<N>\" → polygon.borders[N]. Polygon edges\n // là sub-segment do JSXGraph auto-tạo bên trong polygon; chúng không\n // có scene id riêng. Synthetic id cho phép construct tools (vd\n // perpendicular qua một cạnh đa giác) tham chiếu cạnh như một line.\n const m = /^(.+):border:(\\d+)$/.exec(id);\n if (m) {\n const poly = this.elements.get(m[1]) as { borders?: unknown[] } | undefined;\n if (!poly) throw new Error(`[scene/2d] resolveRef: chưa render polygon id=\"${m[1]}\"`);\n const borders = poly.borders;\n const idx = parseInt(m[2], 10);\n if (!Array.isArray(borders) || !borders[idx]) {\n throw new Error(`[scene/2d] resolveRef: polygon \"${m[1]}\" không có border[${idx}]`);\n }\n return borders[idx];\n }\n const el = this.elements.get(id);\n if (!el) throw new Error(`[scene/2d] resolveRef: chưa render id=\"${id}\"`);\n return el;\n },\n defaults: { theme: this.theme, _functionExpr: this.functionExpr },\n paramMap: this.paramMap,\n };\n }\n\n /**\n * Rebuild `paramMap` và `functionExpr` từ state hiện tại.\n * Chỉ chạy khi domain='graph2d'. Chi phí thấp vì parameters thường ≤ 8.\n */\n private rebuildGraphMaps(state: State): void {\n if (state.meta.domain !== 'graph2d') return;\n const params: Record<string, number> = {};\n const fns: Record<string, string> = {};\n for (const id of state.order) {\n const obj = state.objects[id];\n if (obj.kind === 'parameter') {\n params[obj.label] = (obj.attrs as { value: number }).value;\n } else if (obj.kind === 'function2d') {\n fns[obj.id] = (obj.attrs as { expression: string }).expression;\n }\n }\n this.paramMap = params;\n this.functionExpr = fns;\n }\n\n private create(obj: SceneObject): void {\n try {\n const def = getKind(obj.kind);\n const el = def.render(obj, this.ctx());\n this.elements.set(obj.id, el);\n this.attachFreePointDragSync(obj, el);\n } catch (err) {\n console.warn(`[scene/render/2d] không render được ${obj.kind} id=\"${obj.id}\":`, err);\n }\n }\n\n /**\n * Đồng bộ toạ độ live của free point về scene.constraint khi user kéo bằng\n * tay (Move tool / mobile drag). JSXGraph mutate obj.X()/Y() ngay nhưng\n * constraint vẫn giữ giá trị lúc tạo → serialize sẽ ra SVG y hệt cũ →\n * fileId SHA-256 trùng → Excalidraw bỏ qua refresh. (Regression từ\n * commit f41f366 sau scene v2 port.)\n *\n * Chỉ áp dụng cho free point — glider/intersection/midpoint không drag được\n * trực tiếp (toạ độ derived từ ref khác).\n */\n private attachFreePointDragSync(obj: SceneObject, el: unknown): void {\n if (obj.kind !== 'point') return;\n const c = (obj.attrs as { constraint?: { kind?: string } }).constraint;\n if (!c || c.kind !== 'free') return;\n \n const point = el as any;\n if (typeof point.on !== 'function') return;\n const sceneId = obj.id;\n point.on('up', () => {\n if (this.disposed) return;\n if (typeof point.X !== 'function' || typeof point.Y !== 'function') return;\n const x = point.X();\n const y = point.Y();\n if (!Number.isFinite(x) || !Number.isFinite(y)) return;\n const cur = this.store.getState().objects[sceneId];\n if (!cur) return;\n const curC = (cur.attrs as { constraint?: { kind?: string; x?: number; y?: number } }).constraint;\n if (!curC || curC.kind !== 'free') return;\n if (curC.x === x && curC.y === y) return;\n this.store.dispatch({\n type: 'UPDATE_ATTRS',\n payload: { id: sceneId, patch: { constraint: { kind: 'free', x, y } } },\n });\n });\n }\n\n private remove(id: string): void {\n // Selection halo (nếu có) phải bị xoá TRƯỚC element gốc — halo tham chiếu\n // tới point1/point2/center/vertices của element gốc qua lambda; xoá element\n // gốc trước sẽ làm halo dangling.\n this.removeHalo(id);\n this.selectedIds.delete(id);\n const el = this.elements.get(id);\n if (!el) return;\n try {\n const helpers = (el as Record<string, unknown>)._helpers;\n // Element chính bị remove trước, sau đó helpers (glider phụ trợ cho\n // tangent ...). Helpers thường là parent của element chính — nếu xoá\n // parent trước, JSXGraph có thể phàn nàn dangling reference.\n (this.board as { removeObject?: (e: unknown) => void }).removeObject?.(el);\n if (Array.isArray(helpers)) {\n for (const h of helpers) {\n try {\n (this.board as { removeObject?: (e: unknown) => void }).removeObject?.(h);\n } catch { /* ignore */ }\n }\n }\n } catch (err) {\n console.warn(`[scene/render/2d] không remove được id=\"${id}\":`, err);\n }\n this.elements.delete(id);\n }\n\n private applyDiff(prev: State | undefined, next: State): void {\n if (this.disposed) return;\n\n // Rebuild paramMap + functionExpr TRƯỚC khi diff, để ctx() có đúng\n // paramMap khi render lần đầu tiên.\n this.rebuildGraphMaps(next);\n\n const prevObjs = prev?.objects ?? {};\n const nextObjs = next.objects;\n\n // Xoá ids biến mất.\n for (const id of Object.keys(prevObjs)) {\n if (!(id in nextObjs)) this.remove(id);\n }\n\n // Thêm/cập nhật theo state.order — đảm bảo refs có trước.\n for (const id of next.order) {\n const cur = nextObjs[id];\n const old = prevObjs[id] as SceneObject | undefined;\n if (!old) {\n this.create(cur);\n continue;\n }\n if (Object.is(old, cur)) continue;\n const def = getKind(cur.kind);\n const existing = this.elements.get(id);\n if (def.update && existing) {\n try { def.update(cur, old, this.ctx(), existing); continue; }\n catch (err) { console.warn(`[scene/render/2d] update fail, recreate:`, err); }\n }\n this.remove(id);\n this.create(cur);\n }\n\n // Sau diff bình thường: nếu domain='graph2d', detect parameter value changes\n // và force re-render các function2d phụ thuộc.\n if (next.meta.domain === 'graph2d' && prev) {\n const changedParams = new Set<string>();\n for (const id of next.order) {\n const cur = next.objects[id];\n const old = prev.objects[id] as SceneObject | undefined;\n if (cur.kind !== 'parameter' || old?.kind !== 'parameter') continue;\n if ((cur.attrs as { value: number }).value !== (old.attrs as { value: number }).value) {\n changedParams.add(cur.label);\n }\n }\n if (changedParams.size > 0) {\n for (const id of next.order) {\n const obj = next.objects[id];\n if (obj.kind !== 'function2d') continue;\n const expr = (obj.attrs as { expression: string }).expression;\n const refs = collectFreeVars(expr);\n if (refs.some((r) => changedParams.has(r))) {\n this.remove(id);\n this.create(obj);\n }\n }\n }\n }\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.unsubscribe();\n for (const id of Array.from(this.elements.keys())) this.remove(id);\n this.disposed = true;\n }\n\n /** Return the rendered JSXGraph element for a scene id, or null if not found. */\n getElement(id: string): unknown {\n return this.elements.get(id) ?? null;\n }\n\n /** Return a read-only view of the scene id → JSXGraph element map (for hit-test). */\n listElements(): Map<string, unknown> {\n return this.elements;\n }\n\n // Selection halo overlay model: thay vì đổi màu element gốc thành đỏ, tạo\n // một halo element gray phía sau (lower layer) → giữ nguyên màu gốc. Hỗ\n // trợ multi-select cho cả canvas click-selection lẫn ObjectListPanel.\n private selectedIds: Set<string> = new Set();\n private haloMap: Map<string, unknown[]> = new Map();\n\n highlight(ids: string | string[] | null): void {\n if (this.disposed) return;\n const newIds = new Set<string>(\n ids == null ? [] : Array.isArray(ids) ? ids : [ids],\n );\n // Remove halos cho ids đã bị bỏ chọn.\n for (const id of this.selectedIds) {\n if (!newIds.has(id)) this.removeHalo(id);\n }\n // Add halos cho ids mới chọn.\n for (const id of newIds) {\n if (!this.selectedIds.has(id) && this.elements.has(id)) this.addHalo(id);\n }\n this.selectedIds = newIds;\n try {\n (this.board as { update?: () => void }).update?.();\n } catch { /* ignore */ }\n }\n\n private removeHalo(id: string): void {\n const halos = this.haloMap.get(id);\n if (!halos) return;\n const board = this.board as { removeObject?: (e: unknown) => void };\n for (const h of halos) {\n try { board.removeObject?.(h); } catch { /* ignore */ }\n }\n this.haloMap.delete(id);\n }\n\n private addHalo(id: string): void {\n const el = this.elements.get(id) as\n | {\n elType?: string;\n getAttribute?: (k: string) => unknown;\n X?: () => number;\n Y?: () => number;\n point1?: unknown;\n point2?: unknown;\n center?: unknown;\n Radius?: () => number;\n vertices?: unknown[];\n }\n | undefined;\n if (!el) return;\n const board = this.board as {\n create?: (kind: string, parents: unknown[], attrs?: unknown) => unknown;\n };\n if (!board.create) return;\n\n // Selection palette — gray fill + darker gray border (xem\n // tham chiếu /tmp/ss.png).\n const SEL_STROKE = '#475569'; // slate-600\n const SEL_FILL = '#cbd5e1'; // slate-300\n const haloBase = {\n strokeColor: SEL_STROKE,\n strokeOpacity: 0.55,\n fillColor: SEL_FILL,\n fillOpacity: 0.3,\n fixed: true,\n withLabel: false,\n name: '',\n highlight: false,\n layer: 4,\n needsRegularUpdate: true,\n };\n const halos: unknown[] = [];\n try {\n switch (el.elType) {\n case 'point':\n case 'glider':\n case 'intersection': {\n const baseSize = (el.getAttribute?.('size') as number | undefined) ?? 4;\n const halo = board.create('point', [\n () => el.X?.() ?? 0,\n () => el.Y?.() ?? 0,\n ], {\n ...haloBase,\n size: baseSize + 6,\n face: 'o',\n strokeWidth: 2,\n strokeOpacity: 0.75,\n fillOpacity: 0.25,\n });\n halos.push(halo);\n break;\n }\n case 'segment': {\n if (el.point1 && el.point2) {\n const halo = board.create('segment', [el.point1, el.point2], {\n ...haloBase,\n strokeWidth: 9,\n straightFirst: false,\n straightLast: false,\n });\n halos.push(halo);\n }\n break;\n }\n case 'line':\n case 'arrow':\n case 'ray':\n case 'vector':\n case 'tangent':\n case 'normal':\n case 'parallel':\n case 'perpendicular':\n case 'bisector': {\n if (el.point1 && el.point2) {\n const halo = board.create('line', [el.point1, el.point2], {\n ...haloBase,\n strokeWidth: 9,\n });\n halos.push(halo);\n }\n break;\n }\n case 'circle': {\n if (el.center && typeof el.Radius === 'function') {\n const halo = board.create('circle', [el.center, () => el.Radius?.() ?? 0], {\n ...haloBase,\n strokeWidth: 9,\n fillOpacity: 0,\n });\n halos.push(halo);\n }\n break;\n }\n case 'polygon': {\n if (Array.isArray(el.vertices) && el.vertices.length >= 3) {\n // JSXGraph polygon.vertices có thể append vertex đầu lặp lại ở\n // cuối để đóng path — trim cho an toàn.\n const last = el.vertices.length - 1;\n const verts = el.vertices[last] === el.vertices[0]\n ? el.vertices.slice(0, last)\n : el.vertices.slice();\n const halo = board.create('polygon', verts, {\n ...haloBase,\n fillOpacity: 0.2,\n borders: {\n strokeColor: SEL_STROKE,\n strokeWidth: 7,\n strokeOpacity: 0.55,\n highlight: false,\n },\n });\n halos.push(halo);\n }\n break;\n }\n default:\n // Các kind khác (curve, arc, sector, angle, ...) — chưa hỗ trợ halo.\n break;\n }\n } catch (err) {\n console.warn('[scene/render/2d] halo create fail:', err);\n }\n if (halos.length) this.haloMap.set(id, halos);\n }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ // src/core/scene/registry.ts
3
+ var registry = /* @__PURE__ */ new Map();
4
+ function registerKind(def) {
5
+ if (registry.has(def.type)) {
6
+ console.warn(`[scene] kind "${def.type}" \u0111\xE3 \u0111\u01B0\u1EE3c \u0111\u0103ng k\xFD \u2014 ghi \u0111\xE8 \u0111\u1ECBnh ngh\u0129a c\u0169`);
7
+ }
8
+ registry.set(def.type, def);
9
+ }
10
+ function getKind(type) {
11
+ const def = registry.get(type);
12
+ if (!def) throw new Error(`[scene] unknown kind: ${type}`);
13
+ return def;
14
+ }
15
+
16
+ export { getKind, registerKind };
17
+ //# sourceMappingURL=chunk-B4NJJZFR.mjs.map
18
+ //# sourceMappingURL=chunk-B4NJJZFR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/scene/registry.ts"],"names":[],"mappings":";AAGA,IAAM,QAAA,uBAAe,GAAA,EAAqB;AAEnC,SAAS,aAA0C,GAAA,EAAuB;AAC/E,EAAA,IAAI,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA,EAAG;AAC1B,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,cAAA,EAAiB,GAAA,CAAI,IAAI,CAAA,6GAAA,CAA0C,CAAA;AAAA,EAClF;AACA,EAAA,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,GAAyB,CAAA;AAClD;AAEO,SAAS,QAAQ,IAAA,EAAuB;AAC7C,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC7B,EAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAE,CAAA;AACzD,EAAA,OAAO,GAAA;AACT","file":"chunk-B4NJJZFR.mjs","sourcesContent":["// src/core/scene/registry.ts\nimport type { KindDef } from './types';\n\nconst registry = new Map<string, KindDef>();\n\nexport function registerKind<A = Record<string, unknown>>(def: KindDef<A>): void {\n if (registry.has(def.type)) {\n console.warn(`[scene] kind \"${def.type}\" đã được đăng ký — ghi đè định nghĩa cũ`);\n }\n registry.set(def.type, def as unknown as KindDef);\n}\n\nexport function getKind(type: string): KindDef {\n const def = registry.get(type);\n if (!def) throw new Error(`[scene] unknown kind: ${type}`);\n return def;\n}\n\nexport function listKinds(): KindDef[] {\n return Array.from(registry.values());\n}\n\n// Chỉ dùng cho test — reset registry giữa các test case.\nexport function __clearRegistryForTests(): void {\n registry.clear();\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { paletteFor } from './chunk-AZIARTGX.mjs';
3
- import { JxgRenderer } from './chunk-BKSXPNPQ.mjs';
2
+ import { paletteFor } from './chunk-M42TGYT6.mjs';
3
+ import { JxgRenderer } from './chunk-AYSFWUPK.mjs';
4
4
  import { renderJsxgOffscreen } from './chunk-ICR4CVOE.mjs';
5
- import { createStore } from './chunk-ZBJBQKJ2.mjs';
5
+ import { createStore } from './chunk-IHUFOV7L.mjs';
6
6
 
7
7
  // src/stamps/graph-2d/render.ts
8
8
  var DEFAULT_WIDTH = 600;
@@ -53,5 +53,5 @@ async function renderGraphSvgFromState(state, _isDark, width = DEFAULT_WIDTH, he
53
53
  }
54
54
 
55
55
  export { renderGraphSvgFromState };
56
- //# sourceMappingURL=chunk-LVNCYP4J.mjs.map
57
- //# sourceMappingURL=chunk-LVNCYP4J.mjs.map
56
+ //# sourceMappingURL=chunk-CJBLJUWG.mjs.map
57
+ //# sourceMappingURL=chunk-CJBLJUWG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stamps/graph-2d/render.ts"],"names":[],"mappings":";;;;;;AAUA,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,cAAA,GAAiB,GAAA;AAEvB,eAAsB,wBACpB,KAAA,EACA,OAAA,EACA,KAAA,GAAQ,aAAA,EACR,SAAS,cAAA,EACQ;AACjB,EAAA,MAAM,OAAA,GAAU,WAAW,KAAK,CAAA;AAChC,EAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AACnB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,KAAW,SAAA,GAAY,KAAK,IAAA,GAAO,IAAA;AACrD,EAAA,MAAM,IAAA,GAAyC;AAAA,IAC7C,MAAM,IAAA,IAAQ,GAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ;AAAA,GAChB;AACA,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,mBAAA,CAAoB;AAAA,MAC9C,IAAA;AAAA,MACA,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,MACtB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,eAAA,EAAiB,KAAA;AAAA,MACjB,YAAA,EAAc,CAAC,GAAA,KAAQ;AAErB,QAAA,MAAM,OAAQ,GAAA,CAAY,OAAA;AAC1B,QAAA,IAAI,CAAC,IAAA,EAAM;AACX,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,KAAK,OAAA,GAAU,UAAA;AACpB,QAAA,IAAA,CAAK,KAAK,cAAA,GAAiB,KAAA;AAC3B,QAAA,IAAA,CAAK,KAAK,UAAA,GAAa,KAAA;AACvB,QAAA,IAAA,CAAK,KAAK,QAAA,GAAW,KAAA;AACrB,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,KAAA;AAChC,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,EAAC;AAC5B,QAAA,IAAA,CAAK,MAAM,OAAA,GAAU,UAAA;AACrB,QAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,KAAA;AACjC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAChC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAAA,MAClC,CAAA;AAAA,MACA,KAAA,EAAO,CAAC,KAAA,KAAU;AAChB,QAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,QAAA,OAAO,IAAI,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,EAAA;AAAA,EACT;AACF","file":"chunk-LVNCYP4J.mjs","sourcesContent":["// src/stamps/graph-2d/render.ts\n// Offscreen SVG export từ graph2d State. Dùng cho insert/restore stamp.\n//\n// LƯU Ý: Luôn dùng light palette — Excalidraw tự invert trong dark mode.\nimport type { State } from '../../core/scene/types';\nimport { createStore } from '../../core/scene/store';\nimport { JxgRenderer } from '../../core/scene/render/JxgRenderer';\nimport { paletteFor } from './editor/theme';\nimport { renderJsxgOffscreen } from '../shared/jxgOffscreenRender';\n\nconst DEFAULT_WIDTH = 600;\nconst DEFAULT_HEIGHT = 400;\n\nexport async function renderGraphSvgFromState(\n state: State,\n _isDark: boolean,\n width = DEFAULT_WIDTH,\n height = DEFAULT_HEIGHT,\n): Promise<string> {\n const palette = paletteFor(false);\n const meta = state.meta;\n const view = meta.domain === 'graph2d' ? meta.view : null;\n const bbox: [number, number, number, number] = [\n view?.xMin ?? -10,\n view?.yMax ?? 10,\n view?.xMax ?? 10,\n view?.yMin ?? -10,\n ];\n try {\n const { svgString } = await renderJsxgOffscreen({\n bbox,\n dims: { width, height },\n axis: view?.showAxis ?? true,\n grid: view?.showGrid ?? true,\n keepAspectRatio: false,\n applyOptions: (JXG) => {\n \n const opts = (JXG as any).Options;\n if (!opts) return;\n opts.text = opts.text || {};\n opts.text.display = 'internal';\n opts.text.useASCIIMathML = false;\n opts.text.useMathJax = false;\n opts.text.useKatex = false;\n opts.text.strokeColor = palette.label;\n opts.label = opts.label || {};\n opts.label.display = 'internal';\n opts.label.strokeColor = palette.label;\n opts.axis = opts.axis || {};\n opts.axis.strokeColor = palette.axis;\n opts.grid = opts.grid || {};\n opts.grid.strokeColor = palette.grid;\n },\n setup: (board) => {\n const store = createStore(state);\n return new JxgRenderer(store, board);\n },\n });\n return svgString;\n } catch {\n // Match old contract: callers expect '' when no SVG produced.\n return '';\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/stamps/graph-2d/render.ts"],"names":[],"mappings":";;;;;;AAUA,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,cAAA,GAAiB,GAAA;AAEvB,eAAsB,wBACpB,KAAA,EACA,OAAA,EACA,KAAA,GAAQ,aAAA,EACR,SAAS,cAAA,EACQ;AACjB,EAAA,MAAM,OAAA,GAAU,WAAW,KAAK,CAAA;AAChC,EAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AACnB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,KAAW,SAAA,GAAY,KAAK,IAAA,GAAO,IAAA;AACrD,EAAA,MAAM,IAAA,GAAyC;AAAA,IAC7C,MAAM,IAAA,IAAQ,GAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ;AAAA,GAChB;AACA,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,mBAAA,CAAoB;AAAA,MAC9C,IAAA;AAAA,MACA,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,MACtB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,eAAA,EAAiB,KAAA;AAAA,MACjB,YAAA,EAAc,CAAC,GAAA,KAAQ;AAErB,QAAA,MAAM,OAAQ,GAAA,CAAY,OAAA;AAC1B,QAAA,IAAI,CAAC,IAAA,EAAM;AACX,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,KAAK,OAAA,GAAU,UAAA;AACpB,QAAA,IAAA,CAAK,KAAK,cAAA,GAAiB,KAAA;AAC3B,QAAA,IAAA,CAAK,KAAK,UAAA,GAAa,KAAA;AACvB,QAAA,IAAA,CAAK,KAAK,QAAA,GAAW,KAAA;AACrB,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,KAAA;AAChC,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,EAAC;AAC5B,QAAA,IAAA,CAAK,MAAM,OAAA,GAAU,UAAA;AACrB,QAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,KAAA;AACjC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAChC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAAA,MAClC,CAAA;AAAA,MACA,KAAA,EAAO,CAAC,KAAA,KAAU;AAChB,QAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,QAAA,OAAO,IAAI,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,EAAA;AAAA,EACT;AACF","file":"chunk-CJBLJUWG.mjs","sourcesContent":["// src/stamps/graph-2d/render.ts\n// Offscreen SVG export từ graph2d State. Dùng cho insert/restore stamp.\n//\n// LƯU Ý: Luôn dùng light palette — Excalidraw tự invert trong dark mode.\nimport type { State } from '../../core/scene/types';\nimport { createStore } from '../../core/scene/store';\nimport { JxgRenderer } from '../../core/scene/render/JxgRenderer';\nimport { paletteFor } from './editor/theme';\nimport { renderJsxgOffscreen } from '../shared/jxgOffscreenRender';\n\nconst DEFAULT_WIDTH = 600;\nconst DEFAULT_HEIGHT = 400;\n\nexport async function renderGraphSvgFromState(\n state: State,\n _isDark: boolean,\n width = DEFAULT_WIDTH,\n height = DEFAULT_HEIGHT,\n): Promise<string> {\n const palette = paletteFor(false);\n const meta = state.meta;\n const view = meta.domain === 'graph2d' ? meta.view : null;\n const bbox: [number, number, number, number] = [\n view?.xMin ?? -10,\n view?.yMax ?? 10,\n view?.xMax ?? 10,\n view?.yMin ?? -10,\n ];\n try {\n const { svgString } = await renderJsxgOffscreen({\n bbox,\n dims: { width, height },\n axis: view?.showAxis ?? true,\n grid: view?.showGrid ?? true,\n keepAspectRatio: false,\n applyOptions: (JXG) => {\n \n const opts = (JXG as any).Options;\n if (!opts) return;\n opts.text = opts.text || {};\n opts.text.display = 'internal';\n opts.text.useASCIIMathML = false;\n opts.text.useMathJax = false;\n opts.text.useKatex = false;\n opts.text.strokeColor = palette.label;\n opts.label = opts.label || {};\n opts.label.display = 'internal';\n opts.label.strokeColor = palette.label;\n opts.axis = opts.axis || {};\n opts.axis.strokeColor = palette.axis;\n opts.grid = opts.grid || {};\n opts.grid.strokeColor = palette.grid;\n },\n setup: (board) => {\n const store = createStore(state);\n return new JxgRenderer(store, board);\n },\n });\n return svgString;\n } catch {\n // Match old contract: callers expect '' when no SVG produced.\n return '';\n }\n}\n"]}
@@ -1,13 +1,13 @@
1
1
  "use client";
2
- import { renderGraphSvgFromState } from './chunk-LVNCYP4J.mjs';
2
+ import { renderGraphSvgFromState } from './chunk-CJBLJUWG.mjs';
3
3
  import { isGraph2DCustomData } from './chunk-O4WIZFRQ.mjs';
4
- import { parseSceneState } from './chunk-IBTRMWD6.mjs';
4
+ import { parseSceneState } from './chunk-I24QOHPU.mjs';
5
5
  import { svgToStampFile } from './chunk-5UTGXHLJ.mjs';
6
6
  import { lazy } from 'react';
7
7
  import { jsxs, jsx } from 'react/jsx-runtime';
8
8
 
9
9
  var Graph2DStampHost = lazy(
10
- () => import('./host-GKNQBBUE.mjs').then((m) => ({ default: m.Graph2DStampHost }))
10
+ () => import('./host-QK53UYMD.mjs').then((m) => ({ default: m.Graph2DStampHost }))
11
11
  );
12
12
  var Graph2DIcon = /* @__PURE__ */ jsxs(
13
13
  "svg",
@@ -57,5 +57,5 @@ var graph2dStamp = {
57
57
  };
58
58
 
59
59
  export { graph2dStamp };
60
- //# sourceMappingURL=chunk-YIPI3WUL.mjs.map
61
- //# sourceMappingURL=chunk-YIPI3WUL.mjs.map
60
+ //# sourceMappingURL=chunk-ESVPQWHX.mjs.map
61
+ //# sourceMappingURL=chunk-ESVPQWHX.mjs.map